cancel
Showing results for 
Search instead for 
Did you mean: 

Dealing with CAN bus initialisation error (INAK)

Diez.R.
Associate II

Hi all:

I have a bare-metal firmware running on an STM32F407VGT6, and I am implementing a CAN bus interface. It is a very simple "slave" device that responds to short commands.

Most basic CAN bus operations are working, but I still haven't finished the error handling upon initialisation.

I am using the Standard Peripheral Library, but I think the issue is still the same with HAL.

The first thing I noticed is that the SPL routine CAN_Init() does a busy wait at the end for bit INAK (Initialization acknowledge) in register CAN_MSR (CAN Master Status Register).

A busy wait is very uncommon in an embedded library. First of all, INAK_TIMEOUT is hard-coded to 0x0000FFFF, and the time surely depends on the current CPU frequency, which can vary greatly.

And then the firmware may want to initialise other things in parallel, but CAN_Init() blocks anything else.

CAN_Init() actually performs 2 busy waits. The first one is to enter CAN bus initialisation mode, but after a peripheral reset, that is probably never going to last long (or fail).

The second busy wait to leave the initialisation mode can fail. The documentation is:

INRQ : Initialization request

The software clears this bit to switch the hardware into normal mode. Once 11 consecutive recessive bits have been monitored on the Rx signal the CAN hardware is synchronized and ready for transmission and reception. Hardware signals this event by clearing the INAK bit in

the CAN_MSR register.

So that may fail if the CAN bus cable is not attached or correctly wired.

So what is the strategy to deal with such an initialisation failure?

Once the CAN bus is running, there is automatic bus error management with flag ABOM (Automatic Bus-Off Management), so you do not have to handle everything in software. The documentation is not explicit about it, but I guess this automatic error management will make the device recover from a temporaray cable disconnection without too much fuss.

But then, why is the initialisation different? Or is the general expectation in the CAN bus world that "slave" devices must only start after all cables are properly fitted?

Do I have to implement a state machine in my firmware to deal with a failed initialisation, and block all CAN bus operation until the hardware has initialised once (the first time)? The CAN bus interface is not the only thing that the device can do, so it should be able to operate without a CAN bus "connection". The intent is that the device starts using the CAN bus as soon as it is detected (as soon as someone plugs the cable).

But maybe a busy wait is not necessary. Will the CAN hardware forever wait until those 11 consecutive recessive bits are seen on the bus? Or does the firmware need to enter and exit initialisation mode again after the hardware has spent some time trying?

Another related question is: Assuming that ABOM is enabled, is there any other situation that would make the CAN hardware disable itself, so that I need to go through the initialisation again?

Thanks in advance,

  R. Diez

0 REPLIES 0