/*
 * main.c
 *
 *  Created on: Dec 19, 2014
 *      Author: hutch
 */

#include <stdio.h>
//#include "platform.h"
#include "supportFiles/leds.h"
#include "supportFiles/globalTimer.h"
#include "supportFiles/interrupts.h"
#include "supportFiles/intervalTimer.h"
#include "supportFiles/buttons.h"
#include "supportFiles/switches.h"
#include <stdbool.h>
#include <stdlib.h>
#include "isr.h"

//#include "queue.h"

//#include "xparameters.h"

//#include "filter.h"
//#include "histogram.h"
//#include "detector.h"
//#include "transmitter.h"

//queue_t zQueue;
#define Z_QUEUE_SIZE 1000

#define TOTAL_SECONDS 10

int main() {

//    init_platform();
#ifdef INTERVALTIMER_H_
	intervalTimer_initAll();
	intervalTimer_resetAll();
	intervalTimer_testAll();
#endif

//	transmitter_runTest();
//	exit(0);

	printf("Laser Tag Test Program\n\r");
	// Find out how many timer ticks per second.
	u32 privateTimerTicksPerSecond = interrupts_getPrivateTimerTicksPerSecond();
	printf("private timer ticks per second: %ld\n\r", privateTimerTicksPerSecond);
	// Initialize the GPIO LED driver and print out an error message if it fails (argument = true).
	leds_init(true);
//	transmitter_init();
	// Init all interrupts (but does not enable the interrupts at the devices).
	// Prints an error message if an internal failure occurs because the argument = true.
	interrupts_initAll(true);
	interrupts_enableTimerGlobalInts();
	// Start the private ARM timer running.
	interrupts_startArmPrivateTimer();
	printf("This program will run for %d seconds, run the filters and print out statistics at the end of the run.\n\r",
			TOTAL_SECONDS);
	printf("Starting timer interrupts.\n\r");
	//	interrupts_enableSysMonEocInts();  // Enable EOC interrupts and count their occurrences.
	// Enable global interrupt of System Monitor.
	interrupts_enableSysMonGlobalInts();
#ifdef INTERVALTIMER_H_
	// Start a duration timer and compare its timing against the time computed by the timerIsr().
	intervalTimer_start(1);
#endif
	int countInterruptsViaInterruptsIsrFlag = 0;
	// Wait until TOTAL seconds have expired. globalTimerTickCount is incremented by timer isr.
//	int sampleCount = 0;
//	filter_init();
	isr_init();
	// Enable interrupts at the ARM.
	interrupts_enableArmInts();
	while (interrupts_isrInvocationCount() < (TOTAL_SECONDS * privateTimerTicksPerSecond)) {
		if (interrupts_isrFlagGlobal) {
			countInterruptsViaInterruptsIsrFlag++;
			interrupts_isrFlagGlobal = 0;
//			detector_tick();	// Power is computed, still need to find the channel with the max power.
			// Transmitter state machine is invoked in the timer ISR so it gets called precisely.
//			if (buttons_read() & BUTTONS_BTN0_MASK) {
//				transmitter_start();
//				uint16_t switchValue = switches_read();
//				transmitter_setFrequencyNumber(switchValue);
//			} else
//				transmitter_stop();
//			transmitter_tick();
//			queue_size_t elementCount = interrupts_getAdcSampleCount();
//			for (queue_size_t i=0; i<elementCount; i++) {		// Always drain the ADC queue.
//				interrupts_disableArmInts();
//				filter_addNewInput(interrupts_popAdcData());	// Copy the input into the main filter input queue.
//				interrupts_enableArmInts();
//				sampleCount++;
//				if (sampleCount == FILTER_FIR_DECIMATION_FACTOR) {	      // Only invoke the filters after every DECIMATION_FACTOR times.
//					sampleCount = 0;
//					filter_firFilter();																			// Runs the filter on the accumulated input and places the output in the y-queue.
//					for (int filterNumber=0; filterNumber<FILTER_IIR_FILTER_COUNT; filterNumber++) {
//						filter_iirFilter(filterNumber);
//						filter_computePower(filterNumber);
//					}
//				}
//			}
		}
	}
	interrupts_disableArmInts();
#ifdef INTERVALTIMER_H_
 	intervalTimer_stop(1);
#endif
//	histogram_init();
//	for (int i=0; i<HISTOGRAM_BAR_COUNT; i++) {
//		histogram_setBarData(i, i*22);
//	}
//	histogram_runTest();

    interrupts_disableArmInts();
//  	printf("elements remaining in ADC queue:%ld\n\r", isr_adcQueueElementCount());

#ifdef INTERVALTIMER_H_
	double runningSeconds, isrRunningSeconds;
	intervalTimer_getTotalDurationInSeconds(1, &runningSeconds);
	printf("Measured run time by interval timer in seconds: %g.\n\r", runningSeconds);
	intervalTimer_getTotalDurationInSeconds(0, &isrRunningSeconds);
	printf("Measured run time in timerIsr (using interval timer): %g.\n\r", isrRunningSeconds);
	printf("Detected interrupts via global flag: %d\n\r", countInterruptsViaInterruptsIsrFlag);
#endif
    printf("During %d seconds, an average of %7.3f ADC samples were collected per second.\n\r",
    		TOTAL_SECONDS, (float) isr_getTotalAdcSampleCount() / (float) TOTAL_SECONDS);
#ifdef QUEUE_H_
//   printf("The last captured ADC samples are printed below.\n\r");
//   queue_t* adcDataQueue1 = getAdcDataQueue1();
//   queueSize_t bufferSize = queue_size(adcDataQueue1);
//   queueSize_t elementsPushed = queue_elementsPushed(adcDataQueue1);
//   printf("bufferSize->%ld\r\n", bufferSize);
//   printf("elements pushed->%ld\r\n", elementsPushed);
#endif
//#define Z_OUTPUT_QUEUE_SIZE 5000
//   queue_t zOutputQueue[FILTER_IIR_FILTER_COUNT];
//   for (int i=0; i<FILTER_IIR_FILTER_COUNT; i++)
//  	 queue_init(&(zOutputQueue[i]), Z_OUTPUT_QUEUE_SIZE);
////   filter_runTest(true);
//   filter_init();
//   intervalTimer_reset(1);
//   intervalTimer_start(1);
//   for (unsigned int i=0; i<bufferSize; i++) {
//  	 filter_addNewInput(queue_readElementAt(adcDataQueue1, i));	// Copy the input into the main filter input queue.
//  	 if (i%FILTER_FIR_DECIMATION_FACTOR == 0) {	                // Only invoke the filters after every DECIMATION_FACTOR times.
//  		 filter_firFilter();																			// Runs the filter on the accumulated input and places the output in the y-queue.
//  		 for (int filterNumber=0; filterNumber<FILTER_IIR_FILTER_COUNT; filterNumber++) {
//  			 filter_iirFilter(filterNumber);
//  		 	 filter_computePower(filterNumber);
//  		 }
//  	 }
//   }
//   intervalTimer_stop(1);
//   intervalTimer_getTotalDurationInSeconds(1, &isrRunningSeconds);
//   printf("Measured run time in filters (using interval timer): %g.\n\r", isrRunningSeconds);
//
   return 0;
}







