
#include "globals.h"
#include <stdio.h>


#include <math.h>    
#include "arm_math.h"

unsigned short ADCSamples[2][100];
unsigned int   ADCPage = 0;

float32_t ADC_Average_Samples (int page);

/*----------------------------------------------------------------------------
 *        Task 'ADC_Sample_Task': Record ADC Samples
 *---------------------------------------------------------------------------*/
__task void ADC_Sample_Task (void) {
    int isamp = 0;


    while(1) {
        os_dly_wait(1);
        if (++isamp == 100) {
            if (ADCPage == 1) {
                ADCPage = 0;
                os_evt_set(0x0002, idADC_Calc_Task);
            } else {
                ADCPage = 1;
                os_evt_set(0x0001, idADC_Calc_Task);
            }
            isamp = 0;
        }
		
        ADCSamples[ADCPage][isamp] = GetValADC();			/* Put ADC Data Register contents into AD_value */
		

    }
}

/*----------------------------------------------------------------------------
 *        Task 'ADC_Calc_Task': Do Calculation on ADC Samples
 *---------------------------------------------------------------------------*/
__task void ADC_Calc_Task (void) {
    char* Message;
    U16 ret_flags;
    float32_t variance;

    while(1) {

        os_evt_wait_or(0x0003, 0xFFFF);	  // wait for event flasgs to occur
        ret_flags = os_evt_get ();		  // read back the flags to determine which array to process
		variance = ADC_Average_Samples(ret_flags - 1);  //process the ready sample array

        do {
            Message = _alloc_box(mpoolCom);		 // allocate memory (125bytes) from mpoolcom, if available
												 // initialises the pointer to the start of this block
        }  while(!Message);						 // we wait here until we get memory allocated
        sprintf (Message, "ADC Variance over 100 Samples is: %f \n", variance);
        printf ("%s", Message);
		_free_box(mpoolCom, Message);			// after the message has been sent
												// the allocated memory is released
    }

}



/* ----------------------------------------------------------------------
* Defines each of the tests performed
* ------------------------------------------------------------------- */
#define MAX_BLOCKSIZE	100
#define DELTA           (0.000001f)


/* ----------------------------------------------------------------------
* Declare I/O buffers 
* ------------------------------------------------------------------- */
float32_t wire1[MAX_BLOCKSIZE];
float32_t wire2[MAX_BLOCKSIZE];
float32_t wire3[MAX_BLOCKSIZE];

/* ----------------------------------------------------------------------
* Declare Global variables 
* ------------------------------------------------------------------- */
uint32_t blockSize = 100;

/*----------------------------------------------------------------------------
 *        Utility function to average samples
 *---------------------------------------------------------------------------*/
float32_t ADC_Average_Samples (int page) {
    int i;
    float fvoltage[100];
	float32_t mean, oneByBlockSize;
	float32_t variance;

    for (i=0; i < 100; ++i) {
        fvoltage[i] = 3.3f * ((ADCSamples[page][i]) / 0xCFF);
    }

	/* Calculation of mean value of input */
	
	/* x' = 1/blockSize * (x(0)* 1 + x(1) * 1 + ... + x(n-1) * 1) */
	
	/* Fill wire1 buffer with 1.0 value */
	arm_fill_f32(1.0,  wire1, blockSize);
	
	/* Calculate the dot product of wire1 and wire2 */
	/* (x(0)* 1 + x(1) * 1 + ...+ x(n-1) * 1) */
	arm_dot_prod_f32(fvoltage, wire1, blockSize, &mean);
	
	/* Calculation of 1/blockSize */
	oneByBlockSize = 1.0 / (blockSize);
	
	/* 1/blockSize * (x(0)* 1 + x(1) * 1 + ... + x(n-1) * 1)  */
	arm_mult_f32(&mean, &oneByBlockSize, &mean, 1);
	
	
	/* Calculation of variance value of input */
	
	/* (1/blockSize) * (x(0) - x') * (x(0) - x') + (x(1) - x') * (x(1) - x') + ... + (x(n-1) - x') * (x(n-1) - x') */
	
	/* Fill wire2 with mean value x' */
	arm_fill_f32(mean,  wire2, blockSize);
	
	/* wire3 contains (x-x') */		
	arm_sub_f32(fvoltage, wire2, wire3, blockSize);
	
	/* wire2 contains (x-x') */				
	arm_copy_f32(wire3, wire2, blockSize);
	
	/* (x(0) - x') * (x(0) - x') + (x(1) - x') * (x(1) - x') + ... + (x(n-1) - x') * (x(n-1) - x') */
	arm_dot_prod_f32(wire2, wire3, blockSize, &variance); 

    /* Calculation of 1/blockSize */
	oneByBlockSize = 1.0 / (blockSize - 1);

	/* Calculation of variance */		
	arm_mult_f32(&variance, &oneByBlockSize, &variance, 1);
	
	return (variance);

}





