cancel
Showing results for 
Search instead for 
Did you mean: 

CAN-Bus no callback/received frame; FDCAN STM32G474

Hello,

when I try to receive a CAN-Frame it is not received by the Microcontroller, it is within the range, I have no idea what the issue is.

Thanks to everybody in advance, Best Regards, Seppel

0693W00000bhUdqQAE.png0693W00000bhUe5QAE.png 

0693W00000bhUeFQAU.png 

void FDCAN_Config(FDCAN_HandleTypeDef *pHfdcan)
{
 
    pHandleToFdCan = pHfdcan;
 
  /* Configure Rx filter */
  sFilterConfig.IdType = FDCAN_STANDARD_ID;
  sFilterConfig.FilterIndex = 0;
  sFilterConfig.FilterType = FDCAN_FILTER_RANGE;
  sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
  sFilterConfig.FilterID1 = 0x700;
  sFilterConfig.FilterID2 = 0x7FF;
  if (HAL_FDCAN_ConfigFilter(pHandleToFdCan, &sFilterConfig) != HAL_OK)
  {
    Error_Handler();
  }
 
  /* Configure global filter:
     Filter all remote frames with STD and EXT ID
     Reject non matching frames with STD ID and EXT ID */
  if (HAL_FDCAN_ConfigGlobalFilter(pHandleToFdCan, FDCAN_REJECT, FDCAN_REJECT, FDCAN_REJECT, FDCAN_REJECT) != HAL_OK)
  {
    Error_Handler();
  }
 
 
 
  /* Start the FDCAN module */
  if (HAL_FDCAN_Start(pHandleToFdCan) != HAL_OK)
  {
    Error_Handler();
  }
 
  if (HAL_FDCAN_ActivateNotification(pHandleToFdCan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
  {
    Error_Handler();
  }
 
}

0693W00000bhUf3QAE.png 

P.S. TX works perfectly fine, as you can see it Ack's the 0x701 Frame that was received.

22 REPLIES 22

This one?

Call:

/* FDCAN2 init function */
void MX_FDCAN2_Init(void)
{
 
  /* USER CODE BEGIN FDCAN2_Init 0 */
 
  /* USER CODE END FDCAN2_Init 0 */
 
  /* USER CODE BEGIN FDCAN2_Init 1 */
 
  /* USER CODE END FDCAN2_Init 1 */
  hfdcan2.Instance = FDCAN2;
  hfdcan2.Init.ClockDivider = FDCAN_CLOCK_DIV1;
  hfdcan2.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
  hfdcan2.Init.Mode = FDCAN_MODE_NORMAL;
  hfdcan2.Init.AutoRetransmission = DISABLE;
  hfdcan2.Init.TransmitPause = DISABLE;
  hfdcan2.Init.ProtocolException = DISABLE;
  hfdcan2.Init.NominalPrescaler = 4;
  hfdcan2.Init.NominalSyncJumpWidth = 1;
  hfdcan2.Init.NominalTimeSeg1 = 59;
  hfdcan2.Init.NominalTimeSeg2 = 20;
  hfdcan2.Init.DataPrescaler = 8;
  hfdcan2.Init.DataSyncJumpWidth = 1;
  hfdcan2.Init.DataTimeSeg1 = 29;
  hfdcan2.Init.DataTimeSeg2 = 10;
  hfdcan2.Init.StdFiltersNbr = 0;
  hfdcan2.Init.ExtFiltersNbr = 0;
  hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
  if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN FDCAN2_Init 2 */
 
  /* USER CODE END FDCAN2_Init 2 */
 
}

/**
  * @brief  Initializes the FDCAN peripheral according to the specified
  *         parameters in the FDCAN_InitTypeDef structure.
  * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
  *         the configuration information for the specified FDCAN.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_FDCAN_Init(FDCAN_HandleTypeDef *hfdcan)
{
  uint32_t tickstart;
 
  /* Check FDCAN handle */
  if (hfdcan == NULL)
  {
    return HAL_ERROR;
  }
 
  /* Check function parameters */
  assert_param(IS_FDCAN_ALL_INSTANCE(hfdcan->Instance));
  if (hfdcan->Instance == FDCAN1)
  {
    assert_param(IS_FDCAN_CKDIV(hfdcan->Init.ClockDivider));
  }
  assert_param(IS_FDCAN_FRAME_FORMAT(hfdcan->Init.FrameFormat));
  assert_param(IS_FDCAN_MODE(hfdcan->Init.Mode));
  assert_param(IS_FUNCTIONAL_STATE(hfdcan->Init.AutoRetransmission));
  assert_param(IS_FUNCTIONAL_STATE(hfdcan->Init.TransmitPause));
  assert_param(IS_FUNCTIONAL_STATE(hfdcan->Init.ProtocolException));
  assert_param(IS_FDCAN_NOMINAL_PRESCALER(hfdcan->Init.NominalPrescaler));
  assert_param(IS_FDCAN_NOMINAL_SJW(hfdcan->Init.NominalSyncJumpWidth));
  assert_param(IS_FDCAN_NOMINAL_TSEG1(hfdcan->Init.NominalTimeSeg1));
  assert_param(IS_FDCAN_NOMINAL_TSEG2(hfdcan->Init.NominalTimeSeg2));
  if (hfdcan->Init.FrameFormat == FDCAN_FRAME_FD_BRS)
  {
    assert_param(IS_FDCAN_DATA_PRESCALER(hfdcan->Init.DataPrescaler));
    assert_param(IS_FDCAN_DATA_SJW(hfdcan->Init.DataSyncJumpWidth));
    assert_param(IS_FDCAN_DATA_TSEG1(hfdcan->Init.DataTimeSeg1));
    assert_param(IS_FDCAN_DATA_TSEG2(hfdcan->Init.DataTimeSeg2));
  }
  assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.StdFiltersNbr, SRAMCAN_FLS_NBR));
  assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.ExtFiltersNbr, SRAMCAN_FLE_NBR));
  assert_param(IS_FDCAN_TX_FIFO_QUEUE_MODE(hfdcan->Init.TxFifoQueueMode));
 
