2018-05-08 05:00 AM
Hi,
I was just started with CAN peripheral on my stm32f446re nucleo board.
The problem i am facing is HAL_CAN_Init() added by cubeMx code generation software is failing at the below line of code
it is returning HAL_ERROR in CAN1 LOOP BACK MODE
That means the controller has not set SLAK to zero even if we clear the SLEEP bit
i believe that CAN TX is internally connected to can rx and can rx is not sampled .
on the board i have made no connection to the can tx and can rx. its just a single board.
Please let me know what i am doing wrong .
/* Exit from sleep mode */
CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);/* Get tick */
tickstart = HAL_GetTick();/* Check Sleep mode leave acknowledge */
while ((hcan->Instance->MSR & CAN_MSR_SLAK) != RESET) { if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE) { /* Update error code */ hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;/* Change CAN state */
hcan->State = HAL_CAN_STATE_ERROR;return HAL_ERROR;
}here is picture of all reg contents
#stm32f4-nucleo #smt32f407-can-bus #stm32f4Solved! Go to Solution.
2020-01-24 06:13 AM
Hi all,
Even though this thread is already a year old, the following solution might be helpful for others:
I had the same issue in my new project and found out, that the timeout error can be fixed by simply setting the wait time to
5 * CAN_TIMEOUT_VALUE:
in HAL_CAN_Init:
...
/* Exit from sleep mode */
CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
/* Get tick */
tickstart = HAL_GetTick();
/* Check Sleep mode leave acknowledge */
while ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U)
{
if ((HAL_GetTick() - tickstart) > 5*CAN_TIMEOUT_VALUE)
{
/* Update error code */
hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
/* Change CAN state */
hcan->State = HAL_CAN_STATE_ERROR;
return HAL_ERROR;
}
}
Then the timeout is not happening.
2020-01-24 06:34 AM
Maybe a better solution would be to just change the value "CAN_TIMEOUT_VALUE" to be higher.
Adding magic numbers in the code is never great idea.
2020-01-24 06:42 AM
You are right and you are free to do so!
My answer was simply to show, where the problem is located and to supply a working solution.
CAN_TIMEOUT_VALUE however is used in more other places and I did not want to change the other behaviours. Then please declare a second value for the special timeout location and place that in place.