Beispiel #1
0
void CANIntHandler(void) {
  unsigned long status_flags;
  status_flags = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);

  if (status_flags == CAN_INT_INTID_STATUS) {
    status_flags = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
    // TODO: process the error?
  } else if (status_flags == 1) { // Wheel A
    sCANMessage.pui8MsgData = (uint8_t *)&wheel_a_data;
    CANMessageGet(CAN0_BASE, 1, &sCANMessage, 1);
  } else if (status_flags == 2) { // Wheel B
    sCANMessage.pui8MsgData = (uint8_t *)&wheel_b_data;
    CANMessageGet(CAN0_BASE, 2, &sCANMessage, 1);
  } else if (status_flags == 3) { // Engine
    sCANMessage.pui8MsgData = (uint8_t *)&engine_data;
    CANMessageGet(CAN0_BASE, 3, &sCANMessage, 1);
  } else if (status_flags == 4) { // Fuel
    sCANMessage.pui8MsgData = (uint8_t *)&fuel_data;
    CANMessageGet(CAN0_BASE, 4, &sCANMessage, 1);
  } else {
    //
    // Spurious interrupt handling can go here.
    //
  }
}
Beispiel #2
0
int getFormMachine(char* id)
{
	int value = -999; // error code
	
		int rc = 0;
	
	g_MsgObjectRx.ulMsgID = (0x400);
    g_MsgObjectRx.ulMsgIDMask = 0x7f8;        
    g_MsgObjectRx.ulFlags = MSG_OBJ_USE_ID_FILTER;
    g_MsgObjectRx.ulMsgLen = snprintf(ucBufferIn, BUFFER_LEN, "%s", id, value);            
    g_MsgObjectRx.pucMsgData = ucBufferIn;
	
	CANMessageSet(CAN0_BASE, 1, &g_MsgObjectRx, MSG_OBJ_TYPE_RX);
    
	printf("getFormMachine Message: %s\n", g_MsgObjectRx.pucMsgData);
	
    while((CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT)) & 1 == 0)
    {
    }
	
	CANMessageGet(CAN0_BASE, 1, &g_MsgObjectRx, true);
		value = atoi(strstr(g_MsgObjectRx.pucMsgData) + 1);
		printf("getFromMachine GetMessage: %s\n", g_MsgObjectRx.pucMsgData);
	
	return rc;
	
	return value;
}
Beispiel #3
0
int can_recv(can_msg_t *msg)
{
	tCANMsgObject MsgObjectRx;
	int i;
	unsigned long MsgObjNr,temp;

	MsgObjNr = CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT);
	if(MsgObjNr == 0)
		return 1;

	//find which msg object receives the can frame
	for (i = 0; i < 31; i++) {
		temp = 1 << i;
		if (MsgObjNr & temp)
			break;
	}

	MsgObjectRx.pucMsgData = (unsigned char *)msg->data;
	CANMessageGet(CAN0_BASE, i + 1, &MsgObjectRx, 1);
	msg->dlc = MsgObjectRx.ulMsgLen;
	if (MsgObjectRx.ulFlags & MSG_OBJ_EXTENDED_ID) {
		msg->flag = 1;
		msg->id = (MsgObjectRx.ulMsgID & 0x1FFFFFFF);
	} else {
		msg->flag = 0;
		msg->id = (MsgObjectRx.ulMsgID & 0x000007FF);
	}

	return 0;
}
Beispiel #4
0
//*****************************************************************************
//
// The CAN controller interrupt handler.
//
//*****************************************************************************
void CAN0_Handler(void){ uint8_t data[8];
  uint32_t ulIntStatus, ulIDStatus;
  int i;
  tCANMsgObject xTempMsgObject;
  xTempMsgObject.pucMsgData = data;
  ulIntStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); // cause?
  if(ulIntStatus & CAN_INT_INTID_STATUS){  // receive?
    ulIDStatus = CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT);
    for(i = 0; i < 64; i++){    //test every bit of the mask
      if( (0x1 << i) & ulIDStatus){  // if active, get data
        CANMessageGet(CAN0_BASE, (i+1), &xTempMsgObject, true);
        if(xTempMsgObject.ulMsgID == RCV_ID){
          if(CAN0_Fifo_Put(data[0])==0||CAN0_Fifo_Put(data[1])==0||
             CAN0_Fifo_Put(data[2])==0||CAN0_Fifo_Put(data[3])==0||
             CAN0_Fifo_Put(data[4])==0||CAN0_Fifo_Put(data[5])==0||
             CAN0_Fifo_Put(data[6])==0||CAN0_Fifo_Put(data[7])==0){
            PacketLost++;//increment the packet lost
          }
          MailFlag = true;   // new mail
        }
      }
    }
  }
  CANIntClear(CAN0_BASE, ulIntStatus);  // acknowledge
}
//*****************************************************************************
//
// The CAN controller interrupt handler.
//
//*****************************************************************************
void
CANIntHandler(void)
{
    unsigned long ulStatus;

    //
    // Find the cause of the interrupt, if it is a status interrupt then just
    // acknowledge the interrupt by reading the status register.
    //
    ulStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);

    //
    // The first eight message objects make up the Transmit message FIFO.
    //
    if(ulStatus <= 8)
    {
        //
        // Increment the number of bytes transmitted.
        //
        g_sCAN.ulBytesTransmitted += 8;
    }
    //
    // The second eight message objects make up the Receive message FIFO.
    //
    else if((ulStatus > 8) && (ulStatus <= 16))
    {
        //
        // Read the data out and acknowledge that it was read.
        //
        CANMessageGet(CAN0_BASE, ulStatus, &g_sCAN.MsgObjectRx, 1);

        //
        // Advance the read pointer.
        //
        g_sCAN.MsgObjectRx.pucMsgData += 8;

        //
        // Decrement the expected bytes remaining.
        //
        g_sCAN.ulBytesRemaining -= 8;
    }
    else
    {
        //
        // This was a status interrupt so read the current status to
        // clear the interrupt and return.
        //
        CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
    }

    //
    // Acknowledge the CAN controller interrupt has been handled.
    //
    CANIntClear(CAN0_BASE, ulStatus);
}
Beispiel #6
0
void setup(){
	Serial.begin(9600);
	Serial.println("DEBUG1");
	SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
	SysCtlPeripheralEnable(GPIO_PORTE_BASE);
	GPIOPinTypeCAN(GPIO_PORTE_BASE, GPIO_PIN_4 | GPIO_PIN_5);

	GPIOPinConfigure(GPIO_PE4_CAN0RX);
	GPIOPinConfigure(GPIO_PE5_CAN0TX);

	tCANMsgObject sCANMessage;
    uint8_t ucMsgData[8];

			Serial.println("DEBUG2");

	uint8_t pui8BufferIn[8];
	uint8_t pui8BufferOut[8];

			Serial.println("DEBUG3");

	CANInit(CAN0_BASE);

		    CANBitRateSet(CAN0_BASE, SysCtlClockGet(), 500000);

	CANEnable(CAN0_BASE);

  sCANMessage.ui32MsgID = 0;                        // CAN msg ID - 0 for any
    sCANMessage.ui32MsgIDMask = 0;                    // mask is 0 for any ID
    sCANMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER;
    sCANMessage.ui32MsgLen = 8;                       // allow up to 8 bytes

    //
    // Now load the message object into the CAN peripheral.  Once loaded the
    // CAN will receive any message on the bus, and an interrupt will occur.
    // Use message object 1 for receiving messages (this is not the same as
    // the CAN ID which can be any value in this example).
    //
    CANMessageSet(CAN0_BASE, 1, &sCANMessage, MSG_OBJ_TYPE_RX);

			Serial.println("DEBUG5");

	while((CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT) & 1) == 0)
	{
        //
        // Read the message out of the message object.
        //
		CANMessageGet(CAN0_BASE, 1, &sCANMessage, true);
			Serial.println(sCANMessage.ui32MsgLen);

	}
				Serial.println(sCANMessage.ui32MsgLen);

			Serial.println(sCANMessage.ui32MsgID);

}
Beispiel #7
0
void CAN_ISR(void)
{
    unsigned long ulStatus;

    ulStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);
    switch(ulStatus)
    {
    case MSG_NUM_RX: // message received
    	CANMessageGet(CAN0_BASE, MSG_NUM_RX, &g_MsgRx, /*clear int*/ 1);
    	NetworkRxCallback(g_ulRxData); // call user function upon receiving a message
    	break;
    default: // status or other interrupt: clear it without further action
    	CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
    	CANIntClear(CAN0_BASE, ulStatus);
    }
}
//*****************************************************************************
//
// This function handles connection with the other CAN device and also
// handles incoming commands.
//
// /return None.
//
//*****************************************************************************
void
CANMain(void)
{
    unsigned char pucData[8];

    //
    // The data has been received.
    //
    if((g_ulFlags & FLAG_DATA_RECV) == 0)
    {
        return;
    }

    //
    // Read the data from the message object.
    //
    g_MsgObjectRx.pucMsgData = pucData;
    g_MsgObjectRx.ulMsgLen = 8;
    CANMessageGet(CAN0_BASE, MSGOBJ_NUM_DATA_RX, &g_MsgObjectRx, 1);

    //
    // Indicate that the data has been read.
    //
    g_ulFlags &= (~FLAG_DATA_RECV);

    switch(g_MsgObjectRx.pucMsgData[0])
    {
        case CMD_GET_VERSION:
        {
            //
            // Send the Version.
            //
            g_ulFlags |= FLAG_DATA_TX_PEND;

            g_MsgObjectTx.pucMsgData = (unsigned char *)&g_ulVersion;
            g_MsgObjectTx.ulMsgLen = 4;
            CANMessageSet(CAN0_BASE, MSGOBJ_NUM_DATA_TX, &g_MsgObjectTx,
                          MSG_OBJ_TYPE_TX);
        }
    }

    //
    // Clear the flag.
    //
    g_ulFlags &= ~(FLAG_DATA_RECV);
}
Beispiel #9
0
int platform_can_recv( unsigned id, u32 *canid, u8 *idtype, u8 *len, u8 *data )
{
    // wait for a message
    if( can_rx_flag != 0 )
    {
        can_msg_rx.pucMsgData = data;
        CANMessageGet(CAN0_BASE, 1, &can_msg_rx, 0);
        can_rx_flag = 0;

        *canid = ( u32 )can_msg_rx.ulMsgID;
        *idtype = ( can_msg_rx.ulFlags & MSG_OBJ_EXTENDED_ID )? ELUA_CAN_ID_EXT : ELUA_CAN_ID_STD;
        *len = can_msg_rx.ulMsgLen;
        return PLATFORM_OK;
    }
    else
        return PLATFORM_UNDERFLOW;
}
//*****************************************************************************
//
// This function handles incoming commands.
//
//*****************************************************************************
void
ProcessCmd(void)
{
    unsigned char pucData[8];

    //
    // If no data has been received, then there is nothing to do.
    //
    if((g_ulFlags & FLAG_DATA_RECV) == 0)
    {
        return;
    }

    //
    // Receive the command.
    //
    g_MsgObjectRx.pucMsgData = pucData;
    g_MsgObjectRx.ulMsgLen = 8;
    CANMessageGet(CAN0_BASE, MSGOBJ_NUM_DATA_RX, &g_MsgObjectRx, 1);

    //
    // Clear the flag to indicate that the data has been read.
    //
    g_ulFlags &= (~FLAG_DATA_RECV);

    switch(g_MsgObjectRx.pucMsgData[0])
    {
        //
        // This is a request for the firmware version for this application.
        //
        case CMD_GET_VERSION:
        {
            //
            // Send the Version.
            //
            g_ulFlags |= FLAG_DATA_TX_PEND;

            g_MsgObjectTx.pucMsgData = (unsigned char *)&g_ulVersion;
            g_MsgObjectTx.ulMsgLen = 4;
            CANMessageSet(CAN0_BASE, MSGOBJ_NUM_DATA_TX,
                          &g_MsgObjectTx, MSG_OBJ_TYPE_TX);
            break;
        }
    }
}
//*****************************************************************************
//
// This function sends a message to retrieve the firmware version from the
// target board.
//
//*****************************************************************************
int
CANGetTargetVersion(unsigned long *pulVersion)
{
    static unsigned char ucVerCmd = CMD_GET_VERSION;

    //
    // If there was already a previous message being transmitted then just
    // return.
    //
    if(g_ulFlags & FLAG_DATA_TX_PEND)
    {
        return(-1);
    }

    //
    // A transmit request is about to be pending.
    //
    g_ulFlags |= FLAG_DATA_TX_PEND;

    //
    // Send the button update request.
    //
    g_MsgObjectTx.pucMsgData = &ucVerCmd;
    g_MsgObjectTx.ulMsgLen = 1;

    CANMessageSet(CAN0_BASE, MSGOBJ_NUM_DATA_TX, &g_MsgObjectTx,
                  MSG_OBJ_TYPE_TX);

    //
    // Wait for some data back from the target.
    //
    while ((g_ulFlags & FLAG_DATA_RECV) == 0)
    {
    }

    //
    // Read the data from the message object.
    //
    g_MsgObjectRx.pucMsgData = (unsigned char *)pulVersion;
    g_MsgObjectRx.ulMsgLen = 4;
    CANMessageGet(CAN0_BASE, MSGOBJ_NUM_DATA_RX, &g_MsgObjectRx, 1);

    return(0);
}
Beispiel #12
0
int sendToMachine(char* id, int value)
{
	int rc = 0;
	
	g_MsgObjectRx.ulMsgID = (0x400);
    g_MsgObjectRx.ulMsgIDMask = 0x7f8;        
    g_MsgObjectRx.ulFlags = MSG_OBJ_USE_ID_FILTER;
    g_MsgObjectRx.ulMsgLen = snprintf(ucBufferIn, BUFFER_LEN, "%s:%d", id, value);            
    g_MsgObjectRx.pucMsgData = ucBufferIn;
	
	CANMessageSet(CAN0_BASE, 1, &g_MsgObjectRx, MSG_OBJ_TYPE_RX);
    printf("setToMachine SetMessage: %s\n", g_MsgObjectRx.pucMsgData);
    while((CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT)) & 1 == 0)
    {}
		CANMessageGet(CAN0_BASE, 1, &g_MsgObjectRx, true);
		printf("setToMachine Message: %s\n", g_MsgObjectRx.pucMsgData);
    
	
	return rc;
}
Beispiel #13
0
//*****************************************************************************
//
// The CAN controller interrupt handler.
//
//*****************************************************************************
void CAN0_Handler(void){ uint8_t data[4];
  uint32_t ulIntStatus, ulIDStatus;
	unsigned long temp;
  int i;
  tCANMsgObject xTempMsgObject;
  xTempMsgObject.pucMsgData = data;
  ulIntStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); // cause?
  if(ulIntStatus & CAN_INT_INTID_STATUS){  // receive?
    ulIDStatus = CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT);
    for(i = 0; i < 32; i++){    //test every bit of the mask
      if( (0x1 << i) & ulIDStatus){  // if active, get data
        CANMessageGet(CAN0_BASE, (i+1), &xTempMsgObject, true);
        if(xTempMsgObject.ulMsgID == Ping1_ID){
          //temp = (data[0]<<24)&0xFF000000 + (data[1]<<16)&0x00FF0000 + (data[2]<<8)&0x0000FF00 + data[3]&0x000000FF;
					temp = (data[0]<<24) + (data[1]<<16) + (data[2]<<8) + data[3];
					Mailbox = temp;
        }else if(xTempMsgObject.ulMsgID == Ping2_ID){
					temp = (data[0]<<24) + (data[1]<<16) + (data[2]<<8) + data[3];
					Mailbox2 = temp;
				}else if(xTempMsgObject.ulMsgID == Ping3_ID){
					temp = (data[0]<<24) + (data[1]<<16) + (data[2]<<8) + data[3];
					Mailbox3 = temp;
				}else if(xTempMsgObject.ulMsgID == Ping4_ID){
					temp = (data[0]<<24) + (data[1]<<16) + (data[2]<<8) + data[3];
					Mailbox4 = temp;
				}else if(xTempMsgObject.ulMsgID == Button1_ID){
					button1Pressed = 1;
					//add thread that compensates for wall hit
				}else if(xTempMsgObject.ulMsgID == Button2_ID){
					button2Pressed = 1;
					//add thread that compensates for wall hit
				}else if(xTempMsgObject.ulMsgID == IR_ID){
					temp = (data[0]<<24) + (data[1]<<16) + (data[2]<<8) + data[3];
					Mailbox5 = temp;
				}
      }
    }
  }
  CANIntClear(CAN0_BASE, ulIntStatus);  // acknowledge
}
Beispiel #14
0
void CAN0_Handler(void)
{ 
  unsigned char data[8];
  unsigned long ulIntStatus, ulIDStatus;
  CANmsgType rxMsg;
  int i;
  tCANMsgObject xTempMsgObject;
  xTempMsgObject.pucMsgData = data;
  
//  rxMsg.timestamp = OS_getTime();    //timestamp the CAN message
  
  ulIntStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);
  if(ulIntStatus & CAN_INT_INTID_STATUS)
  {  // receive?
    ulIDStatus = CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT);
    for(i = 0; i < 32; i++)
    {    //test every bit of the mask
      if( (0x1 << i) & ulIDStatus)
      {  // if active, get data
        CANMessageGet(CAN0_BASE, (i+1), &xTempMsgObject, true);
        rxMsg.byte0 = data[0];
        rxMsg.byte1 = data[1];
        rxMsg.byte2 = data[2];
        rxMsg.byte3 = data[3];
        rxMsg.byte4 = data[4];
        rxMsg.byte5 = data[5];
        rxMsg.byte6 = data[6];
        rxMsg.byte7 = data[7];
        rxMsg.length = xTempMsgObject.ulMsgLen;
        rxMsg.ID = xTempMsgObject.ulMsgID;
        if(CAN_RX_FIFOFifo_Put(rxMsg) == CANFIFOFAIL);
          CAN_Data_lost++;
        OS_Signal(&CANmessagesReceived);
        break;
      }
    }
  }
  CANIntClear(CAN0_BASE, ulIntStatus);  // acknowledge
}
Beispiel #15
0
//*****************************************************************************
//
// The CAN controller interrupt handler.
//
//*****************************************************************************
void CAN0_Handler(void){ unsigned char data[4];
  unsigned long ulIntStatus, ulIDStatus;
  int i;
  tCANMsgObject xTempMsgObject;
  xTempMsgObject.pucMsgData = data;
  ulIntStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); // cause?
  if(ulIntStatus & CAN_INT_INTID_STATUS){  // receive?
    ulIDStatus = CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT);
    for(i = 0; i < 32; i++){    //test every bit of the mask
      if( (0x1 << i) & ulIDStatus){  // if active, get data
        CANMessageGet(CAN0_BASE, (i+1), &xTempMsgObject, true);
        if(xTempMsgObject.ulMsgID == RCV_ID){
          RCVData[0] = data[0];
          RCVData[1] = data[1];
          RCVData[2] = data[2];
          RCVData[3] = data[3];
          MailFlag = true;   // new mail
        }
      }
    }
  }
  CANIntClear(CAN0_BASE, ulIntStatus);  // acknowledge
}
Beispiel #16
0
//*****************************************************************************
//
// Configure the CAN and enter a loop to receive CAN messages.
//
//*****************************************************************************
int
main(void)
{
    tCANMsgObject sCANMessage;
    uint8_t pui8MsgData[8];

    //
    // Set the clocking to run directly from the external crystal/oscillator.
    // TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
    // crystal used on your board.
    //
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                   SYSCTL_XTAL_16MHZ);

    //
    // Set up the serial console to use for displaying messages.  This is
    // just for this example program and is not needed for CAN operation.
    //
    InitConsole();

    //
    // For this example CAN0 is used with RX and TX pins on port B4 and B5.
    // The actual port and pins used may be different on your part, consult
    // the data sheet for more information.
    // GPIO port B needs to be enabled so these pins can be used.
    // TODO: change this to whichever GPIO port you are using
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    //
    // Configure the GPIO pin muxing to select CAN0 functions for these pins.
    // This step selects which alternate function is available for these pins.
    // This is necessary if your part supports GPIO pin function muxing.
    // Consult the data sheet to see which functions are allocated per pin.
    // TODO: change this to select the port/pin you are using
    //
    GPIOPinConfigure(GPIO_PB4_CAN0RX);
    GPIOPinConfigure(GPIO_PB5_CAN0TX);

    //
    // Enable the alternate function on the GPIO pins.  The above step selects
    // which alternate function is available.  This step actually enables the
    // alternate function instead of GPIO for these pins.
    // TODO: change this to match the port/pin you are using
    //
    GPIOPinTypeCAN(GPIO_PORTB_BASE, GPIO_PIN_4 | GPIO_PIN_5);

    //
    // The GPIO port and pins have been set up for CAN.  The CAN peripheral
    // must be enabled.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);

    //
    // Initialize the CAN controller
    //
    CANInit(CAN0_BASE);

    //
    // Set up the bit rate for the CAN bus.  This function sets up the CAN
    // bus timing for a nominal configuration.  You can achieve more control
    // over the CAN bus timing by using the function CANBitTimingSet() instead
    // of this one, if needed.
    // In this example, the CAN bus is set to 500 kHz.  In the function below,
    // the call to SysCtlClockGet() is used to determine the clock rate that
    // is used for clocking the CAN peripheral.  This can be replaced with a
    // fixed value if you know the value of the system clock, saving the extra
    // function call.  For some parts, the CAN peripheral is clocked by a fixed
    // 8 MHz regardless of the system clock in which case the call to
    // SysCtlClockGet() should be replaced with 8000000.  Consult the data
    // sheet for more information about CAN peripheral clocking.
    //
    CANBitRateSet(CAN0_BASE, SysCtlClockGet(), 500000);

    //
    // Enable interrupts on the CAN peripheral.  This example uses static
    // allocation of interrupt handlers which means the name of the handler
    // is in the vector table of startup code.  If you want to use dynamic
    // allocation of the vector table, then you must also call CANIntRegister()
    // here.
    //
    // CANIntRegister(CAN0_BASE, CAN0_IRQHandler); // if using dynamic vectors
    //
    CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);

    //
    // Enable the CAN interrupt on the processor (NVIC).
    //
    IntEnable(INT_CAN0);

    //
    // Enable the CAN for operation.
    //
    CANEnable(CAN0_BASE);

    //
    // Initialize a message object to receive CAN messages with ID 0x1001.
    // The expected ID must be set along with the mask to indicate that all
    // bits in the ID must match.
    //
    sCANMessage.ui32MsgID = 0x1001;
    sCANMessage.ui32MsgIDMask = 0xfffff;
    sCANMessage.ui32Flags = (MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER |
                             MSG_OBJ_EXTENDED_ID);
    sCANMessage.ui32MsgLen = 8;

    //
    // Now load the message object into the CAN peripheral message object 1.
    // Once loaded the CAN will receive any messages with this CAN ID into
    // this message object, and an interrupt will occur.
    //
    CANMessageSet(CAN0_BASE, 1, &sCANMessage, MSG_OBJ_TYPE_RX);

    //
    // Change the ID to 0x2001, and load into message object 2 which will be
    // used for receiving any CAN messages with this ID.  Since only the CAN
    // ID field changes, we don't need to reload all the other fields.
    //
    sCANMessage.ui32MsgID = 0x2001;
    CANMessageSet(CAN0_BASE, 2, &sCANMessage, MSG_OBJ_TYPE_RX);

    //
    // Change the ID to 0x3001, and load into message object 3 which will be
    // used for receiving any CAN messages with this ID.  Since only the CAN
    // ID field changes, we don't need to reload all the other fields.
    //
    sCANMessage.ui32MsgID = 0x3001;
    CANMessageSet(CAN0_BASE, 3, &sCANMessage, MSG_OBJ_TYPE_RX);

    //
    // Enter loop to process received messages.  This loop just checks flags
    // for each of the 3 expected messages.  The flags are set by the interrupt
    // handler, and if set this loop reads out the message and displays the
    // contents to the console.  This is not a robust method for processing
    // incoming CAN data and can only handle one messages at a time per message
    // object.  If many messages are being received close together using the
    // same message object, then some messages may be dropped.  In a real
    // application, some other method should be used for queuing received
    // messages in a way to ensure they are not lost.  You can also make use
    // of CAN FIFO mode which will allow messages to be buffered before they
    // are processed.
    //
    for(;;)
    {
        //
        // If the flag for message object 1 is set, that means that the RX
        // interrupt occurred and there is a message ready to be read from
        // this CAN message object.
        //
        if(g_bRXFlag1)
        {
            //
            // Reuse the same message object that was used earlier to configure
            // the CAN for receiving messages.  A buffer for storing the
            // received data must also be provided, so set the buffer pointer
            // within the message object.  This same buffer is used for all
            // messages in this example, but your application could set a
            // different buffer each time a message is read in order to store
            // different messages in different buffers.
            //
            sCANMessage.pui8MsgData = pui8MsgData;

            //
            // Read the message from the CAN.  Message object number 1 is used
            // (which is not the same thing as CAN ID).  The interrupt clearing
            // flag is not set because this interrupt was already cleared in
            // the interrupt handler.
            //
            CANMessageGet(CAN0_BASE, 1, &sCANMessage, 0);

            //
            // Clear the pending message flag so that the interrupt handler can
            // set it again when the next message arrives.
            //
            g_bRXFlag1 = 0;

            //
            // Print information about the message just received.
            //
            PrintCANMessageInfo(&sCANMessage, 1);
        }

        //
        // Check for message received on message object 2.  If so then
        // read message and print information.
        //
        if(g_bRXFlag2)
        {
            sCANMessage.pui8MsgData = pui8MsgData;
            CANMessageGet(CAN0_BASE, 2, &sCANMessage, 0);
            g_bRXFlag2 = 0;
            PrintCANMessageInfo(&sCANMessage, 2);
        }

        //
        // Check for message received on message object 3.  If so then
        // read message and print information.
        //
        if(g_bRXFlag3)
        {
            sCANMessage.pui8MsgData = pui8MsgData;
            CANMessageGet(CAN0_BASE, 3, &sCANMessage, 0);
            g_bRXFlag3 = 0;
            PrintCANMessageInfo(&sCANMessage, 3);
        }
    }

    //
    // Return no errors
    //
    return(0);
}
Beispiel #17
0
//*****************************************************************************
//
// Set up the system, initialize the UART, Graphics, and CAN. Then poll the
// UART for data. If there is any data send it, if there is any thing received
// print it out to the UART. If there are errors call the error handling
// function.
//
//*****************************************************************************
int
main(void)
{
    //
    // Enable lazy stacking for interrupt handlers.  This allows floating-point
    // instructions to be used within interrupt handlers, but at the expense of
    // extra stack usage.
    //
    ROM_FPULazyStackingEnable();

    //
    // Set the clocking to run directly from the crystal.
    //
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |
                       SYSCTL_OSC_MAIN);

    //
    // Initialize the UART
    //
    ConfigureUART();

    //
    // Initialize the graphical display
    //
    InitGraphics();

    //
    // Initialize CAN0
    //
    InitCAN0();

    //
    // Print welcome message
    //
    UARTprintf("\nCAN Example App\n");
    UARTprintf("Type something to see it show up on the other terminal: \n\n");

    //
    // Poll UART for data, transmit across CAN when something is entered
    //
    while(1)
    {
        //
        // If the flag is set, that means that the RX interrupt occurred and
        // there is a message ready to be read from the CAN
        //
        if(g_bRXFlag)
        {
            //
            // Reuse the same message object that was used earlier to configure
            // the CAN for receiving messages.  A buffer for storing the
            // received data must also be provided, so set the buffer pointer
            // within the message object.
            //
            g_sCAN0RxMessage.pui8MsgData = (uint8_t *) &g_ui8RXMsgData;

            //
            // Read the message from the CAN.  Message object RXOBJECT is used
            // (which is not the same thing as CAN ID).  The interrupt clearing
            // flag is not set because this interrupt was already cleared in
            // the interrupt handler.
            //
            CANMessageGet(CAN0_BASE, RXOBJECT, &g_sCAN0RxMessage, 0);

            //
            // Clear the pending message flag so that the interrupt handler can
            // set it again when the next message arrives.
            //
            g_bRXFlag = 0;

            //
            // Check to see if there is an indication that some messages were
            // lost.
            //
            if(g_sCAN0RxMessage.ui32Flags & MSG_OBJ_DATA_LOST)
            {
                UARTprintf("\nCAN message loss detected\n");
            }

            //
            // Print the received character to the UART terminal
            //
            UARTprintf("%c", g_ui8RXMsgData);

            //
            // Print the received character to the display, 
            // clear line with spaces
            //
            GrStringDrawCentered(&g_sContext, "RX Data", -1,
                                 GrContextDpyWidthGet(&g_sContext) / 2,
                                 SCREENLINE2, 0);
            GrStringDrawCentered(&g_sContext, (const char *) &g_ui8RXMsgData,
                                 1, GrContextDpyWidthGet(&g_sContext) / 2,
                                 SCREENLINE3, true);
            GrFlush(&g_sContext);
        }
        else
        {
            //
            // Error Handling
            //
            if(g_ui32ErrFlag != 0)
            {
                CANErrorHandler();
            }

            //
            // See if there is something new to transmit
            //
            while(ROM_UARTCharsAvail(UART0_BASE))
            {
                //
                // Read the next character from the UART terminal
                //
                g_ui8TXMsgData = ROM_UARTCharGetNonBlocking(UART0_BASE);

                //
                // Write the character to the display
                // clear line with spaces
                //
                GrStringDrawCentered(&g_sContext, "TX Data", -1,
                                     GrContextDpyWidthGet(&g_sContext) / 2,
                                     SCREENLINE4, true);
                GrStringDrawCentered(&g_sContext,
                                     (const char *)&g_ui8TXMsgData, 1,
                                     GrContextDpyWidthGet(&g_sContext) / 2,
                                     SCREENLINE5, true);
                GrFlush(&g_sContext);

                //
                // Send the CAN message using object number TXOBJECT (not the
                // same thing as CAN ID, which is also TXOBJECT in this
                // example).  This function will cause the message to be
                // transmitted right away.
                //
                CANMessageSet(CAN0_BASE, TXOBJECT, &g_sCAN0TxMessage,
                              MSG_OBJ_TYPE_TX);
            }
        }
    }
}
Beispiel #18
0
//*****************************************************************************
//
// This function is the interrupt handler for the CAN peripheral.  It checks
// for the cause of the interrupt, and maintains a count of all messages that
// have been transmitted.
//
//*****************************************************************************
extern "C" void CAN0IntHandler(void) {
	unsigned long ulStatus;
// Read the CAN interrupt status to find the cause of the interrupt
	ulStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);

