AnsweredAssumed Answered

[BUG?] STM32F3 CAN transmit timeout

Question asked by Valentin on May 12, 2016
Latest reply on Nov 29, 2017 by Alex S
Hi,
I just noticed another oddity in the CubeMX HAL drivers:
when I send a CAN message on an empty bus the function HAL_CAN_Transmit(...) waits in a loop for the timeout and then cancel the sending of the frame:

/* Check End of transmission flag */
    while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
    {
      /* Check for the Timeout */
      if(Timeout != HAL_MAX_DELAY)
      {
        if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
        {
          hcan->State = HAL_CAN_STATE_TIMEOUT;
          /* Process unlocked */
          __HAL_UNLOCK(hcan);
          return HAL_TIMEOUT;
        }
      }
    }

But if I watch the bus activity, the controller continues to retry sending the message over and over again even though the timeout has occurred.
After having a look at the control registers, I suggest to add the following line to fix this and make the timeout work as expected (by me):

    /* Check End of transmission flag */
    while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
    {
      /* Check for the Timeout */
      if(Timeout != HAL_MAX_DELAY)
      {
        if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
        {
          hcan->State = HAL_CAN_STATE_TIMEOUT;
          /* Process unlocked */
          __HAL_UNLOCK(hcan);
          hcan->Instance->TSR |= (((uint32_t) 1 << (7 + transmitmailbox * 8))); // TODO: try to stop all retransmission tries
          return HAL_TIMEOUT;
        }
      }
    }

Setting the ABRQx bit in the CAN_TSR register cancels re-transmitting the message in transmit mailbox x.
Seems to work for me. During the loop the message is bein re-sent on the bus and after timeout - silence.

Opinions?

note: I have the ABOM bit SET so there is no hardware bus off management. I still think that after the timeout the retransmission tries should stop.

Outcomes