cancel
Showing results for 
Search instead for 
Did you mean: 

How to escape CAN error passive state on STM32F4 microcontroler?

ASene.1
Associate

Hi there!

I have trouble escaping CAN error passive state on STM32F417VG microcontroller.

The goal of my application is to automatically detect external CAN bus baud rate (either 250kHz or 500kHz) then send CAN messages on the bus at the right frequency.

To do so, I first initialize my CAN peripheral in silent mode with 250kHz frequency. I then wait a while and check if an error occurred in HAL_CAN_ErrorCallback (meaning real bus CAN frequency is not 250kHz).

I then follow the same process with 500kHz silent mode and check for error triggering (meaning real bus CAN frequency is not 500kHz).

From that point, I am able to know which is the CAN frequency used on my external bus CAN.

However, that method implies error triggering leading the "Receive error counter " CAN1->ESR->REC to reach its maximal value of 0xFF.

The reference manual says that "in case of an error during reception, this counter is incremented by 1 or by 8 depending on the error condition as defined by the CAN standard. After every successful reception the counter is decremented by 1 or reset to 120 if its value was higher than 128. When the counter value exceeds 127, the CAN controller enters the error passive state.".

In my case, the counter value exceeds 127. The CAN controller thus enters the error passive state and set CAN1->ESR->EWGF and CAN1->ESR->EPVF bits.

FYI :

  • CAN1->ESR->EWGF: This bit is set by hardware when the warning limit has been reached (Receive Error Counter or Transmit Error Counter≥96).
  • CAN1->ESR->EPVF: This bit is set by hardware when the Error Passive limit has been reached (Receive Error Counter or Transmit Error Counter>127).

As long as one of these two bits are set, I cannot send/receive CAN messages.

If other nodes send CAN messages on the bus, I can see CAN1->ESR->REC being decremented. At a certain point, CAN1->ESR->REC is small enough for CAN1->ESR->EWGF and CAN1->ESR->EPVF bits to be reset. I then can successfully send/receive CAN messages.

However, in my case, other nodes do not communicate very often. As a result, CAN1->ESR->REC decrement is very slow, and my application is blocked during a long time.

Does somebody have a solution to escape that CAN error passive state? FYI, CAN1->ESR->REC register and CAN1->ESR->EWGF and CAN1->ESR->EPVF bits are read only.

I found some other threads about similar issues, but I did not find any solution other than resetting the MCU.

Thank you for your help,

Have a nice day,

Aubin

4 REPLIES 4
Jaroslav JANOS
ST Employee

Hi @ASene.1​ ,

as it is written in the reference manual, "After every successful reception the counter is decremented by 1 or reset to 120 if its value was higher than 128." When the value of REC (and TEC as well) is lower than 128, the device returns back to the active mode and the EPVF flag should not be set.

Also it is not true, that in the error passive state you cannot send/receive messages. This state only implies that error frames are recessive, so the device cannot interrupt transmission of other devices. You only cannot send/receive messages in the bus-off state, but that happens only when TEC=255.

BR,

Jaroslav

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

ASene.1
Associate

Hi Jaroslav JANOS,

Thank you very much for your reply.

Regarding your first remark, I totally agree. I understand the standard way to get out from error passive state is to get both receive and transmit error counters under 128 by wating for successful receptions. However, in my application, other nodes do not send many messages. As a result, I have very few successful receptions and register decrementation is very slow. This is why I am looking for another way to reset REC and TEC.

Regarding your second remark, you are right: I was wrong saying I could not send/ receive messages anymore in error passive state. However, when my CAN peripheral is in error passive state, its behaviour does not allow my application to communicate as usual.

What happens is that my CAN RX call-back HAL_CAN_RxCpltCallback does not trigger as expected. I observed the following:

-         My device successfully sends a CAN message on the bus, triggering HAL_CAN_TxCpltCallback,

-         The target node answers as expected,

-         My device does not trigger HAL_CAN_RxCpltCallback,

-         If my device successfully sends a second CAN message on the bus, triggering HAL_CAN_TxCpltCallback, I Immediately enter HAL_CAN_RxCpltCallback. However, the CAN message corresponds to my first request.

I do not understand that behaviour. But I know that not being in error passive state solves the problem.

Thank you for your help,

Aubin

Jaroslav JANOS
ST Employee

Hi @ASene.1​ again,

concerning the reset of REC, I do not know about any other way to reset the counter than resetting the MCU, as you already suggested.

Regarding the second issue, could you please try to monitor (poll) corresponding status flags/registers and interrupt flags, if this issue is related to the hardware or to the HAL?

Thank you,

Jaroslav

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hi @ASene.1​, just curious to know if you were able to find any other method to reset the error counters?