Skip to main content
Mark Shoe
Associate III
April 25, 2017
Question

How to stop HAL_CAN_ErrorCallback

  • April 25, 2017
  • 8 replies
  • 4894 views
Posted on April 25, 2017 at 20:27

My hardware has to disconnect the CAN bus sometimes. When i do the callback HAL_CAN_ErrorCallback will pop up. My CAN bus has to continue work so i clear all flags that i found:

__HAL_CAN_CLEAR_FLAG(hcan,CAN_FLAG_EWG);

__HAL_CAN_CLEAR_FLAG(hcan,CAN_FLAG_EPV);

__HAL_CAN_CLEAR_FLAG(hcan,CAN_FLAG_BOF);

__HAL_CAN_CLEAR_FLAG(hcan,CAN_TSR_RQCP0);

__HAL_CAN_CLEAR_FLAG(hcan,CAN_TSR_RQCP1);

__HAL_CAN_CLEAR_FLAG(hcan,CAN_TSR_RQCP2);

__HAL_CAN_CLEAR_FLAG(hcan,CAN_FLAG_TXOK0);

__HAL_CAN_CLEAR_FLAG(hcan,CAN_FLAG_TXOK1);

__HAL_CAN_CLEAR_FLAG(hcan,CAN_FLAG_TXOK2);

__HAL_CAN_CLEAR_FLAG(hcan,CAN_FLAG_TME0);

__HAL_CAN_CLEAR_FLAG(hcan,CAN_FLAG_TME1);

__HAL_CAN_CLEAR_FLAG(hcan,CAN_FLAG_TME2);

__HAL_CAN_CLEAR_FLAG(hcan,CAN_FLAG_FF0);

__HAL_CAN_CLEAR_FLAG(hcan,CAN_FLAG_FOV0);

__HAL_CAN_CLEAR_FLAG(hcan,CAN_FLAG_FF1);

__HAL_CAN_CLEAR_FLAG(hcan,CAN_FLAG_FOV1);

__HAL_CAN_CLEAR_FLAG(hcan,CAN_FLAG_WKU);

__HAL_CAN_CLEAR_FLAG(hcan,CAN_FLAG_SLAKI);

__HAL_CAN_CLEAR_FLAG(hcan,CAN_FLAG_BOF);

