/*
 * sys_utils.c
 *
 * Copyright (c) 2012 Texas Instruments Incorporated ALL RIGHTS RESERVED
 * 
 */

#include "soc_AM335x.h"
#include "dmtimer.h"
#include "gpio_v2.h"
#include "sys_utils.h"

#include <xdc/std.h>
#include <ti/sysbios/family/arm/a8/Cache.h>
#include <ti/sysbios/family/arm/a8/intcps/Hwi.h>

#define	TIMER_INITIAL_COUNT			( 0xFFFFFFFF )
#define	TIMER_RELOAD_COUNT			( TIMER_INITIAL_COUNT - 24000 )	// 1000 µs
#define RUN_LED_TIME_MS				( 250 )

void		dmtimer_isr				( void );
extern void DMTimer3ModuleClkConfig	( void );

TMR_FRM		run_led_timer;

//TIMESTAMP_TYPE	timestamp={0,0,0,0,0,0,0,0};

void led_init() {

/*	// GM 11/07/2013 - Abilito il pin GPIO0_13 per debug (FPGA_PROG_EN# su IARD)
	 GPIODirModeSet(SOC_GPIO_0_REGS,13,GPIO_DIR_OUTPUT);

	 // GM 31/05/2013 - Abilito il pin GPIO3_1 per debug (FPGA_DATA0 su IARD)
	 GPIODirModeSet(SOC_GPIO_3_REGS,1,GPIO_DIR_OUTPUT);
	 GPIODirModeSet(SOC_GPIO_3_REGS,0,GPIO_DIR_OUTPUT);

	 led_reset( LED_H12_RED );
	 led_reset( LED_H13_GREEN );

	 delete_timer( &run_led_timer );
	 load_timer( &run_led_timer, RUN_LED_TIME_MS );
	 start_timer ( &run_led_timer );
*/
	 return;
}

void led_set	( int led_id )
{
/*	GPIOPinWrite( SOC_GPIO_0_REGS, 13, GPIO_PIN_HIGH );

	switch ( led_id )
	{
	case	LED_H12_RED:
		GPIOPinWrite( SOC_GPIO_3_REGS, 1, GPIO_PIN_LOW );
		break;
	case	LED_H13_GREEN:
		GPIOPinWrite( SOC_GPIO_3_REGS, 0, GPIO_PIN_LOW);
		break;
	default:
		break;
	}*/

	return;

}

void led_reset		( int led_id )
{
/*	GPIOPinWrite( SOC_GPIO_0_REGS, 13, GPIO_PIN_HIGH );

	switch ( led_id )
	{
	case	LED_H12_RED:
		GPIOPinWrite( SOC_GPIO_3_REGS, 1, GPIO_PIN_HIGH );
		break;
	case	LED_H13_GREEN:
		GPIOPinWrite( SOC_GPIO_3_REGS, 0, GPIO_PIN_HIGH);
		break;
	default:
		break;
	}
*/
	return;

}

void led_toggle		( int led_id )
{
/*	GPIOPinWrite( SOC_GPIO_0_REGS, 13, GPIO_PIN_HIGH );

	switch ( led_id )
	{
	case	LED_H12_RED:
		GPIOPinWrite(SOC_GPIO_3_REGS, 1,((~GPIOPinRead(SOC_GPIO_3_REGS, 1)) >> 1) & 0x1);
		break;
	case	LED_H13_GREEN:
		GPIOPinWrite(SOC_GPIO_3_REGS, 0,((~GPIOPinRead(SOC_GPIO_3_REGS, 0)) >> 0) & 0x1);
		break;
	default:
		break;
	}*/

	return;

}

void	run_led_blinker	( void )
{

/*	if ( evaluate_timer( &run_led_timer ) == TIMER_EXPIRED )
	{
		start_timer ( &run_led_timer );
		led_toggle( LED_H13_GREEN );
	}*/

}

/*****************************************************************************/
/* Usato per i buffer di trasmissione. */
void _CacheDataCleanBuff(unsigned int startAddr,
                               unsigned int numBytes)
{
	Cache_wb((xdc_Ptr)startAddr, numBytes, Cache_Type_ALLD, 1);
}

/*****************************************************************************/
/* Usato per i buffer di ricezione. */
void _CacheDataInvalidateBuff(unsigned int startAddr,
                                    unsigned int numBytes)
{
	Cache_inv((xdc_Ptr)startAddr, numBytes, Cache_Type_ALLD, 1);
}

/********************************************************************/
/*                                                                 	*/
/* File name     	: SoftTimer.c                                   */
/* Author        	:  												*/
/*                                                                 	*/
/* Date          	: 13-01-05     			                        */
/* Release			:                                  		        */
/*                 	                                                */
/*                  	                                            */
/*                    	                                            */
/* Description	 	: Software timer routines	                    */
/*                      	                                        */
/*                        	                                        */
/* Note				:												*/
/*                              	                                */
/********************************************************************/

