/*
 * TaskExecuter.c
 *
 * Created: 22.2.2016 23:04:31
 *  Author: Chenda
 */ 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
#include <stdbool.h>
#include "conf/config.h"
#include "conf/conf_brd.h"

/*  API  */
#include "modules/API_common_defs.h"
#include "modules/uart/UART_API_Layer.h"
#include "modules/regulator/REG_API_Layer.h"

#include "Common/PeipherialFunctions.h"

#include "DebugSettings.h"
#include "DeviceStatus.h"
#include "Command_defs.h"
#include "TaskExecuter.h"
#include "Command_proc.h"

#include <util/delay.h>

/************************************************************************/
/* Global variable declaration                                          */
/************************************************************************/
//static volatile U8 cpt_sof;
//static volatile bool Next100ms;

static struct stApplicationStructure stAppStruct;
static struct stApplicationStructure *spAPP = &stAppStruct;
static struct stMinimumStatusReportingStructure stDevStat;
/************************************************************************/
/* Private functions                                                    */
/************************************************************************/
// API routines
void API_init(void);
void API_tasks(void);
// Timer events routines
void T_EV_tasks(void);
void T_EV_tick(void);
// CMD routines
void CMD_tasks(void);

// Error processing
void ERROR_tasks(void);

// Debug function
void Debug(void);

/************************************************************************/
/* Public functions                                                     */
/************************************************************************/
void TE_INIT(void)  
{
	spAPP->SCPI_StatStr = &stDevStat;
	mStatusLed_Enab();
	mStatusLed_On();
	
	/*  Main initialization  */
	API_init();
	CMD_PROC_INIT(spAPP);
	
	//debug
	/*
	spAPP->CMD.CMD_No = INST_SEL_PAR_QRY;
	spAPP->CMD.CMD_src = spAPP->API.UART0->RX.SourceAdd;
	spAPP->CMD.CMD_trg = spAPP->API.UART0->RX.TargetAdd;
	spAPP->CMD.DATA_len = spAPP->API.UART0->RX.DataLength;
	spAPP->CMD.DATA_buff[spAPP->CMD.DATA_len] = 0;
	spAPP->CMD.SrcAPI = spAPP->API.UART0;
	*/
	_delay_ms(750);
	mStatusLed_Off();
	
	sei();
}

void TE (void)
{
	API_tasks();		// DONE - API tasks routine
	CMD_tasks();		// CMD executing - continue in long term CMD & process new CMD & responds for long term CMD	
	
	// dodelat - kvuli postupnemu pingovani zdroju, popripade aji lokalniho ovladani
	// - zavest casovac preruseni
	//T_EV_tasks();		// Timer event tasks routine works only if USB host is connected
	
	ERROR_tasks();		// Error handling - must be at the end of the loop	
}

/************************************************************************/
/* Private functions                                                    */
/************************************************************************/
void Debug(void)
{
	static uint8_t OldTick = 0;
	if (spAPP->T_EVENTS.Tick100ms != OldTick) {
		OldTick = spAPP->T_EVENTS.Tick100ms;
		//lcd_blk_togle();
	}
}

// Error processing
void ERROR_tasks(void)
{
	// catching unhandled errors
	if (!spAPP->ERROR.InitiateReset) {
		// checking API errors	
		if (spAPP->API.UART0->RX.Event == API_ERROR) {
			spAPP->API.UART0->RX.Event = API_NO_ACTION;
			mSRS_ERREV_QUEUE_WR(spAPP->SCPI_StatStr,spAPP->API.UART0->RX.ErrorNumber);
		}
		if (spAPP->API.UART0->TX.Event == API_ERROR) {
			spAPP->API.UART0->TX.Event = API_NO_ACTION;
			mSRS_ERREV_QUEUE_WR(spAPP->SCPI_StatStr,spAPP->API.UART0->TX.ErrorNumber);
		}
		if (spAPP->API.REG->Event == API_ERROR) {
			spAPP->API.REG->Event = API_NO_ACTION;
			mSRS_ERREV_QUEUE_WR(spAPP->SCPI_StatStr,spAPP->API.REG->ErrorNumber);
		}
		// checking application errors
	}
	if (spAPP->ERROR.InitiateReset) {
		// enabling WDT to initiate error
		soft_reset();
	}
}

// Command routines
void CMD_tasks(void)
{
	if (spAPP->CMD.CMD_No == NO_COMMAND) {
		// no ongoing command execution so check for new command
		CMD_PROC_CHECK();
	}
	if (spAPP->CMD.CMD_No != NO_COMMAND) {
		// command execution ongoing
		CMD_PROC_EXEC();		
	}
}

// Timer events routines
void T_EV_tasks(void)
{
	//T_EV_tick();
}

void T_EV_tick(void)
{
	/*
	if (Next100ms) {
		// next 100ms
		Next100ms = false;
		spAPP->T_EVENTS.Tick100ms++;
	}
	*/
}

// API routines
void API_init(void)
{
	spAPP->API.UART0 = UART_API_U0_INIT();
	spAPP->API.REG = REG_API_INIT();
}

void API_tasks(void)
{
	UART_API_U0();
	REG_API();
}