The CAN bus does work after that however every receive message the ErrorCallback comes back, what do i need to clear?

    This topic has been closed for replies.

    8 replies

    Mark Shoe
    Mark ShoeAuthor
    Associate III
    May 29, 2017
    Posted on May 29, 2017 at 18:32

    When printing the cause of the Error callback with:

    printf('ERR CB %d\r\n',hcan->ErrorCode);

    It gives a 3 for and is HAL_CAN_ERROR_EPV | HAL_CAN_ERROR_EWG

    Good idea of ST so say ''user can add his own code' but what should i do? My CAN just has to continue error or not.

    Anyone???

    Mark Shoe
    Mark ShoeAuthor
    Associate III
    August 17, 2017
    Posted on August 17, 2017 at 22:30

    It seems the CAN is not populair here. I am still having problems. On every CAN receive interrupt there is also a call to the HAL_CAN_ErrorCallback  and that is because the EPV and EWG flags are high. This happens after can trouble such as disconnect cable. The documentation tells it is not needed to clear them because they are read only. And indeed clearing them does not work. Resetting my cpu (M0) is the only way to come out of this error. Calling MX_CAN_Init(); again does not help also.

    Tesla DeLorean
    Guru
    August 18, 2017
    Posted on August 18, 2017 at 01:57

    >>

    It seems the CAN is not popular here.

    Responding because other haven't, but for my perspective HAL is not much liked, and as such I don't commit time/resources to it's issues.

    I suspect ST expects you to count and clear the error, blink an LED or something, log an error, adapt your response based on the frequency of the error, or time since last observed. Depending on the implementation you might broadcast a message to other nodes that you were down, or resume some other protocol based transfer. I'm not sure much of this has been well thought out, or applied to some real-world application.

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    Elkin Granados
    Associate II
    August 18, 2017
    Posted on August 18, 2017 at 21:24

    Hi, if you could give to use more information maybe we could help you better, for example: how are you making the communication? do you have two modules connected each other throughCAN bus IC as

    the

    SN65HVD230? Are you using Cubemx to initialize the peripheral? Are you using polling or interrupt method to make the frame Tx and Rx? how are you setting the filters? What exactly means '

    My hardware has to disconnect the CAN bus sometimes', Is a physical disconnect or just disabling the peripheral? Could you share the code to check it?

    Althoughthere is no to muchinformation maybe this post coulb bring to you some help:

    https://community.st.com/0D50X00009XkYECSA3

    T J
    Senior III
    September 9, 2017
    Posted on September 09, 2017 at 09:08

    Hi,  

    I'm using the STM32F7 series

    I was having the same problem and found this post.

    I fixed it just now...

    the fix was, a lose connector between the Isolated CAN Transceiver PCB and the CAN pins on the main PCB

    I re-enabled the BOF EWG and EPV interrupts and they have stopped firing.

    Mark Shoe
    Mark ShoeAuthor
    Associate III
    December 21, 2017
    Posted on December 21, 2017 at 10:18

    How do you re enable the 

    BOF EWG and EPV

     is it:

    __HAL_CAN_ENABLE_IT(&hcan, CAN_IT_BOF | | CAN_IT_EWG | CAN_IT_EPV );

    When you disable the BOFIE, EPVIE, EWGIE, IRQ's there will never be a new message IRQ anymore.

    Right now i have a very stupid solution, if no messages a received for 10 seconds the CPU will reboot. Most of the problems when HAL_CAN_ErrorCallback comes up are solved with calling MX_CAN_Init(); in the error callback.

    Best solution should be resetting all can setting in the error callback but how?

    T J
    Senior III
    December 22, 2017
    Posted on December 22, 2017 at 01:03

    I found the only errors are actual CAN-BUS contention issues, where two devices are transmitting at the same time...

    once all that is fixed the errors never appear again.

    My addressing scheme now has unique address channels for transmitting and separately receiving frames.

    I don't transmit and receive on one CAN-BUS address.

    I never reinitialize the can-bus peripheral on any of the processors.

    Mark Shoe
    Mark ShoeAuthor
    Associate III
    January 5, 2018
    Posted on January 05, 2018 at 19:36

    Basically what happens if there is a lot of CAN traffic in the:

    CAN error status register (CAN_ESR) the BOFF EPVF EWGF will be set.

    Bit 2 BOFF: Bus-off flag

    Bit 1 EPVF: Error passive flag

    Bit 0 EWGF: Error warning flag

    When this happens the CAN peripheral is shut down. The only way to get out of this situation is calling MX_CAN1_Init(); again.

    Simpy clearing the error flag does not help, the errors are there for some reason.

    T J
    Senior III
    January 5, 2018
    Posted on January 05, 2018 at 23:08

    I don't get any errors any more. I never reinitialise any part of the network.

    it sounds like the network your attaching to, is contentious, is it a preexisting network ? or still on the bench ?

    did you look at the canbus wires, on a scope ?

    is it possible that your clock source is drifting ? 

    2 boards, both with a drifting clocks ?

    if the canbus frequency between boards, drifts by 5%, you would likely see these errors.

    did you check the frequency on a scope ?

    Mark Shoe
    Mark ShoeAuthor
    Associate III
    January 6, 2018
    Posted on January 06, 2018 at 10:48

    It is an existing (6 year) network with 12 microchip 18F modules on it. Length 30 meter 125kb. 120E on both sides. And a third party CAN-USB translator for debugging. The CAN on the microchip was working within a few minutes. It does not have so may error conditions so never stops receiving or reaches the state off bus.

    So my STM32 CAN works prefect for hours or sometimes days. Then a problem happens. A CAN cable hardware disconnect or whatever. 

    I need to recover from the 

    CAN_ESR error state. The reference manual or HAL manual does not tell how.

    T J
    Senior III
    January 6, 2018
    Posted on January 06, 2018 at 22:01

    I am not sure I can help you,

    I had to power cycle many times before I fixed my issues,

    Now, I don't see any errors anymore.

    the trick was to make sure that every messageID was unique in the network.

    my nodes all have a separate 16 'ID's'  some channels are TX and some are Rx. much like endpoints

    no two nodes can transmit the same ID.

    Did you set the ABOM bit ?

    (the automatic Bus Off repair mechanism )

    T J
    Senior III
    January 6, 2018
    Posted on January 06, 2018 at 23:49

    I checked my '767 code, I dont enable most interrupts.. maybe that's why I don't see any issues ??

    void initCairoCan (void) {

                CAN_Config();

                canRxpointerIN = 0;

                canRxMsgIN  =0;

                canRxMsgOUT =0;

                canRxMsgTableEMPTY = true;

                canRxMsgTableFULL = false;

                for(int i = 0; i<16;i++)

                    IOCanMsgFlag[i] =false;

    //    // Receive Interrupts //

    ////    __HAL_CAN_ENABLE_IT(&hcan1, CAN_IT_FF0);        //!< FIFO 0 full interrupt            //

    ////    __HAL_CAN_ENABLE_IT(&hcan1, CAN_IT_FOV0);       //!< FIFO 0 overrun interrupt         //

    ////    __HAL_CAN_ENABLE_IT(&hcan1, CAN_IT_FF1);        //!< FIFO 1 full interrupt            //

    ////    __HAL_CAN_ENABLE_IT(&hcan1, CAN_IT_FOV1);       //!< FIFO 1 overrun interrupt         //

    ////    __HAL_CAN_ENABLE_IT(&hcan1, CAN_IT_FMP0);       //!< FIFO 0 message pending interrupt //

    ////    __HAL_CAN_ENABLE_IT(&hcan1, CAN_IT_FMP1);       //!< FIFO 1 message pending interrupt //

    //

    //    // Operating Mode Interrupts //

    ////    __HAL_CAN_ENABLE_IT(&hcan1, CAN_IT_WKU);        //!< Wake-up interrupt           //

    //    __HAL_CAN_ENABLE_IT(&hcan1, CAN_IT_SLK);        //!< Sleep acknowledge interrupt //

    //

    ////    // Error Interrupts //

    //    __HAL_CAN_ENABLE_IT(&hcan1, CAN_IT_EWG);        //!< Error warning interrupt   //

    //    __HAL_CAN_ENABLE_IT(&hcan1, CAN_IT_EPV);        //!< Error passive interrupt   //

    //    __HAL_CAN_ENABLE_IT(&hcan1, CAN_IT_BOF);        //!< Bus-off interrupt         //

    //    __HAL_CAN_ENABLE_IT(&hcan1, CAN_IT_LEC);        //!< Last error code interrupt //

    //    __HAL_CAN_ENABLE_IT(&hcan1, CAN_IT_ERR);        //!< Error Interrupt           //

    //    

        

        /* Enable Transmit mailbox empty Interrupt */

        __HAL_CAN_ENABLE_IT (&hcan1, CAN_IT_TME);       //!< Transmit mailbox empty interrupt //

        __HAL_CAN_ENABLE_IT (&hcan1, CAN_IT_FMP0);       //!< FIFO 0 message pending interrupt //

        __HAL_CAN_ENABLE_IT (&hcan1, CAN_IT_FMP1);       //!< FIFO 1 message pending interrupt //

          

                    canTxMsgIN  =0;

                    canTxMsgOUT =0;

                    canTxMsgTableEMPTY         = true;

                    canTxMsgTableFULL         = false;

                    canTxMsgTableOverflow = false;

                    canTxMsgOverrun = false;

                    blockCanTx = false;

    }