1 year, 8 months ago.

How to disable CAN Bus Off mode?


I am using a Nucleo F446RE with a mcp2561 transceiver. We are now using can.reset() when either the tderror or rderror reaches a critical value, but the only problem is that this function raises a fatal error "Cannot initialize CAN" when there is something wrong with the bus. In our case that happens when a motorcontroller initializes.

In the ideal case we want to handle this error ourselves but since it is a fatal error this is not possible, as far as I know. The other option is to never let the nucleo go in to bus-off mode. Any ideas how to do this?


1 Answer

1 year, 8 months ago.

Hello Mo K,

According to the STM reference manual the error management as described in the CAN protocol is handled entirely by hardware using a Transmit Error Counter (TEC value, in CAN_ESR register) and a Receive Error Counter (REC value, in the CAN_ESR register), which get incremented or decremented according to the error condition:

  • Tthe BOFF (Bus-off flag) bit is set by hardware (read only for software) when it enters the bus-off state.
  • The bus-off state is entered on TEC (Transmitter Error Counter) overflow, greater than 255.

Because also TEC bits are read only I'm afraid there is no way preventing the CAN controller to enter bus-off state when TEC overflows.

You can however improve the situation by enabling Automatic Recovery from Bus-Off state:

Depending on the ABOM bit in the CAN_MCR register bxCAN will recover from Bus-Off (become error active again) either utomatically or on software request. But in both cases the bxCAN has to wait at least for the recovery sequence specified in the CAN standard (128 occurrences of 11 consecutive recessive bits monitored on CANRX). If ABOM is set, the bxCAN will start the recovering sequence automatically after it has entered Bus-Off state. If ABOM is cleared, the software must initiate the recovering sequence by requesting bxCAN to enter and to leave initialization mode.

You can enable ABOM (Automatic Bus-Off Management/Recovery) by modifying mbed-os/targets/TARGET_STM/can_api.c :

void can_init_freq(can_t *obj, PinName rd, PinName td, int hz)


    //obj->CanHandle.Init.ABOM = DISABLE;
    obj->CanHandle.Init.ABOM = ENABLE;


Accepted Answer

Thank you so much for this! I was also struggling with this

posted by Woepa Jouz 15 Jun 2019

Thanks a lot! I will try it tomorrow

posted by Mo K 15 Jun 2019