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.

TMS320F28075:CAN communication

Part Number: TMS320F28075
Other Parts Discussed in Thread: CONTROLSUITE

Hi,

I try to use the example code for CAN communication

C:\ti\controlSUITE\device_support\F2807x\v180\F2807x_examples_Cpu1\can_loopback_interrupts

I face 2 problems

1.

I keep it in external loopback mode and change its GPIO pins, but change GPIO31-CANTXA to something other than GPIO31, such as GPIO_SetupPinMux (32, GPIO_MUX_CPU1, 1), an error will occur, and I find the point where the error occurred is ulStatus & ~ (CAN_ES_TXOK | CAN_ES_RXOK)) == 5, what is the problem with this?

2.

I removed the external loopback mode and changed it to CAN communication. Annotate HWREG (CANA_BASE + CAN_O_CTL) | = CAN_CTL_TEST; HWREG (CANA_BASE + CAN_O_TEST) = CAN_TEST_EXL;
Change the GPIO setting to GPIO_SetupPinMux (70, GPIO_MUX_CPU1, 6);
// GPIO31-CANTXA
GPIO_SetupPinMux (71, GPIO_MUX_CPU1, 6);
GPIO_SetupPinOptions (70, GPIO_INPUT, GPIO_ASYNC);
GPIO_SetupPinOptions (71, GPIO_OUTPUT, GPIO_PUSHPULL);
I can send messages, but I still ca n’t receive them. Is there something I missed?
The complete code is as follows:

//###########################################################################
// FILE: can_loopback_interrupts.c
// TITLE: Example to demonstrate basic CAN setup and use.
//
//! \addtogroup cpu01_example_list
//! <h1>CAN External Loopback with Interrupts (can_loopback_interrupts)</h1>
//!
//! This example shows the basic setup of CAN in order to transmit and receive
//! messages on the CAN bus. The CAN peripheral is configured to transmit
//! messages with a specific CAN ID. A message is then transmitted once per
//! second, using a simple delay loop for timing. The message that is sent is
//! a 4 byte message that contains an incrementing pattern. A CAN interrupt
//! handler is used to confirm message transmission and count the number of
//! messages that have been sent.
//!
//! This example sets up the CAN controller in External Loopback test mode.
//! Data transmitted is visible on the CAN0TX pin and can be received with
//! an appropriate mailbox configuration.
//!
//! This example uses the following interrupt handlers:\n
//! - INT_CANA0 - CANIntHandler
//!
//
//###########################################################################
// $TI Release: F2807x Support Library v180 $
// $Release Date: Fri Nov 6 16:33:02 CST 2015 $
// $Copyright: Copyright (C) 2014-2015 Texas Instruments Incorporated -
// http://www.ti.com/ ALL RIGHTS RESERVED $
//###########################################################################

#include "F28x_Project.h" // Device Headerfile and Examples Include File
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "inc/hw_can.h"
#include "driverlib/can.h"

//*****************************************************************************
// A counter that keeps track of the number of times the TX interrupt has
// occurred, which should match the number of TX messages that were sent.
//*****************************************************************************
volatile unsigned long g_ulTxMsgCount = 0;
volatile unsigned long g_ulRxMsgCount = 0;
int i;
//unsigned long u32CanAErrorStatus;
//unsigned long uCanAErrFlag;
//*****************************************************************************
// A flag to indicate that some transmission error occurred.
//*****************************************************************************
volatile unsigned long g_bErrFlag = 0;

tCANMsgObject sTXCANMessage;
tCANMsgObject sRXCANMessage;
unsigned char ucTXMsgData[8] ={ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
unsigned char ucRXMsgData[8];

//unsigned long u32CntTXMsgData = 0x12345678;

//*****************************************************************************
// 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.
//*****************************************************************************
interrupt void
CANIntHandler(void)
{
unsigned long ulStatus;

// Read the CAN interrupt status to find the cause of the interrupt
ulStatus = CANIntStatus(CANA_BASE, CAN_INT_STS_CAUSE);

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

//Check to see if an error occurred.
if(((ulStatus & ~(CAN_ES_TXOK | CAN_ES_RXOK)) != 7) &&
((ulStatus & ~(CAN_ES_TXOK | CAN_ES_RXOK)) != 0)){
// Set a flag to indicate some errors may have occurred.
g_bErrFlag = 1;
}
}

// Check if the cause is message object 1, which what we are using for
// sending messages.
else if(ulStatus == 1)
{
// Getting to this point means that the TX interrupt occurred on
// message object 1, and the message TX is complete. Clear the
// message object interrupt.
CANIntClear(CANA_BASE, 1);

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

// Since the message was sent, clear any error flags.
g_bErrFlag = 0;
}

// Check if the cause is message object 1, which what we are using for
// receiving messages.
else if(ulStatus == 2)
{

// Get the received message
CANMessageGet(CANA_BASE, 2, &sRXCANMessage, true);

// Getting to this point means that the TX interrupt occurred on
// message object 1, and the message TX is complete. Clear the
// message object interrupt.
CANIntClear(CANA_BASE, 2);

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

// Since the message was sent, clear any error flags.
g_bErrFlag = 0;
}

// Otherwise, something unexpected caused the interrupt. This should
// never happen.
else
{
// Spurious interrupt handling can go here.
}

//canaRegs.CAN_GLB_INT_CLR.bit.INT0_FLG_CLR = 1;
CANGlobalIntClear(CANA_BASE, CAN_GLB_INT_CANINT0);
PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
}

