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.

CCS/TMS320F28377D: CAN communication

Part Number: TMS320F28377D
Other Parts Discussed in Thread: C2000WARE

Tool/software: Code Composer Studio

Excuse me, I have some problems in debugging CAN communication recently。

First,I used TMS320F28377D Code Examples/All CPU1 Examples / can_external_transmit to debug CAN and define TX_MSG_OBJ_ID 2; RX_MSG_OBJ_ID 1。I can receive message and retransmit the message, but encounter some ploblems. As Figure 1-3 shows,

status = CANIntStatus(CANA_BASE, CAN_INT_STS_CAUSE); àstatus = 0x00008000

status = CANStatusGet(CANA_BASE, CAN_STS_CONTROL); à status = 0x00000008

How can I deal with the proplems and Why ?

Second, I can receive message for specific ID(0x00005555). But if I want to receive all messages first, and then judge ID Whether is used. How Can I configure the sRXCANMessage structure?

sRXCANMessage.ui32MsgID = 0x00005555;

sRXCANMessage.ui32MsgIDMask = 0;

sRXCANMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE;

   sRXCANMessage.ui32MsgLen = MSG_DATA_LENGTH;    

   sRXCANMessage.pucMsgData = rxMsgData;

   CANMessageSet(CANA_BASE, RX_MSG_OBJ_ID, &sRXCANMessage,

                   MSG_OBJ_TYPE_RX);

Thank you very much!