#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
  if (hfdcan->State == HAL_FDCAN_STATE_RESET)
  {
    /* Allocate lock resource and initialize it */
    hfdcan->Lock = HAL_UNLOCKED;
 
    /* Reset callbacks to legacy functions */
    hfdcan->TxEventFifoCallback         = HAL_FDCAN_TxEventFifoCallback;         /* Legacy weak TxEventFifoCallback */
    hfdcan->RxFifo0Callback             = HAL_FDCAN_RxFifo0Callback;             /* Legacy weak RxFifo0Callback     */
    hfdcan->RxFifo1Callback             = HAL_FDCAN_RxFifo1Callback;             /* Legacy weak RxFifo1Callback     */
    hfdcan->TxFifoEmptyCallback         = HAL_FDCAN_TxFifoEmptyCallback;         /* Legacy weak TxFifoEmptyCallback */
    hfdcan->TxBufferCompleteCallback    = HAL_FDCAN_TxBufferCompleteCallback;    /* Legacy weak
                                                                                    TxBufferCompleteCallback        */
    hfdcan->TxBufferAbortCallback       = HAL_FDCAN_TxBufferAbortCallback;       /* Legacy weak
                                                                                    TxBufferAbortCallback           */
    hfdcan->HighPriorityMessageCallback = HAL_FDCAN_HighPriorityMessageCallback; /* Legacy weak
                                                                                    HighPriorityMessageCallback     */
    hfdcan->TimestampWraparoundCallback = HAL_FDCAN_TimestampWraparoundCallback; /* Legacy weak
                                                                                    TimestampWraparoundCallback     */
    hfdcan->TimeoutOccurredCallback     = HAL_FDCAN_TimeoutOccurredCallback;     /* Legacy weak
                                                                                    TimeoutOccurredCallback         */
    hfdcan->ErrorCallback               = HAL_FDCAN_ErrorCallback;               /* Legacy weak ErrorCallback       */
    hfdcan->ErrorStatusCallback         = HAL_FDCAN_ErrorStatusCallback;         /* Legacy weak ErrorStatusCallback */
 
    if (hfdcan->MspInitCallback == NULL)
    {
      hfdcan->MspInitCallback = HAL_FDCAN_MspInit;  /* Legacy weak MspInit */
    }
 
    /* Init the low level hardware: CLOCK, NVIC */
    hfdcan->MspInitCallback(hfdcan);
  }
#else
  if (hfdcan->State == HAL_FDCAN_STATE_RESET)
  {
    /* Allocate lock resource and initialize it */
    hfdcan->Lock = HAL_UNLOCKED;
 
    /* Init the low level hardware: CLOCK, NVIC */
    HAL_FDCAN_MspInit(hfdcan);
  }
