This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28379D: Communicating two F28379d launchpads using CAN

Part Number: TMS320F28379D

Hello,

I am trying to communicate two F28379d launchpads using CAN for example can_ex3_external_transmit.

I followed this advice from one of the thread,

"In Launchpad, GPIO12 and GPIO17 have direct connections to the CAN transceiver. This means that the CANB should be used in the can_ex3_external_transmit_code. Value for DEVICE_GPIO_CFG_CANRXB should be changed to GPIO_17_CANRXB and DEVICE_GPIO_CFG_CANTXB to GPIO_12_CANTXB. On the first Launchpad you need to modify the example code so that CANB will be transmitting and you can remove the ISR for the receive routines (essentially remove references and functions pertaining to CANB and replace references and functions on CANA to CANB on the ex3 sample code). On the second Launchpad, you just need to delete references and functions on CANA. The ex3 sample code is already has an ISR set for CANB to receive data from the CAN bus".

Updated the code accordingly but no luck. Please advice me in this matter.

Regards,

Sohail

Here is code:

for transmission:

//#############################################################################
//
// FILE: can_ex3_external_transmit.c
//
// TITLE: CAN External Transmit Example
//
//! \addtogroup driver_example_list
//! <h1> CAN-A to CAN-B External Transmit </h1>
//!
//! This example initializes CAN module A and CAN module B for external
//! communication. CAN-A module is setup to transmit incrementing data for "n"
//! number of times to the CAN-B module, where "n" is the value of TXCOUNT.
//! CAN-B module is setup to trigger an interrupt service routine (ISR) when
//! data is received. An error flag will be set if the transmitted data doesn't
//! match the received data.
//!
//! \note Both CAN modules on the device need to be
//! connected to each other via CAN transceivers. GPIOs will be different
//! on Launchpad.
//!
//! \b Hardware \b Required \n
//! - A C2000 board with two CAN transceivers
//!
//! \b External \b Connections \n
//! - ControlCARD CANA is on GPIO31 (CANTXA) and GPIO30 (CANRXA)
//! - ControlCARD CANB is on GPIO8 (CANTXB) and GPIO10 (CANRXB)
//!
//! \b Watch \b Variables \n
//! - TXCOUNT - Adjust to set the number of messages to be transmitted
//! - txMsgCount - A counter for the number of messages sent
//! - rxMsgCount - A counter for the number of messages received
//! - txMsgData - An array with the data being sent
//! - rxMsgData - An array with the data that was received
//! - errorFlag - A flag that indicates an error has occurred
//!
//
//#############################################################################
// $TI Release: F2837xD Support Library v3.05.00.00 $
// $Release Date: Thu Oct 18 15:48:42 CDT 2018 $
// $Copyright:
// Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################

//
// Included Files
//
#include "driverlib.h"
#include "device.h"

//
// Defines
//
#define TXCOUNT 100
#define MSG_DATA_LENGTH 4
#define TX_MSG_OBJ_ID 1
#define RX_MSG_OBJ_ID 1

//
// Globals
//
volatile unsigned long i;
volatile uint32_t txMsgCount = 0;
volatile uint32_t rxMsgCount = 0;
volatile uint32_t errorFlag = 0;
uint16_t txMsgData[4];
uint16_t rxMsgData[4];

//
// Function Prototypes
//
__interrupt void canbISR(void);

//
// Main
//
void main(void)
{
//
// Initialize device clock and peripherals
//
Device_init();

//
// Initialize GPIO and configure GPIO pins for CANTX/CANRX
// on module A and B
//
Device_initGPIO();
//GPIO_setPinConfig(DEVICE_GPIO_CFG_CANRXA);
//GPIO_setPinConfig(DEVICE_GPIO_CFG_CANTXA);
GPIO_setPinConfig(GPIO_17_CANRXB);
GPIO_setPinConfig(GPIO_12_CANTXB);

//
// Initialize the CAN controllers
//
//CAN_initModule(CANA_BASE);
CAN_initModule(CANB_BASE);

//
// Set up the CAN bus bit rate to 500kHz for each module
// Refer to the Driver Library User Guide for information on how to set
// tighter timing control. Additionally, consult the device data sheet
// for more information about the CAN module clocking.
//
//CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 500000, 16);
CAN_setBitRate(CANB_BASE, DEVICE_SYSCLK_FREQ, 500000, 16);

//
// Enable interrupts on the CAN B peripheral.
//
//CAN_enableInterrupt(CANB_BASE, CAN_INT_IE0 | CAN_INT_ERROR |
// CAN_INT_STATUS);

//
// Initialize PIE and clear PIE registers. Disables CPU interrupts.
//
Interrupt_initModule();

//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
//
//Interrupt_initVectorTable();

//
// Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
//
EINT;
ERTM;

//
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
// This registers the interrupt handler in PIE vector table.
//
//Interrupt_register(INT_CANB0, &canbISR);

//
// Enable the CAN-B interrupt signal
//
//Interrupt_enable(INT_CANB0);
//CAN_enableGlobalInterrupt(CANB_BASE, CAN_GLOBAL_INT_CANINT0);

//
// Initialize the transmit message object used for sending CAN messages.
// Message Object Parameters:
// CAN Module: A
// Message Object ID Number: 1
// Message Identifier: 0x95555555
// Message Frame: Extended
// Message Type: Transmit
// Message ID Mask: 0x0
// Message Object Flags: None
// Message Data Length: 4 Bytes
//
CAN_setupMessageObject(CANB_BASE, TX_MSG_OBJ_ID, 0x95555555,
CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_TX, 0,
CAN_MSG_OBJ_NO_FLAGS, MSG_DATA_LENGTH);

//
// Initialize the receive message object used for receiving CAN messages.
// Message Object Parameters:
// CAN Module: B
// Message Object ID Number: 1
// Message Identifier: 0x95555555
// Message Frame: Extended
// Message Type: Receive
// Message ID Mask: 0x0
// Message Object Flags: Receive Interrupt
// Message Data Length: 4 Bytes
//
/*CAN_setupMessageObject(CANB_BASE, RX_MSG_OBJ_ID, 0x95555555,
CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_RX, 0,
CAN_MSG_OBJ_RX_INT_ENABLE, MSG_DATA_LENGTH);*/

//
// Initialize the transmit message object data buffer to be sent
//
txMsgData[0] = 0x12;
txMsgData[1] = 0x34;
txMsgData[2] = 0x56;
txMsgData[3] = 0x78;

//
// Start CAN module A and B operations
//
//CAN_startModule(CANA_BASE);
CAN_startModule(CANB_BASE);

//
// Transmit messages from CAN-A to CAN-B
//
for(i = 0; i < TXCOUNT; i++)
{
//
// Check the error flag to see if errors occurred
//
if(errorFlag)
{
asm(" ESTOP0");
}

//
// Verify that the number of transmitted messages equal the number of
// messages received before sending a new message
//
if(txMsgCount == rxMsgCount)
{
CAN_sendMessage(CANB_BASE, TX_MSG_OBJ_ID, MSG_DATA_LENGTH,
txMsgData);
txMsgCount++;
}
else
{
errorFlag = 1;
}

//
// Delay 0.25 second before continuing
//
DEVICE_DELAY_US(250000);

//
// Increment the value in the transmitted message data.
//
txMsgData[0] += 0x01;
txMsgData[1] += 0x01;
txMsgData[2] += 0x01;
txMsgData[3] += 0x01;

//
// Reset data if exceeds a byte
//
if(txMsgData[0] > 0xFF)
{
txMsgData[0] = 0;
}
if(txMsgData[1] > 0xFF)
{
txMsgData[1] = 0;
}
if(txMsgData[2] > 0xFF)
{
txMsgData[2] = 0;
}
if(txMsgData[3] > 0xFF)
{
txMsgData[3] = 0;
}
}

//
// Stop application
//
asm(" ESTOP0");
}

