Ejemplo n.º 1
0
uint32_t CAN::getMailbox(CANListener* listener, uint32_t src,
		uint32_t srcMask) {
	ASSERT(_tableIdx<32);
	_table[_tableIdx].listener = listener;
	_table[_tableIdx].src = src;
	_table[_tableIdx].mode = RECV;
	_table[_tableIdx].srcMask = srcMask;
	_table[_tableIdx].msgObject = (tCANMsgObject*) Sys::malloc(
			sizeof(tCANMsgObject));
	_table[_tableIdx].msgObject->pucMsgData = (unsigned char*) Sys::malloc(8);
	_table[_tableIdx].msgObject->ulMsgID = src;
	_table[_tableIdx].msgObject->ulMsgIDMask = srcMask;
	_table[_tableIdx].msgObject->ulMsgLen = 8;
	_table[_tableIdx].msgObject->ulFlags = MSG_OBJ_RX_INT_ENABLE
			| MSG_OBJ_USE_ID_FILTER;
	CANMessageSet(_CAN_BASE, _tableIdx + 1, _table[_tableIdx].msgObject,
			MSG_OBJ_TYPE_RX);
//	CANIntEnable(_CAN_BASE, _tableIdx + 1);
	_tableIdx++;
	_table[_tableIdx].msgObject = (tCANMsgObject*) Sys::malloc(
			sizeof(tCANMsgObject));
	_table[_tableIdx].listener = listener;
	_table[_tableIdx].mode = SEND;
	_tableIdx++;
	return _tableIdx - 2;
}
Ejemplo n.º 2
0
void platform_can_send( unsigned id, u32 canid, u8 idtype, u8 len, const u8 *data )
{
    tCANMsgObject msg_tx;
    const char *s = ( char * )data;
    char *d;

    // Wait for outgoing messages to clear
    while( can_tx_flag == 1 );

    msg_tx.ulFlags = MSG_OBJ_TX_INT_ENABLE;

    if( idtype == ELUA_CAN_ID_EXT )
        msg_tx.ulFlags |= MSG_OBJ_EXTENDED_ID;

    msg_tx.ulMsgIDMask = 0;
    msg_tx.ulMsgID = canid;
    msg_tx.ulMsgLen = len;
    msg_tx.pucMsgData = ( u8 * )can_tx_buf;

    d = can_tx_buf;
    DUFF_DEVICE_8( len,  *d++ = *s++ );

    can_tx_flag = 1;
    CANMessageSet(CAN0_BASE, 2, &msg_tx, MSG_OBJ_TYPE_TX);
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
Archivo: CANL.c Proyecto: baw959/RTOS
void BCAN_init(unsigned long bitRate)
{
  tCANMsgObject sCANMessage;
  //unsigned char ucMsgData[8];
  
  GPIO_PORTE_AFSEL_R |= 0x30; //PORTE AFSEL bits 5,4
  GPIO_PORTE_PCTL_R = (GPIO_PORTE_PCTL_R&0xFF00FFFF)|0x00880000;
  GPIO_PORTE_DEN_R |= 0x30;
  GPIO_PORTE_DIR_R |= 0x20;
  
  CAN_RX_FIFOFifo_Init();
  OS_InitSemaphore(&CANmessagesReceived,0);
  
  CANInit(CAN0_BASE);
  CANBitRateSet(CAN0_BASE, 80000000, 250000);
  //CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);    //these are enabled later with a seperate call
  //IntEnable(INT_CAN0);                              //since the filesystem can't seem to initialize while the ECU is shooting out CAN messages
  //CANEnable(CAN0_BASE);
  
  sCANMessage.ulMsgID = 0; // CAN msg ID - 0 for any
  sCANMessage.ulMsgIDMask = 0; // mask is 0 for any ID
  sCANMessage.ulFlags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER;
  sCANMessage.ulMsgLen = 8; // allow up to 8 bytes
  
  CANMessageSet(CAN0_BASE, 1, &sCANMessage, MSG_OBJ_TYPE_RX);
}
//*******************************************************************************
//					app_can_SetupMultipleMsg
//*******************************************************************************
void app_can_SendMultipleMsg(const uint64_t* pui64_msg, const uint16_t msg_length)	//msg_length is in Byte (max. is 256 Byte)
{
    const uint8_t CAN8BytePacketsNo = msg_length/8;		// CAN 8-byte Packets number to transmit
    uint8_t CANByteOnLastPacket = msg_length%8;			// Byte to transmit with last CAN frame (last frame could have length = 8 Bytes)

    uint8_t notExistShortCANPacket;
    uint8_t MsgVectorLastIndex;
    if(CANByteOnLastPacket) {							// If you need to transmit a CAN frame with n < 8 bytes of data
        notExistShortCANPacket = 0;						// exist a CAN frame which data length is < 8 bytes
        MsgVectorLastIndex = CAN8BytePacketsNo;			// thus last index of the CAN messages vector is  "CAN8BytePacketsNo".
    }													// Note that ther's some 8 bytes packets and further (shorter) packet
    // if all CAN frame which data length is < 8 bytes
    else {												// If all CAN frame are 8 Bytes lenght
        notExistShortCANPacket = 1;						// not exist a CAN frame which data length is < 8 bytes,
        MsgVectorLastIndex = CAN8BytePacketsNo - 1;		// thus last index of the CAN messages vector is  "CAN8BytePacketsNo - 1".
    }

    tCANMsgObject sCANMsgObject[CAN8BytePacketsNo];		// Declaration of "msg_lenght" CANMSGObject structure

    if(CANByteOnLastPacket==0) CANByteOnLastPacket=8;	// Impossible to have CANByteOnLastPacket=0. If it's =0, means
    // the last packet is an 8-bytes packet.
    // It occurs when msg_length is an integer multiple of 8: (8,16,24,...).

    /*____________________initialize and set all but the last CAN Message Objects_________________________*/
    volatile uint8_t i;
    for(i=0; i<=(CAN8BytePacketsNo - notExistShortCANPacket - 1); i++) {
        sCANMsgObject[i].ui32MsgID = CANMSG_ID;
        sCANMsgObject[i].ui32MsgIDMask = 0;
        sCANMsgObject[i].ui32Flags = MSG_OBJ_TX_INT_ENABLE | MSG_OBJ_FIFO;	// frame put into CAN message FIFO queue.
        sCANMsgObject[i].ui32MsgLen = 8;									// 8 byte each frame
        sCANMsgObject[i].pui8MsgData = (uint8_t*) &pui64_msg[i];

        CANMessageSet(CAN0_BASE,i+1,&sCANMsgObject[i], MSG_OBJ_TYPE_TX);	// ObjId is in the range [1-32], not [0-31].
    }

    /*________________________initialize and set the last CAN Message Objects____________________________*/
    // if exist a CAN frame which data length is < 8 bytes, then vector index of last CAN frame is "CAN8BytePacketsNo + 1"
    // if NOT exist a CAN frame which data length is < 8 bytes, then vector index of last CAN frame is "CAN8BytePacketsNo"
    sCANMsgObject[MsgVectorLastIndex].ui32MsgID = CANMSG_ID;
    sCANMsgObject[MsgVectorLastIndex].ui32MsgIDMask = 0;
    sCANMsgObject[MsgVectorLastIndex].ui32Flags = MSG_OBJ_TX_INT_ENABLE;		// On last frame must no exist flag MSG_OBJ_FIFO
    sCANMsgObject[MsgVectorLastIndex].ui32MsgLen = CANByteOnLastPacket;
    sCANMsgObject[MsgVectorLastIndex].pui8MsgData = (uint8_t*) &pui64_msg[MsgVectorLastIndex];

    CANMessageSet(CAN0_BASE,MsgVectorLastIndex+1,&sCANMsgObject[MsgVectorLastIndex], MSG_OBJ_TYPE_TX);	// ObjId is in the range [1-32], not [0-31].
}
Ejemplo n.º 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);

}
Ejemplo n.º 7
0
//Set up a message object.  Can be a TX object or an RX object.
void static CAN0_Setup_Message_Object( unsigned long MessageID, \
                                unsigned long MessageFlags, \
                                unsigned long MessageLength, \
                                unsigned char * MessageData, \
                                unsigned long ObjectID, \
                                tMsgObjType eMsgType){
  tCANMsgObject xTempObject;
  xTempObject.ulMsgID = MessageID;          // 11 or 29 bit ID
  xTempObject.ulMsgLen = MessageLength;
  xTempObject.pucMsgData = MessageData;
  xTempObject.ulFlags = MessageFlags;
  CANMessageSet(CAN0_BASE, ObjectID, &xTempObject, eMsgType);
}
Ejemplo n.º 8
0
void NetworkMsgInit(void)
{
	g_MsgRx.ulMsgID = MSG_ID_RX;
	g_MsgRx.ulMsgIDMask = 0;
	g_MsgRx.ulFlags = MSG_OBJ_RX_INT_ENABLE;
	g_MsgRx.ulMsgLen = 4;
	g_MsgRx.pucMsgData = (unsigned char *)&g_ulRxData;
    CANMessageSet(CAN0_BASE, MSG_NUM_RX, &g_MsgRx, MSG_OBJ_TYPE_RX);

    g_MsgTx.ulMsgID = MSG_ID_TX;
    g_MsgTx.ulMsgIDMask = 0;
    g_MsgTx.ulFlags = 0;
    g_MsgTx.ulMsgLen = 4;
}
Ejemplo n.º 9
0
//*****************************************************************************
//
// 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);
}
//*****************************************************************************
//
// This functions sends out a button update message.
//
//*****************************************************************************
void SendMessage(unsigned char *data,volatile unsigned long count)
{
    tx_msg_object.ulFlags = MSG_OBJ_EXTENDED_ID;
    tx_msg_object.ulMsgID = 0x10;
    tx_msg_object.ulMsgIDMask = 0;
    tx_msg_object.ulMsgLen = 8;
    tx_msg_object.pucMsgData = data;                //allocate memory for TX buffer
    tx_msg_object.pucMsgData[0] = 1 + count;
    tx_msg_object.pucMsgData[1] = 2 + count;
    tx_msg_object.pucMsgData[2] = 3 + count;
    tx_msg_object.pucMsgData[3] = 4 + count;
    tx_msg_object.pucMsgData[4] = 5 + count;
    tx_msg_object.pucMsgData[5] = 6 + count;
    tx_msg_object.pucMsgData[6] = 7 + count;
    tx_msg_object.pucMsgData[7] = 8 + count;
    CANMessageSet(CAN0_BASE, 1, &tx_msg_object, MSG_OBJ_TYPE_TX);
}
//*****************************************************************************
//
// This functions sends out a button update message.
//
//*****************************************************************************
void
SendButtonMsg(unsigned char ucEvent, unsigned char ucButton)
{
    //
    // Set the flag to indicate that a button status is being sent.
    //
    g_ulFlags |= FLAG_BUTTON_PEND;

    //
    // Send the button status.
    //
    g_MsgObjectButton.pucMsgData[0] = ucEvent;
    g_MsgObjectButton.pucMsgData[1] = ucButton;

    CANMessageSet(CAN0_BASE, MSGOBJ_NUM_BUTTON, &g_MsgObjectButton,
                  MSG_OBJ_TYPE_TX);
}
//*****************************************************************************
//
// 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;
        }
    }
}
Ejemplo n.º 13
0
//*****************************************************************************
//
// 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);
}
Ejemplo n.º 14
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;
}
Ejemplo n.º 15
0
static int can_init(const can_cfg_t *cfg)
{
	tCANMsgObject MsgObjectRx;
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
	GPIOPinTypeCAN(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1);
	CANInit(CAN0_BASE);

	//PLLclock is 400M, and can module clock is 8M(400/50)
	if (CANBitRateSet(CAN0_BASE, 8000000, cfg->baud) == 0)
		return 1;

	//can receive setting,set MsgIDMask value to zero, receive all!
	MsgObjectRx.ulFlags = MSG_OBJ_NO_FLAGS | MSG_OBJ_USE_ID_FILTER;
	MsgObjectRx.ulMsgIDMask = 0;
	CANMessageSet(CAN0_BASE, LM3S_RxMsgObjNr, &MsgObjectRx, MSG_OBJ_TYPE_RX);
	CANEnable(CAN0_BASE);

	return 0;
}
Ejemplo n.º 16
0
/*
	nonblocked send, success return 0, else return -1
*/
int can_send(const can_msg_t *msg)
{
	unsigned long status;
	tCANMsgObject MsgObjectTx;

	status = CANStatusGet(CAN0_BASE, CAN_STS_TXREQUEST);
	if(status & (unsigned long)(1 << (LM3S_TxMsgObjNr - 1)))
		return 1;

	MsgObjectTx.ulMsgID = msg->id;
	MsgObjectTx.ulMsgLen = msg->dlc;
	MsgObjectTx.pucMsgData = (unsigned char *)msg->data;
	if (msg->flag) {
		MsgObjectTx.ulFlags = MSG_OBJ_EXTENDED_ID;
	} else {
		MsgObjectTx.ulFlags = MSG_OBJ_NO_FLAGS;
	}

	CANRetrySet(CAN0_BASE, LM3S_TxMsgObjNr);	//set retry send
	CANMessageSet(CAN0_BASE, LM3S_TxMsgObjNr, &MsgObjectTx, MSG_OBJ_TYPE_TX);

	return 0;
}
Ejemplo n.º 17
0
void send(){
	// Bounds-check each pwm signal
	if(pwm0 > MAX_WIDTH_0)
		pwm0= MAX_WIDTH_0;
	else if(pwm0 < MIN_WIDTH_0)
		pwm0= MIN_WIDTH_0;
	
	if(pwm1 > MAX_WIDTH_1)
		pwm1= MAX_WIDTH_1;
	else if(pwm1 < MIN_WIDTH_1)
		pwm1= MIN_WIDTH_1;
	
	// Write both unsigned longs to the 8-byte space and send it
	msg[0]= (pwm0 & 0xFF000000) >> 24;
	msg[1]= (pwm0 & 0x00FF0000) >> 16;
	msg[2]= (pwm0 & 0x0000FF00) >> 8;
	msg[3]= pwm0 & 0x000000FF;
	msg[4]= (pwm1 & 0xFF000000) >> 24;
	msg[5]= (pwm1 & 0x00FF0000) >> 16;
	msg[6]= (pwm1 & 0x0000FF00) >> 8;
	msg[7]= pwm1 & 0x000000FF;
	transmit.pucMsgData= msg;
	CANMessageSet(CAN0_BASE, 1, &transmit, MSG_OBJ_TYPE_TX);
}
Ejemplo n.º 18
0
//*****************************************************************************
//
// This function sends a message to set the current brightness for the LED on
// the target board.
//
//*****************************************************************************
void
CANUpdateTargetLED(unsigned char ucLevel, tBoolean bFlash)
{
    //
    // If there was already a previous message being transmitted then just
    // return.
    //
    if(g_ulFlags & FLAG_LED_TX_PEND)
    {
        return;
    }

    //
    // Set the global LED level.
    //
    g_ucLEDLevel = ucLevel;

    //
    // If a flash was requested then set the flag.
    //
    if(bFlash == true)
    {
        g_ucLEDLevel |= LED_FLASH_ONCE;
    }

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

    //
    // Send the button update request.
    //
    CANMessageSet(CAN0_BASE, MSGOBJ_NUM_LED, &g_MsgObjectLED,
                  MSG_OBJ_TYPE_TX);
}
Ejemplo n.º 19
0
void CAN::send(uint32_t mailbox, uint32_t dstAddress, uint8_t* data,
		uint32_t length) {
	ASSERT(length<9);
	uint32_t idx = mailbox + 1; // +1 for transmission
	tCANMsgObject* mo = _table[idx].msgObject;
	_table[idx].mode = SEND;

	mo->ulMsgID = dstAddress; // CAN message ID
	mo->ulMsgIDMask = 0; // no mask needed for TX
	mo->ulFlags = MSG_OBJ_TX_INT_ENABLE + MSG_OBJ_FIFO; // enable interrupt on TX
	mo->ulMsgLen = length; // size of message is length
	mo->pucMsgData = data; // ptr to message content
	CANIntEnable(_CAN_BASE, idx + 1);
	CANMessageSet(_CAN_BASE, idx + 1, mo, MSG_OBJ_TYPE_TX);
	/*	uint32_t st;
	 while ((st = CANStatusGet(_CAN_BASE, CAN_STS_TXREQUEST)) == 0) {

	 }
	 CANMessageGet(_CAN_BASE, st, mo, true);
	 while (CANStatusGet(_CAN_BASE, CAN_STS_TXREQUEST) == 0) {

	 }
	 st = CANStatusGet(_CAN_BASE, CAN_STS_TXREQUEST);*/
}
Ejemplo n.º 20
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);
}
Ejemplo n.º 21
0
int main(void) {
  char txtBuffer[32];

  SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                 SYSCTL_XTAL_16MHZ);

  SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);

  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);

  GPIOPinConfigure(GPIO_PE4_CAN0RX);
  GPIOPinConfigure(GPIO_PE5_CAN0TX);

  GPIOPinTypeCAN(GPIO_PORTE_BASE, GPIO_PIN_4 | GPIO_PIN_5);

  CANInit(CAN0_BASE);

  CANBitRateSet(CAN0_BASE, SysCtlClockGet(), 500000);

  CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);

  IntEnable(INT_CAN0);

  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.ui32MsgIDMask = 0x7ff; // mask is 0 for any ID
  sCANMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER;
  sCANMessage.ui32MsgLen = 16; // 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).
  //
  sCANMessage.ui32MsgID = 0x0b0; // wheels A
  sCANMessage.pui8MsgData = (uint8_t *)&wheel_a_data;
  CANMessageSet(CAN0_BASE, 1, &sCANMessage, MSG_OBJ_TYPE_RX);

  sCANMessage.ui32MsgID = 0x0b2; // wheels B
  sCANMessage.pui8MsgData = (uint8_t *)&wheel_b_data;
  CANMessageSet(CAN0_BASE, 2, &sCANMessage, MSG_OBJ_TYPE_RX);

  sCANMessage.ui32MsgID = 0x2c4; // engine
  sCANMessage.pui8MsgData = (uint8_t *)&engine_data;
  CANMessageSet(CAN0_BASE, 3, &sCANMessage, MSG_OBJ_TYPE_RX);

  sCANMessage.ui32MsgID = 0x398; // fuel
  sCANMessage.pui8MsgData = (uint8_t *)&fuel_data;
  CANMessageSet(CAN0_BASE, 4, &sCANMessage, MSG_OBJ_TYPE_RX);

  lcd_port_setup();
  lcd_init();

  for (;;) {
    unsigned int li, lf, ri, rf, fi, ff; // integral and fractional parts for left, right wheels' speed, and fuel consumption
    unsigned long int v = 0; // Average speed
    float vf, ef; // Float versions of speed and economy
    li = ntohs(wheel_a_data.wheel2);
    v += li;
    lf = li%100;
    li /= 100;
    ri = ntohs(wheel_a_data.wheel1);
    v += ri;
    rf = ri%100;
    ri /= 100;
    snprintf(txtBuffer, 21, "L %3d.%02d -- R %3d.%02d", li, lf, ri, rf);
    lcd_goto(0,0);
    lcd_puts(txtBuffer);
    
    li = ntohs(wheel_b_data.wheel2);
    v += li;
    lf = li%100;
    li /= 100;
    ri = ntohs(wheel_b_data.wheel1);
    v += ri;
    rf = ri%100;
    ri /= 100;
    snprintf(txtBuffer, 21, "L %3d.%02d -- R %3d.%02d", li, lf, ri, rf);
    lcd_goto(1,0);
    lcd_puts(txtBuffer);
    
    vf = v / 400.0;
    snprintf(txtBuffer, 21, "%4d RPM %3d.%02d KM/H", ntohs(engine_data.rpm), (int)vf, ((int)(vf*100))%100);
    lcd_goto(2,0);
    lcd_puts(txtBuffer);
    
    fi = ntohs(fuel_data.fuel);
    ff = fi % 100;
    fi /= 100;
    if (vf >= .01) {
      ef = vf/(fi/100.0);
      snprintf(txtBuffer, 21, "%2d.%02d L/H %2d.%02d KM/L", fi, ff, (int)ef, ((int)(ef*100))%100);
    } else {
      snprintf(txtBuffer, 21, "%2d.%02d L/H --.-- KM/L", fi, ff);
    }
    lcd_goto(3,0);
    lcd_puts(txtBuffer);
  }

  return (0);
}
//*****************************************************************************
//
// Configure the CAN and enter a loop to transmit periodic CAN messages.
//
//*****************************************************************************
int
main(void)
{
    //
    // 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 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, 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 the message object that will be used for sending CAN
    // messages.  The message will be 4 bytes that will contain an incrementing
    // value.  Initially it will be set to 0.
    //

    //
    // Initialize message object 1 to be able to send CAN message 1.  This
    // message object is not shared so it only needs to be initialized one
    // time, and can be used for repeatedly sending the same message ID.
    //
    g_sCANMsgObject1.ui32MsgID = 0x1001;
    g_sCANMsgObject1.ui32MsgIDMask = 0;
    g_sCANMsgObject1.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
    g_sCANMsgObject1.ui32MsgLen = sizeof(g_pui8Msg1);
    g_sCANMsgObject1.pui8MsgData = g_pui8Msg1;

    //
    // Initialize message object 2 to be able to send CAN message 2.  This
    // message object is not shared so it only needs to be initialized one
    // time, and can be used for repeatedly sending the same message ID.
    //
    g_sCANMsgObject2.ui32MsgID = 0x2001;
    g_sCANMsgObject2.ui32MsgIDMask = 0;
    g_sCANMsgObject2.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
    g_sCANMsgObject2.ui32MsgLen = sizeof(g_pui8Msg2);
    g_sCANMsgObject2.pui8MsgData = g_pui8Msg2;

    //
    // Enter loop to send messages.  Four messages will be sent once per
    // second.  The contents of each message will be changed each time.
    //
    for(;;)
    {
        //
        // Send message 1 using CAN controller message object 1.  This is
        // the only message sent using this message object.  The
        // CANMessageSet() function will cause the message to be sent right
        // away.
        //
        PrintCANMessageInfo(&g_sCANMsgObject1, 1);
        CANMessageSet(CAN0_BASE, 1, &g_sCANMsgObject1, MSG_OBJ_TYPE_TX);

        //
        // Send message 2 using CAN controller message object 2.  This is
        // the only message sent using this message object.  The
        // CANMessageSet() function will cause the message to be sent right
        // away.
        //
        PrintCANMessageInfo(&g_sCANMsgObject2, 2);
        CANMessageSet(CAN0_BASE, 2, &g_sCANMsgObject2, MSG_OBJ_TYPE_TX);

        //
        // Load message object 3 with message 3.  This is needs to be done each
        // time because message object 3 is being shared for two different
        // messages.
        //
        g_sCANMsgObject3.ui32MsgID = 0x3001;
        g_sCANMsgObject3.ui32MsgIDMask = 0;
        g_sCANMsgObject3.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
        g_sCANMsgObject3.ui32MsgLen = sizeof(g_pui8Msg3);
        g_sCANMsgObject3.pui8MsgData = g_pui8Msg3;

        //
        // Clear the flag that indicates that message 3 has been sent.  This
        // flag will be set in the interrupt handler when a message has been
        // sent using message object 3.
        //
        g_bMsgObj3Sent = 0;

        //
        // Now send message 3 using CAN controller message object 3.  This is
        // the first message sent using this message object.  The
        // CANMessageSet() function will cause the message to be sent right
        // away.
        //
        PrintCANMessageInfo(&g_sCANMsgObject3, 3);
        CANMessageSet(CAN0_BASE, 3, &g_sCANMsgObject3, MSG_OBJ_TYPE_TX);

        //
        // Wait for the indication from the interrupt handler that message
        // object 3 is done, because we are re-using it for another message.
        //
        while(!g_bMsgObj3Sent)
        {
        }

        //
        // Load message object 3 with message 4.  This is needed because
        // message object 3 is being shared for two different messages.
        //
        g_sCANMsgObject3.ui32MsgID = 0x3002;
        g_sCANMsgObject3.ui32MsgIDMask = 0;
        g_sCANMsgObject3.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
        g_sCANMsgObject3.ui32MsgLen = sizeof(g_pui8Msg4);
        g_sCANMsgObject3.pui8MsgData = g_pui8Msg4;

        //
        // Now send message 4 using CAN controller message object 3.  This is
        // the second message sent using this message object.  The
        // CANMessageSet() function will cause the message to be sent right
        // away.
        //
        PrintCANMessageInfo(&g_sCANMsgObject3, 3);
        CANMessageSet(CAN0_BASE, 3, &g_sCANMsgObject3, MSG_OBJ_TYPE_TX);

        //
        // Wait 1 second before continuing
        //
        SimpleDelay();

        //
        // Check the error flag to see if errors occurred
        //
        if(g_bErrFlag)
        {
            UARTprintf(" error - cable connected?\n");
        }
        else
        {
            //
            // If no errors then print the count of message sent
            //
            UARTprintf(" total count = %u\n",
                       g_ui32Msg1Count + g_ui32Msg2Count + g_ui32Msg3Count);
        }

        //
        // Change the value in the message data for each of the messages.
        //
        (*(uint32_t *)g_pui8Msg1)++;
        (*(uint32_t *)g_pui8Msg2)++;
        (*(uint32_t *)g_pui8Msg3)++;
        (*(uint32_t *)&g_pui8Msg4[0])++;
        (*(uint32_t *)&g_pui8Msg4[4])--;
    }

    //
    // Return no errors
    //
    return(0);
}
Ejemplo n.º 23
0
//*****************************************************************************
//
// Configure the CAN and enter a loop to transmit periodic CAN messages.
//
//*****************************************************************************
int
main(void)
{
    tCANMsgObject sCANMessage;
    uint32_t ui32MsgData;
    uint8_t *pui8MsgData;

    pui8MsgData = (uint8_t *)&ui32MsgData;

    //
    // 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 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 the message object that will be used for sending CAN
    // messages.  The message will be 4 bytes that will contain an incrementing
    // value.  Initially it will be set to 0.
    //
    ui32MsgData = 0;
    sCANMessage.ui32MsgID = 1;
    sCANMessage.ui32MsgIDMask = 0;
    sCANMessage.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
    sCANMessage.ui32MsgLen = sizeof(pui8MsgData);
    sCANMessage.pui8MsgData = pui8MsgData;

    //
    // Enter loop to send messages.  A new message will be sent once per
    // second.  The 4 bytes of message content will be treated as an uint32_t
    // and incremented by one each time.
    //
    while(1)
    {
        //
        // Print a message to the console showing the message count and the
        // contents of the message being sent.
        //
        UARTprintf("Sending msg: 0x%02X %02X %02X %02X",
                   pui8MsgData[0], pui8MsgData[1], pui8MsgData[2],
                   pui8MsgData[3]);

        //
        // Send the CAN message using object number 1 (not the same thing as
        // CAN ID, which is also 1 in this example).  This function will cause
        // the message to be transmitted right away.
        //
        CANMessageSet(CAN0_BASE, 1, &sCANMessage, MSG_OBJ_TYPE_TX);

        //
        // Now wait 1 second before continuing
        //
        SimpleDelay();

        //
        // Check the error flag to see if errors occurred
        //
        if(g_bErrFlag)
        {
            UARTprintf(" error - cable connected?\n");
        }
        else
        {
            //
            // If no errors then print the count of message sent
            //
            UARTprintf(" total count = %u\n", g_ui32MsgCount);
        }

        //
        // Increment the value in the message data.
        //
        ui32MsgData++;
    }

    //
    // Return no errors
    //
    return(0);
}
Ejemplo n.º 24
0
void NetworkTx(unsigned long ulData)
{
	g_MsgTx.pucMsgData = (unsigned char *)&ulData;
	CANMessageSet(CAN0_BASE, MSG_NUM_TX, &g_MsgTx, MSG_OBJ_TYPE_TX);
}
//*****************************************************************************
//
// This function configures the transmit FIFO and copies data into the FIFO.
//
//*****************************************************************************
int
CANTransmitFIFO(unsigned char *pucData, unsigned long ulSize)
{
    int iIdx;

    //
    // This is the message object used to send button updates.  This message
    // object will not be "set" right now as that would trigger a transmission.
    //
    g_sCAN.MsgObjectTx.ulMsgID = TRANSMIT_MESSAGE_ID;
    g_sCAN.MsgObjectTx.ulMsgIDMask = 0;

    //
    // This enables interrupts for transmitted messages.
    //
    g_sCAN.MsgObjectTx.ulFlags = MSG_OBJ_TX_INT_ENABLE;

    //
    // Return the maximum possible number of bytes that can be sent in a single
    // FIFO.
    //
    if(ulSize > CAN_FIFO_SIZE)
    {
        return(CAN_FIFO_SIZE);
    }

    //
    // Loop through all eight message objects that are part of the transmit
    // FIFO.
    //
    for(iIdx = 0; iIdx < 8; iIdx++)
    {
        //
        // If there are more than eight bytes remaining then use a full message
        // to transfer these 8 bytes.
        //
        if(ulSize > 8)
        {
            //
            // Set the length of the message, which can only be eight bytes
            // in this case as it is all that can be sent with a single message
            // object.
            //
            g_sCAN.MsgObjectTx.ulMsgLen = 8;
            g_sCAN.MsgObjectTx.pucMsgData = &pucData[iIdx * 8];

            //
            // Set the MSG_OBJ_FIFO to indicate that this is not the last
            // data in a chain of FIFO entries.
            //
            g_sCAN.MsgObjectTx.ulFlags |= MSG_OBJ_FIFO;

            //
            // There are now eight less bytes to transmit.
            //
            ulSize -= 8;

            //
            // Write out this message object.
            //
            CANMessageSet(CAN0_BASE, iIdx + 1, &g_sCAN.MsgObjectTx,
                          MSG_OBJ_TYPE_TX);
        }
        //
        // If there are less than or exactly eight bytes remaining then use a
        // message object to transfer these 8 bytes and do not set the
        // MSG_OBJ_FIFO flag to indicate that this is the last of the entries
        // in this FIFO.
        //
        else
        {
            //
            // Set the length to the remaining bytes and transmit the data.
            //
            g_sCAN.MsgObjectTx.ulMsgLen = ulSize;
            g_sCAN.MsgObjectTx.pucMsgData = &pucData[iIdx * 8];

            //
            // Write out this message object.
            //
            CANMessageSet(CAN0_BASE, iIdx + 1, &g_sCAN.MsgObjectTx,
                          MSG_OBJ_TYPE_TX);
        }
    }
    return(0);
}
//*****************************************************************************
//
// This function configures the receive FIFO and should only be called once.
//
//*****************************************************************************
int
CANReceiveFIFO(unsigned char *pucData, unsigned long ulSize)
{
    int iIdx;

    if(ulSize > CAN_FIFO_SIZE)
    {
        return(CAN_FIFO_SIZE);
    }

    //
    // Configure the receive message FIFO to accept the transmit message object.
    //
    g_sCAN.MsgObjectRx.ulMsgID = RECEIVE_MESSAGE_ID;
    g_sCAN.MsgObjectRx.ulMsgIDMask = 0;

    //
    // This enables interrupts for received messages.
    //
    g_sCAN.MsgObjectRx.ulFlags = MSG_OBJ_RX_INT_ENABLE;

    //
    // Remember the beginning of the FIFO location.
    //
    g_sCAN.MsgObjectRx.pucMsgData = pucData;

    //
    // Transfer bytes in multiples of eight bytes.
    //
    for(iIdx=0; iIdx < (CAN_FIFO_SIZE / 8); iIdx++)
    {
        //
        // If there are more than eight remaining to be sent then just queue up
        // eight bytes and go on to the next message object(s) for the
        // remaining bytes.
        //
        if(ulSize > 8)
        {
            //
            // The length is always eight as the full buffer is divisible by 8.
            //
            g_sCAN.MsgObjectRx.ulMsgLen = 8;

            //
            // There are now eight less bytes to receive.
            //
            ulSize -=8;

            //
            // Set the MSG_OBJ_FIFO to indicate that this is not the last
            // data in a chain of FIFO entries.
            //
            g_sCAN.MsgObjectRx.ulFlags |= MSG_OBJ_FIFO;

            //
            // Make sure that all message objects up to the last indicate that
            // they are part of a FIFO.
            //
            CANMessageSet(CAN0_BASE, iIdx + 9, &g_sCAN.MsgObjectRx,
                          MSG_OBJ_TYPE_RX);
        }
        else
        {
            //
            // Get the remaining bytes.
            //
            g_sCAN.MsgObjectRx.ulMsgLen = ulSize;

            //
            // This is the last message object in a FIFO so don't set the FIFO
            // to indicate that the FIFO ends with this message object.
            //
            CANMessageSet(CAN0_BASE, iIdx + 9, &g_sCAN.MsgObjectRx,
                          MSG_OBJ_TYPE_RX);
        }
    }
    return(0);
}
Ejemplo n.º 27
0
//*****************************************************************************
//
// This function configures the message objects used by this application.
// The following four message objects used by this application:
// MSGOBJ_ID_BUTTON, MSGOBJ_ID_LED, MSGOBJ_ID_DATA_TX, and MSGOBJ_ID_DATA_RX.
//
//*****************************************************************************
void
CANConfigureNetwork(void)
{
    //
    // Set the identifier and mask for the button object.
    //
    g_MsgObjectButton.ulMsgID = MSGOBJ_ID_BUTTON;
    g_MsgObjectButton.ulMsgIDMask = 0;

    //
    // This enables interrupts for received messages.
    //
    g_MsgObjectButton.ulFlags = MSG_OBJ_RX_INT_ENABLE;

    //
    // Set the size of the message and the data buffer used.
    //
    g_MsgObjectButton.ulMsgLen = 2;
    g_MsgObjectButton.pucMsgData = g_pucButtonMsg;

    //
    // Configure the Button receive message object.
    //
    CANMessageSet(CAN0_BASE, MSGOBJ_NUM_BUTTON, &g_MsgObjectButton,
                  MSG_OBJ_TYPE_RX);

    //
    // This message object will receive updates to the LED.
    //
    g_MsgObjectLED.ulMsgID = MSGOBJ_ID_LED;
    g_MsgObjectLED.ulMsgIDMask = 0;

    //
    // This enables interrupts for received messages.
    //
    g_MsgObjectLED.ulFlags = MSG_OBJ_TX_INT_ENABLE;

    //
    // Set the length of the message and the data buffer used.
    //
    g_MsgObjectLED.ulMsgLen = 1;
    g_MsgObjectLED.pucMsgData = &g_ucLEDLevel;

    //
    // This message object will transmit commands.
    //
    g_MsgObjectTx.ulMsgID = MSGOBJ_ID_DATA_TX;
    g_MsgObjectTx.ulMsgIDMask = 0;

    //
    // This enables interrupts for received messages.
    //
    g_MsgObjectTx.ulFlags = MSG_OBJ_TX_INT_ENABLE;

    //
    // The length of the message, which should only be one byte.  Don't set
    // the pointer until it is used.
    //
    g_MsgObjectTx.ulMsgLen = 1;
    g_MsgObjectTx.pucMsgData = (unsigned char *)0xffffffff;

    //
    // This message object will received data from commands.
    //
    g_MsgObjectRx.ulMsgID = MSGOBJ_ID_DATA_RX;
    g_MsgObjectRx.ulMsgIDMask = 0;

    //
    // This enables interrupts for received messages.
    //
    g_MsgObjectRx.ulFlags = MSG_OBJ_RX_INT_ENABLE;

    //
    // The length of the message, which should only be one byte.  Don't set
    // the pointer until it is used.
    //
    g_MsgObjectRx.ulMsgLen = 1;
    g_MsgObjectRx.pucMsgData = (unsigned char *)0xffffffff;

    //
    // Configure the data receive message object.
    //
    CANMessageSet(CAN0_BASE, MSGOBJ_NUM_DATA_RX, &g_MsgObjectRx,
                  MSG_OBJ_TYPE_RX);
}
Ejemplo n.º 28
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);
	}
}
//*****************************************************************************
//
// Configure CAN message objects for the application.
//
// This function configures the message objects used by this application.
// The following four message objects used by this application:
// MSGOBJ_ID_BUTTON, MSGOBJ_ID_LED, MSGOBJ_ID_DATA_TX, and MSGOBJ_ID_DATA_RX.
//
// /return None.
//
//*****************************************************************************
void
CANConfigureNetwork(void)
{
    //
    // This is the message object used to send button updates.  This message
    // object will not be "set" right now as that would trigger a transmission.
    //
    g_MsgObjectButton.ulMsgID = MSGOBJ_ID_BUTTON;
    g_MsgObjectButton.ulMsgIDMask = 0;

    //
    // This enables interrupts for transmitted messages.
    //
    g_MsgObjectButton.ulFlags = MSG_OBJ_TX_INT_ENABLE;

    //
    // Set the length of the message, which should only be two bytes and the
    // data is always whatever is in g_pucButtonMsg.
    //
    g_MsgObjectButton.ulMsgLen = 2;
    g_MsgObjectButton.pucMsgData = g_pucButtonMsg;

    //
    // This message object will receive updates for the LED brightness.
    //
    g_MsgObjectLED.ulMsgID = MSGOBJ_ID_LED;
    g_MsgObjectLED.ulMsgIDMask = 0;

    //
    // This enables interrupts for received messages.
    //
    g_MsgObjectLED.ulFlags = MSG_OBJ_RX_INT_ENABLE;

    //
    // The length of the message, which should only be one byte.
    //
    g_MsgObjectLED.ulMsgLen = 1;
    g_MsgObjectLED.pucMsgData = &g_ucLEDLevel;
    CANMessageSet(CAN0_BASE, MSGOBJ_NUM_LED, &g_MsgObjectLED,
                  MSG_OBJ_TYPE_RX);

    //
    // This message object will transmit commands and command responses.  It
    // will not be "set" right now as that would trigger a transmission.
    //
    g_MsgObjectTx.ulMsgID = MSGOBJ_ID_DATA_TX;
    g_MsgObjectTx.ulMsgIDMask = 0;

    //
    // This enables interrupts for transmitted messages.
    //
    g_MsgObjectTx.ulFlags = MSG_OBJ_TX_INT_ENABLE;

    //
    // The length of the message, which should only be one byte.  Don't set
    // the pointer until it is used.
    //
    g_MsgObjectTx.ulMsgLen = 1;
    g_MsgObjectTx.pucMsgData = (unsigned char *)0xffffffff;

    //
    // This message object will receive commands or data from commands.
    //
    g_MsgObjectRx.ulMsgID = MSGOBJ_ID_DATA_RX;
    g_MsgObjectRx.ulMsgIDMask = 0;

    //
    // This enables interrupts for received messages.
    //
    g_MsgObjectRx.ulFlags = MSG_OBJ_RX_INT_ENABLE;

    //
    // The length of the message, which should only be one byte.  Don't set
    // the pointer until it is used.
    //
    g_MsgObjectRx.ulMsgLen = 1;
    g_MsgObjectRx.pucMsgData = (unsigned char *)0xffffffff;
    CANMessageSet(CAN0_BASE, MSGOBJ_NUM_DATA_RX, &g_MsgObjectRx,
                  MSG_OBJ_TYPE_RX);
}
Ejemplo n.º 30
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);
}