#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
 
  /* Exit from Sleep mode */
  CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CSR);
 
  /* Get tick */
  tickstart = HAL_GetTick();
 
  /* Check Sleep mode acknowledge */
  while ((hfdcan->Instance->CCCR & FDCAN_CCCR_CSA) == FDCAN_CCCR_CSA)
  {
    if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE)
    {
      /* Update error code */
      hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
 
      /* Change FDCAN state */
      hfdcan->State = HAL_FDCAN_STATE_ERROR;
 
      return HAL_ERROR;
    }
  }
 
  /* Request initialisation */
  SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT);
 
  /* Get tick */
  tickstart = HAL_GetTick();
 
  /* Wait until the INIT bit into CCCR register is set */
  while ((hfdcan->Instance->CCCR & FDCAN_CCCR_INIT) == 0U)
  {
    /* Check for the Timeout */
    if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE)
    {
      /* Update error code */
      hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
 
      /* Change FDCAN state */
      hfdcan->State = HAL_FDCAN_STATE_ERROR;
 
      return HAL_ERROR;
    }
  }
 
  /* Enable configuration change */
  SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CCE);
 
  /* Check FDCAN instance */
  if (hfdcan->Instance == FDCAN1)
  {
    /* Configure Clock divider */
    FDCAN_CONFIG->CKDIV = hfdcan->Init.ClockDivider;
  }
 
  /* Set the no automatic retransmission */
  if (hfdcan->Init.AutoRetransmission == ENABLE)
  {
    CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_DAR);
  }
  else
  {
    SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_DAR);
  }
 
  /* Set the transmit pause feature */
  if (hfdcan->Init.TransmitPause == ENABLE)
  {
    SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_TXP);
  }
  else
  {
    CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_TXP);
  }
 
  /* Set the Protocol Exception Handling */
  if (hfdcan->Init.ProtocolException == ENABLE)
  {
    CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_PXHD);
  }
  else
  {
    SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_PXHD);
  }
 
  /* Set FDCAN Frame Format */
  MODIFY_REG(hfdcan->Instance->CCCR, FDCAN_FRAME_FD_BRS, hfdcan->Init.FrameFormat);
 
  /* Reset FDCAN Operation Mode */
  CLEAR_BIT(hfdcan->Instance->CCCR, (FDCAN_CCCR_TEST | FDCAN_CCCR_MON | FDCAN_CCCR_ASM));
  CLEAR_BIT(hfdcan->Instance->TEST, FDCAN_TEST_LBCK);
 
  /* Set FDCAN Operating Mode:
               | Normal | Restricted |    Bus     | Internal | External
               |        | Operation  | Monitoring | LoopBack | LoopBack
     CCCR.TEST |   0    |     0      |     0      |    1     |    1
     CCCR.MON  |   0    |     0      |     1      |    1     |    0
     TEST.LBCK |   0    |     0      |     0      |    1     |    1
     CCCR.ASM  |   0    |     1      |     0      |    0     |    0
  */
  if (hfdcan->Init.Mode == FDCAN_MODE_RESTRICTED_OPERATION)
  {
    /* Enable Restricted Operation mode */
    SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_ASM);
  }
  else if (hfdcan->Init.Mode != FDCAN_MODE_NORMAL)
  {
    if (hfdcan->Init.Mode != FDCAN_MODE_BUS_MONITORING)
    {
      /* Enable write access to TEST register */
      SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_TEST);
 
      /* Enable LoopBack mode */
      SET_BIT(hfdcan->Instance->TEST, FDCAN_TEST_LBCK);
 
      if (hfdcan->Init.Mode == FDCAN_MODE_INTERNAL_LOOPBACK)
      {
        SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_MON);
      }
    }
    else
    {
      /* Enable bus monitoring mode */
      SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_MON);
    }
  }
  else
  {
    /* Nothing to do: normal mode */
  }
 
  /* Set the nominal bit timing register */
  hfdcan->Instance->NBTP = ((((uint32_t)hfdcan->Init.NominalSyncJumpWidth - 1U) << FDCAN_NBTP_NSJW_Pos) | \
                            (((uint32_t)hfdcan->Init.NominalTimeSeg1 - 1U) << FDCAN_NBTP_NTSEG1_Pos)    | \
                            (((uint32_t)hfdcan->Init.NominalTimeSeg2 - 1U) << FDCAN_NBTP_NTSEG2_Pos)    | \
                            (((uint32_t)hfdcan->Init.NominalPrescaler - 1U) << FDCAN_NBTP_NBRP_Pos));
 
  /* If FD operation with BRS is selected, set the data bit timing register */
  if (hfdcan->Init.FrameFormat == FDCAN_FRAME_FD_BRS)
  {
    hfdcan->Instance->DBTP = ((((uint32_t)hfdcan->Init.DataSyncJumpWidth - 1U) << FDCAN_DBTP_DSJW_Pos)  | \
                              (((uint32_t)hfdcan->Init.DataTimeSeg1 - 1U) << FDCAN_DBTP_DTSEG1_Pos)     | \
                              (((uint32_t)hfdcan->Init.DataTimeSeg2 - 1U) << FDCAN_DBTP_DTSEG2_Pos)     | \
                              (((uint32_t)hfdcan->Init.DataPrescaler - 1U) << FDCAN_DBTP_DBRP_Pos));
  }
 
  /* Select between Tx FIFO and Tx Queue operation modes */
  SET_BIT(hfdcan->Instance->TXBC, hfdcan->Init.TxFifoQueueMode);
 
  /* Calculate each RAM block address */
  FDCAN_CalcultateRamBlockAddresses(hfdcan);
 
  /* Initialize the Latest Tx request buffer index */
  hfdcan->LatestTxFifoQRequest = 0U;
 
  /* Initialize the error code */
  hfdcan->ErrorCode = HAL_FDCAN_ERROR_NONE;
 
  /* Initialize the FDCAN state */
  hfdcan->State = HAL_FDCAN_STATE_READY;
 
  /* Return function status */
  return HAL_OK;
}

Not quite.  FDCAN_InitTypeDef structure declaration.

This is the type for your Init above.