Best Regards.

  • Hi,

    I do not see Fig 1-3 that you are referring to but the CAN_INIT_STS_CAUSE of 0x8000 indicates that LEC (last error code) in CAN_ES (CAN status register) is not 0x7.  Can you display the contents of CAN_ES register when you are having the issue?  This will give a better indication of the issue you are running into.  Not sure why you are not getting messages from IDs other than 0x00005555.  Message ID mask is already set to 0 so all message IDs should be received.  Let's first look into CAN_ES, maybe there is an underlying error that prevents the CAN from receiving messages.

    Regards,

    Joseph

  • Hi,JosePh

    1.when I recived a message from ID 0x00005555 and rechansmit the message, The CAN_ES register TxOK = 1 as figure 1 show, but I still receive a error.

    status = CANIntStatus(CANA_BASE, CAN_INT_STS_CAUSE); -------> status = 0x00008000

    status = CANStatusGet(CANA_BASE, CAN_STS_CONTROL); --------> status = 0x00000008

    The CAN_ES register LEC = 0x7 as figure 2 show.   How can I Solve the issue?

    2.Another question, when I config sRXCANMessage.ui32MsgID = 0x00005555;sRXCANMessage.ui32MsgIDMask = 0; I  can receved an interrupt  from

    other ID just like 0x00006666 and the CAN_ES register indicate the RxOK = 1, as the figure3 show. but  I can't receive any information from ID = 0x00006666, because status = CANIntStatus(CANA_BASE, CAN_INT_STS_CAUSE); -------> status = 0x00008000  as  figure 4 show, I can't find a way to solve this prolem, could you help me ?

    thanks and best regards.

  • Hi Rizhao,

    It looks like there is are pending interrupts that cause you to get these status.  Can you also inspect the values of CAN_IPEN_X and CAN_IPEN_21?  Sorry, these function calls in you code are deprecated which makes debugging a lot longer since I have to go back to old examples just to understand these functions.  It would be good if you can migrate to the latest C2000Ware CAN functions when you get a chance.

    Thanks and regards,

    Joseph

  • Hi Joseph,

    I follow your advice and migrate to the latest C2000Ware CAN functions, but still have the same problem. when I send ID=0x95555555 message, I can receive it and occur an error. If I change ID to 0x95555556, Ican't receive the message. Figure1-4 shows ID=0x95555555 related register and Figure5-8 shows ID=0x95555556 related register. I migrate can_ex3_external_transmit.c as follow. Could you help me to check the problems ? thank you very much!

    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    #include "stdlib.h"
    #include "string.h"
    #include "math.h"
    //
    // Defines
    //
    #define TXCOUNT  100000
    #define MSG_DATA_LENGTH    8
    #define TX_MSG_OBJ_ID      2
    #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[8];
    uint16_t rxMsgData[8];
    
    //
    // Function Prototypes
    //
    __interrupt void canaISR(void);     // Receive interrupt for CAN-A.
                                        // No Transmit interrupt for CAN-A
    //__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(DEVICE_GPIO_CFG_CANRXA);
        GPIO_setPinConfig(DEVICE_GPIO_CFG_CANTXA);
        //GPIO_setPinConfig(DEVICE_GPIO_CFG_CANRXB);
        //GPIO_setPinConfig(DEVICE_GPIO_CFG_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, 250000, 20);
        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(CANA_BASE, CAN_INT_IE0 | CAN_INT_ERROR |
                             CAN_INT_STATUS);
       // 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_CANA0, &canaISR);
        //Interrupt_register(INT_CANB0, &canbISR);
        //
        // Enable the CAN-B interrupt signal
        //
        Interrupt_enable(INT_CANA0);
        //Interrupt_enable(INT_CANB0);
    	//
        // Set GLBINT0_EN bit in CAN_GLB_INT_EN register
    	//
        CAN_enableGlobalInterrupt(CANA_BASE, CAN_GLOBAL_INT_CANINT0);
        //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
        //      No interrupts are enabled for the Transmit side
        //
        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(CANA_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;
        txMsgData[4] = 0x01;
        txMsgData[5] = 0x02;
        txMsgData[6] = 0x03;
        txMsgData[7] = 0x04;
        //
        // 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 > 500)
            {
                asm("   ESTOP0");
            }
    
            //
            // Verify that the number of transmitted messages equal the number of
            // messages received before sending a new message
            //
            if(txMsgCount < rxMsgCount && rxMsgCount != 0)
            {
                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;
                }
                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.
            //
        }
    
        //
        // Stop application
        //
        asm("   ESTOP0");
    }
    
    //
    // 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
    canaISR(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(CANA_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(CANA_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(CANA_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(CANA_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(rxMsgData[0] == txMsgData[0] && rxMsgData[1] == txMsgData[1] && rxMsgData[2] == txMsgData[2] && rxMsgData[3] == txMsgData[3])
            {
                memset(rxMsgData,0,sizeof(rxMsgData));
            }
            else
                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(CANA_BASE, CAN_GLOBAL_INT_CANINT0);
    
        //
        // Acknowledge this interrupt located in group 9
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }

  • Hi Joseph,

    Could you please help check the latest feedback? Thank you.

  • Hi Aki,

    Sorry, have not had a chance to debug this.  I should have a response before the end of the week.

    Regards,

    Joseph

  • Hi Rizhao/Aki,

             Apologies for the late response.  Can you verify if MSG_OBJ_USE_ID_FILTER is set in the application.  There is a similar post that I have responded to having the same issue on message ID filtering.  I think same thing applies here.  This is the post:

    https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/904797

    Regards,

    Joseph

  • Hi Rizhao/Aki,

    When you get a chance, make these changes to allow reception of message from all IDs:

        CAN_setupMessageObject(CANA_BASE, RX_MSG_OBJ_ID, 0x95555555,
                               CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_RX, 0,
                               CAN_MSG_OBJ_RX_INT_ENABLE|CAN_MSG_OBJ_USE_ID_FILTER, MSG_DATA_LENGTH);
    Adding the CAN_MSG_OBJ_USE_ID_FILTER will allow message filtering, and since mask is set to '0', messages from other IDs will be received.  This should address your second issue.  Try this and see if the ID issue gests resolved then e can debug the first issue about CAN status.
    Regards,
    Joseph
  • Hi Joseph,

    Thank you very much for your advice,  The issue can be solved.

    Best Regards,

    rizhao.qin

  • Hi Joseph,

    Thank you for the strong support!