cembeddedstm32can-bushal

STM32 FDCAN filters not filtering anything


The problem

I am unable to get the HAL CAN filters to filter anything. I have FDCAN working perfectly on my STM32H723VGT6 uController. I would like to now implement CAN filters, but when I configure the FDCAN filter, nothing is filtered, all Rx messages still trigger the RxFIFI0 callback.

What I have tried:

// Can init (hfcan points to hfdcan1)
{
    FDCAN_FilterConfig->IdType = FDCAN_STANDARD_ID;
    FDCAN_FilterConfig->FilterType = FDCAN_FILTER_DUAL;
    FDCAN_FilterConfig->FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
    
    FDCAN_FilterConfig->FilterIndex = 0;
    FDCAN_FilterConfig->FilterID1 = 0x262;
    FDCAN_FilterConfig->FilterID2 = 0x362;
    if (HAL_FDCAN_ConfigFilter(hfdcan, FDCAN_FilterConfig) != HAL_OK) 
    {
        return Result_Fault;
    }
    
    if (HAL_FDCAN_Start(hfdcan) != HAL_OK) return Result_Init_Fault;
    if (HAL_FDCAN_ActivateNotification(hfdcan, can_interuppt_fifo, 0) != HAL_OK) return Result_Init_Fault;
}

Standard callback:

void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
    /* Prevent unused argument(s) compilation warning */
    UNUSED(RxFifo0ITs);
    
    // This callback is successfully called Rx messages are received with no problem. 
}

And the can.c file:

void MX_FDCAN1_Init(void)
{

  /* USER CODE BEGIN FDCAN1_Init 0 */

  /* USER CODE END FDCAN1_Init 0 */

  /* USER CODE BEGIN FDCAN1_Init 1 */

  /* USER CODE END FDCAN1_Init 1 */
  hfdcan1.Instance = FDCAN1;
  hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
  hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
  hfdcan1.Init.AutoRetransmission = DISABLE;
  hfdcan1.Init.TransmitPause = DISABLE;
  hfdcan1.Init.ProtocolException = DISABLE;
  hfdcan1.Init.NominalPrescaler = 23;
  hfdcan1.Init.NominalSyncJumpWidth = 1;
  hfdcan1.Init.NominalTimeSeg1 = 8;
  hfdcan1.Init.NominalTimeSeg2 = 3;
  hfdcan1.Init.DataPrescaler = 1;
  hfdcan1.Init.DataSyncJumpWidth = 1;
  hfdcan1.Init.DataTimeSeg1 = 1;
  hfdcan1.Init.DataTimeSeg2 = 1;
  hfdcan1.Init.MessageRAMOffset = 0;
  hfdcan1.Init.StdFiltersNbr = 0;
  hfdcan1.Init.ExtFiltersNbr = 0;
  hfdcan1.Init.RxFifo0ElmtsNbr = 1;
  hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
  hfdcan1.Init.RxFifo1ElmtsNbr = 0;
  hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
  hfdcan1.Init.RxBuffersNbr = 0;
  hfdcan1.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
  hfdcan1.Init.TxEventsNbr = 0;
  hfdcan1.Init.TxBuffersNbr = 0;
  hfdcan1.Init.TxFifoQueueElmtsNbr = 10;
  hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
  hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
  if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN FDCAN1_Init 2 */

  /* USER CODE END FDCAN1_Init 2 */
}

Given that CAN filters are supposed to be really simply, what have I missed?


Solution

  • I found the answer in this post: How to set FDCAN Masking Filter with stm32H503?

    After calling:

        if (HAL_FDCAN_ConfigFilter(hfdcan, FDCAN_FilterConfig) != HAL_OK) 
        {
            return Result_Fault;
        }
    

    The following line needs to be added to enable the filters:

        if (HAL_FDCAN_ConfigGlobalFilter(hfdcan, FDCAN_REJECT, FDCAN_REJECT, FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE) != HAL_OK) return Result_Init_Fault;
    

    Hope this helps