cancel
Showing results for 
Search instead for 
Did you mean: 

Problem resetting CAN after Bus Errors on STM32F446

GS1
Senior III

Hi all,

I have the problem concerning resetting the CAN bus after the other side was set to a wrong bitrate:

Example:

My system is sending data with 500 kBit. But the receiver is set to 1 MBit.

This results of course in Errors when sending data.

I handle this by resetting the CAN Bus port after a couple of Errors.

As soon as the receiver switches to the correct bitrate of 500 kBit, my system should then work properly, but it still gets Error Interrupts - even after another reset.

The debugger runs into "Error Warning" and "Error Passive" Interrupt states. And only a small part of the messages will be transmitted.

Sometimes it works as expected, but most times it is still getting Error Interrupts.

How can I safely return to a working CAN interface?

Here is what I do to reset the CAN Bus:

HAL_CAN_DeInit(&hcan1);

MX_CAN1_Init();   // Je nach Konfig aus SysInfo für Baudrate initialisieren

/* CAN1 init function */

void MX_CAN1_Init(void)

{

 hcan1.pTxMsg = &CANTxMessage;

 hcan1.pRxMsg = &CANRxMessage;

 hcan1.Instance = CAN1;

 hcan1.Init.Prescaler = 9;

 hcan1.Init.Mode = CAN_MODE_NORMAL;

 hcan1.Init.SJW = CAN_SJW_1TQ;

 hcan1.Init.BS1 = CAN_BS1_3TQ;

 hcan1.Init.BS2 = CAN_BS2_1TQ;

 hcan1.Init.TTCM = DISABLE;

 hcan1.Init.ABOM = ENABLE;

 hcan1.Init.AWUM = DISABLE;

 hcan1.Init.NART = DISABLE;

 hcan1.Init.RFLM = DISABLE;

 hcan1.Init.TXFP = DISABLE;

 if (HAL_CAN_Init(&hcan1) != HAL_OK)

 {

   _Error_Handler(__FILE__, __LINE__);

 }

}

1 ACCEPTED SOLUTION

Accepted Solutions
GS1
Senior III

I have a solution:

As resetting of the REC Counter is necessary to get rid of the Error interrupts, and the system can not expect that the other system is sending out data, I initialized the CAN controller in Loopback mode. (I tried the loopback mode yesterday in another way, but that was probably not enough to reset the counter.)

Now the sent data will be received in the CAN receiver which resets the counter.

I don't even need a CAN port reset to get the bus working again.

BR

GS

View solution in original post

9 REPLIES 9
Jack Peacock_2
Senior III

It takes time to clear off the CAN bus errors. You need to stop the CAN bus, short delay for other side to change rate and clear its errors, then connect to the bus again after all your own errors are cleared. This is a common CAN bus issues when nodes are attached or detached, especially if there are only two nodes.

Or you can remain connected, live with the errors by not transmitting while clearing the error flags continuously, until the bus is stable for some period of time, then resume transmitting. You'll need some logic like this anyway at reset/power up since both node will not start and synchronize immediately.

Jack Peacock

GS1
Senior III

Hi Jack,

I have tried above things, but the problem persists. I tracked the problem down to the following:

I attach my unit to a PCAN Explorer CAN tool in order to read my incoming CAN data from the system.

When I simply disconnect the cable and reattach it, there is no problem and my system reconnects and starts to send all CAN Messages correctly.

But: If I chose onother bitrate on the PCAN tool - which of course then leads to Errors on the bus, (which is ok) - and then select with the correct bitrate again, the system receives error interrupts and only transmits half of the data messages.

When looking at the CAN registers during debut, it seems that the problem is caused by the REC (Receive Error Counter) in the ESR (Error Status Register) - REC number.

The Receive Error Counter increases obviously due to the wrong Acknowledes caused by the faulty bitrate. In case it counted up to 0xFF (236 Receive Errors counted - the manual tells, that the system goes into Error Passive). After the call to MX_CAN1_Init, this register is still set to 0xFF and will not be cleared by the Reset. Errors are still there after the next transmissions. Unfortunately this is a read only register.

