cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_CAN_Init() is failing

n.serina
Associate III
Posted on May 08, 2018 at 14:00

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 

0690X0000060B1YQAU.png

#stm32f4-nucleo #smt32f407-can-bus #stm32f4
12 REPLIES 12
GS1
Senior III

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.

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.​

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.