//
// CAN B ISR - The interrupt service routine called when a CAN interrupt is
// triggered on CAN module B.
//
/*__interrupt void
canbISR(void)
{
uint32_t status;

//
// Read the CAN-B interrupt status to find the cause of the interrupt
//
status = CAN_getInterruptCause(CANB_BASE);

//
// If the cause is a controller status interrupt, then get the status
//
if(status == CAN_INT_INT0ID_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.
//
status = CAN_getStatus(CANB_BASE);

//
// Check to see if an error occurred.
//
if(((status & ~(CAN_STATUS_RXOK)) != CAN_STATUS_LEC_MSK) &&
((status & ~(CAN_STATUS_RXOK)) != CAN_STATUS_LEC_NONE))
{
//
// Set a flag to indicate some errors may have occurred.
//
errorFlag = 1;
}
}
//
// Check if the cause is the CAN-B receive message object 1
//
else if(status == RX_MSG_OBJ_ID)
{
//
// Get the received message
//
CAN_readMessage(CANB_BASE, RX_MSG_OBJ_ID, rxMsgData);

//
// Getting to this point means that the RX interrupt occurred on
// message object 1, and the message RX is complete. Clear the
// message object interrupt.
//
CAN_clearInterruptStatus(CANB_BASE, RX_MSG_OBJ_ID);

//
// Increment a counter to keep track of how many messages have been
// received. In a real application this could be used to set flags to
// indicate when a message is received.
//
rxMsgCount++;

//
// Since the message was received, clear any error flags.
//
errorFlag = 0;
}
//
// If something unexpected caused the interrupt, this would handle it.
//
else
{
//
// Spurious interrupt handling can go here.
//
}

//
// Clear the global interrupt flag for the CAN interrupt line
//
CAN_clearGlobalInterruptStatus(CANB_BASE, CAN_GLOBAL_INT_CANINT0);

//
// Acknowledge this interrupt located in group 9
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}
*/
//
// End of File
//

for receiving data:

//#############################################################################
//
// FILE: can_ex3_external_transmit.c
//
// TITLE: CAN External Transmit Example
//
//! \addtogroup driver_example_list
//! <h1> CAN-A to CAN-B External Transmit </h1>
//!
//! This example initializes CAN module A and CAN module B for external
//! communication. CAN-A module is setup to transmit incrementing data for "n"
//! number of times to the CAN-B module, where "n" is the value of TXCOUNT.
//! CAN-B module is setup to trigger an interrupt service routine (ISR) when
//! data is received. An error flag will be set if the transmitted data doesn't
//! match the received data.
//!
//! \note Both CAN modules on the device need to be
//! connected to each other via CAN transceivers. GPIOs will be different
//! on Launchpad.
//!
//! \b Hardware \b Required \n
//! - A C2000 board with two CAN transceivers
//!
//! \b External \b Connections \n
//! - ControlCARD CANA is on GPIO31 (CANTXA) and GPIO30 (CANRXA)
//! - ControlCARD CANB is on GPIO8 (CANTXB) and GPIO10 (CANRXB)
//!
//! \b Watch \b Variables \n
//! - TXCOUNT - Adjust to set the number of messages to be transmitted
//! - txMsgCount - A counter for the number of messages sent
//! - rxMsgCount - A counter for the number of messages received
//! - txMsgData - An array with the data being sent
//! - rxMsgData - An array with the data that was received
//! - errorFlag - A flag that indicates an error has occurred
//!
//
//#############################################################################
// $TI Release: F2837xD Support Library v3.05.00.00 $
// $Release Date: Thu Oct 18 15:48:42 CDT 2018 $
// $Copyright:
// Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################

//
// Included Files
//
#include "driverlib.h"
#include "device.h"

//
// Defines
//
#define TXCOUNT 100
#define MSG_DATA_LENGTH 4
#define TX_MSG_OBJ_ID 1
#define RX_MSG_OBJ_ID 1

//
// Globals
//
volatile unsigned long i;
volatile uint32_t txMsgCount = 0;
volatile uint32_t rxMsgCount = 0;
volatile uint32_t errorFlag = 0;
uint16_t txMsgData[4];
uint16_t rxMsgData[4];

//
// Function Prototypes
//
__interrupt void canbISR(void);

//
// Main
//
void main(void)
{
//
// Initialize device clock and peripherals
//
Device_init();

//
// Initialize GPIO and configure GPIO pins for CANTX/CANRX
// on module A and B
//
Device_initGPIO();
//GPIO_setPinConfig(DEVICE_GPIO_CFG_CANRXA);
//GPIO_setPinConfig(DEVICE_GPIO_CFG_CANTXA);
GPIO_setPinConfig(GPIO_17_CANRXB);
GPIO_setPinConfig(GPIO_12_CANTXB);

//
// Initialize the CAN controllers
//
//CAN_initModule(CANA_BASE);
CAN_initModule(CANB_BASE);

//
// Set up the CAN bus bit rate to 500kHz for each module
// Refer to the Driver Library User Guide for information on how to set
// tighter timing control. Additionally, consult the device data sheet
// for more information about the CAN module clocking.
//
//CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 500000, 16);
CAN_setBitRate(CANB_BASE, DEVICE_SYSCLK_FREQ, 500000, 16);

//
// Enable interrupts on the CAN B peripheral.
//
//CAN_enableInterrupt(CANB_BASE, CAN_INT_IE0 | CAN_INT_ERROR |
// CAN_INT_STATUS);

//
// Initialize PIE and clear PIE registers. Disables CPU interrupts.
//
Interrupt_initModule();

//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
//
Interrupt_initVectorTable();

//
// Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
//
EINT;
ERTM;

//
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
// This registers the interrupt handler in PIE vector table.
//
//Interrupt_register(INT_CANB0, &canbISR);

//
// Enable the CAN-B interrupt signal
//
//Interrupt_enable(INT_CANB0);
//CAN_enableGlobalInterrupt(CANB_BASE, CAN_GLOBAL_INT_CANINT0);

//
// Initialize the transmit message object used for sending CAN messages.
// Message Object Parameters:
// CAN Module: A
// Message Object ID Number: 1
// Message Identifier: 0x95555555
// Message Frame: Extended
// Message Type: Transmit
// Message ID Mask: 0x0
// Message Object Flags: None
// Message Data Length: 4 Bytes
//
/*CAN_setupMessageObject(CANA_BASE, TX_MSG_OBJ_ID, 0x95555555,
CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_TX, 0,
CAN_MSG_OBJ_NO_FLAGS, MSG_DATA_LENGTH);*/

//
// Initialize the receive message object used for receiving CAN messages.
// Message Object Parameters:
// CAN Module: B
// Message Object ID Number: 1
// Message Identifier: 0x95555555
// Message Frame: Extended
// Message Type: Receive
// Message ID Mask: 0x0
// Message Object Flags: Receive Interrupt
// Message Data Length: 4 Bytes
//
CAN_setupMessageObject(CANB_BASE, RX_MSG_OBJ_ID, 0x95555555,
CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_RX, 0,
CAN_MSG_OBJ_RX_INT_ENABLE, MSG_DATA_LENGTH);

//
// Initialize the transmit message object data buffer to be sent
//
txMsgData[0] = 0x12;
txMsgData[1] = 0x34;
txMsgData[2] = 0x56;
txMsgData[3] = 0x78;

//
// Start CAN module A and B operations
//
//CAN_startModule(CANA_BASE);
CAN_startModule(CANB_BASE);

//
// Transmit messages from CAN-A to CAN-B
//
/*for(i = 0; i < TXCOUNT; i++)
{
//
// Check the error flag to see if errors occurred
//
if(errorFlag)
{
asm(" ESTOP0");
}

//
// Verify that the number of transmitted messages equal the number of
// messages received before sending a new message
//
if(txMsgCount == rxMsgCount)
{
CAN_sendMessage(CANA_BASE, TX_MSG_OBJ_ID, MSG_DATA_LENGTH,
txMsgData);
txMsgCount++;
}
else
{
errorFlag = 1;
}

//
// Delay 0.25 second before continuing
//
DEVICE_DELAY_US(250000);

//
// Increment the value in the transmitted message data.
//
txMsgData[0] += 0x01;
txMsgData[1] += 0x01;
txMsgData[2] += 0x01;
txMsgData[3] += 0x01;

//
// Reset data if exceeds a byte
//
if(txMsgData[0] > 0xFF)
{
txMsgData[0] = 0;
}
if(txMsgData[1] > 0xFF)
{
txMsgData[1] = 0;
}
if(txMsgData[2] > 0xFF)
{
txMsgData[2] = 0;
}
if(txMsgData[3] > 0xFF)
{
txMsgData[3] = 0;
}
}*/

//
// Stop application
//
asm(" ESTOP0");
}

