/*****************************************************************************/
/* FILE NAME: main.c                            COPYRIGHT (c) Freescale 2010 */
/*                                                       All Rights Reserved */
/*  									     								 */
/* MPC5668 Example Projects Suite					     					 */
/* FlexCAN Example - Re-use and derived from AN2865 						 */
/*							            					 				 */
/*									    									 */
/* Revision History														     */
/*      Rev: 1.0 		Author:	Steven McLaughlin	DATE: 19/10/2010    	 */
/*									     									 */
/*	This code example demostrates a CAN frame being transmitted from CAN_A	 */
/* 	and recieved at CAN_C on the device. Physical connections should be made */
/*	between PD0 and PD4 (CAN Tx) and PD1 and PD5 (CAN Rx). A connection 	 */
/*	between PE1 and a LED should be made. The user must also enable the 	 */ 
/*  CAN_A transciever on the EVB											 */
/*  Note the header file has been adjusted to recieved byte data on the CAN  */
/*	message buffers 														 */
/*****************************************************************************/

/****************************** Includes *************************************/
#include "mpc5668.h"
/***************************** Global variables ******************************/
uint32_t RxCODE;               					/* Received message buffer code */
uint32_t RxID;                 					/* Received message ID */
uint32_t RxLENGTH;             					/* Recieved message number of data bytes */
uint8_t  RxDATA[8];            					/* Received message data string*/
uint32_t RxTIMESTAMP;          					/* Received message time */   
/****************************** Function Prototypes **************************/
                     
void initCAN_C (void) {
  uint8_t   i;

  CAN_C.MCR.R = 0x5000003F;       				/* Put in Freeze Mode & enable all 64 message buffers */
  CAN_C.CTRL.R = 0x04DB0006;        			/* Configure for 40MHz OSC, 500KHz bit time */
  for (i=0; i<64; i++) {
    CAN_C.BUF[i].CS.B.CODE = 0;   				/* Inactivate all message buffers */
  } 
  CAN_C.BUF[4].CS.B.IDE = 0;      				/* MB 4 will look for a standard ID */
  CAN_C.BUF[4].ID.B.STD_ID = 555; 				/* MB 4 will look for ID = 555 */
  CAN_C.BUF[4].CS.B.CODE = 4;     				/* MB 4 set to RX EMPTY */
  CAN_C.RXGMASK.R = 0x1FFFFFFF;   				/* Global acceptance mask */
  SIU.PCR[52].R = 0x0620;         				/* Configure pad as CNTXC, open drain */
  SIU.PCR[53].R = 0x0500;         				/* Configure pad as CNRXC */
  CAN_C.MCR.R = 0x0000003F;       				/* Negate FlexCAN C halt state for  64 MB */
}

void initCAN_A (void) {
  uint8_t   i;

  CAN_A.MCR.R = 0x5000003F;       				/* Put in Freeze Mode & enable all 64 message buffers */
  CAN_A.CTRL.R = 0x04DB0006;        			/* Configure for 40MHz OSC, 500KHz bit time */
  for (i=0; i<64; i++) {
    CAN_A.BUF[i].CS.B.CODE = 0;   				/* Inactivate all message buffers */
  } 
  CAN_A.BUF[0].CS.B.CODE = 8;     				/* Message Buffer 0 set to TX INACTIVE */
  SIU.PCR[48].R = 0x0620;         				/* Configure pad as CNTXA, open drain */
  SIU.PCR[49].R = 0x0500;         				/* Configure pad as CNRXA */
  CAN_A.MCR.R = 0x0000003F;       				/* Negate FlexCAN A halt state for 64 MB */
}

void TransmitMsg (void) {
  uint8_t	i;
												/* Assumption:  Message buffer CODE is INACTIVE */
  const uint8_t TxData[] = {"Hello"};  			/* Transmit string*/
  CAN_A.BUF[0].CS.B.IDE = 0;           			/* Use standard ID length */
  CAN_A.BUF[0].ID.B.STD_ID = 555;      			/* Transmit ID is 555 */
  CAN_A.BUF[0].CS.B.RTR = 0;           			/* Data frame, not remote Tx request frame */
  CAN_A.BUF[0].CS.B.LENGTH = sizeof(TxData) -1 ; /* # bytes to transmit w/o null */
  for (i=0; i<sizeof(TxData); i++) {
    CAN_A.BUF[0].DATA.B[i] = TxData[i];      	/* Data to be transmitted */
  }
  CAN_A.BUF[0].CS.B.SRR = 1;           			/* Tx frame (not req'd for standard frame)*/
  CAN_A.BUF[0].CS.B.CODE =0xC;         			/* Activate msg. buf. to transmit data frame */ 
}

void RecieveMsg (void) {
  uint8_t j;
  uint32_t dummy;
  //while (!CAN_C.IFLAG1.B.BUF04I) {};  		/* MPC551x: Wait for CAN C MB 4 flag */
  RxCODE   = CAN_C.BUF[4].CS.B.CODE;      		/* Read CODE, ID, LENGTH, DATA, TIMESTAMP */
  RxID     = CAN_C.BUF[4].ID.B.STD_ID;
  RxLENGTH = CAN_C.BUF[4].CS.B.LENGTH;
  for (j=0; j<RxLENGTH; j++) { 
    RxDATA[j] = CAN_C.BUF[4].DATA.B[j];
  }
  RxTIMESTAMP = CAN_C.BUF[4].CS.B.TIMESTAMP; 
  dummy = CAN_C.TIMER.R;                		/* Read TIMER to unlock message buffers */    
  CAN_C.IFLAG1.R = 0x00000010;          		/* MPC551x: Clear CAN C MB 4 flag */
}

void main(void) {
  volatile uint32_t count = 0; 
  SIU.PCR[65].R=0x0200;							/* OBE on PE1 - LED connection */
  initCAN_C();             						/* Initialize FLEXCAN C & one of its buffers for receive*/
  initCAN_A();             						/* Initialize FlexCAN A & one of its buffers for transmit*/
  TransmitMsg();           						/* Transmit one message from a FlexCAN A buffer */
  RecieveMsg();            						/* Wait for the message to be recieved at FlexCAN C */
  
  while (1) {              
    for (count=0; count<100000; count++);		/* loops to toggle PE1*/
			SIU.GPDO[65].R = 0x01;
			for (count=0; count<100000; count++);
			SIU.GPDO[65].R = 0x00;	
	              
  }
}