//*****************************************************************************
// Configure the CAN and enter a loop to transmit periodic CAN messages.
//*****************************************************************************
int main(void)
{
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2807x_SysCtrl.c file.
InitSysCtrl();

// Step 2. Initialize GPIO:
// This example function is found in the F2807x_Gpio.c file and
// illustrates how to set the GPIO to its default state.
InitGpio();

//GPIO 73 - XCLKOUT
//GPIO_SetupPinMux(73, GPIO_MUX_CPU1, 3);
//GPIO_SetupPinOptions(73, GPIO_OUTPUT, GPIO_PUSHPULL); // -> SYSCLOCK/8 = 25MHz
//GpioCtrlRegs.GPAMUX1.bit.GPIO10=0;
//GpioCtrlRegs.GPADIR.bit.GPIO10=0;
//GpioDataRegs.GPADAT.bit.GPIO10=0;
//GPIO30 - CANRXA
GPIO_SetupPinMux(70, GPIO_MUX_CPU1, 6);
//GPIO31 - CANTXA
GPIO_SetupPinMux(71, GPIO_MUX_CPU1, 6);
GPIO_SetupPinOptions(70, GPIO_INPUT, GPIO_ASYNC);
GPIO_SetupPinOptions(71, GPIO_OUTPUT, GPIO_PUSHPULL);
//GPIO30 - CANRXB
//GPIO_SetupPinMux(73, GPIO_MUX_CPU1, 6);
//GPIO31 - CANTXB
//GPIO_SetupPinMux(72, GPIO_MUX_CPU1, 6);
//GPIO_SetupPinOptions(73, GPIO_INPUT, GPIO_ASYNC);
//GPIO_SetupPinOptions(72, GPIO_OUTPUT, GPIO_PUSHPULL);

// Initialize the CAN controller
CANInit(CANA_BASE);
//CANInit(CANB_BASE);
// Setup CAN to be clocked off the PLL output clock
CANClkSourceSelect(CANA_BASE, 0); /* 500kHz CAN-Clock */

// 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(CANA_BASE, 120000000, 500000);
//CANBitRateSet(CANA_BASE, 120000000, 1000000);
// 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.
//CANIntEnable(CANA_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);

// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
DINT;

// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the F2807x_PieCtrl.c file.
InitPieCtrl();

// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;

// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in F2807x_DefaultIsr.c.
// This function is found in F2807x_PieVect.c.
InitPieVectTable();

// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
// Register interrupt handler in RAM vector table
EALLOW;
PieVectTable.CANA0_INT = CANIntHandler;
EDIS;

// Enable the CAN interrupt on the processor (PIE).
PieCtrlRegs.PIEIER9.bit.INTx5 = 1;
IER |= 0x0100; /* M_INT9 */
EINT;

// Enable test mode and select external loopback
//HWREG(CANA_BASE + CAN_O_CTL) |= CAN_CTL_TEST;
//HWREG(CANA_BASE + CAN_O_TEST) = CAN_TEST_EXL;

// Enable the CAN for operation.
CANEnable(CANA_BASE);
//CANEnable(CANB_BASE);
CANGlobalIntEnable(CANA_BASE, CAN_GLB_INT_CANINT0);

// 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 0x12345678.
//ucTXMsgData[0] = (u32CntTXMsgData>>24) & 0xFF;
//ucTXMsgData[1] = (u32CntTXMsgData>>16) & 0xFF;
//ucTXMsgData[2] = (u32CntTXMsgData>>8) & 0xFF;
//ucTXMsgData[3] = (u32CntTXMsgData) & 0xFF;
sTXCANMessage.ui32MsgID = 1; // CAN message ID - use 1
sTXCANMessage.ui32MsgIDMask = 0; // no mask needed for TX
sTXCANMessage.ui32Flags = MSG_OBJ_TX_INT_ENABLE; // enable interrupt on TX
sTXCANMessage.ui32MsgLen = sizeof(ucTXMsgData); // size of message is 8
sTXCANMessage.pucMsgData = ucTXMsgData; // ptr to message content

// Initialize the message object that will be used for receiving CAN
// messages.
*(unsigned long *)ucRXMsgData = 0;
sRXCANMessage.ui32MsgID = 1; // CAN message ID - use 1
sRXCANMessage.ui32MsgIDMask = 0; // no mask needed for TX
sRXCANMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE; //MSG_OBJ_USE_EXT_FILTER | MSG_OBJ_EXTENDED_ID; // enable interrupt on RX
sRXCANMessage.ui32MsgLen = sizeof(ucRXMsgData); // size of message is 8
sRXCANMessage.pucMsgData = ucRXMsgData; // ptr to message content

// Setup the message object being used to receive messages
CANMessageSet(CANA_BASE, 2, &sRXCANMessage, MSG_OBJ_TYPE_RX);

// 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.
ucTXMsgData[0] = 0x12;
ucTXMsgData[1] = 0x34;
ucTXMsgData[2] = 0x56;
ucTXMsgData[3] = 0x78;

// 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 unsigned
// long and incremented by one each time.
for(;;)
{
// Check the error flag to see if errors occurred
if(g_bErrFlag)
{
asm(" ESTOP0");
}

if(g_ulTxMsgCount == g_ulRxMsgCount){
CANMessageSet(CANA_BASE, 1, &sTXCANMessage, MSG_OBJ_TYPE_TX);
}else{
//g_bErrFlag = 1;
}

// Now wait 1 second before continuing
DELAY_US(1000*1000);

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

  • Hi Lin,

    If you check the datasheet (Signal Descriptions section), there are no mux options for CAN functionality on GPIO32.  You can't just choose a GPIO and assign it arbitrarily as CAN channels.

    For your second issue, GPIO70 can be connected as CANRXA, but mux position is 5, not 6 as in your code.  GPIO71 can be connected as CANTXA, but mux position is also 5, not 6 as it appears in your code.  Again, consult the datasheet for the correct mux assignment for the CAN channels you need to use.

    Regards,

    Joseph 

  • Hi Casuga,

    thanks for your reply,

    I successfully solved the first problem,I found the mux options settings in another data sheet.

    But the second problem is still unresolved.I have changed the GPIO settings

    GPIO_SetupPinMux(70, GPIO_MUX_CPU1, 5); GPIO_SetupPinMux(71, GPIO_MUX_CPU1, 5);

    I write 'ulStatus' into the variable and observed that it was 5

    The new complete code is as follows:

    //###########################################################################
    // FILE: can_loopback_interrupts.c
    // TITLE: Example to demonstrate basic CAN setup and use.
    //
    //! \addtogroup cpu01_example_list
    //! <h1>CAN External Loopback with Interrupts (can_loopback_interrupts)</h1>
    //!
    //! This example shows the basic setup of CAN in order to transmit and receive
    //! messages on the CAN bus. The CAN peripheral is configured to transmit
    //! messages with a specific CAN ID. A message is then transmitted once per
    //! second, using a simple delay loop for timing. The message that is sent is
    //! a 4 byte message that contains an incrementing pattern. A CAN interrupt
    //! handler is used to confirm message transmission and count the number of
    //! messages that have been sent.
    //!
    //! This example sets up the CAN controller in External Loopback test mode.
    //! Data transmitted is visible on the CAN0TX pin and can be received with
    //! an appropriate mailbox configuration.
    //!
    //! This example uses the following interrupt handlers:\n
    //! - INT_CANA0 - CANIntHandler
    //!
    //
    //###########################################################################
    // $TI Release: F2807x Support Library v180 $
    // $Release Date: Fri Nov 6 16:33:02 CST 2015 $
    // $Copyright: Copyright (C) 2014-2015 Texas Instruments Incorporated -
    // http://www.ti.com/ ALL RIGHTS RESERVED $
    //###########################################################################

    #include "F28x_Project.h" // Device Headerfile and Examples Include File
    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_can.h"
    #include "driverlib/can.h"

    //*****************************************************************************
    // A counter that keeps track of the number of times the TX interrupt has
    // occurred, which should match the number of TX messages that were sent.
    //*****************************************************************************
    volatile unsigned long g_ulTxMsgCount = 0;
    volatile unsigned long g_ulRxMsgCount = 0;
    //int i;
    //unsigned long u32CanAErrorStatus;
    //unsigned long uCanAErrFlag;
    //*****************************************************************************
    // A flag to indicate that some transmission error occurred.
    //*****************************************************************************
    volatile unsigned long g_bErrFlag = 0;

    tCANMsgObject sTXCANMessage;
    tCANMsgObject sRXCANMessage;
    unsigned char ucTXMsgData[8] ={ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    unsigned char ucRXMsgData[8];
    unsigned long ii;
    unsigned long aa;
    //unsigned long u32CntTXMsgData = 0x12345678;

    //*****************************************************************************
    // 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.
    //*****************************************************************************
    interrupt void
    CANIntHandler(void)
    {
    unsigned long ulStatus;

    // Read the CAN interrupt status to find the cause of the interrupt
    ulStatus = CANIntStatus(CANA_BASE, CAN_INT_STS_CAUSE);

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

    //Check to see if an error occurred.
    if(((ulStatus & ~(CAN_ES_TXOK | CAN_ES_RXOK)) != 7) &&
    ((ulStatus & ~(CAN_ES_TXOK | CAN_ES_RXOK)) != 0)){
    // Set a flag to indicate some errors may have occurred.
    g_bErrFlag = 1;
    }
    }

    // Check if the cause is message object 1, which what we are using for
    // sending messages.
    else if(ulStatus == 1)
    {
    // Getting to this point means that the TX interrupt occurred on
    // message object 1, and the message TX is complete. Clear the
    // message object interrupt.
    CANIntClear(CANA_BASE, 1);

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

    // Since the message was sent, clear any error flags.
    g_bErrFlag = 0;
    }

    // Check if the cause is message object 1, which what we are using for
    // receiving messages.
    else if(ulStatus == 2)
    {

    // Get the received message
    CANMessageGet(CANA_BASE, 2, &sRXCANMessage, true);

    // Getting to this point means that the TX interrupt occurred on
    // message object 1, and the message TX is complete. Clear the
    // message object interrupt.
    CANIntClear(CANA_BASE, 2);

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

    // Since the message was sent, clear any error flags.
    g_bErrFlag = 0;
    }

    // Otherwise, something unexpected caused the interrupt. This should
    // never happen.
    else
    {
    // Spurious interrupt handling can go here.
    }
    ii=ulStatus;
    aa=(ulStatus & ~(CAN_ES_TXOK | CAN_ES_RXOK));
    //canaRegs.CAN_GLB_INT_CLR.bit.INT0_FLG_CLR = 1;
    CANGlobalIntClear(CANA_BASE, CAN_GLB_INT_CANINT0);
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
    }

    //*****************************************************************************
    // Configure the CAN and enter a loop to transmit periodic CAN messages.
    //*****************************************************************************
    int main(void)
    {
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2807x_SysCtrl.c file.
    InitSysCtrl();

    // Step 2. Initialize GPIO:
    // This example function is found in the F2807x_Gpio.c file and
    // illustrates how to set the GPIO to its default state.
    InitGpio();

    //GPIO 73 - XCLKOUT
    //GPIO_SetupPinMux(73, GPIO_MUX_CPU1, 3);
    //GPIO_SetupPinOptions(73, GPIO_OUTPUT, GPIO_PUSHPULL); // -> SYSCLOCK/8 = 25MHz
    //GpioCtrlRegs.GPAMUX1.bit.GPIO10=0;
    //GpioCtrlRegs.GPADIR.bit.GPIO10=0;
    //GpioDataRegs.GPADAT.bit.GPIO10=0;
    //GPIO30 - CANRXA
    GPIO_SetupPinMux(70, GPIO_MUX_CPU1, 5);
    //GPIO31 - CANTXA
    GPIO_SetupPinMux(71, GPIO_MUX_CPU1, 5);
    GPIO_SetupPinOptions(70, GPIO_INPUT, GPIO_ASYNC);
    GPIO_SetupPinOptions(71, GPIO_OUTPUT, GPIO_PUSHPULL);
    //GPIO30 - CANRXB
    //GPIO_SetupPinMux(73, GPIO_MUX_CPU1, 6);
    //GPIO31 - CANTXB
    //GPIO_SetupPinMux(72, GPIO_MUX_CPU1, 6);
    //GPIO_SetupPinOptions(73, GPIO_INPUT, GPIO_ASYNC);
    //GPIO_SetupPinOptions(72, GPIO_OUTPUT, GPIO_PUSHPULL);

    // Initialize the CAN controller
    CANInit(CANA_BASE);
    //CANInit(CANB_BASE);
    // Setup CAN to be clocked off the PLL output clock
    CANClkSourceSelect(CANA_BASE, 0); /* 500kHz CAN-Clock */

    // 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(CANA_BASE, 120000000, 250000);
    //CANBitRateSet(CANA_BASE, 120000000, 1000000);
    // 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.
    CANIntEnable(CANA_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);

    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
    DINT;

    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the F2807x_PieCtrl.c file.
    InitPieCtrl();

    // Disable CPU interrupts and clear all CPU interrupt flags:
    IER = 0x0000;
    IFR = 0x0000;

    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example. This is useful for debug purposes.
    // The shell ISR routines are found in F2807x_DefaultIsr.c.
    // This function is found in F2807x_PieVect.c.
    InitPieVectTable();

    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
    // Register interrupt handler in RAM vector table
    EALLOW;
    PieVectTable.CANA0_INT = CANIntHandler;
    EDIS;

    // Enable the CAN interrupt on the processor (PIE).
    PieCtrlRegs.PIEIER9.bit.INTx5 = 1;
    IER |= 0x0100; /* M_INT9 */
    EINT;

    // Enable test mode and select external loopback
    //HWREG(CANA_BASE + CAN_O_CTL) |= CAN_CTL_TEST;
    //HWREG(CANA_BASE + CAN_O_TEST) = CAN_TEST_EXL;

    // Enable the CAN for operation.
    CANEnable(CANA_BASE);
    //CANEnable(CANB_BASE);
    CANGlobalIntEnable(CANA_BASE, CAN_GLB_INT_CANINT0);

    // 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 0x12345678.
    //ucTXMsgData[0] = (u32CntTXMsgData>>24) & 0xFF;
    //ucTXMsgData[1] = (u32CntTXMsgData>>16) & 0xFF;
    //ucTXMsgData[2] = (u32CntTXMsgData>>8) & 0xFF;
    //ucTXMsgData[3] = (u32CntTXMsgData) & 0xFF;
    sTXCANMessage.ui32MsgID = 1; // CAN message ID - use 1
    sTXCANMessage.ui32MsgIDMask = 0; // no mask needed for TX
    sTXCANMessage.ui32Flags = MSG_OBJ_TX_INT_ENABLE; // enable interrupt on TX
    sTXCANMessage.ui32MsgLen = sizeof(ucTXMsgData); // size of message is 8
    sTXCANMessage.pucMsgData = ucTXMsgData; // ptr to message content

    // Initialize the message object that will be used for receiving CAN
    // messages.
    *(unsigned long *)ucRXMsgData = 0;
    sRXCANMessage.ui32MsgID = 1; // CAN message ID - use 1
    sRXCANMessage.ui32MsgIDMask = 0; // no mask needed for TX
    sRXCANMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE; //MSG_OBJ_USE_EXT_FILTER | MSG_OBJ_EXTENDED_ID; // enable interrupt on RX
    sRXCANMessage.ui32MsgLen = sizeof(ucRXMsgData); // size of message is 8
    sRXCANMessage.pucMsgData = ucRXMsgData; // ptr to message content

    // Setup the message object being used to receive messages
    CANMessageSet(CANA_BASE, 2, &sRXCANMessage, MSG_OBJ_TYPE_RX);

    // 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.
    ucTXMsgData[0] = 0x12;
    ucTXMsgData[1] = 0x34;
    ucTXMsgData[2] = 0x56;
    ucTXMsgData[3] = 0x78;

    // 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 unsigned
    // long and incremented by one each time.
    for(;;)
    {
    // Check the error flag to see if errors occurred
    if(g_bErrFlag)
    {
    asm(" ESTOP0");
    }

    if(g_ulTxMsgCount == g_ulRxMsgCount){
    CANMessageSet(CANA_BASE, 1, &sTXCANMessage, MSG_OBJ_TYPE_TX);
    }else{
    //g_bErrFlag = 1;
    }

    // Now wait 1 second before continuing
    //DELAY_US(1000*1000);

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

  • Hi Lin,

    What kind of hardware are you using?  Is it a TI released one or is it a different design?  There are no obvious issues that I can see in your code.

    Regards,,

    Joseph

  • Hi Casuga,

    thanks for your reply,

    The DSP board we use is designed by ourselves. Following is the circuit diagram of CANBUS

    I'm not sure if the hardware you are referring to is this.