//
// CAN B ISR - The interrupt service routine called when a CAN interrupt is
// triggered on CAN module B.
//
__interrupt void
canbISR(void)
{
uint32_t status;

//
// Read the CAN-B interrupt status to find the cause of the interrupt
//
status = CAN_getInterruptCause(CANB_BASE);

//
// If the cause is a controller status interrupt, then get the status
//
if(status == CAN_INT_INT0ID_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.
//
status = CAN_getStatus(CANB_BASE);

//
// Check to see if an error occurred.
//
if(((status & ~(CAN_STATUS_RXOK)) != CAN_STATUS_LEC_MSK) &&
((status & ~(CAN_STATUS_RXOK)) != CAN_STATUS_LEC_NONE))
{
//
// Set a flag to indicate some errors may have occurred.
//
errorFlag = 1;
}
}
//
// Check if the cause is the CAN-B receive message object 1
//
else if(status == RX_MSG_OBJ_ID)
{
//
// Get the received message
//
CAN_readMessage(CANB_BASE, RX_MSG_OBJ_ID, rxMsgData);

//
// Getting to this point means that the RX interrupt occurred on
// message object 1, and the message RX is complete. Clear the
// message object interrupt.
//
CAN_clearInterruptStatus(CANB_BASE, RX_MSG_OBJ_ID);

//
// Increment a counter to keep track of how many messages have been
// received. In a real application this could be used to set flags to
// indicate when a message is received.
//
rxMsgCount++;

//
// Since the message was received, clear any error flags.
//
errorFlag = 0;
}
//
// If something unexpected caused the interrupt, this would handle it.
//
else
{
//
// Spurious interrupt handling can go here.
//
}

//
// Clear the global interrupt flag for the CAN interrupt line
//
CAN_clearGlobalInterruptStatus(CANB_BASE, CAN_GLOBAL_INT_CANINT0);

//
// Acknowledge this interrupt located in group 9
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}

