Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm trying to communicate over CAN using the HAL_CAN library between two STM32F boards. Specifically the issue seems to be in receiving messages. Following the documentation:

 ==============================================================================
                    ##### How to use this driver #####
  (#) Initialize the CAN low level resources by implementing the
      HAL_CAN_MspInit():
     (++) Enable the CAN interface clock using __HAL_RCC_CANx_CLK_ENABLE()
     (++) Configure CAN pins
         (+++) Enable the clock for the CAN GPIOs
         (+++) Configure CAN pins as alternate function open-drain
     (++) In case of using interrupts (e.g. HAL_CAN_ActivateNotification())
         (+++) Configure the CAN interrupt priority using
               HAL_NVIC_SetPriority()
         (+++) Enable the CAN IRQ handler using HAL_NVIC_EnableIRQ()
         (+++) In CAN IRQ handler, call HAL_CAN_IRQHandler()
  (#) Initialize the CAN peripheral using HAL_CAN_Init() function. This
      function resorts to HAL_CAN_MspInit() for low-level initialization.
  (#) Configure the reception filters using the following configuration
      functions:
        (++) HAL_CAN_ConfigFilter()
  (#) Start the CAN module using HAL_CAN_Start() function. At this level
      the node is active on the bus: it receive messages, and can send
      messages.
  (#) To manage messages transmission, the following Tx control functions
      can be used:
        (++) HAL_CAN_AddTxMessage() to request transmission of a new
             message.
        (++) HAL_CAN_AbortTxRequest() to abort transmission of a pending
             message.
        (++) HAL_CAN_GetTxMailboxesFreeLevel() to get the number of free Tx
             mailboxes.
        (++) HAL_CAN_IsTxMessagePending() to check if a message is pending
             in a Tx mailbox.
        (++) HAL_CAN_GetTxTimestamp() to get the timestamp of Tx message
             sent, if time triggered communication mode is enabled.
  (#) When a message is received into the CAN Rx FIFOs, it can be retrieved
      using the HAL_CAN_GetRxMessage() function. The function
      HAL_CAN_GetRxFifoFillLevel() allows to know how many Rx message are
      stored in the Rx Fifo.
  (#) Calling the HAL_CAN_Stop() function stops the CAN module.
  (#) The deinitialization is achieved with HAL_CAN_DeInit() function.
  *** Polling mode operation ***
  ==============================
  (#) Reception:
        (++) Monitor reception of message using HAL_CAN_GetRxFifoFillLevel()
             until at least one message is received.
        (++) Then get the message using HAL_CAN_GetRxMessage().
  (#) Transmission:
        (++) Monitor the Tx mailboxes availability until at least one Tx
             mailbox is free, using HAL_CAN_GetTxMailboxesFreeLevel().
        (++) Then request transmission of a message using
             HAL_CAN_AddTxMessage().
  *** Interrupt mode operation ***
  ================================
  (#) Notifications are activated using HAL_CAN_ActivateNotification()
      function. Then, the process can be controlled through the
      available user callbacks: HAL_CAN_xxxCallback(), using same APIs
      HAL_CAN_GetRxMessage() and HAL_CAN_AddTxMessage().
  (#) Notifications can be deactivated using
      HAL_CAN_DeactivateNotification() function.
  (#) Special care should be taken for CAN_IT_RX_FIFO0_MSG_PENDING and
      CAN_IT_RX_FIFO1_MSG_PENDING notifications. These notifications trig
      the callbacks HAL_CAN_RxFIFO0MsgPendingCallback() and
      HAL_CAN_RxFIFO1MsgPendingCallback(). User has two possible options
      here.
        (++) Directly get the Rx message in the callback, using
             HAL_CAN_GetRxMessage().
        (++) Or deactivate the notification in the callback without
             getting the Rx message. The Rx message can then be got later
             using HAL_CAN_GetRxMessage(). Once the Rx message have been
             read, the notification can be activated again.
  • I'm calling HAL_CAN_Init, which in turns calls HAL_CAN_MspInit setting the clock, enabling the GPIOs and configuring the CAN pins as alternate function open drain. As I'm using interrupts it also sets the receive interrupt as:
  •     HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
    
  • Reception filters are being set as follows using HAL_CAN_ConfigFilter(), and no error is returned:
  •   sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
      sFilterConfig.FilterIdHigh = 0;
      sFilterConfig.FilterIdLow = 0;
      sFilterConfig.FilterMaskIdHigh = 0;
      sFilterConfig.FilterMaskIdLow = 0;
      sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
      sFilterConfig.FilterActivation = ENABLE;
      sFilterConfig.FilterBank = 0;
      sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
      sFilterConfig.SlaveStartFilterBank = 14;
      HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig)
    
  • HAL_CAN_Start is called and no error is returned:
  • HAL_CAN_Start(&hcan1)
    
  • Using an interrupt triggered by pressing the blue pushbutton a message is sent:
  • void EXTI0_IRQHandler(void)
      /* USER CODE BEGIN EXTI0_IRQn 0 */
    for(int n=0;n<1000000;n++);
    if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET) {
        if(HAL_CAN_GetTxMailboxesFreeLevel(&hcan1)){
            if(HAL_CAN_AddTxMessage(&hcan1, &pHeader, &a, &TxMailbox)==HAL_OK){
                    if(HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_6) == GPIO_PIN_SET){
                        HAL_GPIO_WritePin(GPIOG, GPIO_PIN_6, GPIO_PIN_RESET);
                    } else{
                        HAL_GPIO_WritePin(GPIOG, GPIO_PIN_6, GPIO_PIN_SET);
    
  • I've verified the message is pending as the following returns a positive value:
  • HAL_CAN_IsTxMessagePending(&hcan1, TxMailbox)
    
  • However the following interrupt that should be triggered when a messaged is available to be received is never triggered:
  • void CAN1_RX0_IRQHandler(void)
      HAL_CAN_IRQHandler(&hcan1);
      /* USER CODE BEGIN CAN1_RX0_IRQn 1 */
      HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &pRxHeader, &r);
      HAL_GPIO_WritePin(GPIOK, GPIO_PIN_3, GPIO_PIN_RESET);
      /* USER CODE END CAN1_RX0_IRQn 1 */
    

    Other notes:

  • Have verified the transceivers being used are both receiving 3.3V
  • Any help would be greatly appreciated,

    I am facing the same issues.. I have enabled both CAN interrupts transmission and reception.. however, it does not enter in CAN1_RX0_IRQHandler() anytime.. whereas CAN1_TX_IRQHandler() works fine! and also, i am able to see the data on the bus (verified using logic analyzer)

    if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_TX_MAILBOX_EMPTY) != HAL_OK)
    /* Notification Error */
    Error_Handler();
            

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.