//
// If the cause is a controller status interrupt, then get the status
//
	if (ulStatus == CAN_INT_INTID_STATUS) {
		//
		// Read the controller status.  This will return a field of status
		// error bits that can indicate various errors.  Error processing
		// is not done in this example for simplicity.  Refer to the
		// API documentation for details about the error status bits.
		// The act of reading this status will clear the interrupt.  If the
		// CAN peripheral is not connected to a CAN bus with other CAN devices
		// present, then errors will occur and will be indicated in the
		// controller status.
		//
		ulStatus = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
		if (ulStatus == CAN_STATUS_TXOK) {
		} else if (ulStatus == CAN_STATUS_RXOK) {
		} else
			/*
			 CAN_STS_CONTROL - the main controller status
			 CAN_STS_TXREQUEST - bit mask of objects pending transmissio
			 CAN_STS_NEWDAT - bit mask of objects with new data
			 CAN_STS_MSGVAL - bit mask of objects with valid configuration

			 CAN_STATUS_BUS_OFF - controller is in bus-off condition
			 CAN_STATUS_EWARN - an error counter has reached a limit of at least 96
			 CAN_STATUS_EPASS - CAN controller is in the error passive state
			 CAN_STATUS_RXOK - a message was received successfully (independent of any mes-sage filtering).
			 CAN_STATUS_TXOK - a message was successfully transmitted
			 CAN_STATUS_LEC_MSK - mask of last error code bits (3 bits)
			 CAN_STATUS_LEC_NONE - no error
			 CAN_STATUS_LEC_STUFF - stuffing error detected
			 CAN_STATUS_LEC_FORM - a format error occurred in the fixed format part of amessage
			 CAN_STATUS_LEC_ACK - a transmitted message was not acknowledged
			 CAN_STATUS_LEC_BIT1 - dominant level detected when trying to send in recessive
			 mode
			 CAN_STATUS_LEC_BIT0 - recessive level detected when trying to send in dominant
			 mode
			 CAN_STATUS_LEC_CRC - CRC error in received message
			 */
			can0._countErr++;
	}