In the "FDCAN_HandleTypeDef" struct is a member " FDCAN_MsgRamAddressTypeDef msgRam; "

I have no idea how that is used and I have not seen it in any example,... .

/**
  * @brief  FDCAN handle structure definition
  */
#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
typedef struct __FDCAN_HandleTypeDef
#else
typedef struct
#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
{
  FDCAN_GlobalTypeDef         *Instance;        /*!< Register base address     */
 
  FDCAN_InitTypeDef           Init;             /*!< FDCAN required parameters */
 
  FDCAN_MsgRamAddressTypeDef  msgRam;           /*!< FDCAN Message RAM blocks  */
 
  uint32_t                    LatestTxFifoQRequest; /*!< FDCAN Tx buffer index
                                               of latest Tx FIFO/Queue request */
 
  __IO HAL_FDCAN_StateTypeDef State;            /*!< FDCAN communication state */
 
  HAL_LockTypeDef             Lock;             /*!< FDCAN locking object      */
 
  __IO uint32_t               ErrorCode;        /*!< FDCAN Error code          */
 
#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
  void (* TxEventFifoCallback)(struct __FDCAN_HandleTypeDef *hfdcan, uint32_t TxEventFifoITs);     /*!< FDCAN Tx Event Fifo callback         */
  void (* RxFifo0Callback)(struct __FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs);             /*!< FDCAN Rx Fifo 0 callback             */
  void (* RxFifo1Callback)(struct __FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo1ITs);             /*!< FDCAN Rx Fifo 1 callback             */
  void (* TxFifoEmptyCallback)(struct __FDCAN_HandleTypeDef *hfdcan);                              /*!< FDCAN Tx Fifo Empty callback         */
  void (* TxBufferCompleteCallback)(struct __FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes); /*!< FDCAN Tx Buffer complete callback    */
  void (* TxBufferAbortCallback)(struct __FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes);    /*!< FDCAN Tx Buffer abort callback       */
  void (* HighPriorityMessageCallback)(struct __FDCAN_HandleTypeDef *hfdcan);                      /*!< FDCAN High priority message callback */
  void (* TimestampWraparoundCallback)(struct __FDCAN_HandleTypeDef *hfdcan);                      /*!< FDCAN Timestamp wraparound callback  */
  void (* TimeoutOccurredCallback)(struct __FDCAN_HandleTypeDef *hfdcan);                          /*!< FDCAN Timeout occurred callback      */
  void (* ErrorCallback)(struct __FDCAN_HandleTypeDef *hfdcan);                                    /*!< FDCAN Error callback                 */
  void (* ErrorStatusCallback)(struct __FDCAN_HandleTypeDef *hfdcan, uint32_t ErrorStatusITs);     /*!< FDCAN Error status callback          */
 
  void (* MspInitCallback)(struct __FDCAN_HandleTypeDef *hfdcan);                                  /*!< FDCAN Msp Init callback              */
  void (* MspDeInitCallback)(struct __FDCAN_HandleTypeDef *hfdcan);                                /*!< FDCAN Msp DeInit callback            */
 
#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
 
} FDCAN_HandleTypeDef;

AndrewST
Associate II

I mean this guy:

