cancel
Showing results for 
Search instead for 
Did you mean: 

Nucleo-F446RE - CAN Bus not initializing.

Aaronium
Associate III

Hello!

I have been trying to get the CAN system on this to work unsuccessfully for some time now, and in trying to debug the code have added some SWV ITM console printf's. In running the code, the HAL_CAN_Init, HAL_CAN_ConfigFilter, HAL_CAN_ActivateNotification, and HAL_CAN_AddTxMessage are all getting errors. I have no idea what I am doing wrong, I have used other posts on this forum as a reference, but am still lost.

Thank y'all for your time.

7 REPLIES 7
KnarfB
Principal III

Your code does not look bad. Some details: HAL_CAN_Start is commented out? Put it after HAL_CAN_ActivateNotification.

HAL_CAN_RxFifo0MsgPendingCallback gets already a *hcan parameter, so taking &hcan1 in your call to HAL_CAN_GetRxMessage is wrong.

For testing, put the CAN1_TX in the loop with some delay after each call. What do you have attached to the pins?

What are your specific error messages?

I attach some M0 code for reference, works in loopback when the pins left open.

good luck

KnarfB

I appreciate the help so much. The error notifications I'm getting are from the printf statements inside the if's that link to Error_Handler(). The outputs are listed next to their corresponding functions:

Error initializing CAN -- HAL_CAN_Init

Error configurating filter -- HAL_CAN_ConfigFilter

Error activating notifications -- HAL_CAN_ActivateNotification

Error launching CAN -- HAL_CAN_Start

Error adding TX Message -- HAL_CAN_AddTxMessage

Error adding TX Message

Error adding TX Message

I tweaked the code trying to mimic the example you gave (I appreciate it!), but still am having no luck. Also, how could one call HAL_CAN_GetRxMessage without the &hcan1 argument? There is nothing attached to the pins, the CAN is in loopback mode, which I understand that it means that the CAN TX and RX pins are bound internally?

Thank you again.

Start a debug session and step through the code. Step into HAL_CAN_Init and into HAL_CAN_MspInit to see what exactly causes the error.

> how could one call HAL_CAN_GetRxMessage without the &hcan1 argument

No, the first argument should be hcan1 because thats already a pointer. Check code compilation for warnings, try to understand and fix all warnings.

> There is nothing attached to the pins, the CAN is in loopback mode, which I understand that it means that the CAN TX and RX pins are bound internally?

Yes, leaving RX and TX unconnected should work.

Stepped through the code! The HAL_ERROR of MX_CAN1_Init is returned from this snippet on line 340 of stm32f4xx_hal_can.c, the values of HAL_GetTick()-tickstart = 11, and the CAN_TIMEOUT_VALUE = 10.

while ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U)
  {
    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;
    }
  }

I pulled up the pins per this other persons issue:

https://electronics.stackexchange.com/questions/353005/can-initialization-timeout-error-in-stm32f4/353101

The issues with HAL_CAN_Init, HAL_CAN_ConfigFilter, and HAL_CAN_ActivateNotification have been resolved as a result. The remaining problems are with HAL_CAN_Start and HAL_CAN_AddTXMessage.

The issue with HAL_CAN_Start is now at line 1048 in stm32f4xx_hal_can.c

while ((hcan->Instance->MSR & CAN_MSR_INAK) != 0U)
    {
      /* Check for the Timeout */
      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;
      }
    }

You mean, in the STM32CubeIDE's Connectivity CAN tab you set the RX pin's GPIO settings to Alternate Function push-pull pull-up? That's correct.

Thank you so much for everything, the CAN is working now, but I have one last question. On this other question:

https://community.st.com/s/question/0D50X00009hpjOESAY/can-bus-receive-interrupt

Tesla Delorean said "Make sure you have the IRQ Handler plumbed," do I do that by just adding "HAL_CAN_IRQHandler(&hcan1);" to the interrupt function? I vaguely remember when learning about interrupts that there is some register that is set that needs to be reset, does this account for that?