/******************************************************************************
** Function name:		SysTick_Handler
**
** Description:			System clock event handler. Fires every 100mS
**
** Parameters:			None
** Returned value:	None
**
******************************************************************************/
void SysTick_Handler (void)
{
	CLOCK.T_mS++;

	if(LPC_WDT->WDMOD & 0x1)
	{
		LPC_WDT->WDFEED = 0xAA;
		LPC_WDT->WDFEED = 0x55;
	}

	/// Time sensitive calculations
	bmu_data.watt_hrs += bmu_data.watts / 36000.0;
	if(bmu_data.watts > 0)
	{
	  bmu_data.watt_hrs_out += bmu_data.watts / 36000.0;
	}
	else
	{
    bmu_data.watt_hrs_in -= bmu_data.watts / 36000.0;
  }

	/// CAN Tx
	if(!(LPC_CAN1->SR & 0x00000004)){LPC_CAN1->CMR = 0x22;} // Abort from buffer 1

	can_tx1_buf.Frame = 0x00080000;
  can_tx1_buf.MsgID = BMU_SHUNT;
  can_tx1_buf.DataA = conv_float_uint(bmu_data.bus_v);
  can_tx1_buf.DataB = conv_float_uint(bmu_data.bus_i);
  CAN1_SendMessage( &can_tx1_buf );

  if(!(LPC_CAN1->SR & 0x00000400)){LPC_CAN1->CMR = 0x42;} // Abort from buffer 2

  can_tx1_buf.Frame = 0x00080000;
  can_tx1_buf.MsgID = BMU_SHUNT + 1;
  can_tx1_buf.DataA = conv_float_uint(bmu_data.watt_hrs_out);
  can_tx1_buf.DataB = conv_float_uint(bmu_data.watt_hrs_in);
  CAN1_SendMessage( &can_tx1_buf );

  if(!(LPC_CAN1->SR & 0x00040000)){LPC_CAN1->CMR = 0x82;} // Abort from buffer 3

  can_tx1_buf.Frame = 0x00040000;
  can_tx1_buf.MsgID = BMU_SHUNT + 2;
  can_tx1_buf.DataA = conv_float_uint(bmu_data.watt_hrs);
  can_tx1_buf.DataB = 0x0;
  CAN1_SendMessage( &can_tx1_buf );

	if(CLOCK.T_mS >= 10) // Calculate time
	{
		CLOCK.T_mS = 0;CLOCK.T_S++;

		STATUS_ON;
		store_persistent(); // Store data in eeprom every second
		STATUS_OFF;

		if(CLOCK.T_S >= 60){CLOCK.T_S = 0;CLOCK.T_M++;
		if(CLOCK.T_M >= 60){CLOCK.T_M = 0;CLOCK.T_H++;
		if(CLOCK.T_H >= 24){CLOCK.T_H = 0;CLOCK.T_D++;}}}
	}
}
/*****************************************************************************
** Function name:		main
**
** Descriptions:		main routine for CAN module test
**
** parameters:			None
** Returned value:		int
** 
*****************************************************************************/
int main( void )
{
  /* SystemClockUpdate() updates the SystemFrequency variable */
  SystemClockUpdate();

  /* Please note, the bit timing is based on the setting of the 
  PCLK, if different PCLK is used, please read can.h carefully 
  and set your CAN bit timing accordingly. */  
  //CAN_Init( BITRATE100K24MHZ );
  CAN_Init( BITRATE125K18MHZ );	

#if CAN_WAKEUP
  CAN_WakeupTest();
#endif
  
  /* send one message from CAN1(TX) and verify received message on 
  CAN2(RX) if it's a match, both CAN TX and RX are working. 
  For more details on acceptance filter program, see Philips
  appnote AN10438 and the zip file associated with this appnote. */

#if !ACCEPTANCE_FILTER_ENABLED
  /* Initialize MsgBuf */
  MsgBuf_TX1.Frame = 0x80080000; /* 29-bit, no RTR, DLC is 8 bytes */
  MsgBuf_TX1.MsgID = 0x00012345; /* CAN ID */
  MsgBuf_TX1.DataA = 0x3C3C3C3C;
  MsgBuf_TX1.DataB = 0xC3C3C3C3;

  MsgBuf_RX2.Frame = 0x0;
  MsgBuf_RX2.MsgID = 0x0;
  MsgBuf_RX2.DataA = 0x0;
  MsgBuf_RX2.DataB = 0x0;
  CAN_SetACCF( ACCF_BYPASS );

  /* Test bypass */
  while ( 1 )
  {
	/* Transmit initial message on CAN 1 */
	while ( !(LPC_CAN1->GSR & (1 << 3)) );
	if ( CAN1_SendMessage( &MsgBuf_TX1 ) == FALSE )
	{
	  continue;
	}
 	if ( CAN2RxDone == TRUE )
	{
	  CAN2RxDone = FALSE;
	  if ( MsgBuf_RX2.Frame & (1 << 10) )	/* by pass mode */
	  {
		MsgBuf_RX2.Frame &= ~(1 << 10 );
	  }
	  if ( ( MsgBuf_TX1.Frame != MsgBuf_RX2.Frame ) ||
			( MsgBuf_TX1.MsgID != MsgBuf_RX2.MsgID ) ||
			( MsgBuf_TX1.DataA != MsgBuf_RX2.DataA ) ||
			( MsgBuf_TX1.DataB != MsgBuf_RX2.DataB ) )
	  {
		while ( 1 );
	  }
	  /* Everything is correct, reset buffer */
	  MsgBuf_RX2.Frame = 0x0;
	  MsgBuf_RX2.MsgID = 0x0;
	  MsgBuf_RX2.DataA = 0x0;
	  MsgBuf_RX2.DataB = 0x0;
	} /* Message on CAN 2 received */
  }
#else
  /* Test Acceptance Filter */
  /* Even though the filter RAM is set for all type of identifiers,
  the test module tests explicit standard identifier only */
  MsgBuf_TX1.Frame = 0x00080000; /* 11-bit, no RTR, DLC is 8 bytes */
  MsgBuf_TX1.MsgID = EXP_STD_ID; /* Explicit Standard ID */
  MsgBuf_TX1.DataA = 0x55AA55AA;
  MsgBuf_TX1.DataB = 0xAA55AA55;

  MsgBuf_RX2.Frame = 0x0;
  MsgBuf_RX2.MsgID = 0x0;
  MsgBuf_RX2.DataA = 0x0;
  MsgBuf_RX2.DataB = 0x0;
  CAN_SetACCF( ACCF_ON );

  while ( 1 )
  {
	/* Transmit initial message on CAN 1 */
	while ( !(LPC_CAN1->GSR & (1 << 3)) );
	if ( CAN1_SendMessage( &MsgBuf_TX1 ) == FALSE )
	{
	  continue;
	}

	/* please note: FULLCAN identifier will NOT be received as it's not set 
	in the acceptance filter. */
 	if ( CAN2RxDone == TRUE )
	{
	  CAN2RxDone = FALSE;
	  /* The frame field is not checked, as ID index varies based on the
	  entries set in the filter RAM. */
	  if ( ( MsgBuf_TX1.MsgID != MsgBuf_RX2.MsgID ) ||
			( MsgBuf_TX1.DataA != MsgBuf_RX2.DataA ) ||
			( MsgBuf_TX1.DataB != MsgBuf_RX2.DataB ) )
	  {
		while ( 1 );
	  }
	  /* Everything is correct, reset buffer */
	  MsgBuf_RX2.Frame = 0x0;
	  MsgBuf_RX2.MsgID = 0x0;
	  MsgBuf_RX2.DataA = 0x0;
	  MsgBuf_RX2.DataB = 0x0;
	} /* Message on CAN 2 received */
  }
#endif
}