cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F04 CAN RX Interrupt hits twice then stops

Posted on October 13, 2017 at 09:53

I migrated the HAL libraries to the latest one. I had been working on my CAN TX Queue but not it looks like my CAN1_RX0_IRQHandler is called twice. The first one gets a good CAN packet, the second time looks like it detects an error and then it never gets called again.

During my migration to the new HAL library, I need to made this change to my code:

void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* CanHandle)

{

    if(CanHandle == NULL)

        return;

    

    CCanBus *pCanBus = (CCanBus*) CanHandle->pObject;

    

    // call the aplication callback function

    if (pCanBus->canEventCallback != NULL)

        pCanBus->canEventCallback(pCanBus->pCallbackObject, Callback_RX);

    if (CanHandle->State == HAL_CAN_STATE_BUSY_TX)

       // CanHandle->State = HAL_CAN_STATE_BUSY_TX_RX;

       CanHandle->State = HAL_CAN_STATE_BUSY_TX_RX0;

    else

    {

        //CanHandle->State = HAL_CAN_STATE_BUSY_RX;

        CanHandle->State = HAL_CAN_STATE_BUSY_RX0;

        /* Set CAN error code to none */

        CanHandle->ErrorCode = HAL_CAN_ERROR_NONE;

        /* Enable Error warning Interrupt */

        __HAL_CAN_ENABLE_IT(CanHandle, CAN_IT_EWG);

        /* Enable Error passive Interrupt */

        __HAL_CAN_ENABLE_IT(CanHandle, CAN_IT_EPV);

        /* Enable Bus-off Interrupt */

        __HAL_CAN_ENABLE_IT(CanHandle, CAN_IT_BOF);

        /* Enable Last error code Interrupt */

        __HAL_CAN_ENABLE_IT(CanHandle, CAN_IT_LEC);

        /* Enable Error Interrupt */

        __HAL_CAN_ENABLE_IT(CanHandle, CAN_IT_ERR);

    }

    if(pCanBus->fifoNumber == 0)

        // Enable FIFO 0 message pending Interrupt

        __HAL_CAN_ENABLE_IT(CanHandle, CAN_IT_FMP0);

    else

        // Enable FIFO 1 message pending Interrupt

        __HAL_CAN_ENABLE_IT(CanHandle, CAN_IT_FMP1);      

}

Where I replaced:

// CanHandle->State = HAL_CAN_STATE_BUSY_TX_RX;   by

  CanHandle->State = HAL_CAN_STATE_BUSY_TX_RX0;

So when the CAN1_RX0_IRQHandler gets called for the first time there is a FIFO overrun flag which it is clear by the HAL library and I am able to process a received CAN message.

In the Second time, my callback for CAN error is get called but I am reading the error only. Should I do something else?

Which I dont understand is why the Interrupt stops get called? does the HAL library somehow disabling it?

2 REPLIES 2
Posted on October 13, 2017 at 10:06

Some extra info I found.

When entering to the RX interrupt for the first time and the following function is returning a value of 3

__HAL_CAN_MSG_PENDING   ->   3

Which means I have 3 pending CAN messages, the callback is only digesting only 1 CAN message, how can I handle/process the extra 2 messages, the next interrupt will generate an error.

Posted on October 13, 2017 at 10:31

After digging a little more, on the second interrupt: from the HAL library

  tmp1 = __HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0);

  tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0);

  /* Check End of reception flag for FIFO0 */

  if((tmp1 != 0U) && tmp2)

  {

    /* Call receive function */

    CAN_Receive_IT(hcan, CAN_FIFO0);

  }

tmp1 = 2

tmp2 = 0

So I have 2 pending CAN messages but the HAL_CAN_GET_IT_SOURCE returns 0 because a CAN error is detected.

So what is the proper procedure to clear CAN Errors?