//
// End of File
//

  • Hi Sohail,

    In the transmitting node:

        -remove the following lines:

           if(errorFlag)
          {
           asm(" ESTOP0");
          }

        -delete the following lines

         if(txMsgCount == rxMsgCount)
          {
          CAN_sendMessage(CANB_BASE, TX_MSG_OBJ_ID, MSG_DATA_LENGTH,
          txMsgData);
          txMsgCount++;
          }
          else
          {
          errorFlag = 1;
          }

         and replace it with just:

         CAN_sendMessage(CANB_BASE, TX_MSG_OBJ_ID, MSG_DATA_LENGTH,
          txMsgData);

    What the above does is making the first node strictly transmitting data and not doing any error checking of received data (since you are removing the receiving portion by disabling the interrupt).

    In the receiving node:

    Enable back the interrupts by uncommenting these lines:

    CAN_enableInterrupt(CANB_BASE, CAN_INT_IE0 | CAN_INT_ERROR |
      CAN_INT_STATUS);

    Interrupt_register(INT_CANB0, &canbISR);

    Interrupt_enable(INT_CANB0);
    CAN_enableGlobalInterrupt(CANB_BASE, CAN_GLOBAL_INT_CANINT0);

    Upon successful transmission/reception of CAN frame, the code in the receiving node will go to the CAN ISR routine canbISR for frame error checking and data parsing.  You can then add the variable rxMsgData in the expressions window in CCS and see the received data incremented upon successful transaction.

    Hope this helps.

    Regards,

    Joseph

  • Hi Joseph,

    I updated the changes as you mentioned and tried the CAN communication still not able to get the data.

    I connected CANH, CANL and ground of respective boards.

    Here is my updated receiver code:

    //#############################################################################

    //

    // FILE: can_ex3_external_transmit.c

    //

    // TITLE: CAN External Transmit Example

    //

    //! \addtogroup driver_example_list

    //! <h1> CAN-A to CAN-B External Transmit </h1>

    //!

    //! This example initializes CAN module A and CAN module B for external

    //! communication. CAN-A module is setup to transmit incrementing data for "n"

    //! number of times to the CAN-B module, where "n" is the value of TXCOUNT.

    //! CAN-B module is setup to trigger an interrupt service routine (ISR) when

    //! data is received. An error flag will be set if the transmitted data doesn't

    //! match the received data.

    //!

    //! \note Both CAN modules on the device need to be

    //! connected to each other via CAN transceivers. GPIOs will be different

    //! on Launchpad.

    //!

    //! \b Hardware \b Required \n

    //! - A C2000 board with two CAN transceivers

    //!

    //! \b External \b Connections \n

    //! - ControlCARD CANA is on GPIO31 (CANTXA) and GPIO30 (CANRXA)

    //! - ControlCARD CANB is on GPIO8 (CANTXB) and GPIO10 (CANRXB)

    //!

    //! \b Watch \b Variables \n

    //! - TXCOUNT - Adjust to set the number of messages to be transmitted

    //! - txMsgCount - A counter for the number of messages sent

    //! - rxMsgCount - A counter for the number of messages received

    //! - txMsgData - An array with the data being sent

    //! - rxMsgData - An array with the data that was received

    //! - errorFlag - A flag that indicates an error has occurred

    //!

    //

    //#############################################################################

    // $TI Release: F2837xD Support Library v3.05.00.00 $

    // $Release Date: Thu Oct 18 15:48:42 CDT 2018 $

    // $Copyright:

    // Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/

    //

    // Redistribution and use in source and binary forms, with or without

    // modification, are permitted provided that the following conditions

    // are met:

    //

    // Redistributions of source code must retain the above copyright

    // notice, this list of conditions and the following disclaimer.

    //

    // Redistributions in binary form must reproduce the above copyright

    // notice, this list of conditions and the following disclaimer in the

    // documentation and/or other materials provided with the

    // distribution.

    //

    // Neither the name of Texas Instruments Incorporated nor the names of

    // its contributors may be used to endorse or promote products derived

    // from this software without specific prior written permission.

    //

    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR

    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT

    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,

    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,

    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY

    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE

    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

    // $

    //#############################################################################

    //

    // Included Files

    //

    #include "driverlib.h"

    #include "device.h"

    //

    // Defines

    //

    #define TXCOUNT 100

    #define MSG_DATA_LENGTH 4

    #define TX_MSG_OBJ_ID 1

    #define RX_MSG_OBJ_ID 1

    //

    // Globals

    //

    volatile unsigned long i;

    volatile uint32_t txMsgCount = 0;

    volatile uint32_t rxMsgCount = 0;

    volatile uint32_t errorFlag = 0;

    uint16_t txMsgData[4];

    uint16_t rxMsgData[4];

    //

    // Function Prototypes

    //

    __interrupt void canbISR(void);

    //

    // Main

    //

    void main(void)

    {

    //

    // Initialize device clock and peripherals

    //

    Device_init();

    //

    // Initialize GPIO and configure GPIO pins for CANTX/CANRX

    // on module A and B

    //

    Device_initGPIO();

    //GPIO_setPinConfig(DEVICE_GPIO_CFG_CANRXA);

    //GPIO_setPinConfig(DEVICE_GPIO_CFG_CANTXA);

    GPIO_setPinConfig(GPIO_17_CANRXB);

    GPIO_setPinConfig(GPIO_12_CANTXB);

    //

    // Initialize the CAN controllers

    //

    //CAN_initModule(CANA_BASE);

    CAN_initModule(CANB_BASE);

    //

    // Set up the CAN bus bit rate to 500kHz for each module

    // Refer to the Driver Library User Guide for information on how to set

    // tighter timing control. Additionally, consult the device data sheet

    // for more information about the CAN module clocking.

    //

    //CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 500000, 16);

    CAN_setBitRate(CANB_BASE, DEVICE_SYSCLK_FREQ, 500000, 16);

    //

    // Enable interrupts on the CAN B peripheral.

    //

    CAN_enableInterrupt(CANB_BASE, CAN_INT_IE0 | CAN_INT_ERROR |

    CAN_INT_STATUS);

    //

    // Initialize PIE and clear PIE registers. Disables CPU interrupts.

    //

    Interrupt_initModule();

    //

    // Initialize the PIE vector table with pointers to the shell Interrupt

    // Service Routines (ISR).

    //

    Interrupt_initVectorTable();

    //

    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)

    //

    EINT;

    ERTM;

    //

    // Interrupts that are used in this example are re-mapped to

    // ISR functions found within this file.

    // This registers the interrupt handler in PIE vector table.

    //

    Interrupt_register(INT_CANB0, &canbISR);

    //

    // Enable the CAN-B interrupt signal

    //

    Interrupt_enable(INT_CANB0);

    CAN_enableGlobalInterrupt(CANB_BASE, CAN_GLOBAL_INT_CANINT0);

    //

    // Initialize the transmit message object used for sending CAN messages.

    // Message Object Parameters:

    // CAN Module: A

    // Message Object ID Number: 1

    // Message Identifier: 0x95555555

    // Message Frame: Extended

    // Message Type: Transmit

    // Message ID Mask: 0x0

    // Message Object Flags: None

    // Message Data Length: 4 Bytes

    //

    /*CAN_setupMessageObject(CANA_BASE, TX_MSG_OBJ_ID, 0x95555555,

    CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_TX, 0,

    CAN_MSG_OBJ_NO_FLAGS, MSG_DATA_LENGTH);*/

    //

    // Initialize the receive message object used for receiving CAN messages.

    // Message Object Parameters:

    // CAN Module: B

    // Message Object ID Number: 1

    // Message Identifier: 0x95555555

    // Message Frame: Extended

    // Message Type: Receive

    // Message ID Mask: 0x0

    // Message Object Flags: Receive Interrupt

    // Message Data Length: 4 Bytes

    //

    CAN_setupMessageObject(CANB_BASE, RX_MSG_OBJ_ID, 0x95555555,

    CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_RX, 0,

    CAN_MSG_OBJ_RX_INT_ENABLE, MSG_DATA_LENGTH);

    //

    // Initialize the transmit message object data buffer to be sent

    //

    txMsgData[0] = 0x12;

    txMsgData[1] = 0x34;

    txMsgData[2] = 0x56;

    txMsgData[3] = 0x78;

    //

    // Start CAN module A and B operations

    //

    //CAN_startModule(CANA_BASE);

    CAN_startModule(CANB_BASE);

    //

    // Transmit messages from CAN-A to CAN-B

    //

    /*for(i = 0; i < TXCOUNT; i++)

    {

    //

    // Check the error flag to see if errors occurred

    //

    if(errorFlag)

    {

    asm(" ESTOP0");

    }

    //

    // Verify that the number of transmitted messages equal the number of

    // messages received before sending a new message

    //

    if(txMsgCount == rxMsgCount)

    {

    CAN_sendMessage(CANA_BASE, TX_MSG_OBJ_ID, MSG_DATA_LENGTH,

    txMsgData);

    txMsgCount++;

    }

    else

    {

    errorFlag = 1;

    }

    //

    // Delay 0.25 second before continuing

    //

    DEVICE_DELAY_US(250000);

    //

    // Increment the value in the transmitted message data.

    //

    txMsgData[0] += 0x01;

    txMsgData[1] += 0x01;

    txMsgData[2] += 0x01;

    txMsgData[3] += 0x01;

    //

    // Reset data if exceeds a byte

    //

    if(txMsgData[0] > 0xFF)

    {

    txMsgData[0] = 0;

    }

    if(txMsgData[1] > 0xFF)

    {

    txMsgData[1] = 0;

    }

    if(txMsgData[2] > 0xFF)

    {

    txMsgData[2] = 0;

    }

    if(txMsgData[3] > 0xFF)

    {

    txMsgData[3] = 0;

    }

    }*/

    //

    // Stop application

    //

    // asm(" ESTOP0");

    }

    //

    // CAN B ISR - The interrupt service routine called when a CAN interrupt is

    // triggered on CAN module B.

    //

    __interrupt void

    canbISR(void)

    {

    uint32_t status;

    //

    // Read the CAN-B interrupt status to find the cause of the interrupt

    //

    status = CAN_getInterruptCause(CANB_BASE);

    //

    // If the cause is a controller status interrupt, then get the status

    //

    if(status == CAN_INT_INT0ID_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.

    //

    status = CAN_getStatus(CANB_BASE);

    //

    // Check to see if an error occurred.

    //

    if(((status & ~(CAN_STATUS_RXOK)) != CAN_STATUS_LEC_MSK) &&

    ((status & ~(CAN_STATUS_RXOK)) != CAN_STATUS_LEC_NONE))

    {

    //

    // Set a flag to indicate some errors may have occurred.

    //

    errorFlag = 1;

    }

    }

    //

    // Check if the cause is the CAN-B receive message object 1

    //

    else if(status == RX_MSG_OBJ_ID)

    {

    //

    // Get the received message

    //

    CAN_readMessage(CANB_BASE, RX_MSG_OBJ_ID, rxMsgData);

    //

    // Getting to this point means that the RX interrupt occurred on

    // message object 1, and the message RX is complete. Clear the

    // message object interrupt.

    //

    CAN_clearInterruptStatus(CANB_BASE, RX_MSG_OBJ_ID);

    //

    // Increment a counter to keep track of how many messages have been

    // received. In a real application this could be used to set flags to

    // indicate when a message is received.

    //

    rxMsgCount++;

    //

    // Since the message was received, clear any error flags.

    //

    errorFlag = 0;

    }

    //

    // If something unexpected caused the interrupt, this would handle it.

    //

    else

    {

    //

    // Spurious interrupt handling can go here.

    //

    }

    //

    // Clear the global interrupt flag for the CAN interrupt line

    //

    CAN_clearGlobalInterruptStatus(CANB_BASE, CAN_GLOBAL_INT_CANINT0);

    //

    // Acknowledge this interrupt located in group 9

    //

    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);

    }

    //

    // End of File

    //

    Regards,

    Sohail

  • Hi Sohail,

    In the receiver code, looks like the last statement ends with the function call CAN_startModule(CANB_BASE);.  Can you add a while(1); statement after this line to keep the CPU running?  Can you also add an ESTOP0; statement in the inside ISR function canbISR()?  Adding the ESTOP0 will force the program to halt at the ISR - this is one way of knowing whether a valid message was received by the node and a proper interrupt was generated.

    Regards,

    Joseph

  • Hi Joseph,

    I updated the code. Receiver code is not running properly and discontinuing with error "Break at address "0x3fe493" with no debug information available, or outside of program code."

    Can you suggest how to break out this problem and have working CAN communication?

    Receiver code:

    //#############################################################################

    //

    // FILE: can_ex3_external_transmit.c

    //

    // TITLE: CAN External Transmit Example

    //

    //! \addtogroup driver_example_list

    //! <h1> CAN-A to CAN-B External Transmit </h1>

    //!

    //! This example initializes CAN module A and CAN module B for external

    //! communication. CAN-A module is setup to transmit incrementing data for "n"

    //! number of times to the CAN-B module, where "n" is the value of TXCOUNT.

    //! CAN-B module is setup to trigger an interrupt service routine (ISR) when

    //! data is received. An error flag will be set if the transmitted data doesn't

    //! match the received data.

    //!

    //! \note Both CAN modules on the device need to be

    //! connected to each other via CAN transceivers. GPIOs will be different

    //! on Launchpad.

    //!

    //! \b Hardware \b Required \n

    //! - A C2000 board with two CAN transceivers

    //!

    //! \b External \b Connections \n

    //! - ControlCARD CANA is on GPIO31 (CANTXA) and GPIO30 (CANRXA)

    //! - ControlCARD CANB is on GPIO8 (CANTXB) and GPIO10 (CANRXB)

    //!

    //! \b Watch \b Variables \n

    //! - TXCOUNT - Adjust to set the number of messages to be transmitted

    //! - txMsgCount - A counter for the number of messages sent

    //! - rxMsgCount - A counter for the number of messages received

    //! - txMsgData - An array with the data being sent

    //! - rxMsgData - An array with the data that was received

    //! - errorFlag - A flag that indicates an error has occurred

    //!

    //

    //#############################################################################

    // $TI Release: F2837xD Support Library v3.05.00.00 $

    // $Release Date: Thu Oct 18 15:48:42 CDT 2018 $

    // $Copyright:

    // Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/

    //

    // Redistribution and use in source and binary forms, with or without

    // modification, are permitted provided that the following conditions

    // are met:

    //

    // Redistributions of source code must retain the above copyright

    // notice, this list of conditions and the following disclaimer.

    //

    // Redistributions in binary form must reproduce the above copyright

    // notice, this list of conditions and the following disclaimer in the

    // documentation and/or other materials provided with the

    // distribution.

    //

    // Neither the name of Texas Instruments Incorporated nor the names of

    // its contributors may be used to endorse or promote products derived

    // from this software without specific prior written permission.

    //

    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR

    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT

    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,

    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,

    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY

    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE

    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

    // $

    //#############################################################################

    //

    // Included Files

    //

    #include "driverlib.h"

    #include "device.h"

    //

    // Defines

    //

    #define TXCOUNT 100

    #define MSG_DATA_LENGTH 4

    #define TX_MSG_OBJ_ID 1

    #define RX_MSG_OBJ_ID 1

    //

    // Globals

    //

    volatile unsigned long i;

    volatile uint32_t txMsgCount = 0;

    volatile uint32_t rxMsgCount = 0;

    volatile uint32_t errorFlag = 0;

    //uint16_t txMsgData[4];

    uint16_t rxMsgData[4];

    //

    // Function Prototypes

    //

    __interrupt void canbISR(void);

    //

    // Main

    //

    void main(void)

    {

    //

    // Initialize device clock and peripherals

    //

    Device_init();

    //

    // Initialize GPIO and configure GPIO pins for CANTX/CANRX

    // on module A and B

    //

    Device_initGPIO();

    //GPIO_setPinConfig(DEVICE_GPIO_CFG_CANRXA);

    //GPIO_setPinConfig(DEVICE_GPIO_CFG_CANTXA);

    GPIO_setPinConfig(GPIO_17_CANRXB);

    GPIO_setPinConfig(GPIO_12_CANTXB);

    //

    // Initialize the CAN controllers

    //

    //CAN_initModule(CANA_BASE);

    CAN_initModule(CANB_BASE);

    //

    // Set up the CAN bus bit rate to 500kHz for each module

    // Refer to the Driver Library User Guide for information on how to set

    // tighter timing control. Additionally, consult the device data sheet

    // for more information about the CAN module clocking.

    //

    //CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 500000, 16);

    CAN_setBitRate(CANB_BASE, DEVICE_SYSCLK_FREQ, 500000, 16);

    //

    // Enable interrupts on the CAN B peripheral.

    //

    CAN_enableInterrupt(CANB_BASE, CAN_INT_IE0 | CAN_INT_ERROR |

    CAN_INT_STATUS);

    //

    // Initialize PIE and clear PIE registers. Disables CPU interrupts.

    //

    Interrupt_initModule();

    //

    // Initialize the PIE vector table with pointers to the shell Interrupt

    // Service Routines (ISR).

    //

    Interrupt_initVectorTable();

    //

    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)

    //

    EINT;

    ERTM;

    //

    // Interrupts that are used in this example are re-mapped to

    // ISR functions found within this file.

    // This registers the interrupt handler in PIE vector table.

    //

    Interrupt_register(INT_CANB0, &canbISR);

    //

    // Enable the CAN-B interrupt signal

    //

    Interrupt_enable(INT_CANB0);

    CAN_enableGlobalInterrupt(CANB_BASE, CAN_GLOBAL_INT_CANINT0);

    //

    // Initialize the transmit message object used for sending CAN messages.

    // Message Object Parameters:

    // CAN Module: A

    // Message Object ID Number: 1

    // Message Identifier: 0x95555555

    // Message Frame: Extended

    // Message Type: Transmit

    // Message ID Mask: 0x0

    // Message Object Flags: None

    // Message Data Length: 4 Bytes

    //

    /*CAN_setupMessageObject(CANA_BASE, TX_MSG_OBJ_ID, 0x95555555,

    CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_TX, 0,

    CAN_MSG_OBJ_NO_FLAGS, MSG_DATA_LENGTH);*/

    //

    // Initialize the receive message object used for receiving CAN messages.

    // Message Object Parameters:

    // CAN Module: B

    // Message Object ID Number: 1

    // Message Identifier: 0x95555555

    // Message Frame: Extended

    // Message Type: Receive

    // Message ID Mask: 0x0

    // Message Object Flags: Receive Interrupt

    // Message Data Length: 4 Bytes

    //

    CAN_setupMessageObject(CANB_BASE, RX_MSG_OBJ_ID, 0x95555555,

    CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_RX, 0,

    CAN_MSG_OBJ_RX_INT_ENABLE, MSG_DATA_LENGTH);

    //

    // Initialize the transmit message object data buffer to be sent

    //

    //txMsgData[0] = 0x12;

    //txMsgData[1] = 0x34;

    //txMsgData[2] = 0x56;

    //txMsgData[3] = 0x78;

    //

    // Start CAN module A and B operations

    //

    //CAN_startModule(CANA_BASE);

    CAN_startModule(CANB_BASE);

    while(1);

    //

    // Transmit messages from CAN-A to CAN-B

    //

    /*for(i = 0; i < TXCOUNT; i++)

    {

    //

    // Check the error flag to see if errors occurred

    //

    if(errorFlag)

    {

    asm(" ESTOP0");

    }

    //

    // Verify that the number of transmitted messages equal the number of

    // messages received before sending a new message

    //

    if(txMsgCount == rxMsgCount)

    {

    CAN_sendMessage(CANA_BASE, TX_MSG_OBJ_ID, MSG_DATA_LENGTH,

    txMsgData);

    txMsgCount++;

    }

    else

    {

    errorFlag = 1;

    }

    //

    // Delay 0.25 second before continuing

    //

    DEVICE_DELAY_US(250000);

    //

    // Increment the value in the transmitted message data.

    //

    txMsgData[0] += 0x01;

    txMsgData[1] += 0x01;

    txMsgData[2] += 0x01;

    txMsgData[3] += 0x01;

    //

    // Reset data if exceeds a byte

    //

    if(txMsgData[0] > 0xFF)

    {

    txMsgData[0] = 0;

    }

    if(txMsgData[1] > 0xFF)

    {

    txMsgData[1] = 0;

    }

    if(txMsgData[2] > 0xFF)

    {

    txMsgData[2] = 0;

    }

    if(txMsgData[3] > 0xFF)

    {

    txMsgData[3] = 0;

    }

    }*/

    //

    // Stop application

    //

    //asm(" ESTOP0");

    }

    //

    // CAN B ISR - The interrupt service routine called when a CAN interrupt is

    // triggered on CAN module B.

    //

    __interrupt void

    canbISR(void)

    {

    uint32_t status;

    //

    // Read the CAN-B interrupt status to find the cause of the interrupt

    //

    status = CAN_getInterruptCause(CANB_BASE);

    //

    // If the cause is a controller status interrupt, then get the status

    //

    if(status == CAN_INT_INT0ID_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.

    //

    status = CAN_getStatus(CANB_BASE);

    //

    // Check to see if an error occurred.

    //

    if(((status & ~(CAN_STATUS_RXOK)) != CAN_STATUS_LEC_MSK) &&

    ((status & ~(CAN_STATUS_RXOK)) != CAN_STATUS_LEC_NONE))

    {

    //

    // Set a flag to indicate some errors may have occurred.

    //

    errorFlag = 1;

    }

    }

    //

    // Check if the cause is the CAN-B receive message object 1

    //

    else if(status == RX_MSG_OBJ_ID)

    {

    //

    // Get the received message

    //

    CAN_readMessage(CANB_BASE, RX_MSG_OBJ_ID, rxMsgData);

    //

    // Getting to this point means that the RX interrupt occurred on

    // message object 1, and the message RX is complete. Clear the

    // message object interrupt.

    //

    CAN_clearInterruptStatus(CANB_BASE, RX_MSG_OBJ_ID);

    //

    // Increment a counter to keep track of how many messages have been

    // received. In a real application this could be used to set flags to

    // indicate when a message is received.

    //

    rxMsgCount++;

    ESTOP0;

    //

    // Since the message was received, clear any error flags.

    //

    errorFlag = 0;

    }

    //

    // If something unexpected caused the interrupt, this would handle it.

    //

    else

    {

    //

    // Spurious interrupt handling can go here.

    //

    }

    //

    // Clear the global interrupt flag for the CAN interrupt line

    //

    CAN_clearGlobalInterruptStatus(CANB_BASE, CAN_GLOBAL_INT_CANINT0);

    //

    // Acknowledge this interrupt located in group 9

    //

    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);

    }

    //

    // End of File

    //

    Transmitter code:

        //#############################################################################
        //
        // FILE:   can_ex3_external_transmit.c
        //
        // TITLE:   CAN External Transmit Example
        //
        //! \addtogroup driver_example_list
        //! <h1> CAN-A to CAN-B External Transmit </h1>
        //!
        //! This example initializes CAN module A and CAN module B for external
        //! communication. CAN-A module is setup to transmit incrementing data for "n"
        //! number of times to the CAN-B module, where "n" is the value of TXCOUNT.
        //! CAN-B module is setup to trigger an interrupt service routine (ISR) when
        //! data is received. An error flag will be set if the transmitted data doesn't
        //! match the received data.
        //!
        //! \note Both CAN modules on the device need to be
        //!       connected to each other via CAN transceivers. GPIOs will be different
        //!       on Launchpad.
        //!
        //! \b Hardware \b Required \n
        //!  - A C2000 board with two CAN transceivers
        //!
        //! \b External \b Connections \n
        //!  - ControlCARD CANA is on GPIO31 (CANTXA) and GPIO30 (CANRXA)
        //!  - ControlCARD CANB is on GPIO8 (CANTXB) and GPIO10 (CANRXB)
        //!
        //! \b Watch \b Variables \n
        //!  - TXCOUNT - Adjust to set the number of messages to be transmitted
        //!  - txMsgCount - A counter for the number of messages sent
        //!  - rxMsgCount - A counter for the number of messages received
        //!  - txMsgData - An array with the data being sent
        //!  - rxMsgData - An array with the data that was received
        //!  - errorFlag - A flag that indicates an error has occurred
        //!
        //
        //#############################################################################
        // $TI Release: F2837xD Support Library v3.05.00.00 $
        // $Release Date: Thu Oct 18 15:48:42 CDT 2018 $
        // $Copyright:
        // Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
        //
        // Redistribution and use in source and binary forms, with or without
        // modification, are permitted provided that the following conditions
        // are met:
        //
        //   Redistributions of source code must retain the above copyright
        //   notice, this list of conditions and the following disclaimer.
        //
        //   Redistributions in binary form must reproduce the above copyright
        //   notice, this list of conditions and the following disclaimer in the
        //   documentation and/or other materials provided with the
        //   distribution.
        //
        //   Neither the name of Texas Instruments Incorporated nor the names of
        //   its contributors may be used to endorse or promote products derived
        //   from this software without specific prior written permission.
        //
        // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
        // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
        // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
        // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
        // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
        // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        // $
        //#############################################################################

        //
        // Included Files
        //
        #include "driverlib.h"
        #include "device.h"

        //
        // Defines
        //
        #define TXCOUNT  100
        #define MSG_DATA_LENGTH    4
        #define TX_MSG_OBJ_ID    1
        #define RX_MSG_OBJ_ID    1

        //
        // Globals
        //
        volatile unsigned long i;
        volatile uint32_t txMsgCount = 0;
        volatile uint32_t rxMsgCount = 0;
        volatile uint32_t errorFlag = 0;
        uint16_t txMsgData[4];
        uint16_t rxMsgData[4];

        //
        // Function Prototypes
        //
        __interrupt void canbISR(void);

        //
        // Main
        //
        void main(void)
        {
            //
            // Initialize device clock and peripherals
            //
            Device_init();

            //
            // Initialize GPIO and configure GPIO pins for CANTX/CANRX
            // on module A and B
            //
            Device_initGPIO();
            //GPIO_setPinConfig(DEVICE_GPIO_CFG_CANRXA);
            //GPIO_setPinConfig(DEVICE_GPIO_CFG_CANTXA);
            GPIO_setPinConfig(GPIO_17_CANRXB);
            GPIO_setPinConfig(GPIO_12_CANTXB);

            //
            // Initialize the CAN controllers
            //
            //CAN_initModule(CANA_BASE);
            CAN_initModule(CANB_BASE);

            //
            // Set up the CAN bus bit rate to 500kHz for each module
            // Refer to the Driver Library User Guide for information on how to set
            // tighter timing control. Additionally, consult the device data sheet
            // for more information about the CAN module clocking.
            //
            //CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 500000, 16);
            CAN_setBitRate(CANB_BASE, DEVICE_SYSCLK_FREQ, 500000, 16);

            //
            // Enable interrupts on the CAN B peripheral.
            //
            //CAN_enableInterrupt(CANB_BASE, CAN_INT_IE0 | CAN_INT_ERROR |
              //                  CAN_INT_STATUS);

            //
            // Initialize PIE and clear PIE registers. Disables CPU interrupts.
            //
            Interrupt_initModule();

            //
            // Initialize the PIE vector table with pointers to the shell Interrupt
            // Service Routines (ISR).
            //
            //Interrupt_initVectorTable();

            //
            // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
            //
            EINT;
            ERTM;

            //
            // Interrupts that are used in this example are re-mapped to
            // ISR functions found within this file.
            // This registers the interrupt handler in PIE vector table.
            //
            //Interrupt_register(INT_CANB0, &canbISR);

            //
            // Enable the CAN-B interrupt signal
            //
            //Interrupt_enable(INT_CANB0);
            //CAN_enableGlobalInterrupt(CANB_BASE, CAN_GLOBAL_INT_CANINT0);

            //
            // Initialize the transmit message object used for sending CAN messages.
            // Message Object Parameters:
            //      CAN Module: A
            //      Message Object ID Number: 1
            //      Message Identifier: 0x95555555
            //      Message Frame: Extended
            //      Message Type: Transmit
            //      Message ID Mask: 0x0
            //      Message Object Flags: None
            //      Message Data Length: 4 Bytes
            //
            CAN_setupMessageObject(CANB_BASE, TX_MSG_OBJ_ID, 0x95555555,
                                   CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_TX, 0,
                                   CAN_MSG_OBJ_NO_FLAGS, MSG_DATA_LENGTH);

            //
            // Initialize the receive message object used for receiving CAN messages.
            // Message Object Parameters:
            //      CAN Module: B
            //      Message Object ID Number: 1
            //      Message Identifier: 0x95555555
            //      Message Frame: Extended
            //      Message Type: Receive
            //      Message ID Mask: 0x0
            //      Message Object Flags: Receive Interrupt
            //      Message Data Length: 4 Bytes
            //
            /*CAN_setupMessageObject(CANB_BASE, RX_MSG_OBJ_ID, 0x95555555,
                                   CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_RX, 0,
                                   CAN_MSG_OBJ_RX_INT_ENABLE, MSG_DATA_LENGTH);*/

            //
            // Initialize the transmit message object data buffer to be sent
            //
            txMsgData[0] = 0x12;
            txMsgData[1] = 0x34;
            txMsgData[2] = 0x56;
            txMsgData[3] = 0x78;

            //
            // Start CAN module A and B operations
            //
            //CAN_startModule(CANA_BASE);
            CAN_startModule(CANB_BASE);

            //
            // Transmit messages from CAN-A to CAN-B
            //
            for(i = 0; i < TXCOUNT; i++)
            {
                //
                // Check the error flag to see if errors occurred
                //
                //if(errorFlag)
                //{
                  //  asm("   ESTOP0");
                //}

                //
                // Verify that the number of transmitted messages equal the number of
                // messages received before sending a new message
                //
                /*if(txMsgCount == rxMsgCount)
                {
                    CAN_sendMessage(CANB_BASE, TX_MSG_OBJ_ID, MSG_DATA_LENGTH,
                                    txMsgData);
                    txMsgCount++;
                }
                else
                {
                    errorFlag = 1;
                }*/

                CAN_sendMessage(CANB_BASE, TX_MSG_OBJ_ID, MSG_DATA_LENGTH,
                                                txMsgData);

                //
                // Delay 0.25 second before continuing
                //
                DEVICE_DELAY_US(250000);

                //
                // Increment the value in the transmitted message data.
                //
                txMsgData[0] += 0x01;
                txMsgData[1] += 0x01;
                txMsgData[2] += 0x01;
                txMsgData[3] += 0x01;

                //
                // Reset data if exceeds a byte
                //
                if(txMsgData[0] > 0xFF)
                {
                    txMsgData[0] = 0;
                }
                if(txMsgData[1] > 0xFF)
                {
                    txMsgData[1] = 0;
                }
                if(txMsgData[2] > 0xFF)
                {
                    txMsgData[2] = 0;
                }
                if(txMsgData[3] > 0xFF)
                {
                    txMsgData[3] = 0;
                }
            }

            //
            // Stop application
            //
            asm("   ESTOP0");
        }

        //
        // CAN B ISR - The interrupt service routine called when a CAN interrupt is
        //             triggered on CAN module B.
        //
        /*__interrupt void
        canbISR(void)
        {
            uint32_t status;

            //
            // Read the CAN-B interrupt status to find the cause of the interrupt
            //
            status = CAN_getInterruptCause(CANB_BASE);

            //
            // If the cause is a controller status interrupt, then get the status
            //
            if(status == CAN_INT_INT0ID_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.
                //
                status = CAN_getStatus(CANB_BASE);

                //
                // Check to see if an error occurred.
                //
                if(((status  & ~(CAN_STATUS_RXOK)) != CAN_STATUS_LEC_MSK) &&
                   ((status  & ~(CAN_STATUS_RXOK)) != CAN_STATUS_LEC_NONE))
                {
                    //
                    // Set a flag to indicate some errors may have occurred.
                    //
                    errorFlag = 1;
                }
            }
            //
            // Check if the cause is the CAN-B receive message object 1
            //
            else if(status == RX_MSG_OBJ_ID)
            {
                //
                // Get the received message
                //
                CAN_readMessage(CANB_BASE, RX_MSG_OBJ_ID, rxMsgData);

                //
                // Getting to this point means that the RX interrupt occurred on
                // message object 1, and the message RX is complete.  Clear the
                // message object interrupt.
                //
                CAN_clearInterruptStatus(CANB_BASE, RX_MSG_OBJ_ID);

                //
                // Increment a counter to keep track of how many messages have been
                // received. In a real application this could be used to set flags to
                // indicate when a message is received.
                //
                rxMsgCount++;

                //
                // Since the message was received, clear any error flags.
                //
                errorFlag = 0;
            }
            //
            // If something unexpected caused the interrupt, this would handle it.
            //
            else
            {
                //
                // Spurious interrupt handling can go here.
                //
            }

            //
            // Clear the global interrupt flag for the CAN interrupt line
            //
            CAN_clearGlobalInterruptStatus(CANB_BASE, CAN_GLOBAL_INT_CANINT0);

            //
            // Acknowledge this interrupt located in group 9
            //
            Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
        }
        */
        //
        // End of File
        //

    Regards,

    Sohail

  • Hi Sohail,

    Unfortunately, the code attachments have become lengthy and it is getting hard to decipher which lines are commented out or which one have wrapped around.  I suggest that if you have to insert a code in the future, please use the feature </> (Syntaxhighlighter) in the options above as it makes the code easier to understand.

    Based from your description about the program counter going to "0x3fe493", it is an indication that the program has branched unexpectedly.  Please check that all your settings (clock, power, transceiver connections...etc) are correct.

    Rather than debugging your code, please try the code below.  It is using CANB to receive external CAN frames.  Also, be sure to modify the code accordingly to use the correct GPIO channels for the CANTXB and CANRXB pins that connect to the transceiver.  I've checked out code below and it works with SYSCLK setting of 200MHz and CAN bit rate of 500Kbps.  This is derived from the same external transmit example.

    
    
    #############################################################################
    //
    // FILE:   can_ex3_external_transmit.c
    //
    // TITLE:   CAN External Transmit Example
    //
    //! \addtogroup driver_example_list
    //! <h1> CAN-A to CAN-B External Transmit </h1>
    //!
    //! This example initializes CAN module A and CAN module B for external
    //! communication. CAN-A module is setup to transmit incrementing data for "n"
    //! number of times to the CAN-B module, where "n" is the value of TXCOUNT.
    //! CAN-B module is setup to trigger an interrupt service routine (ISR) when
    //! data is received. An error flag will be set if the transmitted data doesn't
    //! match the received data.
    //!
    //! \note Both CAN modules on the device need to be
    //!       connected to each other via CAN transceivers. GPIOs will be different
    //!       on Launchpad.
    //!
    //! \b Hardware \b Required \n
    //!  - A C2000 board with two CAN transceivers
    //!
    //! \b External \b Connections \n
    //!  - ControlCARD CANA is on GPIO31 (CANTXA) and GPIO30 (CANRXA)
    //!  - ControlCARD CANB is on GPIO8 (CANTXB) and GPIO10 (CANRXB)
    //!
    //!
    //! \b Watch \b Variables \n
    //!  - TXCOUNT - Adjust to set the number of messages to be transmitted
    //!  - txMsgCount - A counter for the number of messages sent
    //!  - rxMsgCount - A counter for the number of messages received
    //!  - txMsgData - An array with the data being sent
    //!  - rxMsgData - An array with the data that was received
    //!  - errorFlag - A flag that indicates an error has occurred
    //!
    //
    //#############################################################################
    // $TI Release: F2837xD Support Library v3.08.00.00 $
    // $Release Date: Mon Dec 23 17:32:30 IST 2019 $
    // $Copyright:
    // Copyright (C) 2013-2019 Texas Instruments Incorporated - http://www.ti.com/
    //
    // Redistribution and use in source and binary forms, with or without 
    // modification, are permitted provided that the following conditions 
    // are met:
    // 
    //   Redistributions of source code must retain the above copyright 
    //   notice, this list of conditions and the following disclaimer.
    // 
    //   Redistributions in binary form must reproduce the above copyright
    //   notice, this list of conditions and the following disclaimer in the 
    //   documentation and/or other materials provided with the   
    //   distribution.
    // 
    //   Neither the name of Texas Instruments Incorporated nor the names of
    //   its contributors may be used to endorse or promote products derived
    //   from this software without specific prior written permission.
    // 
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    // $
    //#############################################################################
    
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    
    //
    // Defines
    //
    #define TXCOUNT  100
    #define MSG_DATA_LENGTH    4
    #define TX_MSG_OBJ_ID      1
    #define RX_MSG_OBJ_ID      1
    
    //
    // Globals
    //
    volatile unsigned long i;
    volatile uint32_t txMsgCount = 0;
    volatile uint32_t rxMsgCount = 0;
    volatile uint32_t errorFlag = 0;
    uint16_t txMsgData[4];
    uint16_t rxMsgData[4];
    
    //
    // Function Prototypes
    //
    __interrupt void canbISR(void);     // Receive interrupt for CAN-B.
                                        // No Transmit interrupt for CAN-A
    //
    // Main
    //
    void main(void)
    {
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Initialize GPIO and configure GPIO pins for CANTX/CANRX
        // on module A and B. The device.h file may need to be modified to
        // reflect the chosen GPIO pins in your board.
        //
        Device_initGPIO();
        GPIO_setPinConfig(GPIO_13_CANRXB);
        GPIO_setPinConfig(GPIO_12_CANTXB);
    
        //
        // Initialize the CAN controllers
        //
        //CAN_initModule(CANA_BASE);
        CAN_initModule(CANB_BASE);
    
        //
        // Set up the CAN bus bit rate to 500kHz for each module
        // Refer to the Driver Library User Guide for information on how to set
        // tighter timing control. Additionally, consult the device data sheet
        // for more information about the CAN module clocking.
        //
        //CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 500000, 20);
        CAN_setBitRate(CANB_BASE, DEVICE_SYSCLK_FREQ, 500000, 20);
    
        //
        // Enable interrupts on the CAN B peripheral.
        // Enables Int.line0, Error & Status Change interrupts
        //
        CAN_enableInterrupt(CANB_BASE, CAN_INT_IE0 | CAN_INT_ERROR |
                            CAN_INT_STATUS);
    
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
    
        //
        // Interrupts that are used in this example are re-mapped to
        // ISR functions found within this file.
        // This registers the interrupt handler in PIE vector table.
        //
        Interrupt_register(INT_CANB0, &canbISR);
    
        //
        // Enable the CAN-B interrupt signal
        //
        Interrupt_enable(INT_CANB0);
    
    	//
        // Set GLBINT0_EN bit in CAN_GLB_INT_EN register
    	//
        CAN_enableGlobalInterrupt(CANB_BASE, CAN_GLOBAL_INT_CANINT0);
    
    
        //
        // Initialize the receive message object used for receiving CAN messages.
        // Message Object Parameters:
        //      CAN Module: B
        //      Message Object ID Number: 1
        //      Message Identifier: 0x95555555
        //      Message Frame: Extended
        //      Message Type: Receive
        //      Message ID Mask: 0x0
        //      Message Object Flags: Receive Interrupt
        //      Message Data Length: 4 Bytes
        //
        CAN_setupMessageObject(CANB_BASE, RX_MSG_OBJ_ID, 0x1FFFFFFF,
                               CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_RX, 0,
                               CAN_MSG_OBJ_RX_INT_ENABLE, MSG_DATA_LENGTH);
    
        //
        // Start CAN module A and B operations
        //
        CAN_startModule(CANB_BASE);
    
        while(1);
    }
    
    //
    // CAN B ISR - The interrupt service routine is called when an interrupt is
    //             triggered on CAN module B. It will be executed twice for every
    //             frame received.
    //             First time for status-change; second time for Mailbox receive.
    //
    __interrupt void
    canbISR(void)
    {
        uint32_t status;
    
        //
        // Read the CAN-B interrupt status (in the CAN_INT register) to find the
        // cause of the interrupt
        //
        status = CAN_getInterruptCause(CANB_BASE);
    
        //
        // If the cause is a controller status interrupt, then get the status.
        // During first iteration of every ISR execution, status = 0x8000,
        // which simply means CAN_ES != 0x07.
        //
        if(status == CAN_INT_INT0ID_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.
            //
            status = CAN_getStatus(CANB_BASE);  // Return CAN_ES value.
            //
    		// Now status = 0x00000010, indicating RxOK.
            //
    
            //
            // Check to see if an error occurred.
            //
            if(((status  & ~(CAN_STATUS_RXOK)) != CAN_STATUS_LEC_MSK) &&
               ((status  & ~(CAN_STATUS_RXOK)) != CAN_STATUS_LEC_NONE))
            {
                //
                // Set a flag to indicate some errors may have occurred.
                //
                errorFlag = 1;
            }
        }
        //
        // Check if the cause is the CAN-B receive message object 1. Will be skipped
        // in the first iteration of every ISR execution
    	//
        else if(status == RX_MSG_OBJ_ID)
        {
            //
            // Get the received message
            //
            CAN_readMessage(CANB_BASE, RX_MSG_OBJ_ID, rxMsgData);
    
            //
            // Getting to this point means that the RX interrupt occurred on
            // message object 1, and the message RX is complete.  Clear the
            // message object interrupt.
            //
            CAN_clearInterruptStatus(CANB_BASE, RX_MSG_OBJ_ID);
    
            //
            // Increment a counter to keep track of how many messages have been
            // received. In a real application this could be used to set flags to
            // indicate when a message is received.
            //
            rxMsgCount++;
    
            //
            // Since the message was received, clear any error flags.
            //
            errorFlag = 0;
        }
        //
        // If something unexpected caused the interrupt, this would handle it.
        //
        else
        {
            //
            // Spurious interrupt handling can go here.
            //
        }
    
        // JC - this ESTOP0 was added in order to allow the program to branch to the ISR and inspect the contents
        // of the CAN_ES register, specifically the Last Error Code (LEC)
        ESTOP0;
    
        //
        // Clear the global interrupt flag for the CAN interrupt line
        //
        CAN_clearGlobalInterruptStatus(CANB_BASE, CAN_GLOBAL_INT_CANINT0);
    
        //
        // Acknowledge this interrupt located in group 9
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }
    
    //
    // End of File
    //
    

    Best regards,

    Joseph

  • Hi Joseph,

    "can_ex3_external_transmit" is breaking at function "SysCtl_delay()" in Device_Init().

    But then I tried same changes to "can_external_transmit" code and CAN communication worked.

    Thanks for the help!!

    Regards,

    Sohail

  • Hi Sohail,

    Your code is probably not allowing enough time delay time where the SysCtl_delay() is called, but it seems like you have an alternate solution for a CAN receiving code.  I'll mark this thread closed for the time being but if you decide to debug the original problem with the delay code, please let me know and see how we can assist you.

    Regards,

    Joseph