/******************************************************************************
 *
 * Freescale Semiconductor Inc.
 * (c) Copyright 2004-2013 Freescale Semiconductor, Inc.
 * ALL RIGHTS RESERVED.
 *
 ******************************************************************************
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************//*!
 *
 * @file main.c
 *
 * @author  
 *
 * @version 1.0
 *
 * @date Aug-28-2013
 *
 * @brief Wearable ECG patch application demo software
 *
 *****************************************************************************/

/*****************************************************************************
 * Header Files
 ****************************************************************************/
#include "derivative.h" /* include peripheral declarations */

#include "mcg.h"
#include "pmc.h"
#include "SwTimer.h"
#include "lpb_ui.h"
#include "twrpi_slcd.h"
#include "hr_analysis.h"

#include "med_ekg.h"

#if defined(USB_DEBUG)
#include "usb_cdc.h"
#endif

/*****************************************************************************
 * User definitions
 ****************************************************************************/
#define SLCD_TASK_TIME_MS	1500

/*****************************************************************************
 * Function prototypes
 ****************************************************************************/
void vfnSlcdPeriodicTask (void);

/*****************************************************************************
 * Globals
 ****************************************************************************/
extern uint8_t u8EcgTaskTimer;

/*****************************************************************************
 * Locals
 ****************************************************************************/
tSLCD SlcdMatrix;
uint8_t u8SlcdTaskTimer;

/*****************************************************************************
 * Functions
 ****************************************************************************/
int main(void)
{	
#if defined(USB_DEBUG)
	//Initialise PLL @48 MHz
	u8PllInit(PLL48,MCG_XTAL,XTAL8);
	
	//Configure clock dividers
	vfnSetSysDividers(CLKDIV_1,CLKDIV_1,CLKDIV_2);
	
	//Initialise USB
	CDC_Init();
	
#else
	//Configure MCG on BLPI using Fast IRC
	if(u8McgFei2Fbi(MCG_IRC_FAST))
		asm("NOP"); //TODO: Error handler
	if(u8McgFbi2Blpi())
		asm("NOP");
	
	//Configure clock dividers to match VLPR criteria (MCG and BUS 4MHZ max, Flash 1MHz max)
	vfnSetSysDividers(CLKDIV_1,CLKDIV_1,CLKDIV_4);
	
	//Enter VLPR mode
	if(u8EnterVlpr(0))
		asm("NOP");
#endif
	
	//Initialise MED-EKG module
	if(u8MedEkgInit())
		asm("NOP");
	
	//Initialise SLCD
	vfnSlcdInit(SLCD_CLK_DEFAULT);
	CLEAR_MATRIX(SlcdMatrix);
	SET_FSL(SlcdMatrix);
	vfnSlcdRefresh(SlcdMatrix);
	
	//Initialise Software timer
	SwTimer_Init();
	
	//Create required timers
	u8SlcdTaskTimer = SwTimer_CreateTimer(vfnSlcdPeriodicTask);
	if(u8SlcdTaskTimer)
		asm("NOP");
	
	u8EcgTaskTimer = SwTimer_CreateTimer(vfnMedEkgPeriodicTask);
	if(u8EcgTaskTimer)
		asm("NOP");	
		
	//Start timers
	SwTimer_StartTimer(u8SlcdTaskTimer, SLCD_TASK_TIME_MS);
	SwTimer_StartTimer(u8EcgTaskTimer, EKG_TASK_TIME_MS);
	
	//Application periodic task
	for(;;)
	{
#if defined(USB_DEBUG)
		
		//Execute CDC periodic task
		CDC_Engine();
		
		//Execute software timer periodic task on LPTMR interrupt
		SwTimer_PeriodicTask();
		
#else
		//Enter VLPS to save power
		if(u8EnterVlps(0))
			asm("NOP");
		
		//Wakeup from VLPS. Execute software timer periodic task
		SwTimer_PeriodicTask();
#endif
	}
	
	return 0;
}

void vfnSlcdPeriodicTask (void)
{
	static uint8_t u8FslLogoStat = 0;
	
	//Restart Timer
	SwTimer_StartTimer(u8SlcdTaskTimer, SLCD_TASK_TIME_MS);
	
	//Update SLCD value
	u8SlcdSetNumber(gu8HrValue, &SlcdMatrix);
	
	//Toggle FSL logo
	if(u8FslLogoStat)
		SET_FSL(SlcdMatrix);
	else
		CLR_FSL(SlcdMatrix);
	
	//Update SLCD
	vfnSlcdRefresh(SlcdMatrix);
			
	u8FslLogoStat = !u8FslLogoStat;
}