//
// Check if the cause is message object 1, which what we are using for
// sending messages.
//
	else if (ulStatus < can0._tableIdx + 1 && ulStatus > 0) {
		uint32_t idx = ulStatus - 1;
		if (can0._table[idx].mode == CAN::RECV) {
			tCANMsgObject* msgObj = (can0._table[idx].msgObject);
			CANIntClear(CAN0_BASE, idx + 1);
			CANMessageGet(CAN0_BASE, idx + 1, msgObj, true);
			can0._countRxd++;
			CANListener* listener = can0._table[idx].listener;
			listener->recv(msgObj->ulMsgID, msgObj->ulMsgLen,
					msgObj->pucMsgData);
			CANMessageSet(CAN0_BASE, ulStatus, msgObj, MSG_OBJ_TYPE_RX);
//			CANMessageSet(CAN0_BASE, ulStatus, msgObj, MSG_OBJ_TYPE_TX); // reload
		} else if (can0._table[idx].mode == CAN::SEND) {
			CANListener* listener = can0._table[idx].listener;
			tCANMsgObject* msgObj = (can0._table[idx].msgObject);
			CANIntClear(CAN0_BASE, idx + 1);
			can0._countTxd++;
			listener->sendDone(msgObj->ulMsgID, E_OK);
		}
	}

	else {
		//
		// Spurious interrupt handling can go here.
		//
		CANIntClear(CAN0_BASE, ulStatus);
	}
}
//*****************************************************************************
//
// The CAN controller Interrupt handler.
//
//*****************************************************************************
void
CANHandler(void)
{
    unsigned long ulStatus;

    //
    // Find the cause of the interrupt, if it is a status interrupt then just
    // acknowledge the interrupt by reading the status register.
    //
    ulStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);

    switch(ulStatus)
    {
        //
        // Let the forground loop handle sending this, just set a flag to
        // indicate that the data should be sent.
        //
        case MSGOBJ_NUM_BUTTON:
        {
            //
            // Read the Button Message.
            //
            CANMessageGet(CAN0_BASE, MSGOBJ_NUM_BUTTON,
                &g_MsgObjectButton, 1);

            //
            // Only respond to buttons being release.
            //
            if(g_MsgObjectButton.pucMsgData[0] == EVENT_BUTTON_RELEASED)
            {
                //
                // Check if the up button was released.
                //
                if(g_MsgObjectButton.pucMsgData[1] == TARGET_BUTTON_UP)
                {
                    //
                    // Adjust the volume up by 10.
                    //
                    AudioVolumeUp(10);
                }

                //
                // Check if the down button was released.
                //
                if(g_MsgObjectButton.pucMsgData[1] == TARGET_BUTTON_DN)
                {
                    //
                    // Adjust the volume down by 10.
                    //
                    AudioVolumeDown(10);
                }
            }
            break;
        }

        //
        // When the LED message object interrupts, just clear the flag so that
        // more LED messages are allowed to transfer.
        //
        case MSGOBJ_NUM_LED:
        {
            g_ulFlags &= (~FLAG_LED_TX_PEND);
            break;
        }

        //
        // When the transmit data message object interrupts, clear the
        // flag so that more data can be trasferred.
        //
        case MSGOBJ_NUM_DATA_TX:
        {
            g_ulFlags &= (~FLAG_DATA_TX_PEND);
            break;
        }

        //
        // When a receive data message object interrupts, set the flag to
        // indicate that new data is ready.
        //
        case MSGOBJ_NUM_DATA_RX:
        {
            g_ulFlags |= FLAG_DATA_RECV;
            break;
        }

        //
        // This was a status interrupt so read the current status to
        // clear the interrupt and return.
        //
        default:
        {
            //
            // Read the controller status to acknowledge this interrupt.
            //
            CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);

            //
            // If there was a LED transmission pending, then stop it and
            // clear the flag.
            //
            if(g_ulFlags & FLAG_LED_TX_PEND)
            {
                //
                // Disable this message object until we retry it later.
                //
                CANMessageClear(CAN0_BASE, MSGOBJ_NUM_LED);

                //
                // Clear the transmit pending flag.
                //
                g_ulFlags &= (~FLAG_LED_TX_PEND);
            }

            //
            // If there was a Data transmission pending, then stop it and
            // clear the flag.
            //
            if(g_ulFlags & FLAG_DATA_TX_PEND)
            {
                //
                // Disable this message object until we retry it later.
                //
                CANMessageClear(CAN0_BASE, MSGOBJ_NUM_DATA_TX);

                //
                // Clear the transmit pending flag.
                //
                g_ulFlags &= (~FLAG_DATA_TX_PEND);
            }
            return;
        }
    }

    //
    // Acknowledge the CAN controller interrupt has been handled.
    //
    CANIntClear(CAN0_BASE, ulStatus);
}
Beispiel #20
0
//*****************************************************************************
//
// Configure the CAN and enter a loop to receive CAN messages.
//
//*****************************************************************************
int
main(void)
{
#if defined(TARGET_IS_TM4C129_RA0) ||                                         \
    defined(TARGET_IS_TM4C129_RA1) ||                                         \
    defined(TARGET_IS_TM4C129_RA2)
    uint32_t ui32SysClock;
#endif

    tCANMsgObject sCANMessage;
    uint8_t pui8MsgData[8];

    //
    // Set the clocking to run directly from the external crystal/oscillator.
    // TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
    // crystal used on your board.
    //
#if defined(TARGET_IS_TM4C129_RA0) ||                                         \
    defined(TARGET_IS_TM4C129_RA1) ||                                         \
    defined(TARGET_IS_TM4C129_RA2)
    ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                       SYSCTL_OSC_MAIN |
                                       SYSCTL_USE_OSC)
                                       25000000);
