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.

TM4C123G Launchpad CAN TX Issue

Other Parts Discussed in Thread: SN65HVD251

Guys,

I just started using TM4C123G Launchpad to establish a CAN bus application. I am using simpletx tivaware (as is) example to run the CAN bus from CAN0(PB4, PB5) into a sn65hvd251 transceiver.

The CAN bus seems to be set up correctly as I can see the right messages being transmitted on my bus monitor. The issue I have is that message transmission does not seem to block on the SimpleDelay() function (even though UARTprintf is).

The console shows a status message every ~1s but CAN messages are being transmitted approx. every 40ms. The console output below shows the messages printed out, but as you see they are skipping ~2400 counts every second. The received message count on the CAN bus monitor correlates very well with the count here.

My question is that a) is this expected? Is there a different delay method I should be using?

b) if this is not expected, does anybody see anything wrong with my code. The interrupt seems to be setup fine because I am getting a count++ for every message received by the CAN monitor.

Thanks

Sid

  • Still  figuring out how to paste code snippets:

    void

    CANIntHandler(void)

    {

    uint32_t ui32Status;

    //

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

    //

    ui32Status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);

    //

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

    //

    if(ui32Status == CAN_INT_INTID_STATUS)

    {

    ui32Status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);

    //

    // 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(ui32Status == 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(CAN0_BASE, 1);

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

    g_ui32MsgCount++;

    //

    // 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.

    //

    }

    }

    ui32MsgData = 0;

    sCANMessage.ui32MsgID = 1;

    sCANMessage.ui32MsgIDMask = 0;

    sCANMessage.ui32Flags = MSG_OBJ_TX_INT_ENABLE;

    sCANMessage.ui32MsgLen = sizeof(pui8MsgData);

    sCANMessage.pui8MsgData = pui8MsgData;

     

     

    while(1)

    {

    //

    // Print a message to the console showing the message count and the

    // contents of the message being sent.

    //

    UARTprintf("Sending msg: 0x%02X %02X %02X %02X",

    pui8MsgData[0], pui8MsgData[1], pui8MsgData[2],

    pui8MsgData[3]);

    //

    // Send the CAN message using object number 1 (not the same thing as

    // CAN ID, which is also 1 in this example). This function will cause

    // the message to be transmitted right away.

    //

    CANMessageSet(CAN0_BASE, 1, &sCANMessage, MSG_OBJ_TYPE_TX);

    //

    // Now wait 1 second before continuing

    //

    SimpleDelay();

     

    //

    // Check the error flag to see if errors occurred

    //

    if(g_bErrFlag)

    {

    UARTprintf(" error - cable connected?\n");

    }

    else

    {

    //

    // If no errors then print the count of message sent

    //

    UARTprintf(" total count = %u\n", g_ui32MsgCount);

    }

    //

    // Increment the value in the message data.

    //

    ui32MsgData++;

    }

    //

    // Return no errors

    //

    return(0);

    }

     

  • Hello Sid,

    If you are using TivaWare 2.1.3 then I would suggest reverting to the older version of TivaWare. This is an incorrect fix done in TivaWare which would be reverted.
  • Hi Amit, I cant seem to find a link to older versions, would be great if you could point me in the right direction.

    Also for my understanding of the issue, would you be able to say where the problem lies. At the moment it appears to me that

    among the 4 operations within the while(1) loop, ui32MsgData++ and the UARTprints seem to be happening approx every 1s but CANMessageSet() almost seems to be operating in a independent non-blocking thread. Is there a register setting or mode for the controller that I am missing where the CAN controller will operate like that?

    I realize that I didn't include my CAN monitor UART output screenshots in the previous post so here they are

    Thanks a lot for the help.

    Sid

  • Hello Sid

    Attached is the older can.c file from driverlib in TivaWare. Overwrite the existing can.c in driverlib and re-generate the driverlib. Use the regenerated driverlib in your project.

    can.c

  • Hello Amit, No change. I dropped the file in driverlib and rebuilt the lib file and my project. Do I need the can header file as well?

    Regards
    Sid
  • Hello Sid

    Did you use the driverlib.lib from the new path where it has been compiled?
  • OK my bad.....I forgot I moved the project into my workspace!

    Everything works as expected now, thanks a lot for your help!

    Regards
    Sid