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.

TM4C1294NCPDT: CAN peripheral not entering bus off state

Part Number: TM4C1294NCPDT

Hi,

I am trying to handle the situation where the CAN bus becomes disconnected.  When I do disconnect the bus and try to transmit a message with automatic retransmition turned on I start getting CAN STATUS interrupts for AckError, and I see the EPASS and EWARN bits set, but BOFF never gets set.  I checked the CAN Error Counter (CANERR) register and see that the Transmit Error Counter (TEC) field only gets up to 128.  Is there some setting that I don't have right to allow that to count up to 255 so I can get into the BUS OFF state?

thanks

  • Hi Jacob,

      Yes, you are correct that the TEC error counter needs to be above 255 to be in bus off state according to the CAN protocol.  You probably don't want to disconnect your node from the bus when testing bus off state but rather with the node connected. With the node connected, try to configure your node with different bit timing from the bus or try to create bit stuffing error. That might eventually lead into bus off state. I'm not an expert on CAN. If the suggestion doesn't work I will need to pass your question to our CAN expert who is current out of office. 

  • Hi Charles, thanks for the quick response.

    Why wouldn't I want to test by disconnecting from the bus?  Seems like a very real possibility that could happen, and that it should generate a bus off state.

    The specific reason I am testing that way is my board starts acting strangely when I'm disconnected from the bus - lots of errors when trying to communicate to other peripherals over SPI.  I eventually traced the problem to a constant flood of CAN status interrupts because of the automatic retransmission.  I need to be able to continue to run even if the CAN bus becomes disconnected so I'd like to detect the bus off condition and do something about it.  I guess I can detect the EPASS condition instead, but I'm still confused as to why the TEC error counter stops at 128.

    Thanks again!

  • Hi Jacob,

      Perhaps you disconnect from the bus when you reach error passive state and hence the counter doesn't increment anymore to get to bus off. I will pass your question to our CAN expert for suggestions.

  • Thank you again for the reply, and for passing the question along to the expert.

    Just to make sure I'm clear, in this test I am physically disconnected from the bus when powering up.  As far as I know CAN doesn't know anything about the state of things yet.  I then try to send a message and that's when the TEC counter starts incrementing and I get flooded with CAN STATUS interrupts telling me there's an AckError (which is expected), and once the TEC gets to 128 EPASS is set too.  At this point I don't change anything, no closing of the CAN peripheral or trying to cancel the message, so I would expect that the TEC would continue to increment, but it doesn't.

    Thanks!

  • Charles is correct. Once you reach the error passive state, the CAN module stops trying to transmit. (It becomes passive, and will only listen.)  With no more transmission attempts, there are no more missed acknowledgements and therefore no additional errors.

    The way the error count reduces, and the CAN module tries again to transmit, is if it sees good CAN messages on the bus. Since there are no other modules on your bus, the CAN module remains quiet.

    To see "Bus Off", setup a network with at least three CAN nodes. Have the TM4C1294 at the wrong baud rate and the other two nodes successfully sending messages. The node at the wrong baud rate will send error frames until it goes passive. Then the other nodes will communicate, but the error count on the node with the wrong baud rate will continue to increase until it goes buss-off.

  • I see that you responded that my answer did not resolve your issue. This is the expected behavior of the CAN module when you try to transmit and there is no other node to acknowledge the transmission. Please let me know what additional questions you have. 

  • Hmm... that is an interesting point.  I would say that was the answer but I still get AckError interrupts continuously and forever until I reset the CAN peripheral. After I get the status interrupt I write 0x07 back to the CANSTS register but then the next interrupt will still have the AckError in it.  I think that's in part because of the automatic retransmission, but yeah, you'd think that would stop when in the error passive state.  Is it possible I'm not clearing an interrupt bit somewhere or something?

    Thanks for the help.

  • Sorry, my earlier answer is not correct. When the CAN module tries to transmit without another node connected, and therefore there is no acknowledge, the transmit error count increments by 8. Once the transmit error count is 128 or higher, the module goes into an error passive mode. Error passive does not mean it stops transmitting, rather it means that it will not transmit an error frame when it sees a problem on the bus. Also, when in the error passive mode, it will allow extra time between transmission retries and it will no longer increment the transmit error count for a missing acknowledge error. This is why missing acknowledge errors alone will not take the node to a bus-off state, nor will it stop the node from trying to send a message. 

    For more details on how a CAN module handles errors see:

    http://www.can-wiki.info/doku.php?id=can_faq:can_faq_erors

  • Ah, OK, that makes sense.  So this is expected behavior.  Thank you for clarifying that.

    Is there a recommended way to handle being disconnected from the bus with auto-retransmission enabled?  As I've said I'm getting flooded with status interrupts in that case which is killing the rest of my application.  I'm thinking of keeping a count of interrupts due to AckErrors and if above a threshold AND I'm in the Error Passive state then I'll do something like a bus off recovery sequence.  Or maybe I'll disable auto-retransmission (to avoid all the interrupts) and just send a periodic message until I detect a successful transmit then allow normal communication to resume.  Any best practices or examples out there?

    Thanks again.

  • It completely depends on the application. Many examples that I do I only enable interrupts on "CAN_INT_MASTER | CAN_INT_ERROR".  I let the CAN hardware take care of the re-transmission attempts when the bus is disconnected. You might add some timeout with a status check if you need to take action at some point because of failure to transmit a message in a timely manor.