Question
[BUG?] STM32F3 CAN transmit timeout
Posted on May 12, 2016 at 03:48
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.
