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.

MSP432E401Y: bl_can.c, MSGLST is sticky

Part Number: MSP432E401Y

Hello

In TI provideded file bl_can.c

C:\ti\simplelink_msp432e4_sdk_4_20_00_12\source\ti\devices\msp432e4\boot_loader\

At

function

CANMessageGetRx(uint8_t *pui8Data, uint32_t *pui32MsgID)

I'm finding that once CAN_IF1MCTL_MSGLST is set, it is stuck there and won't clear.

What's the right way to clear it?

I tried at line 381:

if((ui16MsgCtrl & CAN_IF1MCTL_MSGLST) == CAN_IF1MCTL_MSGLST)
{
 CAN0->IF2CMSK = CAN_IF1CMSK_NEWDAT;
 CAN0->IF2CRQ = MSG_OBJ_BCAST_RX_ID;
 CAN0->IF2MCTL &= 0x3FFF; // clear newdat & lost
 while(CAN0->IF2CRQ & CAN_IF2CRQ_BUSY)
 {
 }
}

  • Hi,

      I think you want to first find out why the MSGLST is set. It means that your incoming message is arriving while the last message has not been processed yet. 

    if((ui16MsgCtrl & CAN_IF1MCTL_MSGLST) == CAN_IF1MCTL_MSGLST)
    {
     CAN0->IF2CMSK = CAN_IF1CMSK_NEWDAT;
     CAN0->IF2CRQ = MSG_OBJ_BCAST_RX_ID;
     CAN0->IF2MCTL &= 0x3FFF; // clear newdat & lost
     while(CAN0->IF2CRQ & CAN_IF2CRQ_BUSY)
     {

      I don't really see a problem here. Have you tried it and what did you see?

  • Hello, the overrun happens because the flash burning takes time. There's other CAN traffic and I can't use a filter for reasons I won't go into. When running under debugger, once I hit the breakpoint in the code shown, I never again hit a breakpoint in the preceding NOT LOST code, but keeping hitting this code. This makes me believe I am not correctly clearing the MSGLST. The TRM is vague about how to clear it,

  • Hi John,

      Are you in interrupt mode? Other than message list, do you see any errors on CANSTS and CANERR registers?

      Perhaps I should also ask what is your intention for the below code. You have already lost a prior message. Are you trying to read the new message? If you are trying to clear the newdat & msglst bits then why would you use &= with F? If newdat & msglst are 1, doing a &= does not clear the bits to 0. 

    if((ui16MsgCtrl & CAN_IF1MCTL_MSGLST) == CAN_IF1MCTL_MSGLST)
    {
     CAN0->IF2CMSK = CAN_IF1CMSK_NEWDAT;
     CAN0->IF2CRQ = MSG_OBJ_BCAST_RX_ID;
     CAN0->IF2MCTL &= 0x3FFF; // clear newdat & lost
     while(CAN0->IF2CRQ & CAN_IF2CRQ_BUSY)
     {

  • Hello

    Again refer to the bl_can.c file from the simplelink sdk
    When I have fallen into the else block at line 380

    CAN0->ERR = 0
    CAN0->STS = 0x0018
    CAN0->IF2MCTL = 0xD084

    This is a non-interrupt bootloader that is re-flashing the application area of the chip based on blocks of data sent in through CAN.
    The next data block isn't sent to me until I send an acknowledgement. The other traffic that caused the overrun is irrelevant to me at that time.

    The intention of the code block is to be able to recover from the overrun, discard lost incoming CAN frames and resume communication.
    The problem is, it doesn't recover, it gets stuck forever falling into that else block at line 380.

    Maybe I need to implement an interrupt service routine, could you point me to an example.

    The CAN0->IF2MCTL &= 0x3FFF
    does clear CAN_IF1MCTL_NEWDAT (0x8000) and CAN_IF1MCTL_MSGLST ((0x4000)

    0011 1111 1111 1111‬
    &
    1101 0000 1000 0100‬
    =
    0001 0000 1000 0100‬

    And I can see this happen in the CCS registers window

  • Hi John,

      Indeed, the link is broken and posted 15 years ago. I copy and paste the reply. 

    The MSG_OBJ_DATA_LOST bit is cleared by writing the bit to a zero in the message object. This requires a read/modify/write sequence using the IFn registers when you are directly accessing the CAN registers as there are many other very important bits in this register so you cannot just clear it.

    If you are using the DriverLib CAN APIs, a call to CANMessageSet() with the results of your CANMessageGet() call will clear the MSG_OBJ_DATA_LOST flag for you. Here is a little code snippet that will do the trick.

    Code:


     
    //
    // Typical read from an interrupt handler.
    //
    CANMessageGet(CAN0_BASE, MSGOBJ_NUM_LED, &sMsgObject, 1);

    if(sMsgObject.ulFlags & MSG_OBJ_DATA_LOST)
    {
        //
        // Clear the MSG_OBJ_DATA_LOST.
        //
        sMsgObject.ulFlags &= ~MSG_OBJ_DATA_LOST;

        //
        // Set the new state of the message object. 
        //
        CANMessageSet(CAN0_BASE, MSGOBJ_NUM_LED, &g_MsgObject, MSG_OBJ_TYPE_RX);
    }
  • Is MSG_OBJ_BCAST_RX_ID the right ID instead of 

    MSGOBJ_NUM_LED ?