/*
 * filter.h
 *
 *  Created on: Dec 6, 2015
 *      Author: Manish Patel, Dan Eddowes
 */

#include <GenericTypeDefs.h>
typedef signed int fix16;

//Blocking Delay Macro using Protothreads timing
#define delayMS(x) {UINT32 init = PT_GET_TIME(); while ((PT_GET_TIME() - init)<(x));}

//System Definitions
#define SCREEN_HEIGHT	ILI9340_TFTHEIGHT   //Touch Screen Dimensions
#define SCREEN_WIDTH	ILI9340_TFTWIDTH
#define WHITE           ILI9340_WHITE       //Touch Screen Colors
#define BLUE            ILI9340_BLUE
#define BLACK           ILI9340_BLACK
#define GREEN           ILI9340_GREEN
#define BIGRED          ILI9340_RED

//Fixed Point Functions
#define multfix16(a,b)  ((fix16)(((( signed long long)(a))*(( signed long long)(b)))>>16)) //multiply two fixed 16:16
#define float2fix16(a)  ((fix16)((a)*65536.0)) // 2^16
#define fix2float16(a)  ((float)(a)/65536.0)
#define fix2int16(a)    ((int)((a)>>16))
#define int2fix16(a)    ((fix16)((a)<<16))
#define divfix16(a,b)   ((fix16)((((signed long long)(a)<<16)/(b))))
#define sqrtfix16(a)    (float2fix16(sqrt(fix2float16(a))))
#define absfix16(a)     abs(a)

typedef signed int fix32 ;
#define multfix32(a,b) ((fix32)(((( signed long long)(a))*(( signed long long)(b)))>>30)) //multiply two fixed 2:30
#define float2fix32(a) ((fix32)((a)*1073741824.0)) // 2^30
#define fix2float32(a) ((float)(a)/1073741824.0) 

//System Function Definitions
void resetScreen(void);
void startTimers(void);

//Text Update Functions
void updateFreqText(char p);
void updateAmpText(char p);

//Drawing Helper Functions
void centerTxt(int height, int col, int colnum);
void drawHDash(int pos);
void drawVDash(int pos);
void drawForwardBack(void);
void drawBandStartError(void);
void drawTransitionError(void);

//State Drawing Functions
void drawState_Start(void);
void drawFFT_Select_State(void);
void drawAmp_Freq(void);
void drawFFT_Draw_State(void);
void drawFWT_Menu_State(void);
void drawInstruction(void);
void drawProcess_Input(void);
void drawCompute(void);

//Input Processing Functions
void findBodeNonZero(void);
void linearInterpolate(void);
void filterMovAvg(void);
void filterMedian(void);
void discreteDerivative(void);
void conditionCheck(void);
void scaleBands(void);

//PM Functions
void pm(long double a, long double b, long double bands[], long double amp[], int numberBands, fix16 h[]);
void initLagrange(long double interpX[]);
void initOsc(long double osc[]);
void initAmpDes(long double ampDes[], long double interpX[], long double bands[], long double amp[]);
void getExtremalFreqs(long double bands[], long double amp[], long double extremalX[], long double extremalY[]);
void sortIndices(int nodesPerBand[], int sortedNumNodes[]);
void selSort(long double array[], int length);
void selSortInt(int array[], int length);
void generateYk(long double extremalX[], long double yk[]);
long double computeDelta(long double yk[], long double extremalY[], long double osc[]);
void lagrange(long double extremalX[], long double newAmp[], long double interpX[], long double interpY[]);
void computeError(long double ampDes[], long double interpY[], long double error[]);
void localMaxAndMin(long double array[], long double bands[], long double interpX[], int result[], int length, int resultLength);
void diff(long double array[], long double result[], int length);
void initArrayMatrix(long double wk[], long double osc[], long double A[]);
void doolittle(int d, long double A[], long double LU[]);
void solveDoolittle(int d, long double LU[],long double b[],long double x[]);

//FFT Functions
void filterDesign();

//Variable Definitions
char buffer[40];
volatile static int ADC_value = 0;
static UINT16 ADC_PDR[6] = {0,25000,2500,500,250,125};

//Bode Plot
static UINT16 bode[320], xNZ[320], yNZ[320], ddx[80];
static int xband[6], yband[6];
static UINT16 x, y, numNZ, errorflg = 0;
static long double XBAND[6], YBAND[6];
static int numBands;

static int tmpADC_val;

//PM Variables
static fix16 h[70];
static int hLength;

//FFT Variables
static float M[33];

//Drawing
static UINT16 x_pos, y_pos;  

//Counters
static UINT8 k, u;
static UINT16 i, j, p; 

//Input Variables
static UINT8 max_freqmag = 0;
static UINT8 prev_freqsel = 0, prev_ampsel = 0;
static UINT16 max_freqval, max_ampval;
static UINT16 freqTbl[6] = {0,100,1000,5000,10000,20000};
volatile static UINT16 stopFilter = 0;

// Filtering variables
volatile static int newValAvail = 0;
//static int index = 0;
volatile static int DAC_VALUE;