typedef struct
{
  uint32_t FrameFormat;                  /*!< Specifies the FDCAN frame format.
                                              This parameter can be a value of @ref FDCAN_frame_format     */
 
  uint32_t Mode;                         /*!< Specifies the FDCAN mode.
                                              This parameter can be a value of @ref FDCAN_operating_mode   */
 
  FunctionalState AutoRetransmission;    /*!< Enable or disable the automatic retransmission mode.
                                              This parameter can be set to ENABLE or DISABLE               */
 
  FunctionalState TransmitPause;         /*!< Enable or disable the Transmit Pause feature.
                                              This parameter can be set to ENABLE or DISABLE               */
 
  FunctionalState ProtocolException;      /*!< Enable or disable the Protocol Exception Handling.
                                              This parameter can be set to ENABLE or DISABLE               */
 
  uint32_t NominalPrescaler;             /*!< Specifies the value by which the oscillator frequency is
                                              divided for generating the nominal bit time quanta.
                                              This parameter must be a number between 1 and 512            */
 
  uint32_t NominalSyncJumpWidth;         /*!< Specifies the maximum number of time quanta the FDCAN
                                              hardware is allowed to lengthen or shorten a bit to perform
                                              resynchronization.
                                              This parameter must be a number between 1 and 128            */
 
  uint32_t NominalTimeSeg1;              /*!< Specifies the number of time quanta in Bit Segment 1.
                                              This parameter must be a number between 2 and 256            */
 
  uint32_t NominalTimeSeg2;              /*!< Specifies the number of time quanta in Bit Segment 2.
                                              This parameter must be a number between 2 and 128            */
 
  uint32_t DataPrescaler;                /*!< Specifies the value by which the oscillator frequency is
                                              divided for generating the data bit time quanta.
                                              This parameter must be a number between 1 and 32             */
 
  uint32_t DataSyncJumpWidth;            /*!< Specifies the maximum number of time quanta the FDCAN
                                              hardware is allowed to lengthen or shorten a data bit to
                                              perform resynchronization.
                                              This parameter must be a number between 1 and 16             */
 
  uint32_t DataTimeSeg1;                 /*!< Specifies the number of time quanta in Data Bit Segment 1.
                                              This parameter must be a number between 1 and 32             */
 
  uint32_t DataTimeSeg2;                 /*!< Specifies the number of time quanta in Data Bit Segment 2.
                                              This parameter must be a number between 1 and 16             */
 
  uint32_t MessageRAMOffset;             /*!< Specifies the message RAM start address.
                                              This parameter must be a number between 0 and 2560           */
 
  uint32_t StdFiltersNbr;                /*!< Specifies the number of standard Message ID filters.
                                              This parameter must be a number between 0 and 128            */
 
  uint32_t ExtFiltersNbr;                /*!< Specifies the number of extended Message ID filters.
                                              This parameter must be a number between 0 and 64             */
 
  uint32_t RxFifo0ElmtsNbr;              /*!< Specifies the number of Rx FIFO0 Elements.
                                              This parameter must be a number between 0 and 64             */
 
  uint32_t RxFifo0ElmtSize;              /*!< Specifies the Data Field Size in an Rx FIFO 0 element.
                                              This parameter can be a value of @ref FDCAN_data_field_size  */
 
  uint32_t RxFifo1ElmtsNbr;              /*!< Specifies the number of Rx FIFO 1 Elements.
                                              This parameter must be a number between 0 and 64             */
 
  uint32_t RxFifo1ElmtSize;              /*!< Specifies the Data Field Size in an Rx FIFO 1 element.
                                              This parameter can be a value of @ref FDCAN_data_field_size  */
 
  uint32_t RxBuffersNbr;                 /*!< Specifies the number of Dedicated Rx Buffer elements.
                                              This parameter must be a number between 0 and 64             */
 
  uint32_t RxBufferSize;                 /*!< Specifies the Data Field Size in an Rx Buffer element.
                                              This parameter can be a value of @ref FDCAN_data_field_size  */
 
  uint32_t TxEventsNbr;                  /*!< Specifies the number of Tx Event FIFO elements.
                                              This parameter must be a number between 0 and 32             */
 
  uint32_t TxBuffersNbr;                 /*!< Specifies the number of Dedicated Tx Buffers.
                                              This parameter must be a number between 0 and 32             */
 
  uint32_t TxFifoQueueElmtsNbr;          /*!< Specifies the number of Tx Buffers used for Tx FIFO/Queue.
                                              This parameter must be a number between 0 and 32             */
 
  uint32_t TxFifoQueueMode;              /*!< Tx FIFO/Queue Mode selection.
                                              This parameter can be a value of @ref FDCAN_txFifoQueue_Mode */
 
  uint32_t TxElmtSize;                   /*!< Specifies the Data Field Size in a Tx Element.
                                              This parameter can be a value of @ref FDCAN_data_field_size  */
 
} FDCAN_InitTypeDef;

Are you working for ST. Is there someone who knows that CAN-Controller and knows how to set up the behaviour of the RX-Queue etc. ? That fancy presentation, nice for marketing, but useless for engineers with no references to HAL function: STM32G4-Peripheral-Flexible_Datarate_Controller_Area_Network_FDCAN.pdf

/**
  * @brief FDCAN Init structure definition
  */
