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.

TM4C1232H6PM: CAN message interrupt without status interrupt

Part Number: TM4C1232H6PM


Tool/software:

Hello,

I'm working on my CAN_ISR (using TivaWare) which looks something like this:

void _canISR(uint32_t CAN_BASE)
{
  uint32_t status = 0x00;
  uint32_t ui32Status = 0x00;

  ui32Status = CANIntStatus(CAN_BASE, CAN_INT_STS_CAUSE);

  //status interrupt or highest priority message interrupt with pending interrupt
  if ((ui32Status == CAN_INT_INTID_STATUS) || ((ui32Status <= 32) && (ui32Status > 0)))
  {
    status = CANStatusGet(CAN_BASE, CAN_STS_CONTROL);


    if (status & CAN_STATUS_RXOK)
    {

            ...

    }

}

I now encounter the problem where status is 0 but ui32Status is not 0 and I don't understand how this can happen. Doesnt every message interrupt also cause a status interrupt?

  • ui32Status = CANIntStatus(CAN_BASE, CAN_INT_STS_CAUSE);

    HI,

      CANIntStatus reads the CANINT register. The value indicates the number of message object that caused the interrupt. For example, if you set up Message Object 0 for transmitting or receiving then CANINT will show a value of 1. However, if there is an error then it will show 0x8000.

    status = CANStatusGet(CAN_BASE, CAN_STS_CONTROL);

    CANStatusGet reads the CANSTS register. Since there is no error, the value is zero after reading. 

  • Hi Charles,

    Thanks a lot for your response!

    I think CANStatusGet(CAN_BASE, CAN_STS_CONTROL); can be not 0 even if there is not error, e.g. if a message is sucessfully received it should contain the RXOK bit.

    So lets say a message is received sucessfully I would expect CANStatusGet() to return RXOK and CANIntStatus() to return the number of the corresponding message object.

    I still can't understand in what scenario CANIntStatus() would be != 0 (indicating a pending interrupt) but CANStatusGet ==0 (indicating no interrupt and no message reception or transmission).

    Can you elaborate on this?

  • Hi Dominic,

    I think CANStatusGet(CAN_BASE, CAN_STS_CONTROL); can be not 0 even if there is not error, e.g. if a message is sucessfully received it should contain the RXOK bit.

    Agree.

    Can you put a breakpoint in CANStatusGet and single step through the code. What is the value of CANSTS when the function is entered. Let's say RXOK is not set but other bits are set. In this case, your if (status & CAN_STATUS_RXOK) will become zero. 

      Please also note the RXOK, TXOK or LEC will be cleared after CANSTAT is read. See below highlighted statement. Please refer to the source code in can.c file in details for CANStatusGet().

    //
    // Just return the global CAN status register since that is what was
    // requested.
    //
    case CAN_STS_CONTROL:
    {
    ui32Status = HWREG(ui32Base + CAN_O_STS);
    HWREG(ui32Base + CAN_O_STS) = ~(CAN_STS_RXOK | CAN_STS_TXOK |
                                    CAN_STS_LEC_M);
    break;
    }

  • Thanks for your reply.

    When I single step through the code usually I get ui32Status == CAN_INT_INTID_STATUS (from CANIntStatus) and status == RXOK (or TXOK). This is the normal and expected behaviour for me.

    I seldom cases I get ui32Status == 2 and status == 0,  which I do not understand how it came to be. When I look at the pending Message Interrupt with CANMessageGet(CAN_BASE,ui32Status,...) I recognize the Message ID, but the Message Length is not what I send with this message.

    - Can the Message be corrupted such that it triggers the Message interrupt but not the Status interrupt?

    - Can multiple CAN messages in fast succession 'damage' each other?

  • When I single step through the code usually I get ui32Status == CAN_INT_INTID_STATUS (from CANIntStatus) and status == RXOK (or TXOK).

    If ui32Status == CAN_INT_INTID_STATUS then some type of error is detected. 

    I seldom cases I get ui32Status == 2 and status == 0, 

    I don't know the answer to this combination. If ui32Status == 2 then it means the interrupt is due to Message Object 1. The status can be either RXOK or TXOK depending on you are using the message object for transmit or receive. 

    Can you put a breakpoint in beginning of _canISR()? Once the processor halts at the breakpoint, use the Register Browser Window to view CAN registers. I hope it will provide some clues. 

  • Thanks for the reply.

    I will work on this with the tools you described.

    Thanks for your kind support!