cancel
Showing results for 
Search instead for 
Did you mean: 

Using STM32F413 bxCAN peripheral. Using MX HAL. From RM0430 I think I understand that the ERROR interrupts (Bus-off, Passive and warning) is generated when these flags are set. But it seems like interrupts happens more often than so.

PÖste.1
Associate II

I have enabled interrupt for BOFF, EPVF and EWGF.

  • When e.g. sending with error the very fist time TEC becomes = 1, all flags remain 0. However I get an interrupt any way - every time I get a send error. Eventually i get flags set as REC/TEC gets large enough. This is nice if you want to track TEC/REC counters but this is not as I understand the RM0430, nor do I need all those interrupts.
  • When I have reached BOF and use CAN_Stop() followed by CAN_Start(), BOF and the other flags as well as TEC, REC gets reset. Fine... but
  • Early after CAN_Start() I again get ERROR interrupt. This time all flags are still set. I understand BOF is still set until 128x11 idle bits has been seen which may take "some time" (128x11 idle bits). But getting BOF ERROR interrupt made me think a new Bus-off occured and I stop again... which I had to solve some way.
  • But why these additional interrupts?
  • At least the RM0430 should mention this special behavior; that one needs to disable ERROR interrupts during CAN_Start() and include a wait for BOF == 0 and then enable ERROR interrupts again. And HAL driver for CAN could also make this much more clearer. Unless you test causing BOF and do recovery you will not experience this "double" BOF - if you are unlucky and very fast you maybe never can recover from BOF.
  • Or, maybe I missed something important, CAN is new to me.

2 REPLIES 2
PÖste.1
Associate II

Hmm, after a short break, I suddenly realize that the HAL_CAN_IRQHandler() services ALL different CAN interrupts, generated by CubeMX. Hence a Tx complete IRQ will also find ERROR interrupt enabled and check the flags, mark this as "errorcode" and at the end of the function will call HAL_CAN_ErrorCallback() which is the one I listen to. Odd that HAL concentrates all IRQ into one function just to then figure out what happend?

This would explain the "additional interrupts" I seen. I have yet to figure out what interrupt then gets triggered by CAN_Start() which in turn triggers HAL_CAN_ErrorCallback().

PÖste.1
Associate II

By testing I now how what happens after a BOF + HAL_CAN_Stop() and HAL_CAN_Start(). I write this in case someone else have same problem and/or if ST can take this input and update the reference manual.

I have state where BOF is active. I have here called HAL_CAN_Stop() and aborted ongoing TX. "NOTIFY" is a polling of the flags every seconds show the state. E is the HAL_GET_GetError() and BOF is the BOF bit of this. The BOFF, EPVF and EWGF is the bxCAN actual flags. As a note: HAL GetError() keeps all errors sticky - once seen it remains set even if the condition itself is cleared.

NOTIFY 0: E=7, BOF=1 BOFF=1 EPVF=1 EWGF=1 REC=255 TEC=252

Now I do a HAL_CAN_Init(), no extra HAL_CAN_Stop() as this has already been done. This clears HAL GetError() only. The BOF state still remains.

NOTIFY 0: E=0, BOF=0 BOFF=1 EPVF=1 EWGF=1 REC=255 TEC=252

Now I do a HAL_CAN_Start(). The IRQ SCE is printout from CAN1_SCE_IRQHandler() and the current BOF/EPVF/EWGF flags.

NOTIFY 0: E=0, BOF=0 BOFF=1 EPVF=1 EWGF=1 REC=255 TEC=252
IRQ SCE 1/1/1 rec=255 tec=0 
NOTIFY 0: E=7, BOF=1 BOFF=0 EPVF=0 EWGF=0 REC=0 TEC=0

Notice that the interrupt is taken even though all flags already was set! Whatever the root cause of this the application may act on this and e.g. stop CAN again thinking it is a new BOF (even though no data been sent yet). As the NOTIFY line shows some second later all flags are 0 (while E shows how HAL captures the errors for ever).

To solve this part of the issue I disable ERROR interrupts before HAL_CAN_Start() and enable again after I waited for BOF flag to become 0 (like up to 100ms):

NOTIFY 0: E=0, BOF=0 BOFF=1 EPVF=1 EWGF=1 REC=255 TEC=252
sce 0/0/0 rec=0 tec=0 
NOTIFY 0: E=0, BOF=0 BOFF=0 EPVF=0 EWGF=0 REC=0 TEC=0

The IRQ still taken (much later, in this case 3ms) but at this time all flags are 0 and no extra BOF or other state is observed.