typedef struct
{
  uint32_t ClockDivider;                 /*!< Specifies the FDCAN kernel clock divider.
                                              The clock is common to all FDCAN instances.
                                              This parameter is applied only at initialisation of
                                              first FDCAN instance.
                                              This parameter can be a value of @ref FDCAN_clock_divider.   */
 
  uint32_t FrameFormat;                  /*!< Specifies the FDCAN frame format.
                                              This parameter can be a value of @ref FDCAN_frame_format     */
 
  uint32_t Mode;                         /*!< Specifies the FDCAN mode.
                                              This parameter can be a value of @ref FDCAN_operating_mode   */
 
  FunctionalState AutoRetransmission;    /*!< Enable or disable the automatic retransmission mode.
                                              This parameter can be set to ENABLE or DISABLE               */
 
  FunctionalState TransmitPause;         /*!< Enable or disable the Transmit Pause feature.
                                              This parameter can be set to ENABLE or DISABLE               */
 
  FunctionalState ProtocolException;      /*!< Enable or disable the Protocol Exception Handling.
                                              This parameter can be set to ENABLE or DISABLE               */
 
  uint32_t NominalPrescaler;             /*!< Specifies the value by which the oscillator frequency is
                                              divided for generating the nominal bit time quanta.
                                              This parameter must be a number between 1 and 512            */
 
  uint32_t NominalSyncJumpWidth;         /*!< Specifies the maximum number of time quanta the FDCAN
                                              hardware is allowed to lengthen or shorten a bit to perform
                                              resynchronization.
                                              This parameter must be a number between 1 and 128            */
 
  uint32_t NominalTimeSeg1;              /*!< Specifies the number of time quanta in Bit Segment 1.
                                              This parameter must be a number between 2 and 256            */
 
  uint32_t NominalTimeSeg2;              /*!< Specifies the number of time quanta in Bit Segment 2.
                                              This parameter must be a number between 2 and 128            */
 
  uint32_t DataPrescaler;                /*!< Specifies the value by which the oscillator frequency is
                                              divided for generating the data bit time quanta.
                                              This parameter must be a number between 1 and 32             */
 
  uint32_t DataSyncJumpWidth;            /*!< Specifies the maximum number of time quanta the FDCAN
                                              hardware is allowed to lengthen or shorten a data bit to
                                              perform resynchronization.
                                              This parameter must be a number between 1 and 16             */
 
  uint32_t DataTimeSeg1;                 /*!< Specifies the number of time quanta in Data Bit Segment 1.
                                              This parameter must be a number between 1 and 32             */
 
  uint32_t DataTimeSeg2;                 /*!< Specifies the number of time quanta in Data Bit Segment 2.
                                              This parameter must be a number between 1 and 16             */
 
  uint32_t StdFiltersNbr;                /*!< Specifies the number of standard Message ID filters.
                                              This parameter must be a number between 0 and 28             */
 
  uint32_t ExtFiltersNbr;                /*!< Specifies the number of extended Message ID filters.
                                              This parameter must be a number between 0 and 8             */
 
  uint32_t TxFifoQueueMode;              /*!< Tx FIFO/Queue Mode selection.
                                              This parameter can be a value of @ref FDCAN_txFifoQueue_Mode */
 
} FDCAN_InitTypeDef;

I am just another user who has FDCAN working on a somewhat similar MPU, that's all.

Did you get the RX Callback working? How did you set it up, could you share some screenshts and code-snippets?

LCE
Principal

I don't know how similar G4 / H7 FDCANs are, so all of the following might only apply to the H7.

The H7 has some 10 kB SRAM reserved for FDCAN.

This "CAN-RAM" is used for:

  • filter settings
  • RX & TX buffers and FIFOs

The RAM layout depends on your INIT settings, how many filters, buffers, etcpp you assign.

Then it calculates the RAM (starting) addresses / pointers from that.

First thing I see in your init:

StdFiltersNbr = 0; ExtFiltersNbr = 0;

Which means you have no filters assigned to memory.

Comparing to my H7 source, I also miss the settings for RX & TX buffers & FIFO, so my H7 init looks like this:

