/*

 ===============================================================================

 Name        : main.c

 Author      : $(author)

 Version     :

 Copyright   : $(copyright)

 Description : main definition

 ===============================================================================

 */



#include <cr_section_macros.h>

#include <stdio.h>

#include <string.h>

#include "board.h"

#include "scheduler.h"

#include "gram_usb_cdc_api.h"

#include "gram_pwm_adc_sampling.h"

#include "gram_beep.h"

#include "gram_buffer.h"

#include "gram_aux.h"

#include "gram_fft.h"

#include "gram_motor_control.h"

#include "tictoc.h"





#define TICKRATE_HZ			(100)		// systick interrupt frequency

#define BEEP_NOTIFY	beep_pulse(40, 6000, 30)



/*****************************************************************************

 * Private types/enumerations/variables

 ****************************************************************************/







/*****************************************************************************

 * Public types/enumerations/variables

 ****************************************************************************/



volatile int USB_tick_count = 0;	// Debug variable

uint8_t buf_str[128];				// Buffer used for string operations



// Buffer for fft of piezo samples

buffer_lin_t FFT_PiezoBuffer = {

		.buffer_size = FFT_LEN,

};



// Buffers used to send measured data

uint16_t PongBufferCurrentData[ADC_CURRENT_SAMPLES_N];

buffer_lin_t PongBufferCurrent={

		.p_data = &PongBufferCurrentData[0],

		.buffer_size = ADC_CURRENT_SAMPLES_N

};

uint16_t PongBufferPiezoData[ADC_PIEZO_SAMPLES_N];

buffer_lin_t PongBufferPiezo={

		.p_data = &PongBufferPiezoData[0],

		.buffer_size = ADC_PIEZO_SAMPLES_N

};



// flags

uint8_t SendPongBufferCurrent = 0;

uint8_t SendPongBufferPiezo = 0;

uint8_t SendSampledCurrentData = 0;

uint8_t SendSampledPiezoData = 0;

uint8_t SendFFT_PiezoData = 0;

uint8_t SendFFT_CurrentData = 0;



/*****************************************************************************

 * Private functions

 ****************************************************************************/



/*****************************************************************************

 * Public functions

 ****************************************************************************/



uint16_t timer_btn_a;

uint16_t timer_btn_b;



void EINT3_IRQHandler(void)

{

	if ( Chip_GPIOINT_GetStatusFalling(LPC_GPIOINT, GPIOINT_PORT2) & (1UL << BTN_A_GPIO_BIT_NUM) ){

		Chip_GPIOINT_ClearIntStatus(LPC_GPIOINT, GPIOINT_PORT2, 1UL << BTN_A_GPIO_BIT_NUM);

		LPC_GPIOINT->IO2.ENR &= ~(1UL << BTN_A_GPIO_BIT_NUM);	// Disable this interrupt

		ResetDelay(&timer_btn_a);	// Start timer to enable interrupt

		SPP_CMD_BtnA_Pushed();

		//Board_LED_Toggle(LEDS_LED_B);

	}

	if ( Chip_GPIOINT_GetStatusFalling(LPC_GPIOINT, GPIOINT_PORT2) & (1UL << BTN_B_GPIO_BIT_NUM) ){

		Chip_GPIOINT_ClearIntStatus(LPC_GPIOINT, GPIOINT_PORT2, 1UL << BTN_B_GPIO_BIT_NUM);

		LPC_GPIOINT->IO2.ENR &= ~(1UL << BTN_B_GPIO_BIT_NUM);	// Disable this interrupt

		ResetDelay(&timer_btn_b);	// Start timer to enable interrupt

		SPP_CMD_BtnB_Pushed();

		//Board_LED_Toggle(LEDS_LED_B);

	}



	//Board_LED_Toggle(0);

}



void SysTick_Handler(void) {

	TickCounter++;

}



void task_1s(void) {

	/*sprintf((char *) buf_str, (char *) "USB tick count per second is %d\r\n\0",

			USB_tick_count);*/

	//usb_printstr(buf_str);



	uint16_t tmp = MotorGetSpeedSet();

	static int8_t dir = 1;

	if(dir){

		tmp += 50;

		if (tmp >= 2100){

			dir = 0;

		}

	}

	else{

		tmp -= 50;

		if (tmp <= 500){

			dir = 1;

		}

	}

	//MotorSetSpeed(tmp);

}



void USB_SendDataTask(void) {

	if (SendPongBufferCurrent){

		static uint8_t TaskID = 0;

		if (TaskID == 0){

			TaskID = USB_SPP_AddDataTask(&PongBufferCurrent, 30);

		}

		else{

			if ( USB_SPP_DataTaskIsDone(TaskID) ){

				//USB_tick_count = Toc(5);

				//if (Toc(5) > 150406)	//todo: monitor this

				//	halt();

				TaskID = 0;

				SendPongBufferCurrent = 0;

			}

		}

	}

	if (SendPongBufferPiezo){

		static uint8_t TaskID = 0;	// TaskID 0 means that it has no task assigned yet

		if (TaskID == 0){

			TaskID = USB_SPP_AddDataTask(&PongBufferPiezo, 31);

		}

		else{

			if ( USB_SPP_DataTaskIsDone(TaskID) ){

				//USB_tick_count = Toc(5);

				//if (Toc(5) > 150406)	//todo: monitor this

				//	halt();

				TaskID = 0;

				SendPongBufferPiezo = 0;

			}

		}

	}

}



