/* GLOBAL VARIABLES */

#define NUM_RESULTS 880         //Number of samples stored per buffer side
#define NUM_DATA_BITS 16        //Number of bits to transmit (currently 16 for test purpose)
#define NUM_DELIM_BITS 22       //Number of bits in sync sequence
#define NUM_MANCH_BITS 22       //Number of bits in manchester encoded sync sequence
#define ALTPADDING 154          //Number of alternating 1/0 bits to transmit as padding in packet (for test)
#define ZEROPADDING 32          //Number of 0s to transmit as padding in packet (for testing)
#define PACKET_SIZE 80         //Size of the data packet payload (80*8bits = 640)
#define RUN_TESTS = 1;
//ALTPADDING 160
int awakeMode = 0;              //Flag indicating we should transmit the initial "awake" packet.
int bitError = 0;               //Count number of bit errors detected in getData()
int bitNumber = 0;              //Number of the bit in the byte we are receiving
int bytesDetected = 0;		//Number of data bits detected used in getData().
int byteValue = 0;              //Value of the byte we will store in the data[] array

int buffRecvd = 0;		//Number of total buffers recieved .
int counterPos = 0;             //Keeps track of position in packetNumber.
int dataStart = 0;	        //Indexes where data begins after sync sequence.
int dataMode =0;		//Flag indicating we should be detecting packet data (instead of sync sequence bits).
int delay = 0;			//Universal counter variable to inject delay time. 
int echoMode = 0;		//Flag indidcating we should be echoing recieved data back (currently not used). 
int errorFlag = 0;
unsigned int findCounter = 0;		//Total number of sync sequences found.
int maskedPacketNumber = 0;     //128 or 0 to output PacketNumber (not currently used).
//int numBitsWanted = 0;
int newSyncMode = 0;		//Flag indicating we should sync again after a full packet is recieved (possibly deprecated) 
int partialByteCounter = 0;     //Number of bits stored for the byte wrapping around the end of the buffer
int packetNumber = 0x00;	//Numbers the outgoing packet
unsigned int packetsSent = 0;		//Number of packets transmitted
int packetShifted = 0;          //Number of packets shifted out of phase
int peakToPeak = 0;		//Difference in value between ADC samples at n, and n+2.
int prevPeakToPeak = 0;		//previous peakToPeak value
int resultsEnd = 1759;          //Index of the final value in the results buffer
int reSyncSamples = 0;		//Counts the number of samples recieved in newSyncMode
int RX = 0;			//Flag indicating we are in receiving mode
int samplesPerBit = 4; //8	//Number of ADC samples per each manchester data bit
int sequenceOverflows = 0;
int shift = 0;			//Shift to mask packetNumber output
int side = 0;			//Indicates which side of the ping-pong RX buffer to process (0 or 1). 
int threshold = 800;		//Threshold value to determine whether an ADC samples is high (1), or low (0). Set in computeThrsehold().
int timer_B_counter = 100;//200;	//Counter for Timer B
int timeoutMode = 0;		//Flag indiacting that too much time has passed since the last RX buffer, so the "awake" sequence should be resent.
int transmitCounter = 0;	//Number of packets transmitted
int TX = 1;			//Flag indicating we are in transmit mode. 
int toggle = 0;			//Toggle previous bit to create Manchester sequence
int timeoutOverflow = 0;	//Number of times timeout threshold has been reached. 

unsigned int timeoutCount = 0;	//Counter for timeout
unsigned int cycleCount = 0;	// (possibly deprecated) 

long long manchSequence = 0xCCC333C33C3;	//Manchester sequence with 4 sampels per chip in hex format

/* GLOBAL BUFFERS */

int results[2*NUM_RESULTS];		//ADC results buffer. Written to by DMA.
//int newSyncBuff[84];			//Buffer used in newSyncMode to find the sequence again
int sequence[NUM_DELIM_BITS] = {1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,1};	// Synchronization sequence in array form(possibly deprecated) 
int barker[NUM_MANCH_BITS] = {1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,1}; // Manchester Synchronization sequence in array form
int awake[32] = {-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,1,-1};	//"Awake" Message
volatile int data[PACKET_SIZE]; //64		//Array storing bits of received data
unsigned int packNums[11];
int partialByte[32];


//Temp variables
int originalStart = 0;
int originalStartsweep = 0;
long long storedCorrelation = 0;
long long tempCorrelation = 0;
int correlationDifference = 0;
int correlationStart = 0;
int oneOff = 0;
int allOff = 0;

//Variables for computing Hamming distance
const long long m1  = 0x5555555555555555; //binary: 0101...
const long long m2  = 0x3333333333333333; //binary: 00110011..
const long long m4  = 0x0f0f0f0f0f0f0f0f; //binary:  4 zeros,  4 ones ...
const long long m8  = 0x00ff00ff00ff00ff; //binary:  8 zeros,  8 ones ...
const long long m16 = 0x0000ffff0000ffff; //binary: 16 zeros, 16 ones ...
const long long m32 = 0x00000000ffffffff; //binary: 32 zeros, 32 ones
const long long hff = 0xffffffffffffffff; //binary: all ones
const long long h01 = 0x0101010101010101; //the sum of 256 to the power of 0,1,2,3...

/* FUNCTION DECLARATIONS */

void Clock_Init(void);				//Sets MCLK, SMCLK, and ALCK frequencies
int computeThreshold(int start, int end);	//Computes the average value in the results[] buffer between (start) and (end). 
void DMA_Init(void);				//Sets DMA registers to store ADC results
int findSequence(int start, int end);		//Searches for sync sequence in results[] between (start) and (end)
int getData(int bufStart, int bufEnd);		//Translates data bits from samples in results[] between (bufStart) and (bufEnd)
int getPackNum(void);                           //Get the number of the packet recieved
int popcount(long long x);
int reSync(int offset_);			//Looks for sync sequence starting at offset_ (possibly deprecated).
void RX_ON(void);				//Sets required regsisters for receiving data and resets registers used to transmit.
long long translate(int start, int length);	//Converts samples in results[] to string form for efficient comparison.
long long transSansThresh(int start, int length);
int runUnitTests(int tests);
void TX_ON(void);				//Sets required regsisters for transmitting data and resets registers used to receive. 