/******************************************************************************
*																			  *
*							GLOBAL FUNCTION PROTOTYPES						  *
*																			  *
******************************************************************************/
void			set_tick_period		(unsigned int	tick);
unsigned int	evaluate_timer		(TMR_FRM *);
void			start_timer			(TMR_FRM *);
void			delete_timer		(TMR_FRM *);
void			load_timer			(TMR_FRM *, unsigned int timeout_ms);
void			tick_reset			(void);
void			tick_increment		(void);

/******************************************************************************
*																			  *
*							LOCAL FUNCTION PROTOTYPES						  *
*																			  *
******************************************************************************/


/******************************************************************************
*																			  *
*								GLOBAL VARIABLES							  *
*																			  *
******************************************************************************/


/******************************************************************************
*																			  *
*								LOCAL VARIABLES								  *
*																			  *
******************************************************************************/
static volatile 		unsigned long		TickCount;
static volatile			unsigned int		tick_period = 1000;	// 1000 µs


/******************************************************************************
*																			  *
*									DEFINE									  *
*																			  *
******************************************************************************/


//---------------------------------------------------------------------------
// SetTickPeriod
//
// Set tick period for timing
//---------------------------------------------------------------------------
void		set_tick_period (unsigned int	tick)
{
	tick_period=tick;
	return;
}


//---------------------------------------------------------------------------
// TickReset
//
// Reset main tick count variable
//---------------------------------------------------------------------------
void		tick_reset (void)
{
	TickCount = 0;
	return;
}

//---------------------------------------------------------------------------
// TickIncrement
//
// Increment main tick count variable. Use this in an interrupt routine
//---------------------------------------------------------------------------
void		tick_increment (void)
{
	TickCount++;
	return;
}


//---------------------------------------------------------------------------
// EvaluateTimer
//
// Probe software timer status
//---------------------------------------------------------------------------
unsigned int evaluate_timer (TMR_FRM *timer)
{
	if (timer->status == TIMER_RUNNING)
		{
		if ((TickCount - timer->ref) >= timer->timeout)
			timer->status = TIMER_EXPIRED;
		}
	return timer->status;
}

//---------------------------------------------------------------------------
// StartTimer
//
// Starts software timer
//---------------------------------------------------------------------------
void		start_timer (TMR_FRM *timer)
{
	timer->ref = TickCount;
	timer->status = TIMER_RUNNING;
	return;
}

//---------------------------------------------------------------------------
// DeleteTimer
//
// Delete software timer and put it in a known initial state
//---------------------------------------------------------------------------
void		delete_timer (TMR_FRM *timer)
{
	timer->status = TIMER_DELETED;
	return;
}

//---------------------------------------------------------------------------
// LoadTimer
//
// Initialize software timer. Tick period argument is tick delta T from
// tick_increment() interrupt routine
//---------------------------------------------------------------------------
void		load_timer (TMR_FRM *timer, unsigned int timeout_ms)
{
	unsigned long	t_out;

	if (timeout_ms <= 32767)
		t_out = (unsigned long)(((unsigned long)timeout_ms*1000)/tick_period);
	else
		t_out = (unsigned long)((unsigned long)(32767*1000)/tick_period);
	timer->timeout = t_out;
	return;
}



//---------------------------------------------------------------------------
// Function	:	dmtimer_isr
//
// Date		:
//
// Note		:
//---------------------------------------------------------------------------
void	dmtimer_isr					( void )
{
	DMTimerIntStatusClear( SOC_DMTIMER_3_REGS, (DMTIMER_INT_OVF_EN_FLAG | DMTIMER_INT_TCAR_EN_FLAG | DMTIMER_INT_MAT_EN_FLAG) );
	TickCount++;

}

//---------------------------------------------------------------------------
// Function	:	dmtimer_init
//
// Date		:
//
// Note		:
//---------------------------------------------------------------------------

void	dmtimer_init					( void )
{

	Hwi_Params 	hwiParams;

	DMTimer3ModuleClkConfig();

	Hwi_Params_init(&hwiParams);
	hwiParams.arg = 69;
	hwiParams.priority = 3;

	Hwi_create( 69,(ti_sysbios_interfaces_IHwi_FuncPtr)dmtimer_isr, &hwiParams, NULL );

	/* Load the counter with the initial count value */
	DMTimerCounterSet( SOC_DMTIMER_3_REGS, TIMER_INITIAL_COUNT );

	/* Load the load register with the reload count value */
	DMTimerReloadSet( SOC_DMTIMER_3_REGS, TIMER_RELOAD_COUNT );

	/* Configure the DMTimer for Auto-reload and compare mode */
	DMTimerModeConfigure( SOC_DMTIMER_3_REGS, DMTIMER_AUTORLD_NOCMP_ENABLE );

	Hwi_enableInterrupt( 69 );

	DMTimerIntEnable( SOC_DMTIMER_3_REGS, DMTIMER_INT_OVF_EN_FLAG );
	DMTimerEnable( SOC_DMTIMER_3_REGS );

	return;
}