#else
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                   SYSCTL_XTAL_16MHZ);
#endif

    //
    // Set up the serial console to use for displaying messages.  This is
    // just for this example program and is not needed for CAN operation.
    //
    InitConsole();

    //
    // For this example CAN0 is used with RX and TX pins on port B4 and B5.
    // The actual port and pins used may be different on your part, consult
    // the data sheet for more information.
    // GPIO port B needs to be enabled so these pins can be used.
    // TODO: change this to whichever GPIO port you are using
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    //
    // Configure the GPIO pin muxing to select CAN0 functions for these pins.
    // This step selects which alternate function is available for these pins.
    // This is necessary if your part supports GPIO pin function muxing.
    // Consult the data sheet to see which functions are allocated per pin.
    // TODO: change this to select the port/pin you are using
    //
    GPIOPinConfigure(GPIO_PB4_CAN0RX);
    GPIOPinConfigure(GPIO_PB5_CAN0TX);

    //
    // Enable the alternate function on the GPIO pins.  The above step selects
    // which alternate function is available.  This step actually enables the
    // alternate function instead of GPIO for these pins.
    // TODO: change this to match the port/pin you are using
    //
    GPIOPinTypeCAN(GPIO_PORTB_BASE, GPIO_PIN_4 | GPIO_PIN_5);

    //
    // The GPIO port and pins have been set up for CAN.  The CAN peripheral
    // must be enabled.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);

    //
    // Initialize the CAN controller
    //
    CANInit(CAN0_BASE);

    //
    // Set up the bit rate for the CAN bus.  This function sets up the CAN
    // bus timing for a nominal configuration.  You can achieve more control
    // over the CAN bus timing by using the function CANBitTimingSet() instead
    // of this one, if needed.
    // In this example, the CAN bus is set to 500 kHz.  In the function below,
    // the call to SysCtlClockGet() or ui32SysClock is used to determine the 
    // clock rate that is used for clocking the CAN peripheral.  This can be 
    // replaced with a  fixed value if you know the value of the system clock, 
    // saving the extra function call.  For some parts, the CAN peripheral is 
    // clocked by a fixed 8 MHz regardless of the system clock in which case 
    // the call to SysCtlClockGet() or ui32SysClock should be replaced with 
    // 8000000.  Consult the data sheet for more information about CAN 
    // peripheral clocking.
    //
