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.

TMS320F280037: CAN message interrupts -- RX works, TX not

Part Number: TMS320F280037
Other Parts Discussed in Thread: C2000WARE

Hey folks,

I am now working with a TMS320F280037 board and using its CAN bus for communication. 

In the application, I have multiple TX, and RX message objects setup in main, something like 

CAN_initModule(CANA_BASE);

CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 500000, 20);

CAN_enableInterrupt(CANA_BASE, CAN_INT_IE0 | CAN_INT_ERROR |CAN_INT_STATUS);

...

Interrupt_register(INT_CANA0, &canaISR);
    
Interrupt_enable(INT_CANA0);
CAN_enableGlobalInterrupt(CANA_BASE, CAN_GLOBAL_INT_CANINT0);

// TX message object, # 1
CAN_setupMessageObject(CANA_BASE, 1, 0x111,
                           CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_TX, 0,
                           CAN_MSG_OBJ_TX_INT_ENABLE, 8);

// TX message object, # 2
CAN_setupMessageObject(CANA_BASE, 2, 0x112,
                           CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_TX, 0,
                           CAN_MSG_OBJ_TX_INT_ENABLE, 8);

// RX message object, # 3
CAN_setupMessageObject(CANA_BASE, 3, 0x101,
                       CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_RX, 0,
                       CAN_MSG_OBJ_RX_INT_ENABLE, 8);
                       
CAN_startModule(CANA_BASE);

and in the canaISR, I defined the action when each of the events (Transmission and receive interrupts) happens, something like

__interrupt void canaISR(void)
{
    uint32_t intr_status;
    uint32_t can_status;

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

    //
    // If the cause is a controller status interrupt, then get the status
    //
    switch (intr_status) {
    case 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.
        //
        can_status = CAN_getStatus(CANA_BASE);

        break;
    }

    case 3: // the RX message object # (which is 3)
    {
        // ... application codes

        CAN_clearInterruptStatus(CANA_BASE, 3);

        break;
    }


    case 1: // TX message object: 1
    case 2: // TX message object: 2
    {
        // basically nothing to do here just clear the status
        CAN_clearInterruptStatus(CANA_BASE, intr_status);
        break;
    }

    default:
    {
        //
        // Spurious interrupt handling can go here.
        //
        break;
    }

    } // end-switch

    //
    // 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);
}
/************************CAN ISR**********************/

Now my observation is, the RX interrput gets correctly operated (the application codes in the RX switch case lines are operated, adding breakpoints it will stop there when a message was received). But the TX interrupt seems not happeing. Adding breakpoint in the TX Messag object switch case lines within canaISR, but not getting triggered.  

I am expecting the TX interrupt to work properly since I have setup the TX message objects as CAN_MSG_OBJ_TX_INT_ENABLE. The RX message objects are setup in a similar manner (using CAN_MSG_OBJ_RX_INT_ENABLE) which works well, so I don't understand why the TX message objects have issue here.

Appreciate for replies and advices.

Regards,

Wei

  • Wei, 

    First of all, I would recommend you to try and run "can_ex5_transmit_receive" which has been validated in order to test your setup. 

    Your code looks okay, can you also check the value of the transmit error counter in the CAN_ERRC register to check that there is an error in transmission. 

    Thanks.

  • Hi Sahil,

    Thanks for your reply. Actually I am using the can_ex5_transmit_receive with some minor alternations, and got the observations I described above.

    I will try to get more details from the experiment and get back here. 

    BTW, not sure whether I am doing correctly, but I imported the can_ex5_transmit_receive example from the resource explorer (offline, I downloaded C2000ware earlier) as the picture shown below. 

    I downloaded the example code from the 280037 folder, but the project imported seems have a default target configuration for 280039C. I changed it to 280037 (See below, the 39C target configs comes with the project imported, and I created an new one named 280037) and built / ran it on 280037 board, but not sure if there are other steps need to be adapted. 

    Regards,

    Wei

  • Wei, 

    I would recommend you try to run the example out of the box from C2000ware first, before you modify the example for testing. 

    I downloaded the example code from the 280037 folder, but the project imported seems have a default target configuration for 280039C. I changed it to 280037 (See below, the 39C target configs comes with the project imported, and I created an new one named 280037) and built / ran it on 280037 board, but not sure if there are other steps need to be adapted. 

    You need not create a new target config for running the example. The example will work as is. 

    Could you also share details of the setup you are using? Specifically, it would help if you could share a pin diagram for connections to the CAN transceiver?

    Thanks.