void MX_FDCAN1_Init(uint32_t u32DataRate)
{
	FDCAN_HandleTypeDef *phCan = &hCan1;
	FDCAN_FilterTypeDef sFilterConfig = { 0 };
 
	phCan->Instance = FDCAN1;
 
	phCan->Init.FrameFormat 			= FDCAN_FRAME_FD_BRS;
	phCan->Init.Mode 					= FDCAN_MODE_NORMAL;//FDCAN_MODE_EXTERNAL_LOOPBACK;//
	phCan->Init.AutoRetransmission 		= ENABLE;
	phCan->Init.TransmitPause 			= ENABLE;
	phCan->Init.ProtocolException 		= ENABLE;
 
/* clock / timing */
 
/* nominal = arbitration phase
 *	NBTP
 * 	80 MHz: tq = NominalPrescaler x (1/fdcan_ker_ck)
 *		->  tq = 12.5 ns
 *	data rate = 1 / ((SyncSeg + Seg1 + Seg2) * tq)
 *		with SyncSeg = 1
 *	0.5 Mbps = 160 * tq
 *		-> TimeSeg1 + TimeSeg2 = 157
 */
	phCan->Init.NominalPrescaler 		= 1;		/* tq = NominalPrescaler x (1/fdcan_ker_ck) */
#if( 1 )
/* 5000 ppm */
	phCan->Init.NominalTimeSeg1 		= 138;		/* NTSEG1 1..256, NominalTimeSeg1 = Propagation_segment + Phase_segment_1 */
	phCan->Init.NominalTimeSeg2 		= 21;		/* NTSEG2 1..128 */
	phCan->Init.NominalSyncJumpWidth 	= 20;		/* NSJW   1..128 should be < NTSEG2 */
#else
/* 500 ppm */
	phCan->Init.NominalTimeSeg1 		= 155;		/* NTSEG1 1..256, NominalTimeSeg1 = Propagation_segment + Phase_segment_1 */
	phCan->Init.NominalTimeSeg2 		= 4; 		/* NTSEG2 1..128 */
	phCan->Init.NominalSyncJumpWidth 	= 3; 		/* NSJW   1..128 should be < NTSEG2 */
#endif
 
/* data = data phase with bit rate switching
 *	DBTP
 * 	80 MHz: tq = DataPrescaler x (1/fdcan_ker_ck)
 *		->  tq = 12.5 ns
 *	data rate = 1 / ((SyncSeg + Seg1 + Seg2) * tq)
 *		with SyncSeg = 1
 */
	phCan->Init.DataPrescaler 			= 1;		/* DBRP 1..32 */
 
	CanInitBsrDataRate(phCan, u32DataRate);
 
/* RAM: filters, buffers */
	/* start pos in RAM of 2560 32-bit words */
	phCan->Init.MessageRAMOffset 		= 0;
 
	phCan->Init.StdFiltersNbr 			= 16;
	phCan->Init.ExtFiltersNbr 			= 16;
 
	phCan->Init.RxFifo0ElmtsNbr 		= 16;
	phCan->Init.RxFifo0ElmtSize 		= FDCAN_DATA_BYTES_64;
 
	phCan->Init.RxFifo1ElmtsNbr 		= 16;
	phCan->Init.RxFifo1ElmtSize 		= FDCAN_DATA_BYTES_64;
 
	phCan->Init.RxBuffersNbr 			= 16;
	phCan->Init.RxBufferSize 			= FDCAN_DATA_BYTES_64;
 
	phCan->Init.TxEventsNbr 			= 0;
	phCan->Init.TxBuffersNbr 			= 4;
	phCan->Init.TxFifoQueueElmtsNbr 	= 4;
	phCan->Init.TxFifoQueueMode 		= FDCAN_TX_FIFO_OPERATION;
	phCan->Init.TxElmtSize 				= FDCAN_DATA_BYTES_64;
 
	if( HAL_FDCAN_Init(phCan) != HAL_OK ) Error_Handler_FL(__FILE__, __LINE__);
 
/* Filters - STANDARD */
	sFilterConfig.FilterType 		= 0;	/* ignored for FDCAN_FILTER_TO_RXBUFFER */
	sFilterConfig.FilterID2 		= 0;	/* ignored for FDCAN_FILTER_TO_RXBUFFER */
 
	/* Configure standard ID reception filter to Rx buffer 0 */
	sFilterConfig.IdType 			= FDCAN_STANDARD_ID;
	sFilterConfig.FilterIndex 		= 0;
	sFilterConfig.FilterConfig 		= FDCAN_FILTER_TO_RXBUFFER;
	sFilterConfig.RxBufferIndex 	= 0;								/* store ID1 to this RX buffer */
	sFilterConfig.FilterID1 		= CAN_FILTER_STD_TEST_RXB_ID1;		/* MessageID and FilterID1 must match exactly */
	HAL_FDCAN_ConfigFilter(phCan, &sFilterConfig);
 
	/* Configure standard ID reception filter to Rx buffer 1 */
	sFilterConfig.IdType 			= FDCAN_STANDARD_ID;
	sFilterConfig.FilterIndex 		= 1;
	sFilterConfig.FilterConfig 		= FDCAN_FILTER_TO_RXBUFFER;
	sFilterConfig.RxBufferIndex 	= 1;							/* store ID1 to this RX buffer */
	sFilterConfig.FilterID1 		= CAN_FILTER_STD_TEST_RXB_ID2;		/* MessageID and FilterID1 must match exactly */
	HAL_FDCAN_ConfigFilter(phCan, &sFilterConfig);
 
	/* Configure standard ID reception filter to Rx buffer 2 */
	sFilterConfig.IdType 			= FDCAN_STANDARD_ID;
	sFilterConfig.FilterIndex 		= 2;
	sFilterConfig.FilterConfig 		= FDCAN_FILTER_TO_RXBUFFER;
	sFilterConfig.RxBufferIndex 	= 2;							/* store ID1 to this RX buffer */
	sFilterConfig.FilterID1 		= CAN_FILTER_STD_TEST_RXB_ID3;		/* MessageID and FilterID1 must match exactly */
	HAL_FDCAN_ConfigFilter(phCan, &sFilterConfig);
 
	/* Configure standard ID reception filter to Rx buffer 3 */
	sFilterConfig.IdType 			= FDCAN_STANDARD_ID;
	sFilterConfig.FilterIndex 		= 3;
	sFilterConfig.FilterConfig 		= FDCAN_FILTER_TO_RXBUFFER;
	sFilterConfig.RxBufferIndex 	= 3;							/* store ID1 to this RX buffer */
	sFilterConfig.FilterID1 		= CAN_FILTER_STD_TEST_RXB_ID4;		/* MessageID and FilterID1 must match exactly */
	HAL_FDCAN_ConfigFilter(phCan, &sFilterConfig);
 
/* Filters - EXTENDED */
	sFilterConfig.RxBufferIndex 	= 0;	/* ignored if not FDCAN_FILTER_TO_RXBUFFER */
 
	/* Configure extended ID reception filter to Rx FIFO 0 */
	sFilterConfig.IdType 			= FDCAN_EXTENDED_ID;
	sFilterConfig.FilterIndex 		= 0;
	sFilterConfig.FilterType 		= FDCAN_FILTER_RANGE_NO_EIDM;	/* Range from FilterID1 to FilterID2, no EIDM mask */
	sFilterConfig.FilterConfig 		= FDCAN_FILTER_TO_RXFIFO0;
	sFilterConfig.FilterID1 		= CAN_FILTER_EXT_TEST_RXF_ID1;
	sFilterConfig.FilterID2 		= CAN_FILTER_EXT_TEST_RXF_ID2;
	HAL_FDCAN_ConfigFilter(phCan, &sFilterConfig);
 
	/* Configure extended ID reception filter to Rx FIFO 1 */
	sFilterConfig.IdType 			= FDCAN_EXTENDED_ID;
	sFilterConfig.FilterIndex 		= 1;
	sFilterConfig.FilterType 		= FDCAN_FILTER_RANGE_NO_EIDM;	/* Range from FilterID1 to FilterID2, no EIDM mask */
	sFilterConfig.FilterConfig 		= FDCAN_FILTER_TO_RXFIFO1;
	sFilterConfig.FilterID1 		= CAN_FILTER_EXT_TEST_RXF_ID3;
	sFilterConfig.FilterID2 		= CAN_FILTER_EXT_TEST_RXF_ID4;
	HAL_FDCAN_ConfigFilter(phCan, &sFilterConfig);
 
	/* Configure global filter to reject all non-matching frames */
	HAL_FDCAN_ConfigGlobalFilter(phCan, FDCAN_REJECT, FDCAN_REJECT, FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE);
 
#if( 0 )
	/* Configure Rx FIFO 0 watermark to 2 */
	HAL_FDCAN_ConfigFifoWatermark(phCan, FDCAN_CFG_RX_FIFO0, 2);
 
	/* Activate Rx FIFO 0 watermark notification */
	HAL_FDCAN_ActivateNotification(phCan, FDCAN_IT_RX_FIFO0_WATERMARK, 0);
#endif
 
	/* timestamp enable, bit time, no prescaler */
	phCan->Instance->TSCC = 1;
 
/* enable TDC = transmitter delay compensation
 *	this is a MUST for high data rates
 */
	/* configure Tx Delay Compensation : TdcOffset = DataTimeSeg1 * DataPrescaler */
	uint32_t u32TdcOffs = ((uint32_t)phCan->Instance->DBTP >> FDCAN_DBTP_DTSEG1_Pos) + 1;
	uint32_t u32TdcFltWdw = 0;
 
	/* set TDC filter window */
	phCan->Instance->TDCR = (u32TdcFltWdw << FDCAN_TDCR_TDCF_Pos);
	/* set TDC offset */
	phCan->Instance->TDCR |= (u32TdcOffs << FDCAN_TDCR_TDCO_Pos);
	/* enable TDC */
	phCan->Instance->DBTP |= FDCAN_DBTP_TDC;
 
/* start FDCAN */
	HAL_FDCAN_Start(phCan);
}
 