#if defined(TARGET_IS_TM4C129_RA0) ||                                         \
    defined(TARGET_IS_TM4C129_RA1) ||                                         \
    defined(TARGET_IS_TM4C129_RA2)
    CANBitRateSet(CAN0_BASE, ui32SysClock, 500000);
#else
    CANBitRateSet(CAN0_BASE, SysCtlClockGet(), 500000);
#endif

    //
    // Enable interrupts on the CAN peripheral.  This example uses static
    // allocation of interrupt handlers which means the name of the handler
    // is in the vector table of startup code.  If you want to use dynamic
    // allocation of the vector table, then you must also call CANIntRegister()
    // here.
    //
    // CANIntRegister(CAN0_BASE, CANIntHandler); // if using dynamic vectors
    //
    CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);

    //
    // Enable the CAN interrupt on the processor (NVIC).
    //
    IntEnable(INT_CAN0);

    //
    // Enable the CAN for operation.
    //
    CANEnable(CAN0_BASE);

    //
    // Initialize a message object to be used for receiving CAN messages with
    // any CAN ID.  In order to receive any CAN ID, the ID and mask must both
    // be set to 0, and the ID filter enabled.
    //
    sCANMessage.ui32MsgID = 0;
    sCANMessage.ui32MsgIDMask = 0;
    sCANMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER;
    sCANMessage.ui32MsgLen = 8;

    //
    // Now load the message object into the CAN peripheral.  Once loaded the
    // CAN will receive any message on the bus, and an interrupt will occur.
    // Use message object 1 for receiving messages (this is not the same as
    // the CAN ID which can be any value in this example).
    //
    CANMessageSet(CAN0_BASE, 1, &sCANMessage, MSG_OBJ_TYPE_RX);

    //
    // Enter loop to process received messages.  This loop just checks a flag
    // that is set by the interrupt handler, and if set it reads out the
    // message and displays the contents.  This is not a robust method for
    // processing incoming CAN data and can only handle one messages at a time.
    // If many messages are being received close together, then some messages
    // may be dropped.  In a real application, some other method should be used
    // for queuing received messages in a way to ensure they are not lost.  You
    // can also make use of CAN FIFO mode which will allow messages to be
    // buffered before they are processed.
    //
    for(;;)
    {
        unsigned int uIdx;

        //
        // If the flag is set, that means that the RX interrupt occurred and
        // there is a message ready to be read from the CAN
        //
        if(g_bRXFlag)
        {
            //
            // Reuse the same message object that was used earlier to configure
            // the CAN for receiving messages.  A buffer for storing the
            // received data must also be provided, so set the buffer pointer
            // within the message object.
            //
            sCANMessage.pui8MsgData = pui8MsgData;

            //
            // Read the message from the CAN.  Message object number 1 is used
            // (which is not the same thing as CAN ID).  The interrupt clearing
            // flag is not set because this interrupt was already cleared in
            // the interrupt handler.
            //
            CANMessageGet(CAN0_BASE, 1, &sCANMessage, 0);

            //
            // Clear the pending message flag so that the interrupt handler can
            // set it again when the next message arrives.
            //
            g_bRXFlag = 0;

            //
            // Check to see if there is an indication that some messages were
            // lost.
            //
            if(sCANMessage.ui32Flags & MSG_OBJ_DATA_LOST)
            {
                UARTprintf("CAN message loss detected\n");
            }

            //
            // Print out the contents of the message that was received.
            //
            UARTprintf("Msg ID=0x%08X len=%u data=0x",
                       sCANMessage.ui32MsgID, sCANMessage.ui32MsgLen);
            for(uIdx = 0; uIdx < sCANMessage.ui32MsgLen; uIdx++)
            {
                UARTprintf("%02X ", pui8MsgData[uIdx]);
            }
            UARTprintf("total count=%u\n", g_ui32MsgCount);
        }
    }

    //
    // Return no errors
    //
    return(0);
}
//*****************************************************************************
//
// The CAN controller interrupt handler.
//
// /return None.
//
//*****************************************************************************
void
CANHandler(void)
{
    unsigned long ulStatus;

    //
    // Find the cause of the interrupt, if it is a status interrupt then just
    // acknowledge the interrupt by reading the status register.
    //
    ulStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);

    switch(ulStatus)
    {
        //
        // Let the forground loop handle sending this, just set a flag to
        // indicate that the data should be sent.
        //
        case MSGOBJ_NUM_BUTTON:
        {
            //
            // Indicate a pending button transmission is complete.
            //
            g_ulFlags &= (~FLAG_BUTTON_PEND);

            break;
        }

        case MSGOBJ_NUM_LED:
        {
            //
            // Read the new LED level and let the foreground handle it.
            //
            CANMessageGet(CAN0_BASE, MSGOBJ_NUM_LED, &g_MsgObjectLED, 1);

            //
            // Limit the LED Level to MAX_LED_BRIGHTNESS.
            //
            if((g_ucLEDLevel & LED_FLASH_VALUE_MASK) > MAX_LED_BRIGHTNESS)
            {
                g_ucLEDLevel = MAX_LED_BRIGHTNESS |
                               (g_ucLEDLevel & LED_FLASH_ONCE);
            }

            //
            // Indicate that the LED needs to be updated.
            //
            g_ulFlags |= FLAG_UPDATE_LED;

            break;
        }

        //
        // The data transmit message object has been sent successfully.
        //
        case MSGOBJ_NUM_DATA_TX:
        {
            //
            // Clear the data transmit pending flag.
            //
            g_ulFlags &= (~FLAG_DATA_TX_PEND);
            break;
        }

        //
        // The data receive message object has received some data.
        //
        case MSGOBJ_NUM_DATA_RX:
        {
            //
            // Indicate that the data message object has new data.
            //
            g_ulFlags |= FLAG_DATA_RECV;
            break;
        }

        //
        // This was a status interrupt so read the current status to
        // clear the interrupt and return.
        //
        default:
        {
            CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);
            return;
        }
    }

    //
    // Acknowledge the CAN controller interrupt has been handled.
    //
    CANIntClear(CAN0_BASE, ulStatus);
}