cancel
Showing results for 
Search instead for 
Did you mean: 

How to user STM32 HAL CAN driver?

hpate.1
Associate
 
3 REPLIES 3

Try looking at some of the examples

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Imen.D
ST Employee

Hello @hpate.1​ and welcome to the Community 🙂

I recommend you start with working CAN example that is relevant for your device and available under STM32CubeXX MCU package. Then you can update the application according to your needs.

For example: CAN application available within STM32CubeF4 at this path:  \STM32Cube_FW_F4_V1.x.x\Projects\STM32469I_EVAL\Examples\CAN\

Hope this bring you some help.

When your question is answered, please close this topic by choosing Select as Best. This will help other users find that answer faster.

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
hpate.1
Associate

Thanks Imen,

I tried as you mentioned and I succeeded HAL driver in my project and compiled successfully.

I am using an STM32F091 based customized card (programmed with CubeMx and Attolic TrueSTUDIO) and I try to use some of the ST's examples in order to learn about its peripherals. I am stuck with the CAN peripheral. The problem is that when the code enters the

HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan)

it returns a HAL_TIMEOUT so the CAN can't be initialized. I want to use CAN in the LOOPBACK mode (without an external transceiver connected) in order to test the functions. As I traced the bug of the program with the Attolic TrueSTUDIO Debugger the code seems to be stuck in the

/* Request leave initialisation */

  CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);

  /* Get tick */

  tickstart = HAL_GetTick();

/* Wait the acknowledge */

while((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)

{

if((HAL_GetTick() - tickstart ) > CAN_TIMEOUT_VALUE)

{

hcan->State= HAL_CAN_STATE_TIMEOUT;

/* Process unlocked */

__HAL_UNLOCK(hcan);

return HAL_TIMEOUT;

}

}

Which is in the stm32f4xx_hal_can.c file.

So I searched the datasheet and I found this

30.4.1 Initialization mode The software initialization can be done while the hardware is in Initialization mode. To enter this mode the software sets the INRQ bit in the CAN_MCR register and waits until the hardware has confirmed the request by setting the INAK bit in the CAN_MSR register. To leave Initialization mode, the software clears the INQR bit. bxCAN has left Initialization mode once the INAK bit has been cleared by hardware.

and also because it is the 0 bit of the CAN_MSR register it also states

Bit 0 INRQ: Initialization request The software clears this bit to switch the hardware into normal mode. Once 11 consecutive recessive bits have been monitored on the Rx signal the CAN hardware is synchronized and ready for transmission and reception. Hardware signals this event by clearing the INAK bit in the CAN_MSR register. Software sets this bit to request the CAN hardware to enter initialization mode. Once the software has set the INRQ bit, the CAN hardware waits until the current CAN activity (transmission or reception) is completed before entering the initialization mode. Hardware signals this event by setting the INAK bit in the CAN_MSR register.

So after this, I can understand that the problem is that the CAN_RX doesn't receive the 11 recessive bits so the Hardware does not clear the INAK Bit in the CAN_MSR Register so the CAN cannot be initialized. I feel that the problem might be the fact that I don't use a transceiver so somehow the CAN_RX can't receive the 11 recessive bits that it needs but if it is not this then I don't know how to fix it. 

So, can the problem be the fact that I don't have an external transceiver or is it something else?