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.

Bug report: TivaWare 2.1.2.111 can.c. Message might not get sent if execution of CANMessageSet() is interrupted by ISR that uses CANIntClear().

Other Parts Discussed in Thread: TM4C1290NCZAD

Hi,

I have been debugging problems with sending CAN messages (on TM4C1290NCZAD) and found out that a message might not get sent if execution of CANMessageSet() is interrupted by a CAN interrupt that uses CANIntClear().

To be more specific: if interrupt arrives after execution of line 1787 in can.c (HWREG(ui32Base + CAN_O_IF1CMSK) = ui16CmdMaskReg;) and before line 1798 (HWREG(ui32Base + CAN_O_IF1CRQ) = ui32ObjID & CAN_IF1CRQ_MNUM_M;) and CANIntClear() is called (in the ISR) then message will not be transferred. The reason for that is the fact that both CANMessageSet() and CANIntClear() use Interface 1 in CAN controller. As a result CANIntClear() (in line 1113: HWREG(ui32Base + CAN_O_IF1CMSK) = CAN_IF1CMSK_CLRINTPND;) overwrites changes made previously by CANMessageSet() in CANIF1CMSK . When ISR is finished and CANMessageSet() is resumed it will request a message transfer but CANIF1CMSK will not be set to write anything to the CAN registers.

There is a workaround for this issue - use of CANMessageGet() to clear the interrupt. CANMessageGet uses interface 2 in CAN controller and therefore does not influence settings done by CANMessageSet().

Please let me know if there is something that I am missing or doing wrong or If you need more details.

Thank you.

  • Hello Peter,

    Thank you for letting us know about this issue. I'll forward this to our software team members so they can review your findings. If, by chance, they see any issues with your explanation/understanding we will come back to clarify. Otherwise, your observation will be entered as a bug and repaired in one of the future builds of TivaWare.
  • Hi Chuck,
    Thank you very much.
    Peter A.
  • Hello Peter

    Or would a simpler fix would be to OR the CLRINTPND in the CANIntClear?

    HWREG(ui32Base + CAN_O_IF1CMSK) |= CAN_IF1CMSK_CLRINTPND;

    Regards
    Amit
  • Hi Amit,

    I can see one problem with this approach:
    You have no control over what has already been written to the IF1CMSK, so you might get undefined behaviour if configuration in CANMessageSet has already been started but has not finished (some of the bits in IF1CMSK have been set).

    But I think that you could use some temporary variable to store current state of CMSK, set CLRINTPND as it is done at the moment (no OR just regular assignment) and restore CMSK before exiting CANIntClear().

    I am not sure if sending of "clear interrupt command" from CANIntClear() can change values of other registers in Interface 1 or if some registers being set before execution of CANIntClear() can interfere with its operation. But If that is the case, then they should also be protected.

    Hope that helps,
    Peter A.
  • Hello Peter,

    If the bit has already been set and a read modify write operation is being performed, then it must not affect the behavior, unless the register reads differently as RO.

    Either ways it is a bug in the API which needs to be corrected, Our expectation was if you have a setup which can reproduce the issue, then the second proposed WA would be less intrusive.

    Regards
    Amit
  • Hi Amit,
    Unfortunately, I did not use any special setup to reproduce the problem. You just need an application that sends and receives a lot of CAN frames. Eventually the problem will occur.

    Thank you for your help,
    Peter A.
  • Hello Peter

    I believe we can make the fix with the read modify write instead of the direct write as it would achieve the same result.

    Regards
    Amit