/******************************************************************************
 *
 * Copyright:
 *    (C) 2000 - 2006 Embedded Artists AB
 *
 * Description:
 *    Sample application that demonstrates how to create processes.
 *
 *****************************************************************************/

#include <general.h>
#include <printf_P.h>
#include <ea_init.h>
#include <lpc246x.h>
#include "can.h"

CAN_MSG MsgBuf_TX1, MsgBuf_TX2; // TX and RX Buffers for CAN message
CAN_MSG MsgBuf_RX1, MsgBuf_RX2; // TX and RX Buffers for CAN message

volatile DWORD CAN1RxDone, CAN2RxDone;

/*****************************************************************************
 *
 * Description:
 *    Delay execution by a specified number of milliseconds by using
 *    timer #1. A polled implementation.
 *
 * Params:
 *    [in] delayInMs - the number of milliseconds to delay.
 *
 ****************************************************************************/
static void
delayMs(tU16 delayInMs)
{
  /*
   * setup timer #1 for delay
   */
  T1TCR = 0x02;          //stop and reset timer
  T1PR  = 0x00;          //set prescaler to zero
  T1MR0 = delayInMs * (Fpclk / 1000);
  T1IR  = 0xff;          //reset all interrrupt flags
  T1MCR = 0x04;          //stop timer on match
  T1TCR = 0x01;          //start timer
  
  //wait until delay time has elapsed
  while (T1TCR & 0x01)
    ;
}


/*****************************************************************************
 *
 * Description:
 *    The first function to execute 
 *
 ****************************************************************************/
int
main(void)
{
  eaInit();

  printf("\n***************************************************");
  printf("\n*                                                 *");
  printf("\n* Test program for LPC2478 EDU Board...           *");
  printf("\n* (C) Embedded Artists 2008                       *");
  printf("\n*                                                 *");
  printf("\n* Test - CAN                                      *");
  printf("\n*                                                 *");
  printf("\n***************************************************\n");

  /* Please note, this PCLK is set in the target.h file. Since the example
  program is set to test USB device, there is only a limited number of
  options to set CCLK and PCLK when USB is used. The default setting is 
  CCLK 48MHz, PCLK is 1/2 CCLK 24MHz. 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 );
	
  /* This test program is connect CAN1 and CAN2 on the board,
  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. */ 
	
  // 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 )
  {
    int i;
    
    delayMs(20);

  	// Transmit initial message on CAN 1
	  while ( !(CAN1GSR & (1 << 3)) );

	  if ( CAN1_SendMessage( &MsgBuf_TX1 ) == FALSE )
  	{
	    continue;
	  }
    printf("\nSent message on CAN1");

    for(i = 0; i < 100; i++)
    {
      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 )
            printf("\nReceived faulty message on CAN2!!!");
  	    }
        printf("\nReceived correct message on CAN2");
  	    // 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
  	  delayMs(5);
  	}
  }

  for(;;)
  {
    delayMs(5);
  }
}