LCE
Principal

Don't forget that CubeMX is just a basic setup-thingy.

So use the debugger or the UART to check register settings, like interrupt enable, memory addresses, ...

I just see that I had to put some interrupt enables in the MSP init with direct register settings.

I usually don't use HAL for the important stuff, but until now FDCAN was only a feasability check.

And yes, it works, although I had some problems getting the 8 Mbps running...

static uint32_t HAL_RCC_FDCAN_CLK_ENABLED = 0;
 
void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef* phCan)
{
	GPIO_InitTypeDef GPIO_InitStruct = { 0 };
 
	if( phCan->Instance == FDCAN1 )
	{
		/* FDCAN1 clock enable */
		HAL_RCC_FDCAN_CLK_ENABLED++;
		if( HAL_RCC_FDCAN_CLK_ENABLED == 1 )
		{
			__HAL_RCC_FDCAN_CLK_ENABLE();
		}
 
		__HAL_RCC_GPIOH_CLK_ENABLE();
		/** FDCAN1 GPIO Configuration
			PH14	------> FDCAN1_RX
			PH13	------> FDCAN1_TX
		*/
		GPIO_InitStruct.Pin 	= FDCAN1_RX_Pin | FDCAN1_TX_Pin;
		GPIO_InitStruct.Mode 	= GPIO_MODE_AF_PP;
		GPIO_InitStruct.Pull 	= GPIO_NOPULL;
		GPIO_InitStruct.Speed 	= GPIO_SPEED_FREQ_LOW;
		GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN1;
		HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
 
	/* FDCAN1 interrupt Init */
		HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn, 10, 0);
		HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn);
		HAL_NVIC_SetPriority(FDCAN1_IT1_IRQn, 10, 0);
		HAL_NVIC_EnableIRQ(FDCAN1_IT1_IRQn);
 
		/* interrupt enable, all lines to 0 */
		phCan->Instance->ILS = 0;
		phCan->Instance->IE = (FDCAN_IE_DRXE | FDCAN_IE_RF1NE | FDCAN_IE_RF0NE );
		phCan->Instance->ILE = FDCAN_ILE_EINT0;
		phCan->Instance->IR = 0xFFFFFFFF;
	}
 
}