int main(void) {

	// Read clock settings and update SystemCoreClock variable

	SystemCoreClockUpdate();

	// Initialize GPIO, Buttons, LEDs...

	Board_Init();

	// Initizlize USB stack

	usb_init();

	// Initialize USB Simple Packet Protocol

	USB_SPP_Init();

	// Initialize stopwatch module

	TicTocInit(LPC_TIMER3);

	// Initialize systick

	SysTick_Config(SystemCoreClock / TICKRATE_HZ);

	// Initialize beeper (PWM)

	beep_init(10);

	// initialize motor PWM, and sampling = ADC, TMR0, TMR1

	PWM_SamplingInit();

	MotorPWM_DutySet(0);



	// Enable GPIO interrupts on BTN1 and BTN2

	Chip_GPIOINT_SetIntFalling(LPC_GPIOINT, GPIOINT_PORT2, 1 << BTN_A_GPIO_BIT_NUM);

	Chip_GPIOINT_SetIntFalling(LPC_GPIOINT, GPIOINT_PORT2, 1 << BTN_B_GPIO_BIT_NUM);

	NVIC_ClearPendingIRQ(EINT3_IRQn);

	NVIC_EnableIRQ(EINT3_IRQn);	// EINT3 is shared with GPIO interrupts



	MotorInit();

	MotorSetSpeed(0);



	// Scheduler counters

	uint16_t timer_led_a;

	ResetDelay(&timer_led_a);

	uint16_t timer_1s_task;

	ResetDelay(&timer_1s_task);

	uint16_t timer_beep;

	ResetDelay(&timer_beep);

	uint16_t timer_start_delay;

	ResetDelay(&timer_start_delay);



	Chip_GPIO_SetPinDIR(LPC_GPIO, 0, 0, 1);

	Chip_GPIO_SetPinDIR(LPC_GPIO, 0, 1, 1);

	Chip_GPIO_SetPinDIR(LPC_GPIO, 1, 19, 1);

	Chip_GPIO_SetPinDIR(LPC_GPIO, 1, 20, 1);

	// set direction of motor rotation

	Chip_GPIO_SetPinState(LPC_GPIO, 1, 19, 0);

	Chip_GPIO_SetPinState(LPC_GPIO, 1, 20, 1);



	SamplingPiezoStart();

	SamplingCurrentStart();



	while (1) {

		// LED blinky task

		if (HasDelayElapsed(50, &timer_led_a, true))

			Board_LED_Toggle(LEDS_LED_A);

		// 1s periodic task for whatever

		if (HasDelayElapsed(100, &timer_1s_task, true))

			task_1s();

		// beeper task - 10ms

		if (HasDelayElapsed(1, &timer_beep, true))

			beep_task();



		if ( !(Chip_GPIOINT_GetIntFalling(LPC_GPIOINT, GPIOINT_PORT2) & 1<<BTN_A_GPIO_BIT_NUM) && HasDelayElapsed(5, &timer_btn_a, false) )

			Chip_GPIOINT_SetIntFalling(LPC_GPIOINT, GPIOINT_PORT2, 1 << BTN_A_GPIO_BIT_NUM);

		if ( !(Chip_GPIOINT_GetIntFalling(LPC_GPIOINT, GPIOINT_PORT2) & 1<<BTN_B_GPIO_BIT_NUM) && HasDelayElapsed(5, &timer_btn_b, false) )

			Chip_GPIOINT_SetIntFalling(LPC_GPIOINT, GPIOINT_PORT2, 1 << BTN_B_GPIO_BIT_NUM);



		// Sending data from buffers to SPP

		USB_SendDataTask();

		// USB Simple Packet Protocol task

		USB_SPP_task();



		// Startup delay: 3s

		if (HasDelayElapsed(300, &timer_start_delay, false)) {

			static uint8_t once = 1;

			if (once){

				once = 0;

			}

		}

		// Handle finished measurement

		if (SamplingCurrentIsDone()){

			uint16_t i;

			for (i=0; i<ADC_CURRENT_SAMPLES_N; i++){

				PongBufferCurrent.p_data[i] = ADC_Motor_Current_Buffer.p_data[i];

			}

			BufferLinSetFull(&PongBufferCurrent);



			if ( USB_SPP_CurrentDataRequestIsActive() ){

				// There is a request to send data

				if (SendPongBufferCurrent == 0){

					// Data sending is not in progress

					SendPongBufferCurrent = 1;

					Tic(5);

				}

				else{

					//halt();

				}

			}



			SamplingCurrentStart();

			Tic(4);



			AnalyzeMotorCurrent();

			//USB_tick_count =

			//MotorGetSpeedActual();

			Motor_PID_Task();

		}

		if (SamplingPiezoIsDone()){

			uint16_t i;

			for (i=0; i<ADC_PIEZO_SAMPLES_N; i++){

				PongBufferPiezo.p_data[i] = ADC_Motor_Piezo_Buffer.p_data[i];

			}

			BufferLinSetFull(&PongBufferPiezo);



			if ( USB_SPP_PiezoDataRequestIsActive() ){

				// There is a request to send data

				if (SendPongBufferPiezo == 0){

					// Data sending is not in progress

					SendPongBufferPiezo = 1;

				}

				else{

					//halt();

				}

			}

			AnalyzeMotorVibration();

			SamplingPiezoStart();

		}

	}

	return 0;

}



 // 5,31 - piezo

 // 6,30 - current

 // 7,32 - FFT piezo