I tried to set the RESET Bit in MCR register -> does not reset REC counter

Also INRQ (HW-Initialisation Request) does not reset the REC counter

The only measure that helps is a complete Hardware Reset (HAL_NVIC_SystemReset()) , but this is not the way I want it to work because this could influence other attached ports like USB!

My question:

Which action will clear the REC Counter in ESR Register ???

Any idea?

Jack Peacock_2
Senior III

The CAN receive error count has to be automatic since it is part of the watchdog protecting the CAN bus from broken nodes. Once REC exceeds a threshold (128) the CAN controller has to be disconnected to preserve bus integrity. To clear the REC you have to disconnect internally (silent mode) so that the CAN peripheral no longer listens to the external bus.

After a random holdoff time reconnect to the CAN bus by setting initialization mode. REC will start to decrement as valid messages are received. If the REC warning limit interrupt occurs again you still have a problem on the bus.

Are you sure your CAN bit timings are compatible with your remote node at the slower rate? From your description you are seeing some kind of timing mismatch. Try starting both ends at the lower rate to verify it works.

Jack Peacock

GS1
Senior III

Thank you for your suggestions!

The lower rate is working perfectly. But only in case both ends start with the same bitrate. In case the other side had the wrong bitrate set and corrects to the lower rate after my system already is powered on, then my system will not connect properly as described above.

I will try your proposal today, but as the receiving system doesn't send out CAN messages, your proposal for waiting that the REC will reduce with received messages might not work as there are no messages sent from the other side.

Yesterday I tried something similar by setting to loopback mode and send the data by myself and this didn't change the REC value either.

Let me see what I can achieve today.

Best regards

GS

GS1
Senior III

I have a solution:

As resetting of the REC Counter is necessary to get rid of the Error interrupts, and the system can not expect that the other system is sending out data, I initialized the CAN controller in Loopback mode. (I tried the loopback mode yesterday in another way, but that was probably not enough to reset the counter.)

Now the sent data will be received in the CAN receiver which resets the counter.

I don't even need a CAN port reset to get the bus working again.

BR

GS

ESawa.1
Associate III

Hey @GS1 ,

I have similar problem like you have solved before. My FDCAN peripheral gets also into Error Passive mode, due to a REC >=128. Then i tried to switch to Internal-Lookback-Mode to receive my own messages to decrement. I can receive my own messages but they do not decrement the REC. The only way to decrement it, is by receiving messages from another can device in Normal Mode. What did you changed after your first test with loopback? 

Best regards,

Eric

 

Hi,

Actually I can not say - probably I detected a bug on my side. 

But here is my working init sequence:

hcan1.Init.Mode = CAN_MODE_LOOPBACK;
hcan1.Init.SJW = CAN_SJW_1TQ;
hcan1.Init.BS1 = sSysInfo.ulCANBS1Out;// CAN_BS1_15TQ;
hcan1.Init.BS2 = sSysInfo.ulCANBS2Out;// CAN_BS2_5TQ;
hcan1.Init.TTCM = DISABLE;
hcan1.Init.ABOM = ENABLE; // => leave Busoff mode when data is coming in
hcan1.Init.AWUM = ENABLE; /* Set the automatic wake-up mode */
hcan1.Init.NART = DISABLE;
hcan1.Init.RFLM = DISABLE;
hcan1.Init.TXFP = DISABLE;
HAL_CAN_Init(&hcan1);

I hope this helps.

BR GS

I just see that you use FDCAN. This might work differently as my CAN device (STM32F446) has no FDCAN.

ESawa.1
Associate III

Hey @GS1,

thanks for your reply. It seems so that the FDCAN is not supporting this way of counting the REC down. I have contacted ST if there is a suggested way for it. The documentation on this part is very rare, so lets see what they say. 

Best regards,

ERic