Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:07

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_fdcan.c
0004   * @author  MCD Application Team
0005   * @brief   FDCAN HAL module driver.
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the Flexible DataRate Controller Area Network
0008   *          (FDCAN) peripheral:
0009   *           + Initialization and de-initialization functions
0010   *           + IO operation functions
0011   *           + Peripheral Configuration and Control functions
0012   *           + Peripheral State and Error functions
0013   ******************************************************************************
0014   * @attention
0015   *
0016   * Copyright (c) 2017 STMicroelectronics.
0017   * All rights reserved.
0018   *
0019   * This software is licensed under terms that can be found in the LICENSE file
0020   * in the root directory of this software component.
0021   * If no LICENSE file comes with this software, it is provided AS-IS.
0022   *
0023   ******************************************************************************
0024   @verbatim
0025   ==============================================================================
0026                         ##### How to use this driver #####
0027   ==============================================================================
0028     [..]
0029       (#) Initialize the FDCAN peripheral using HAL_FDCAN_Init function.
0030 
0031       (#) If needed , configure the reception filters and optional features using
0032           the following configuration functions:
0033             (++) HAL_FDCAN_ConfigClockCalibration
0034             (++) HAL_FDCAN_ConfigFilter
0035             (++) HAL_FDCAN_ConfigGlobalFilter
0036             (++) HAL_FDCAN_ConfigExtendedIdMask
0037             (++) HAL_FDCAN_ConfigRxFifoOverwrite
0038             (++) HAL_FDCAN_ConfigFifoWatermark
0039             (++) HAL_FDCAN_ConfigRamWatchdog
0040             (++) HAL_FDCAN_ConfigTimestampCounter
0041             (++) HAL_FDCAN_EnableTimestampCounter
0042             (++) HAL_FDCAN_DisableTimestampCounter
0043             (++) HAL_FDCAN_ConfigTimeoutCounter
0044             (++) HAL_FDCAN_EnableTimeoutCounter
0045             (++) HAL_FDCAN_DisableTimeoutCounter
0046             (++) HAL_FDCAN_ConfigTxDelayCompensation
0047             (++) HAL_FDCAN_EnableTxDelayCompensation
0048             (++) HAL_FDCAN_DisableTxDelayCompensation
0049             (++) HAL_FDCAN_EnableISOMode
0050             (++) HAL_FDCAN_DisableISOMode
0051             (++) HAL_FDCAN_EnableEdgeFiltering
0052             (++) HAL_FDCAN_DisableEdgeFiltering
0053             (++) HAL_FDCAN_TT_ConfigOperation
0054             (++) HAL_FDCAN_TT_ConfigReferenceMessage
0055             (++) HAL_FDCAN_TT_ConfigTrigger
0056 
0057       (#) Start the FDCAN module using HAL_FDCAN_Start function. At this level
0058           the node is active on the bus: it can send and receive messages.
0059 
0060       (#) The following Tx control functions can only be called when the FDCAN
0061           module is started:
0062             (++) HAL_FDCAN_AddMessageToTxFifoQ
0063             (++) HAL_FDCAN_EnableTxBufferRequest
0064             (++) HAL_FDCAN_AbortTxRequest
0065 
0066       (#) After having submitted a Tx request in Tx Fifo or Queue, it is possible to
0067           get Tx buffer location used to place the Tx request thanks to
0068           HAL_FDCAN_GetLatestTxFifoQRequestBuffer API.
0069           It is then possible to abort later on the corresponding Tx Request using
0070           HAL_FDCAN_AbortTxRequest API.
0071 
0072       (#) When a message is received into the FDCAN message RAM, it can be
0073           retrieved using the HAL_FDCAN_GetRxMessage function.
0074 
0075       (#) Calling the HAL_FDCAN_Stop function stops the FDCAN module by entering
0076           it to initialization mode and re-enabling access to configuration
0077           registers through the configuration functions listed here above.
0078 
0079       (#) All other control functions can be called any time after initialization
0080           phase, no matter if the FDCAN module is started or stopped.
0081 
0082       *** Polling mode operation ***
0083       ==============================
0084     [..]
0085         (#) Reception and transmission states can be monitored via the following
0086             functions:
0087               (++) HAL_FDCAN_IsRxBufferMessageAvailable
0088               (++) HAL_FDCAN_IsTxBufferMessagePending
0089               (++) HAL_FDCAN_GetRxFifoFillLevel
0090               (++) HAL_FDCAN_GetTxFifoFreeLevel
0091 
0092       *** Interrupt mode operation ***
0093       ================================
0094       [..]
0095         (#) There are two interrupt lines: line 0 and 1.
0096             By default, all interrupts are assigned to line 0. Interrupt lines
0097             can be configured using HAL_FDCAN_ConfigInterruptLines function.
0098 
0099         (#) Notifications are activated using HAL_FDCAN_ActivateNotification
0100             function. Then, the process can be controlled through one of the
0101             available user callbacks: HAL_FDCAN_xxxCallback.
0102 
0103   *** Callback registration ***
0104   =============================================
0105 
0106   The compilation define USE_HAL_FDCAN_REGISTER_CALLBACKS when set to 1
0107   allows the user to configure dynamically the driver callbacks.
0108   Use Function HAL_FDCAN_RegisterCallback() or HAL_FDCAN_RegisterXXXCallback()
0109   to register an interrupt callback.
0110 
0111   Function HAL_FDCAN_RegisterCallback() allows to register following callbacks:
0112     (+) TxFifoEmptyCallback          : Tx Fifo Empty Callback.
0113     (+) RxBufferNewMessageCallback   : Rx Buffer New Message Callback.
0114     (+) HighPriorityMessageCallback  : High Priority Message Callback.
0115     (+) TimestampWraparoundCallback  : Timestamp Wraparound Callback.
0116     (+) TimeoutOccurredCallback      : Timeout Occurred Callback.
0117     (+) ErrorCallback                : Error Callback.
0118     (+) MspInitCallback              : FDCAN MspInit.
0119     (+) MspDeInitCallback            : FDCAN MspDeInit.
0120   This function takes as parameters the HAL peripheral handle, the Callback ID
0121   and a pointer to the user callback function.
0122 
0123   For specific callbacks ClockCalibrationCallback, TxEventFifoCallback, RxFifo0Callback, RxFifo1Callback,
0124   TxBufferCompleteCallback, TxBufferAbortCallback, ErrorStatusCallback, TT_ScheduleSyncCallback, TT_TimeMarkCallback,
0125   TT_StopWatchCallback and TT_GlobalTimeCallback, use dedicated register callbacks:
0126   respectively HAL_FDCAN_RegisterClockCalibrationCallback(), HAL_FDCAN_RegisterTxEventFifoCallback(),
0127   HAL_FDCAN_RegisterRxFifo0Callback(), HAL_FDCAN_RegisterRxFifo1Callback(),
0128   HAL_FDCAN_RegisterTxBufferCompleCallback(), HAL_FDCAN_RegisterTxBufferAbortCallback(),
0129   HAL_FDCAN_RegisterErrorStatusCallback(), HAL_FDCAN_TT_RegisterScheduleSyncCallback(),
0130   HAL_FDCAN_TT_RegisterTimeMarkCallback(), HAL_FDCAN_TT_RegisterStopWatchCallback() and
0131   HAL_FDCAN_TT_RegisterGlobalTimeCallback().
0132 
0133   Use function HAL_FDCAN_UnRegisterCallback() to reset a callback to the default
0134   weak function.
0135   HAL_FDCAN_UnRegisterCallback takes as parameters the HAL peripheral handle,
0136   and the Callback ID.
0137   This function allows to reset following callbacks:
0138     (+) TxFifoEmptyCallback          : Tx Fifo Empty Callback.
0139     (+) RxBufferNewMessageCallback   : Rx Buffer New Message Callback.
0140     (+) HighPriorityMessageCallback  : High Priority Message Callback.
0141     (+) TimestampWraparoundCallback  : Timestamp Wraparound Callback.
0142     (+) TimeoutOccurredCallback      : Timeout Occurred Callback.
0143     (+) ErrorCallback                : Error Callback.
0144     (+) MspInitCallback              : FDCAN MspInit.
0145     (+) MspDeInitCallback            : FDCAN MspDeInit.
0146 
0147   For specific callbacks ClockCalibrationCallback, TxEventFifoCallback, RxFifo0Callback,
0148   RxFifo1Callback, TxBufferCompleteCallback, TxBufferAbortCallback, TT_ScheduleSyncCallback,
0149   TT_TimeMarkCallback, TT_StopWatchCallback and TT_GlobalTimeCallback, use dedicated
0150   register callbacks: respectively HAL_FDCAN_UnRegisterClockCalibrationCallback(),
0151   HAL_FDCAN_UnRegisterTxEventFifoCallback(), HAL_FDCAN_UnRegisterRxFifo0Callback(),
0152   HAL_FDCAN_UnRegisterRxFifo1Callback(), HAL_FDCAN_UnRegisterTxBufferCompleCallback(),
0153   HAL_FDCAN_UnRegisterTxBufferAbortCallback(), HAL_FDCAN_UnRegisterErrorStatusCallback(),
0154   HAL_FDCAN_TT_UnRegisterScheduleSyncCallback(), HAL_FDCAN_TT_UnRegisterTimeMarkCallback(),
0155   HAL_FDCAN_TT_UnRegisterStopWatchCallback() and HAL_FDCAN_TT_UnRegisterGlobalTimeCallback().
0156 
0157   By default, after the HAL_FDCAN_Init() and when the state is HAL_FDCAN_STATE_RESET,
0158   all callbacks are set to the corresponding weak functions:
0159   examples HAL_FDCAN_ErrorCallback().
0160   Exception done for MspInit and MspDeInit functions that are
0161   reset to the legacy weak function in the HAL_FDCAN_Init()/ HAL_FDCAN_DeInit() only when
0162   these callbacks are null (not registered beforehand).
0163   if not, MspInit or MspDeInit are not null, the HAL_FDCAN_Init()/ HAL_FDCAN_DeInit()
0164   keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
0165 
0166   Callbacks can be registered/unregistered in HAL_FDCAN_STATE_READY state only.
0167   Exception done MspInit/MspDeInit that can be registered/unregistered
0168   in HAL_FDCAN_STATE_READY or HAL_FDCAN_STATE_RESET state,
0169   thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
0170   In that case first register the MspInit/MspDeInit user callbacks
0171   using HAL_FDCAN_RegisterCallback() before calling HAL_FDCAN_DeInit()
0172   or HAL_FDCAN_Init() function.
0173 
0174   When The compilation define USE_HAL_FDCAN_REGISTER_CALLBACKS is set to 0 or
0175   not defined, the callback registration feature is not available and all callbacks
0176   are set to the corresponding weak functions.
0177 
0178   @endverbatim
0179   ******************************************************************************
0180   */
0181 
0182 /* Includes ------------------------------------------------------------------*/
0183 #include "stm32h7xx_hal.h"
0184 
0185 #if defined(FDCAN1)
0186 
0187 /** @addtogroup STM32H7xx_HAL_Driver
0188   * @{
0189   */
0190 
0191 /** @defgroup FDCAN FDCAN
0192   * @ingroup RTEMSBSPsARMSTM32H7
0193   * @brief FDCAN HAL module driver
0194   * @{
0195   */
0196 
0197 #ifdef HAL_FDCAN_MODULE_ENABLED
0198 
0199 /* Private typedef -----------------------------------------------------------*/
0200 /* Private define ------------------------------------------------------------*/
0201 /** @addtogroup FDCAN_Private_Constants
0202   * @{
0203   */
0204 #define FDCAN_TIMEOUT_VALUE 10U
0205 #define FDCAN_TIMEOUT_COUNT 50U
0206 
0207 #define FDCAN_TX_EVENT_FIFO_MASK (FDCAN_IR_TEFL | FDCAN_IR_TEFF | FDCAN_IR_TEFW | FDCAN_IR_TEFN)
0208 #define FDCAN_RX_FIFO0_MASK (FDCAN_IR_RF0L | FDCAN_IR_RF0F | FDCAN_IR_RF0W | FDCAN_IR_RF0N)
0209 #define FDCAN_RX_FIFO1_MASK (FDCAN_IR_RF1L | FDCAN_IR_RF1F | FDCAN_IR_RF1W | FDCAN_IR_RF1N)
0210 #define FDCAN_ERROR_MASK (FDCAN_IR_ELO | FDCAN_IR_WDI | FDCAN_IR_PEA | FDCAN_IR_PED | FDCAN_IR_ARA)
0211 #define FDCAN_ERROR_STATUS_MASK (FDCAN_IR_EP | FDCAN_IR_EW | FDCAN_IR_BO)
0212 #define FDCAN_TT_SCHEDULE_SYNC_MASK (FDCAN_TTIR_SBC | FDCAN_TTIR_SMC | FDCAN_TTIR_CSM | FDCAN_TTIR_SOG)
0213 #define FDCAN_TT_TIME_MARK_MASK (FDCAN_TTIR_RTMI | FDCAN_TTIR_TTMI)
0214 #define FDCAN_TT_GLOBAL_TIME_MASK (FDCAN_TTIR_GTW | FDCAN_TTIR_GTD)
0215 #define FDCAN_TT_DISTURBING_ERROR_MASK (FDCAN_TTIR_GTE | FDCAN_TTIR_TXU | FDCAN_TTIR_TXO | \
0216                                         FDCAN_TTIR_SE1 | FDCAN_TTIR_SE2 | FDCAN_TTIR_ELC)
0217 #define FDCAN_TT_FATAL_ERROR_MASK (FDCAN_TTIR_IWT | FDCAN_TTIR_WT | FDCAN_TTIR_AW | FDCAN_TTIR_CER)
0218 
0219 #define FDCAN_ELEMENT_MASK_STDID ((uint32_t)0x1FFC0000U) /* Standard Identifier         */
0220 #define FDCAN_ELEMENT_MASK_EXTID ((uint32_t)0x1FFFFFFFU) /* Extended Identifier         */
0221 #define FDCAN_ELEMENT_MASK_RTR   ((uint32_t)0x20000000U) /* Remote Transmission Request */
0222 #define FDCAN_ELEMENT_MASK_XTD   ((uint32_t)0x40000000U) /* Extended Identifier         */
0223 #define FDCAN_ELEMENT_MASK_ESI   ((uint32_t)0x80000000U) /* Error State Indicator       */
0224 #define FDCAN_ELEMENT_MASK_TS    ((uint32_t)0x0000FFFFU) /* Timestamp                   */
0225 #define FDCAN_ELEMENT_MASK_DLC   ((uint32_t)0x000F0000U) /* Data Length Code            */
0226 #define FDCAN_ELEMENT_MASK_BRS   ((uint32_t)0x00100000U) /* Bit Rate Switch             */
0227 #define FDCAN_ELEMENT_MASK_FDF   ((uint32_t)0x00200000U) /* FD Format                   */
0228 #define FDCAN_ELEMENT_MASK_EFC   ((uint32_t)0x00800000U) /* Event FIFO Control          */
0229 #define FDCAN_ELEMENT_MASK_MM    ((uint32_t)0xFF000000U) /* Message Marker              */
0230 #define FDCAN_ELEMENT_MASK_FIDX  ((uint32_t)0x7F000000U) /* Filter Index                */
0231 #define FDCAN_ELEMENT_MASK_ANMF  ((uint32_t)0x80000000U) /* Accepted Non-matching Frame */
0232 #define FDCAN_ELEMENT_MASK_ET    ((uint32_t)0x00C00000U) /* Event type                  */
0233 
0234 #define FDCAN_MESSAGE_RAM_SIZE 0x2800U
0235 #define FDCAN_MESSAGE_RAM_END_ADDRESS (SRAMCAN_BASE + FDCAN_MESSAGE_RAM_SIZE - 0x4U) /* Message RAM width is 4 Bytes */
0236 
0237 /**
0238   * @}
0239   */
0240 
0241 /* Private macro -------------------------------------------------------------*/
0242 /* Private variables ---------------------------------------------------------*/
0243 /** @addtogroup FDCAN_Private_Variables
0244   * @{
0245   */
0246 static const uint8_t DLCtoBytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64};
0247 /**
0248   * @}
0249   */
0250 
0251 /* Private function prototypes -----------------------------------------------*/
0252 /** @addtogroup FDCAN_Private_Functions_Prototypes
0253   * @{
0254   */
0255 static HAL_StatusTypeDef FDCAN_CalcultateRamBlockAddresses(FDCAN_HandleTypeDef *hfdcan);
0256 static void FDCAN_CopyMessageToRAM(const FDCAN_HandleTypeDef *hfdcan, const FDCAN_TxHeaderTypeDef *pTxHeader,
0257                                    const uint8_t *pTxData, uint32_t BufferIndex);
0258 /**
0259   * @}
0260   */
0261 
0262 /* Exported functions --------------------------------------------------------*/
0263 /** @defgroup FDCAN_Exported_Functions FDCAN Exported Functions
0264   * @ingroup RTEMSBSPsARMSTM32H7
0265   * @{
0266   */
0267 
0268 /** @defgroup FDCAN_Exported_Functions_Group1 Initialization and de-initialization functions
0269   * @ingroup RTEMSBSPsARMSTM32H7
0270   *  @brief    Initialization and Configuration functions
0271   *
0272 @verbatim
0273   ==============================================================================
0274               ##### Initialization and de-initialization functions #####
0275   ==============================================================================
0276     [..]  This section provides functions allowing to:
0277       (+) Initialize and configure the FDCAN.
0278       (+) De-initialize the FDCAN.
0279       (+) Enter FDCAN peripheral in power down mode.
0280       (+) Exit power down mode.
0281       (+) Register callbacks.
0282       (+) Unregister callbacks.
0283 
0284 @endverbatim
0285   * @{
0286   */
0287 
0288 /**
0289   * @brief  Initializes the FDCAN peripheral according to the specified
0290   *         parameters in the FDCAN_InitTypeDef structure.
0291   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
0292   *         the configuration information for the specified FDCAN.
0293   * @retval HAL status
0294   */
0295 HAL_StatusTypeDef HAL_FDCAN_Init(FDCAN_HandleTypeDef *hfdcan)
0296 {
0297   uint32_t tickstart;
0298   HAL_StatusTypeDef status;
0299   const uint32_t CvtEltSize[] = {0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7};
0300 
0301   /* Check FDCAN handle */
0302   if (hfdcan == NULL)
0303   {
0304     return HAL_ERROR;
0305   }
0306 
0307   /* Check FDCAN instance */
0308   if (hfdcan->Instance == FDCAN1)
0309   {
0310     hfdcan->ttcan = (TTCAN_TypeDef *)((uint32_t)hfdcan->Instance + 0x100U);
0311   }
0312 
0313   /* Check function parameters */
0314   assert_param(IS_FDCAN_ALL_INSTANCE(hfdcan->Instance));
0315   assert_param(IS_FDCAN_FRAME_FORMAT(hfdcan->Init.FrameFormat));
0316   assert_param(IS_FDCAN_MODE(hfdcan->Init.Mode));
0317   assert_param(IS_FUNCTIONAL_STATE(hfdcan->Init.AutoRetransmission));
0318   assert_param(IS_FUNCTIONAL_STATE(hfdcan->Init.TransmitPause));
0319   assert_param(IS_FUNCTIONAL_STATE(hfdcan->Init.ProtocolException));
0320   assert_param(IS_FDCAN_NOMINAL_PRESCALER(hfdcan->Init.NominalPrescaler));
0321   assert_param(IS_FDCAN_NOMINAL_SJW(hfdcan->Init.NominalSyncJumpWidth));
0322   assert_param(IS_FDCAN_NOMINAL_TSEG1(hfdcan->Init.NominalTimeSeg1));
0323   assert_param(IS_FDCAN_NOMINAL_TSEG2(hfdcan->Init.NominalTimeSeg2));
0324   if (hfdcan->Init.FrameFormat == FDCAN_FRAME_FD_BRS)
0325   {
0326     assert_param(IS_FDCAN_DATA_PRESCALER(hfdcan->Init.DataPrescaler));
0327     assert_param(IS_FDCAN_DATA_SJW(hfdcan->Init.DataSyncJumpWidth));
0328     assert_param(IS_FDCAN_DATA_TSEG1(hfdcan->Init.DataTimeSeg1));
0329     assert_param(IS_FDCAN_DATA_TSEG2(hfdcan->Init.DataTimeSeg2));
0330   }
0331   assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.StdFiltersNbr, 128U));
0332   assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.ExtFiltersNbr, 64U));
0333   assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.RxFifo0ElmtsNbr, 64U));
0334   if (hfdcan->Init.RxFifo0ElmtsNbr > 0U)
0335   {
0336     assert_param(IS_FDCAN_DATA_SIZE(hfdcan->Init.RxFifo0ElmtSize));
0337   }
0338   assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.RxFifo1ElmtsNbr, 64U));
0339   if (hfdcan->Init.RxFifo1ElmtsNbr > 0U)
0340   {
0341     assert_param(IS_FDCAN_DATA_SIZE(hfdcan->Init.RxFifo1ElmtSize));
0342   }
0343   assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.RxBuffersNbr, 64U));
0344   if (hfdcan->Init.RxBuffersNbr > 0U)
0345   {
0346     assert_param(IS_FDCAN_DATA_SIZE(hfdcan->Init.RxBufferSize));
0347   }
0348   assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.TxEventsNbr, 32U));
0349   assert_param(IS_FDCAN_MAX_VALUE((hfdcan->Init.TxBuffersNbr + hfdcan->Init.TxFifoQueueElmtsNbr), 32U));
0350   if (hfdcan->Init.TxFifoQueueElmtsNbr > 0U)
0351   {
0352     assert_param(IS_FDCAN_TX_FIFO_QUEUE_MODE(hfdcan->Init.TxFifoQueueMode));
0353   }
0354   if ((hfdcan->Init.TxBuffersNbr + hfdcan->Init.TxFifoQueueElmtsNbr) > 0U)
0355   {
0356     assert_param(IS_FDCAN_DATA_SIZE(hfdcan->Init.TxElmtSize));
0357   }
0358 
0359 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
0360   if (hfdcan->State == HAL_FDCAN_STATE_RESET)
0361   {
0362     /* Allocate lock resource and initialize it */
0363     hfdcan->Lock = HAL_UNLOCKED;
0364 
0365     /* Reset callbacks to legacy functions */
0366     hfdcan->ClockCalibrationCallback    = HAL_FDCAN_ClockCalibrationCallback;    /* ClockCalibrationCallback    */
0367     hfdcan->TxEventFifoCallback         = HAL_FDCAN_TxEventFifoCallback;         /* TxEventFifoCallback         */
0368     hfdcan->RxFifo0Callback             = HAL_FDCAN_RxFifo0Callback;             /* RxFifo0Callback             */
0369     hfdcan->RxFifo1Callback             = HAL_FDCAN_RxFifo1Callback;             /* RxFifo1Callback             */
0370     hfdcan->TxFifoEmptyCallback         = HAL_FDCAN_TxFifoEmptyCallback;         /* TxFifoEmptyCallback         */
0371     hfdcan->TxBufferCompleteCallback    = HAL_FDCAN_TxBufferCompleteCallback;    /* TxBufferCompleteCallback    */
0372     hfdcan->TxBufferAbortCallback       = HAL_FDCAN_TxBufferAbortCallback;       /* TxBufferAbortCallback       */
0373     hfdcan->RxBufferNewMessageCallback  = HAL_FDCAN_RxBufferNewMessageCallback;  /* RxBufferNewMessageCallback  */
0374     hfdcan->HighPriorityMessageCallback = HAL_FDCAN_HighPriorityMessageCallback; /* HighPriorityMessageCallback */
0375     hfdcan->TimestampWraparoundCallback = HAL_FDCAN_TimestampWraparoundCallback; /* TimestampWraparoundCallback */
0376     hfdcan->TimeoutOccurredCallback     = HAL_FDCAN_TimeoutOccurredCallback;     /* TimeoutOccurredCallback     */
0377     hfdcan->ErrorCallback               = HAL_FDCAN_ErrorCallback;               /* ErrorCallback               */
0378     hfdcan->ErrorStatusCallback         = HAL_FDCAN_ErrorStatusCallback;         /* ErrorStatusCallback         */
0379     hfdcan->TT_ScheduleSyncCallback     = HAL_FDCAN_TT_ScheduleSyncCallback;     /* TT_ScheduleSyncCallback     */
0380     hfdcan->TT_TimeMarkCallback         = HAL_FDCAN_TT_TimeMarkCallback;         /* TT_TimeMarkCallback         */
0381     hfdcan->TT_StopWatchCallback        = HAL_FDCAN_TT_StopWatchCallback;        /* TT_StopWatchCallback        */
0382     hfdcan->TT_GlobalTimeCallback       = HAL_FDCAN_TT_GlobalTimeCallback;       /* TT_GlobalTimeCallback       */
0383 
0384     if (hfdcan->MspInitCallback == NULL)
0385     {
0386       hfdcan->MspInitCallback = HAL_FDCAN_MspInit;  /* Legacy weak MspInit */
0387     }
0388 
0389     /* Init the low level hardware: CLOCK, NVIC */
0390     hfdcan->MspInitCallback(hfdcan);
0391   }
0392 #else
0393   if (hfdcan->State == HAL_FDCAN_STATE_RESET)
0394   {
0395     /* Allocate lock resource and initialize it */
0396     hfdcan->Lock = HAL_UNLOCKED;
0397 
0398     /* Init the low level hardware: CLOCK, NVIC */
0399     HAL_FDCAN_MspInit(hfdcan);
0400   }
0401 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
0402 
0403   /* Exit from Sleep mode */
0404   CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CSR);
0405 
0406   /* Get tick */
0407   tickstart = HAL_GetTick();
0408 
0409   /* Check Sleep mode acknowledge */
0410   while ((hfdcan->Instance->CCCR & FDCAN_CCCR_CSA) == FDCAN_CCCR_CSA)
0411   {
0412     if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE)
0413     {
0414       /* Update error code */
0415       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
0416 
0417       /* Change FDCAN state */
0418       hfdcan->State = HAL_FDCAN_STATE_ERROR;
0419 
0420       return HAL_ERROR;
0421     }
0422   }
0423 
0424   /* Request initialisation */
0425   SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT);
0426 
0427   /* Get tick */
0428   tickstart = HAL_GetTick();
0429 
0430   /* Wait until the INIT bit into CCCR register is set */
0431   while ((hfdcan->Instance->CCCR & FDCAN_CCCR_INIT) == 0U)
0432   {
0433     /* Check for the Timeout */
0434     if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE)
0435     {
0436       /* Update error code */
0437       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
0438 
0439       /* Change FDCAN state */
0440       hfdcan->State = HAL_FDCAN_STATE_ERROR;
0441 
0442       return HAL_ERROR;
0443     }
0444   }
0445 
0446   /* Enable configuration change */
0447   SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CCE);
0448 
0449   /* Set the no automatic retransmission */
0450   if (hfdcan->Init.AutoRetransmission == ENABLE)
0451   {
0452     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_DAR);
0453   }
0454   else
0455   {
0456     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_DAR);
0457   }
0458 
0459   /* Set the transmit pause feature */
0460   if (hfdcan->Init.TransmitPause == ENABLE)
0461   {
0462     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_TXP);
0463   }
0464   else
0465   {
0466     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_TXP);
0467   }
0468 
0469   /* Set the Protocol Exception Handling */
0470   if (hfdcan->Init.ProtocolException == ENABLE)
0471   {
0472     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_PXHD);
0473   }
0474   else
0475   {
0476     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_PXHD);
0477   }
0478 
0479   /* Set FDCAN Frame Format */
0480   MODIFY_REG(hfdcan->Instance->CCCR, FDCAN_FRAME_FD_BRS, hfdcan->Init.FrameFormat);
0481 
0482   /* Reset FDCAN Operation Mode */
0483   CLEAR_BIT(hfdcan->Instance->CCCR, (FDCAN_CCCR_TEST | FDCAN_CCCR_MON | FDCAN_CCCR_ASM));
0484   CLEAR_BIT(hfdcan->Instance->TEST, FDCAN_TEST_LBCK);
0485 
0486   /* Set FDCAN Operating Mode:
0487                | Normal | Restricted |    Bus     | Internal | External
0488                |        | Operation  | Monitoring | LoopBack | LoopBack
0489      CCCR.TEST |   0    |     0      |     0      |    1     |    1
0490      CCCR.MON  |   0    |     0      |     1      |    1     |    0
0491      TEST.LBCK |   0    |     0      |     0      |    1     |    1
0492      CCCR.ASM  |   0    |     1      |     0      |    0     |    0
0493   */
0494   if (hfdcan->Init.Mode == FDCAN_MODE_RESTRICTED_OPERATION)
0495   {
0496     /* Enable Restricted Operation mode */
0497     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_ASM);
0498   }
0499   else if (hfdcan->Init.Mode != FDCAN_MODE_NORMAL)
0500   {
0501     if (hfdcan->Init.Mode != FDCAN_MODE_BUS_MONITORING)
0502     {
0503       /* Enable write access to TEST register */
0504       SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_TEST);
0505 
0506       /* Enable LoopBack mode */
0507       SET_BIT(hfdcan->Instance->TEST, FDCAN_TEST_LBCK);
0508 
0509       if (hfdcan->Init.Mode == FDCAN_MODE_INTERNAL_LOOPBACK)
0510       {
0511         SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_MON);
0512       }
0513     }
0514     else
0515     {
0516       /* Enable bus monitoring mode */
0517       SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_MON);
0518     }
0519   }
0520   else
0521   {
0522     /* Nothing to do: normal mode */
0523   }
0524 
0525   /* Set the nominal bit timing register */
0526   hfdcan->Instance->NBTP = ((((uint32_t)hfdcan->Init.NominalSyncJumpWidth - 1U) << FDCAN_NBTP_NSJW_Pos) | \
0527                             (((uint32_t)hfdcan->Init.NominalTimeSeg1 - 1U) << FDCAN_NBTP_NTSEG1_Pos)    | \
0528                             (((uint32_t)hfdcan->Init.NominalTimeSeg2 - 1U) << FDCAN_NBTP_NTSEG2_Pos)    | \
0529                             (((uint32_t)hfdcan->Init.NominalPrescaler - 1U) << FDCAN_NBTP_NBRP_Pos));
0530 
0531   /* If FD operation with BRS is selected, set the data bit timing register */
0532   if (hfdcan->Init.FrameFormat == FDCAN_FRAME_FD_BRS)
0533   {
0534     hfdcan->Instance->DBTP = ((((uint32_t)hfdcan->Init.DataSyncJumpWidth - 1U) << FDCAN_DBTP_DSJW_Pos)  | \
0535                               (((uint32_t)hfdcan->Init.DataTimeSeg1 - 1U) << FDCAN_DBTP_DTSEG1_Pos)     | \
0536                               (((uint32_t)hfdcan->Init.DataTimeSeg2 - 1U) << FDCAN_DBTP_DTSEG2_Pos)     | \
0537                               (((uint32_t)hfdcan->Init.DataPrescaler - 1U) << FDCAN_DBTP_DBRP_Pos));
0538   }
0539 
0540   if (hfdcan->Init.TxFifoQueueElmtsNbr > 0U)
0541   {
0542     /* Select between Tx FIFO and Tx Queue operation modes */
0543     SET_BIT(hfdcan->Instance->TXBC, hfdcan->Init.TxFifoQueueMode);
0544   }
0545 
0546   /* Configure Tx element size */
0547   if ((hfdcan->Init.TxBuffersNbr + hfdcan->Init.TxFifoQueueElmtsNbr) > 0U)
0548   {
0549     MODIFY_REG(hfdcan->Instance->TXESC, FDCAN_TXESC_TBDS, CvtEltSize[hfdcan->Init.TxElmtSize]);
0550   }
0551 
0552   /* Configure Rx FIFO 0 element size */
0553   if (hfdcan->Init.RxFifo0ElmtsNbr > 0U)
0554   {
0555     MODIFY_REG(hfdcan->Instance->RXESC, FDCAN_RXESC_F0DS,
0556                (CvtEltSize[hfdcan->Init.RxFifo0ElmtSize] << FDCAN_RXESC_F0DS_Pos));
0557   }
0558 
0559   /* Configure Rx FIFO 1 element size */
0560   if (hfdcan->Init.RxFifo1ElmtsNbr > 0U)
0561   {
0562     MODIFY_REG(hfdcan->Instance->RXESC, FDCAN_RXESC_F1DS,
0563                (CvtEltSize[hfdcan->Init.RxFifo1ElmtSize] << FDCAN_RXESC_F1DS_Pos));
0564   }
0565 
0566   /* Configure Rx buffer element size */
0567   if (hfdcan->Init.RxBuffersNbr > 0U)
0568   {
0569     MODIFY_REG(hfdcan->Instance->RXESC, FDCAN_RXESC_RBDS,
0570                (CvtEltSize[hfdcan->Init.RxBufferSize] << FDCAN_RXESC_RBDS_Pos));
0571   }
0572 
0573   /* By default operation mode is set to Event-driven communication.
0574      If Time-triggered communication is needed, user should call the
0575      HAL_FDCAN_TT_ConfigOperation function just after the HAL_FDCAN_Init */
0576   if (hfdcan->Instance == FDCAN1)
0577   {
0578     CLEAR_BIT(hfdcan->ttcan->TTOCF, FDCAN_TTOCF_OM);
0579   }
0580 
0581   /* Initialize the Latest Tx FIFO/Queue request buffer index */
0582   hfdcan->LatestTxFifoQRequest = 0U;
0583 
0584   /* Initialize the error code */
0585   hfdcan->ErrorCode = HAL_FDCAN_ERROR_NONE;
0586 
0587   /* Initialize the FDCAN state */
0588   hfdcan->State = HAL_FDCAN_STATE_READY;
0589 
0590   /* Calculate each RAM block address */
0591   status = FDCAN_CalcultateRamBlockAddresses(hfdcan);
0592 
0593   /* Return function status */
0594   return status;
0595 }
0596 
0597 /**
0598   * @brief  Deinitializes the FDCAN peripheral registers to their default reset values.
0599   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
0600   *         the configuration information for the specified FDCAN.
0601   * @retval HAL status
0602   */
0603 HAL_StatusTypeDef HAL_FDCAN_DeInit(FDCAN_HandleTypeDef *hfdcan)
0604 {
0605   /* Check FDCAN handle */
0606   if (hfdcan == NULL)
0607   {
0608     return HAL_ERROR;
0609   }
0610 
0611   /* Check function parameters */
0612   assert_param(IS_FDCAN_ALL_INSTANCE(hfdcan->Instance));
0613 
0614   /* Stop the FDCAN module: return value is voluntary ignored */
0615   (void)HAL_FDCAN_Stop(hfdcan);
0616 
0617   /* Disable Interrupt lines */
0618   CLEAR_BIT(hfdcan->Instance->ILE, (FDCAN_INTERRUPT_LINE0 | FDCAN_INTERRUPT_LINE1));
0619 
0620 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
0621   if (hfdcan->MspDeInitCallback == NULL)
0622   {
0623     hfdcan->MspDeInitCallback = HAL_FDCAN_MspDeInit; /* Legacy weak MspDeInit */
0624   }
0625 
0626   /* DeInit the low level hardware: CLOCK, NVIC */
0627   hfdcan->MspDeInitCallback(hfdcan);
0628 #else
0629   /* DeInit the low level hardware: CLOCK, NVIC */
0630   HAL_FDCAN_MspDeInit(hfdcan);
0631 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
0632 
0633   /* Reset the FDCAN ErrorCode */
0634   hfdcan->ErrorCode = HAL_FDCAN_ERROR_NONE;
0635 
0636   /* Change FDCAN state */
0637   hfdcan->State = HAL_FDCAN_STATE_RESET;
0638 
0639   /* Return function status */
0640   return HAL_OK;
0641 }
0642 
0643 /**
0644   * @brief  Initializes the FDCAN MSP.
0645   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
0646   *         the configuration information for the specified FDCAN.
0647   * @retval None
0648   */
0649 __weak void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef *hfdcan)
0650 {
0651   /* Prevent unused argument(s) compilation warning */
0652   UNUSED(hfdcan);
0653   /* NOTE: This function Should not be modified, when the callback is needed,
0654             the HAL_FDCAN_MspInit could be implemented in the user file
0655    */
0656 }
0657 
0658 /**
0659   * @brief  DeInitializes the FDCAN MSP.
0660   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
0661   *         the configuration information for the specified FDCAN.
0662   * @retval None
0663   */
0664 __weak void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef *hfdcan)
0665 {
0666   /* Prevent unused argument(s) compilation warning */
0667   UNUSED(hfdcan);
0668   /* NOTE: This function Should not be modified, when the callback is needed,
0669             the HAL_FDCAN_MspDeInit could be implemented in the user file
0670    */
0671 }
0672 
0673 /**
0674   * @brief  Enter FDCAN peripheral in sleep mode.
0675   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
0676   *         the configuration information for the specified FDCAN.
0677   * @retval HAL status
0678   */
0679 HAL_StatusTypeDef HAL_FDCAN_EnterPowerDownMode(FDCAN_HandleTypeDef *hfdcan)
0680 {
0681   uint32_t tickstart;
0682 
0683   /* Request clock stop */
0684   SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CSR);
0685 
0686   /* Get tick */
0687   tickstart = HAL_GetTick();
0688 
0689   /* Wait until FDCAN is ready for power down */
0690   while ((hfdcan->Instance->CCCR & FDCAN_CCCR_CSA) == 0U)
0691   {
0692     if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE)
0693     {
0694       /* Update error code */
0695       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
0696 
0697       /* Change FDCAN state */
0698       hfdcan->State = HAL_FDCAN_STATE_ERROR;
0699 
0700       return HAL_ERROR;
0701     }
0702   }
0703 
0704   /* Return function status */
0705   return HAL_OK;
0706 }
0707 
0708 /**
0709   * @brief  Exit power down mode.
0710   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
0711   *         the configuration information for the specified FDCAN.
0712   * @retval HAL status
0713   */
0714 HAL_StatusTypeDef HAL_FDCAN_ExitPowerDownMode(FDCAN_HandleTypeDef *hfdcan)
0715 {
0716   uint32_t tickstart;
0717 
0718   /* Reset clock stop request */
0719   CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CSR);
0720 
0721   /* Get tick */
0722   tickstart = HAL_GetTick();
0723 
0724   /* Wait until FDCAN exits sleep mode */
0725   while ((hfdcan->Instance->CCCR & FDCAN_CCCR_CSA) == FDCAN_CCCR_CSA)
0726   {
0727     if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE)
0728     {
0729       /* Update error code */
0730       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
0731 
0732       /* Change FDCAN state */
0733       hfdcan->State = HAL_FDCAN_STATE_ERROR;
0734 
0735       return HAL_ERROR;
0736     }
0737   }
0738 
0739   /* Enter normal operation */
0740   CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT);
0741 
0742   /* Return function status */
0743   return HAL_OK;
0744 }
0745 
0746 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
0747 /**
0748   * @brief  Register a FDCAN CallBack.
0749   *         To be used instead of the weak predefined callback
0750   * @param  hfdcan pointer to a FDCAN_HandleTypeDef structure that contains
0751   *         the configuration information for FDCAN module
0752   * @param  CallbackID ID of the callback to be registered
0753   *         This parameter can be one of the following values:
0754   *           @arg @ref HAL_FDCAN_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty callback ID
0755   *           @arg @ref HAL_FDCAN_RX_BUFFER_NEW_MSG_CB_ID Rx buffer new message callback ID
0756   *           @arg @ref HAL_FDCAN_HIGH_PRIO_MESSAGE_CB_ID High priority message callback ID
0757   *           @arg @ref HAL_FDCAN_TIMESTAMP_WRAPAROUND_CB_ID Timestamp wraparound callback ID
0758   *           @arg @ref HAL_FDCAN_TIMEOUT_OCCURRED_CB_ID Timeout occurred callback ID
0759   *           @arg @ref HAL_FDCAN_ERROR_CALLBACK_CB_ID Error callback ID
0760   *           @arg @ref HAL_FDCAN_MSPINIT_CB_ID MspInit callback ID
0761   *           @arg @ref HAL_FDCAN_MSPDEINIT_CB_ID MspDeInit callback ID
0762   * @param  pCallback pointer to the Callback function
0763   * @retval HAL status
0764   */
0765 HAL_StatusTypeDef HAL_FDCAN_RegisterCallback(FDCAN_HandleTypeDef *hfdcan, HAL_FDCAN_CallbackIDTypeDef CallbackID,
0766                                              void (* pCallback)(FDCAN_HandleTypeDef *_hFDCAN))
0767 {
0768   HAL_StatusTypeDef status = HAL_OK;
0769 
0770   if (pCallback == NULL)
0771   {
0772     /* Update the error code */
0773     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
0774 
0775     return HAL_ERROR;
0776   }
0777 
0778   if (hfdcan->State == HAL_FDCAN_STATE_READY)
0779   {
0780     switch (CallbackID)
0781     {
0782       case HAL_FDCAN_TX_FIFO_EMPTY_CB_ID :
0783         hfdcan->TxFifoEmptyCallback = pCallback;
0784         break;
0785 
0786       case HAL_FDCAN_RX_BUFFER_NEW_MSG_CB_ID :
0787         hfdcan->RxBufferNewMessageCallback = pCallback;
0788         break;
0789 
0790       case HAL_FDCAN_HIGH_PRIO_MESSAGE_CB_ID :
0791         hfdcan->HighPriorityMessageCallback = pCallback;
0792         break;
0793 
0794       case HAL_FDCAN_TIMESTAMP_WRAPAROUND_CB_ID :
0795         hfdcan->TimestampWraparoundCallback = pCallback;
0796         break;
0797 
0798       case HAL_FDCAN_TIMEOUT_OCCURRED_CB_ID :
0799         hfdcan->TimeoutOccurredCallback = pCallback;
0800         break;
0801 
0802       case HAL_FDCAN_ERROR_CALLBACK_CB_ID :
0803         hfdcan->ErrorCallback = pCallback;
0804         break;
0805 
0806       case HAL_FDCAN_MSPINIT_CB_ID :
0807         hfdcan->MspInitCallback = pCallback;
0808         break;
0809 
0810       case HAL_FDCAN_MSPDEINIT_CB_ID :
0811         hfdcan->MspDeInitCallback = pCallback;
0812         break;
0813 
0814       default :
0815         /* Update the error code */
0816         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
0817 
0818         /* Return error status */
0819         status =  HAL_ERROR;
0820         break;
0821     }
0822   }
0823   else if (hfdcan->State == HAL_FDCAN_STATE_RESET)
0824   {
0825     switch (CallbackID)
0826     {
0827       case HAL_FDCAN_MSPINIT_CB_ID :
0828         hfdcan->MspInitCallback = pCallback;
0829         break;
0830 
0831       case HAL_FDCAN_MSPDEINIT_CB_ID :
0832         hfdcan->MspDeInitCallback = pCallback;
0833         break;
0834 
0835       default :
0836         /* Update the error code */
0837         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
0838 
0839         /* Return error status */
0840         status =  HAL_ERROR;
0841         break;
0842     }
0843   }
0844   else
0845   {
0846     /* Update the error code */
0847     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
0848 
0849     /* Return error status */
0850     status =  HAL_ERROR;
0851   }
0852 
0853   return status;
0854 }
0855 
0856 /**
0857   * @brief  Unregister a FDCAN CallBack.
0858   *         FDCAN callback is redirected to the weak predefined callback
0859   * @param  hfdcan pointer to a FDCAN_HandleTypeDef structure that contains
0860   *         the configuration information for FDCAN module
0861   * @param  CallbackID ID of the callback to be unregistered
0862   *         This parameter can be one of the following values:
0863   *           @arg @ref HAL_FDCAN_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty callback ID
0864   *           @arg @ref HAL_FDCAN_RX_BUFFER_NEW_MSG_CB_ID Rx buffer new message callback ID
0865   *           @arg @ref HAL_FDCAN_HIGH_PRIO_MESSAGE_CB_ID High priority message callback ID
0866   *           @arg @ref HAL_FDCAN_TIMESTAMP_WRAPAROUND_CB_ID Timestamp wraparound callback ID
0867   *           @arg @ref HAL_FDCAN_TIMEOUT_OCCURRED_CB_ID Timeout occurred callback ID
0868   *           @arg @ref HAL_FDCAN_ERROR_CALLBACK_CB_ID Error callback ID
0869   *           @arg @ref HAL_FDCAN_MSPINIT_CB_ID MspInit callback ID
0870   *           @arg @ref HAL_FDCAN_MSPDEINIT_CB_ID MspDeInit callback ID
0871   * @retval HAL status
0872   */
0873 HAL_StatusTypeDef HAL_FDCAN_UnRegisterCallback(FDCAN_HandleTypeDef *hfdcan, HAL_FDCAN_CallbackIDTypeDef CallbackID)
0874 {
0875   HAL_StatusTypeDef status = HAL_OK;
0876 
0877   if (hfdcan->State == HAL_FDCAN_STATE_READY)
0878   {
0879     switch (CallbackID)
0880     {
0881       case HAL_FDCAN_TX_FIFO_EMPTY_CB_ID :
0882         hfdcan->TxFifoEmptyCallback = HAL_FDCAN_TxFifoEmptyCallback;
0883         break;
0884 
0885       case HAL_FDCAN_RX_BUFFER_NEW_MSG_CB_ID :
0886         hfdcan->RxBufferNewMessageCallback = HAL_FDCAN_RxBufferNewMessageCallback;
0887         break;
0888 
0889       case HAL_FDCAN_HIGH_PRIO_MESSAGE_CB_ID :
0890         hfdcan->HighPriorityMessageCallback = HAL_FDCAN_HighPriorityMessageCallback;
0891         break;
0892 
0893       case HAL_FDCAN_TIMESTAMP_WRAPAROUND_CB_ID :
0894         hfdcan->TimestampWraparoundCallback = HAL_FDCAN_TimestampWraparoundCallback;
0895         break;
0896 
0897       case HAL_FDCAN_TIMEOUT_OCCURRED_CB_ID :
0898         hfdcan->TimeoutOccurredCallback = HAL_FDCAN_TimeoutOccurredCallback;
0899         break;
0900 
0901       case HAL_FDCAN_ERROR_CALLBACK_CB_ID :
0902         hfdcan->ErrorCallback = HAL_FDCAN_ErrorCallback;
0903         break;
0904 
0905       case HAL_FDCAN_MSPINIT_CB_ID :
0906         hfdcan->MspInitCallback = HAL_FDCAN_MspInit;
0907         break;
0908 
0909       case HAL_FDCAN_MSPDEINIT_CB_ID :
0910         hfdcan->MspDeInitCallback = HAL_FDCAN_MspDeInit;
0911         break;
0912 
0913       default :
0914         /* Update the error code */
0915         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
0916 
0917         /* Return error status */
0918         status =  HAL_ERROR;
0919         break;
0920     }
0921   }
0922   else if (hfdcan->State == HAL_FDCAN_STATE_RESET)
0923   {
0924     switch (CallbackID)
0925     {
0926       case HAL_FDCAN_MSPINIT_CB_ID :
0927         hfdcan->MspInitCallback = HAL_FDCAN_MspInit;
0928         break;
0929 
0930       case HAL_FDCAN_MSPDEINIT_CB_ID :
0931         hfdcan->MspDeInitCallback = HAL_FDCAN_MspDeInit;
0932         break;
0933 
0934       default :
0935         /* Update the error code */
0936         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
0937 
0938         /* Return error status */
0939         status =  HAL_ERROR;
0940         break;
0941     }
0942   }
0943   else
0944   {
0945     /* Update the error code */
0946     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
0947 
0948     /* Return error status */
0949     status =  HAL_ERROR;
0950   }
0951 
0952   return status;
0953 }
0954 
0955 /**
0956   * @brief  Register Clock Calibration FDCAN Callback
0957   *         To be used instead of the weak HAL_FDCAN_ClockCalibrationCallback() predefined callback
0958   * @param  hfdcan FDCAN handle
0959   * @param  pCallback pointer to the Clock Calibration Callback function
0960   * @retval HAL status
0961   */
0962 HAL_StatusTypeDef HAL_FDCAN_RegisterClockCalibrationCallback(FDCAN_HandleTypeDef *hfdcan,
0963                                                              pFDCAN_ClockCalibrationCallbackTypeDef pCallback)
0964 {
0965   HAL_StatusTypeDef status = HAL_OK;
0966 
0967   if (pCallback == NULL)
0968   {
0969     /* Update the error code */
0970     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
0971     return HAL_ERROR;
0972   }
0973 
0974   if (hfdcan->State == HAL_FDCAN_STATE_READY)
0975   {
0976     hfdcan->ClockCalibrationCallback = pCallback;
0977   }
0978   else
0979   {
0980     /* Update the error code */
0981     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
0982 
0983     /* Return error status */
0984     status =  HAL_ERROR;
0985   }
0986 
0987   return status;
0988 }
0989 
0990 /**
0991   * @brief  UnRegister the Clock Calibration FDCAN Callback
0992   *         Clock Calibration FDCAN Callback is redirected to the weak
0993   *         HAL_FDCAN_ClockCalibrationCallback() predefined callback
0994   * @param  hfdcan FDCAN handle
0995   * @retval HAL status
0996   */
0997 HAL_StatusTypeDef HAL_FDCAN_UnRegisterClockCalibrationCallback(FDCAN_HandleTypeDef *hfdcan)
0998 {
0999   HAL_StatusTypeDef status = HAL_OK;
1000 
1001   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1002   {
1003     hfdcan->ClockCalibrationCallback = HAL_FDCAN_ClockCalibrationCallback; /* Legacy weak ClockCalibrationCallback  */
1004   }
1005   else
1006   {
1007     /* Update the error code */
1008     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1009 
1010     /* Return error status */
1011     status =  HAL_ERROR;
1012   }
1013 
1014   return status;
1015 }
1016 
1017 /**
1018   * @brief  Register Tx Event Fifo FDCAN Callback
1019   *         To be used instead of the weak HAL_FDCAN_TxEventFifoCallback() predefined callback
1020   * @param  hfdcan FDCAN handle
1021   * @param  pCallback pointer to the Tx Event Fifo Callback function
1022   * @retval HAL status
1023   */
1024 HAL_StatusTypeDef HAL_FDCAN_RegisterTxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan,
1025                                                         pFDCAN_TxEventFifoCallbackTypeDef pCallback)
1026 {
1027   HAL_StatusTypeDef status = HAL_OK;
1028 
1029   if (pCallback == NULL)
1030   {
1031     /* Update the error code */
1032     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1033     return HAL_ERROR;
1034   }
1035 
1036   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1037   {
1038     hfdcan->TxEventFifoCallback = pCallback;
1039   }
1040   else
1041   {
1042     /* Update the error code */
1043     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1044 
1045     /* Return error status */
1046     status =  HAL_ERROR;
1047   }
1048 
1049   return status;
1050 }
1051 
1052 /**
1053   * @brief  UnRegister the Tx Event Fifo FDCAN Callback
1054   *         Tx Event Fifo FDCAN Callback is redirected to the weak HAL_FDCAN_TxEventFifoCallback() predefined callback
1055   * @param  hfdcan FDCAN handle
1056   * @retval HAL status
1057   */
1058 HAL_StatusTypeDef HAL_FDCAN_UnRegisterTxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan)
1059 {
1060   HAL_StatusTypeDef status = HAL_OK;
1061 
1062   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1063   {
1064     hfdcan->TxEventFifoCallback = HAL_FDCAN_TxEventFifoCallback; /* Legacy weak TxEventFifoCallback  */
1065   }
1066   else
1067   {
1068     /* Update the error code */
1069     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1070 
1071     /* Return error status */
1072     status =  HAL_ERROR;
1073   }
1074 
1075   return status;
1076 }
1077 
1078 /**
1079   * @brief  Register Rx Fifo 0 FDCAN Callback
1080   *         To be used instead of the weak HAL_FDCAN_RxFifo0Callback() predefined callback
1081   * @param  hfdcan FDCAN handle
1082   * @param  pCallback pointer to the Rx Fifo 0 Callback function
1083   * @retval HAL status
1084   */
1085 HAL_StatusTypeDef HAL_FDCAN_RegisterRxFifo0Callback(FDCAN_HandleTypeDef *hfdcan,
1086                                                     pFDCAN_RxFifo0CallbackTypeDef pCallback)
1087 {
1088   HAL_StatusTypeDef status = HAL_OK;
1089 
1090   if (pCallback == NULL)
1091   {
1092     /* Update the error code */
1093     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1094     return HAL_ERROR;
1095   }
1096 
1097   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1098   {
1099     hfdcan->RxFifo0Callback = pCallback;
1100   }
1101   else
1102   {
1103     /* Update the error code */
1104     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1105 
1106     /* Return error status */
1107     status =  HAL_ERROR;
1108   }
1109 
1110   return status;
1111 }
1112 
1113 /**
1114   * @brief  UnRegister the Rx Fifo 0 FDCAN Callback
1115   *         Rx Fifo 0 FDCAN Callback is redirected to the weak HAL_FDCAN_RxFifo0Callback() predefined callback
1116   * @param  hfdcan FDCAN handle
1117   * @retval HAL status
1118   */
1119 HAL_StatusTypeDef HAL_FDCAN_UnRegisterRxFifo0Callback(FDCAN_HandleTypeDef *hfdcan)
1120 {
1121   HAL_StatusTypeDef status = HAL_OK;
1122 
1123   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1124   {
1125     hfdcan->RxFifo0Callback = HAL_FDCAN_RxFifo0Callback; /* Legacy weak RxFifo0Callback  */
1126   }
1127   else
1128   {
1129     /* Update the error code */
1130     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1131 
1132     /* Return error status */
1133     status =  HAL_ERROR;
1134   }
1135 
1136   return status;
1137 }
1138 
1139 /**
1140   * @brief  Register Rx Fifo 1 FDCAN Callback
1141   *         To be used instead of the weak HAL_FDCAN_RxFifo1Callback() predefined callback
1142   * @param  hfdcan FDCAN handle
1143   * @param  pCallback pointer to the Rx Fifo 1 Callback function
1144   * @retval HAL status
1145   */
1146 HAL_StatusTypeDef HAL_FDCAN_RegisterRxFifo1Callback(FDCAN_HandleTypeDef *hfdcan,
1147                                                     pFDCAN_RxFifo1CallbackTypeDef pCallback)
1148 {
1149   HAL_StatusTypeDef status = HAL_OK;
1150 
1151   if (pCallback == NULL)
1152   {
1153     /* Update the error code */
1154     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1155     return HAL_ERROR;
1156   }
1157 
1158   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1159   {
1160     hfdcan->RxFifo1Callback = pCallback;
1161   }
1162   else
1163   {
1164     /* Update the error code */
1165     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1166 
1167     /* Return error status */
1168     status =  HAL_ERROR;
1169   }
1170 
1171   return status;
1172 }
1173 
1174 /**
1175   * @brief  UnRegister the Rx Fifo 1 FDCAN Callback
1176   *         Rx Fifo 1 FDCAN Callback is redirected to the weak HAL_FDCAN_RxFifo1Callback() predefined callback
1177   * @param  hfdcan FDCAN handle
1178   * @retval HAL status
1179   */
1180 HAL_StatusTypeDef HAL_FDCAN_UnRegisterRxFifo1Callback(FDCAN_HandleTypeDef *hfdcan)
1181 {
1182   HAL_StatusTypeDef status = HAL_OK;
1183 
1184   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1185   {
1186     hfdcan->RxFifo1Callback = HAL_FDCAN_RxFifo1Callback; /* Legacy weak RxFifo1Callback  */
1187   }
1188   else
1189   {
1190     /* Update the error code */
1191     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1192 
1193     /* Return error status */
1194     status =  HAL_ERROR;
1195   }
1196 
1197   return status;
1198 }
1199 
1200 /**
1201   * @brief  Register Tx Buffer Complete FDCAN Callback
1202   *         To be used instead of the weak HAL_FDCAN_TxBufferCompleteCallback() predefined callback
1203   * @param  hfdcan FDCAN handle
1204   * @param  pCallback pointer to the Tx Buffer Complete Callback function
1205   * @retval HAL status
1206   */
1207 HAL_StatusTypeDef HAL_FDCAN_RegisterTxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan,
1208                                                              pFDCAN_TxBufferCompleteCallbackTypeDef pCallback)
1209 {
1210   HAL_StatusTypeDef status = HAL_OK;
1211 
1212   if (pCallback == NULL)
1213   {
1214     /* Update the error code */
1215     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1216     return HAL_ERROR;
1217   }
1218 
1219   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1220   {
1221     hfdcan->TxBufferCompleteCallback = pCallback;
1222   }
1223   else
1224   {
1225     /* Update the error code */
1226     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1227 
1228     /* Return error status */
1229     status =  HAL_ERROR;
1230   }
1231 
1232   return status;
1233 }
1234 
1235 /**
1236   * @brief  UnRegister the Tx Buffer Complete FDCAN Callback
1237   *         Tx Buffer Complete FDCAN Callback is redirected to
1238   *         the weak HAL_FDCAN_TxBufferCompleteCallback() predefined callback
1239   * @param  hfdcan FDCAN handle
1240   * @retval HAL status
1241   */
1242 HAL_StatusTypeDef HAL_FDCAN_UnRegisterTxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan)
1243 {
1244   HAL_StatusTypeDef status = HAL_OK;
1245 
1246   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1247   {
1248     hfdcan->TxBufferCompleteCallback = HAL_FDCAN_TxBufferCompleteCallback; /* Legacy weak TxBufferCompleteCallback  */
1249   }
1250   else
1251   {
1252     /* Update the error code */
1253     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1254 
1255     /* Return error status */
1256     status =  HAL_ERROR;
1257   }
1258 
1259   return status;
1260 }
1261 
1262 /**
1263   * @brief  Register Tx Buffer Abort FDCAN Callback
1264   *         To be used instead of the weak HAL_FDCAN_TxBufferAbortCallback() predefined callback
1265   * @param  hfdcan FDCAN handle
1266   * @param  pCallback pointer to the Tx Buffer Abort Callback function
1267   * @retval HAL status
1268   */
1269 HAL_StatusTypeDef HAL_FDCAN_RegisterTxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan,
1270                                                           pFDCAN_TxBufferAbortCallbackTypeDef pCallback)
1271 {
1272   HAL_StatusTypeDef status = HAL_OK;
1273 
1274   if (pCallback == NULL)
1275   {
1276     /* Update the error code */
1277     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1278     return HAL_ERROR;
1279   }
1280 
1281   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1282   {
1283     hfdcan->TxBufferAbortCallback = pCallback;
1284   }
1285   else
1286   {
1287     /* Update the error code */
1288     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1289 
1290     /* Return error status */
1291     status =  HAL_ERROR;
1292   }
1293 
1294   return status;
1295 }
1296 
1297 /**
1298   * @brief  UnRegister the Tx Buffer Abort FDCAN Callback
1299   *         Tx Buffer Abort FDCAN Callback is redirected to
1300   *         the weak HAL_FDCAN_TxBufferAbortCallback() predefined callback
1301   * @param  hfdcan FDCAN handle
1302   * @retval HAL status
1303   */
1304 HAL_StatusTypeDef HAL_FDCAN_UnRegisterTxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan)
1305 {
1306   HAL_StatusTypeDef status = HAL_OK;
1307 
1308   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1309   {
1310     hfdcan->TxBufferAbortCallback = HAL_FDCAN_TxBufferAbortCallback; /* Legacy weak TxBufferAbortCallback  */
1311   }
1312   else
1313   {
1314     /* Update the error code */
1315     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1316 
1317     /* Return error status */
1318     status =  HAL_ERROR;
1319   }
1320 
1321   return status;
1322 }
1323 
1324 /**
1325   * @brief  Register Error Status FDCAN Callback
1326   *         To be used instead of the weak HAL_FDCAN_ErrorStatusCallback() predefined callback
1327   * @param  hfdcan FDCAN handle
1328   * @param  pCallback pointer to the Error Status Callback function
1329   * @retval HAL status
1330   */
1331 HAL_StatusTypeDef HAL_FDCAN_RegisterErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan,
1332                                                         pFDCAN_ErrorStatusCallbackTypeDef pCallback)
1333 {
1334   HAL_StatusTypeDef status = HAL_OK;
1335 
1336   if (pCallback == NULL)
1337   {
1338     /* Update the error code */
1339     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1340     return HAL_ERROR;
1341   }
1342 
1343   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1344   {
1345     hfdcan->ErrorStatusCallback = pCallback;
1346   }
1347   else
1348   {
1349     /* Update the error code */
1350     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1351 
1352     /* Return error status */
1353     status =  HAL_ERROR;
1354   }
1355 
1356   return status;
1357 }
1358 
1359 /**
1360   * @brief  UnRegister the Error Status FDCAN Callback
1361   *         Error Status FDCAN Callback is redirected to the weak HAL_FDCAN_ErrorStatusCallback() predefined callback
1362   * @param  hfdcan FDCAN handle
1363   * @retval HAL status
1364   */
1365 HAL_StatusTypeDef HAL_FDCAN_UnRegisterErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan)
1366 {
1367   HAL_StatusTypeDef status = HAL_OK;
1368 
1369   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1370   {
1371     hfdcan->ErrorStatusCallback = HAL_FDCAN_ErrorStatusCallback; /* Legacy weak ErrorStatusCallback  */
1372   }
1373   else
1374   {
1375     /* Update the error code */
1376     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1377 
1378     /* Return error status */
1379     status =  HAL_ERROR;
1380   }
1381 
1382   return status;
1383 }
1384 
1385 /**
1386   * @brief  Register TT Schedule Synchronization FDCAN Callback
1387   *         To be used instead of the weak HAL_FDCAN_TT_ScheduleSyncCallback() predefined callback
1388   * @param  hfdcan FDCAN handle
1389   * @param  pCallback pointer to the TT Schedule Synchronization Callback function
1390   * @retval HAL status
1391   */
1392 HAL_StatusTypeDef HAL_FDCAN_RegisterTTScheduleSyncCallback(FDCAN_HandleTypeDef *hfdcan,
1393                                                            pFDCAN_TT_ScheduleSyncCallbackTypeDef pCallback)
1394 {
1395   HAL_StatusTypeDef status = HAL_OK;
1396 
1397   if (pCallback == NULL)
1398   {
1399     /* Update the error code */
1400     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1401     return HAL_ERROR;
1402   }
1403 
1404   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1405   {
1406     hfdcan->TT_ScheduleSyncCallback = pCallback;
1407   }
1408   else
1409   {
1410     /* Update the error code */
1411     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1412 
1413     /* Return error status */
1414     status =  HAL_ERROR;
1415   }
1416 
1417   return status;
1418 }
1419 
1420 /**
1421   * @brief  UnRegister the TT Schedule Synchronization FDCAN Callback
1422   *         TT Schedule Synchronization Callback is redirected to the weak
1423   *         HAL_FDCAN_TT_ScheduleSyncCallback() predefined callback
1424   * @param  hfdcan FDCAN handle
1425   * @retval HAL status
1426   */
1427 HAL_StatusTypeDef HAL_FDCAN_UnRegisterTTScheduleSyncCallback(FDCAN_HandleTypeDef *hfdcan)
1428 {
1429   HAL_StatusTypeDef status = HAL_OK;
1430 
1431   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1432   {
1433     hfdcan->TT_ScheduleSyncCallback = HAL_FDCAN_TT_ScheduleSyncCallback; /* Legacy weak TT_ScheduleSyncCallback  */
1434   }
1435   else
1436   {
1437     /* Update the error code */
1438     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1439 
1440     /* Return error status */
1441     status =  HAL_ERROR;
1442   }
1443 
1444   return status;
1445 }
1446 
1447 /**
1448   * @brief  Register TT Time Mark FDCAN Callback
1449   *         To be used instead of the weak HAL_FDCAN_TT_TimeMarkCallback() predefined callback
1450   * @param  hfdcan FDCAN handle
1451   * @param  pCallback pointer to the TT Time Mark Callback function
1452   * @retval HAL status
1453   */
1454 HAL_StatusTypeDef HAL_FDCAN_RegisterTTTimeMarkCallback(FDCAN_HandleTypeDef *hfdcan,
1455                                                        pFDCAN_TT_TimeMarkCallbackTypeDef pCallback)
1456 {
1457   HAL_StatusTypeDef status = HAL_OK;
1458 
1459   if (pCallback == NULL)
1460   {
1461     /* Update the error code */
1462     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1463     return HAL_ERROR;
1464   }
1465 
1466   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1467   {
1468     hfdcan->TT_TimeMarkCallback = pCallback;
1469   }
1470   else
1471   {
1472     /* Update the error code */
1473     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1474 
1475     /* Return error status */
1476     status =  HAL_ERROR;
1477   }
1478 
1479   return status;
1480 }
1481 
1482 /**
1483   * @brief  UnRegister the TT Time Mark FDCAN Callback
1484   *         TT Time Mark Callback is redirected to the weak HAL_FDCAN_TT_TimeMarkCallback() predefined callback
1485   * @param  hfdcan FDCAN handle
1486   * @retval HAL status
1487   */
1488 HAL_StatusTypeDef HAL_FDCAN_UnRegisterTTTimeMarkCallback(FDCAN_HandleTypeDef *hfdcan)
1489 {
1490   HAL_StatusTypeDef status = HAL_OK;
1491 
1492   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1493   {
1494     hfdcan->TT_TimeMarkCallback = HAL_FDCAN_TT_TimeMarkCallback; /* Legacy weak TT_TimeMarkCallback  */
1495   }
1496   else
1497   {
1498     /* Update the error code */
1499     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1500 
1501     /* Return error status */
1502     status =  HAL_ERROR;
1503   }
1504 
1505   return status;
1506 }
1507 
1508 /**
1509   * @brief  Register TT Stop Watch FDCAN Callback
1510   *         To be used instead of the weak HAL_FDCAN_TT_StopWatchCallback() predefined callback
1511   * @param  hfdcan FDCAN handle
1512   * @param  pCallback pointer to the TT Stop Watch Callback function
1513   * @retval HAL status
1514   */
1515 HAL_StatusTypeDef HAL_FDCAN_RegisterTTStopWatchCallback(FDCAN_HandleTypeDef *hfdcan,
1516                                                         pFDCAN_TT_StopWatchCallbackTypeDef pCallback)
1517 {
1518   HAL_StatusTypeDef status = HAL_OK;
1519 
1520   if (pCallback == NULL)
1521   {
1522     /* Update the error code */
1523     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1524     return HAL_ERROR;
1525   }
1526 
1527   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1528   {
1529     hfdcan->TT_StopWatchCallback = pCallback;
1530   }
1531   else
1532   {
1533     /* Update the error code */
1534     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1535 
1536     /* Return error status */
1537     status =  HAL_ERROR;
1538   }
1539 
1540   return status;
1541 }
1542 
1543 /**
1544   * @brief  UnRegister the TT Stop Watch FDCAN Callback
1545   *         TT Stop Watch Callback is redirected to the weak HAL_FDCAN_TT_StopWatchCallback() predefined callback
1546   * @param  hfdcan FDCAN handle
1547   * @retval HAL status
1548   */
1549 HAL_StatusTypeDef HAL_FDCAN_UnRegisterTTStopWatchCallback(FDCAN_HandleTypeDef *hfdcan)
1550 {
1551   HAL_StatusTypeDef status = HAL_OK;
1552 
1553   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1554   {
1555     hfdcan->TT_StopWatchCallback = HAL_FDCAN_TT_StopWatchCallback; /* Legacy weak TT_StopWatchCallback  */
1556   }
1557   else
1558   {
1559     /* Update the error code */
1560     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1561 
1562     /* Return error status */
1563     status =  HAL_ERROR;
1564   }
1565 
1566   return status;
1567 }
1568 
1569 /**
1570   * @brief  Register TT Global Time FDCAN Callback
1571   *         To be used instead of the weak HAL_FDCAN_TT_GlobalTimeCallback() predefined callback
1572   * @param  hfdcan FDCAN handle
1573   * @param  pCallback pointer to the TT Global Time Callback function
1574   * @retval HAL status
1575   */
1576 HAL_StatusTypeDef HAL_FDCAN_RegisterTTGlobalTimeCallback(FDCAN_HandleTypeDef *hfdcan,
1577                                                          pFDCAN_TT_GlobalTimeCallbackTypeDef pCallback)
1578 {
1579   HAL_StatusTypeDef status = HAL_OK;
1580 
1581   if (pCallback == NULL)
1582   {
1583     /* Update the error code */
1584     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1585     return HAL_ERROR;
1586   }
1587 
1588   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1589   {
1590     hfdcan->TT_GlobalTimeCallback = pCallback;
1591   }
1592   else
1593   {
1594     /* Update the error code */
1595     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1596 
1597     /* Return error status */
1598     status =  HAL_ERROR;
1599   }
1600 
1601   return status;
1602 }
1603 
1604 /**
1605   * @brief  UnRegister the TT Global Time FDCAN Callback
1606   *         TT Global Time Callback is redirected to the weak HAL_FDCAN_TT_GlobalTimeCallback() predefined callback
1607   * @param  hfdcan FDCAN handle
1608   * @retval HAL status
1609   */
1610 HAL_StatusTypeDef HAL_FDCAN_UnRegisterTTGlobalTimeCallback(FDCAN_HandleTypeDef *hfdcan)
1611 {
1612   HAL_StatusTypeDef status = HAL_OK;
1613 
1614   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1615   {
1616     hfdcan->TT_GlobalTimeCallback = HAL_FDCAN_TT_GlobalTimeCallback; /* Legacy weak TT_GlobalTimeCallback  */
1617   }
1618   else
1619   {
1620     /* Update the error code */
1621     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1622 
1623     /* Return error status */
1624     status =  HAL_ERROR;
1625   }
1626 
1627   return status;
1628 }
1629 
1630 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
1631 
1632 /**
1633   * @}
1634   */
1635 
1636 /** @defgroup FDCAN_Exported_Functions_Group2 Configuration functions
1637   * @ingroup RTEMSBSPsARMSTM32H7
1638   *  @brief    FDCAN Configuration functions.
1639   *
1640 @verbatim
1641   ==============================================================================
1642               ##### Configuration functions #####
1643   ==============================================================================
1644     [..]  This section provides functions allowing to:
1645       (+) HAL_FDCAN_ConfigClockCalibration        : Configure the FDCAN clock calibration unit
1646         (+) HAL_FDCAN_GetClockCalibrationState      : Get the clock calibration state
1647         (+) HAL_FDCAN_ResetClockCalibrationState    : Reset the clock calibration state
1648         (+) HAL_FDCAN_GetClockCalibrationCounter    : Get the clock calibration counters values
1649       (+) HAL_FDCAN_ConfigFilter                  : Configure the FDCAN reception filters
1650       (+) HAL_FDCAN_ConfigGlobalFilter            : Configure the FDCAN global filter
1651       (+) HAL_FDCAN_ConfigExtendedIdMask          : Configure the extended ID mask
1652       (+) HAL_FDCAN_ConfigRxFifoOverwrite         : Configure the Rx FIFO operation mode
1653       (+) HAL_FDCAN_ConfigFifoWatermark           : Configure the FIFO watermark
1654       (+) HAL_FDCAN_ConfigRamWatchdog             : Configure the RAM watchdog
1655       (+) HAL_FDCAN_ConfigTimestampCounter        : Configure the timestamp counter
1656         (+) HAL_FDCAN_EnableTimestampCounter        : Enable the timestamp counter
1657         (+) HAL_FDCAN_DisableTimestampCounter       : Disable the timestamp counter
1658         (+) HAL_FDCAN_GetTimestampCounter           : Get the timestamp counter value
1659         (+) HAL_FDCAN_ResetTimestampCounter         : Reset the timestamp counter to zero
1660       (+) HAL_FDCAN_ConfigTimeoutCounter          : Configure the timeout counter
1661         (+) HAL_FDCAN_EnableTimeoutCounter          : Enable the timeout counter
1662         (+) HAL_FDCAN_DisableTimeoutCounter         : Disable the timeout counter
1663         (+) HAL_FDCAN_GetTimeoutCounter             : Get the timeout counter value
1664         (+) HAL_FDCAN_ResetTimeoutCounter           : Reset the timeout counter to its start value
1665       (+) HAL_FDCAN_ConfigTxDelayCompensation     : Configure the transmitter delay compensation
1666         (+) HAL_FDCAN_EnableTxDelayCompensation     : Enable the transmitter delay compensation
1667         (+) HAL_FDCAN_DisableTxDelayCompensation    : Disable the transmitter delay compensation
1668       (+) HAL_FDCAN_EnableISOMode                 : Enable ISO 11898-1 protocol mode
1669       (+) HAL_FDCAN_DisableISOMode                : Disable ISO 11898-1 protocol mode
1670       (+) HAL_FDCAN_EnableEdgeFiltering           : Enable edge filtering during bus integration
1671       (+) HAL_FDCAN_DisableEdgeFiltering          : Disable edge filtering during bus integration
1672 
1673 @endverbatim
1674   * @{
1675   */
1676 
1677 /**
1678   * @brief  Configure the FDCAN clock calibration unit according to the specified
1679   *         parameters in the FDCAN_ClkCalUnitTypeDef structure.
1680   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1681   *         the configuration information for the specified FDCAN.
1682   * @param  sCcuConfig pointer to an FDCAN_ClkCalUnitTypeDef structure that
1683   *         contains the clock calibration information
1684   * @retval HAL status
1685   */
1686 HAL_StatusTypeDef HAL_FDCAN_ConfigClockCalibration(FDCAN_HandleTypeDef *hfdcan,
1687                                                    const FDCAN_ClkCalUnitTypeDef *sCcuConfig)
1688 {
1689   /* Check function parameters */
1690   assert_param(IS_FDCAN_CLOCK_CALIBRATION(sCcuConfig->ClockCalibration));
1691   if (sCcuConfig->ClockCalibration == FDCAN_CLOCK_CALIBRATION_DISABLE)
1692   {
1693     assert_param(IS_FDCAN_CKDIV(sCcuConfig->ClockDivider));
1694   }
1695   else
1696   {
1697     assert_param(IS_FDCAN_MAX_VALUE(sCcuConfig->MinOscClkPeriods, 0xFFU));
1698     assert_param(IS_FDCAN_CALIBRATION_FIELD_LENGTH(sCcuConfig->CalFieldLength));
1699     assert_param(IS_FDCAN_MIN_VALUE(sCcuConfig->TimeQuantaPerBitTime, 4U));
1700     assert_param(IS_FDCAN_MAX_VALUE(sCcuConfig->TimeQuantaPerBitTime, 0x25U));
1701     assert_param(IS_FDCAN_MAX_VALUE(sCcuConfig->WatchdogStartValue, 0xFFFFU));
1702   }
1703 
1704   /* FDCAN1 should be initialized in order to use clock calibration */
1705   if (hfdcan->Instance != FDCAN1)
1706   {
1707     /* Update error code */
1708     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
1709 
1710     return HAL_ERROR;
1711   }
1712 
1713   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1714   {
1715     if (sCcuConfig->ClockCalibration == FDCAN_CLOCK_CALIBRATION_DISABLE)
1716     {
1717       /* Bypass clock calibration */
1718       SET_BIT(FDCAN_CCU->CCFG, FDCANCCU_CCFG_BCC);
1719 
1720       /* Configure clock divider */
1721       MODIFY_REG(FDCAN_CCU->CCFG, FDCANCCU_CCFG_CDIV,
1722                  (sCcuConfig->ClockDivider << FDCANCCU_CCFG_CDIV_Pos));
1723     }
1724     else /* sCcuConfig->ClockCalibration == ENABLE */
1725     {
1726       /* Clock calibration unit generates time quanta clock */
1727       CLEAR_BIT(FDCAN_CCU->CCFG, FDCANCCU_CCFG_BCC);
1728 
1729       /* Configure clock calibration unit */
1730       MODIFY_REG(FDCAN_CCU->CCFG,
1731                  (FDCANCCU_CCFG_TQBT | FDCANCCU_CCFG_CFL | FDCANCCU_CCFG_OCPM),
1732                  ((sCcuConfig->TimeQuantaPerBitTime << FDCANCCU_CCFG_TQBT_Pos) |
1733                   sCcuConfig->CalFieldLength | (sCcuConfig->MinOscClkPeriods << FDCANCCU_CCFG_OCPM_Pos)));
1734 
1735       /* Configure the start value of the calibration watchdog counter */
1736       MODIFY_REG(FDCAN_CCU->CWD, FDCANCCU_CWD_WDC, sCcuConfig->WatchdogStartValue);
1737     }
1738 
1739     /* Return function status */
1740     return HAL_OK;
1741   }
1742   else
1743   {
1744     /* Update error code */
1745     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1746 
1747     return HAL_ERROR;
1748   }
1749 }
1750 
1751 /**
1752   * @brief  Get the clock calibration state.
1753   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1754   *         the configuration information for the specified FDCAN.
1755   * @retval State clock calibration state (can be a value of @arg FDCAN_calibration_state)
1756   */
1757 uint32_t HAL_FDCAN_GetClockCalibrationState(const FDCAN_HandleTypeDef *hfdcan)
1758 {
1759   /* Prevent unused argument(s) compilation warning */
1760   UNUSED(hfdcan);
1761 
1762   return (FDCAN_CCU->CSTAT & FDCANCCU_CSTAT_CALS);
1763 }
1764 
1765 /**
1766   * @brief  Reset the clock calibration state.
1767   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1768   *         the configuration information for the specified FDCAN.
1769   * @retval HAL status
1770   */
1771 HAL_StatusTypeDef HAL_FDCAN_ResetClockCalibrationState(FDCAN_HandleTypeDef *hfdcan)
1772 {
1773   /* FDCAN1 should be initialized in order to use clock calibration */
1774   if (hfdcan->Instance != FDCAN1)
1775   {
1776     /* Update error code */
1777     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
1778 
1779     return HAL_ERROR;
1780   }
1781 
1782   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1783   {
1784     /* Calibration software reset */
1785     SET_BIT(FDCAN_CCU->CCFG, FDCANCCU_CCFG_SWR);
1786 
1787     /* Return function status */
1788     return HAL_OK;
1789   }
1790   else
1791   {
1792     /* Update error code */
1793     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1794 
1795     return HAL_ERROR;
1796   }
1797 }
1798 
1799 /**
1800   * @brief  Get the clock calibration counter value.
1801   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1802   *         the configuration information for the specified FDCAN.
1803   * @param  Counter clock calibration counter.
1804   *         This parameter can be a value of @arg FDCAN_calibration_counter.
1805   * @retval Value clock calibration counter value
1806   */
1807 uint32_t HAL_FDCAN_GetClockCalibrationCounter(const FDCAN_HandleTypeDef *hfdcan, uint32_t Counter)
1808 {
1809   /* Prevent unused argument(s) compilation warning */
1810   UNUSED(hfdcan);
1811 
1812   /* Check function parameters */
1813   assert_param(IS_FDCAN_CALIBRATION_COUNTER(Counter));
1814 
1815   if (Counter == FDCAN_CALIB_TIME_QUANTA_COUNTER)
1816   {
1817     return ((FDCAN_CCU->CSTAT & FDCANCCU_CSTAT_TQC) >> FDCANCCU_CSTAT_TQC_Pos);
1818   }
1819   else if (Counter == FDCAN_CALIB_CLOCK_PERIOD_COUNTER)
1820   {
1821     return (FDCAN_CCU->CSTAT & FDCANCCU_CSTAT_OCPC);
1822   }
1823   else /* Counter == FDCAN_CALIB_WATCHDOG_COUNTER */
1824   {
1825     return ((FDCAN_CCU->CWD & FDCANCCU_CWD_WDV) >> FDCANCCU_CWD_WDV_Pos);
1826   }
1827 }
1828 
1829 /**
1830   * @brief  Configure the FDCAN reception filter according to the specified
1831   *         parameters in the FDCAN_FilterTypeDef structure.
1832   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1833   *         the configuration information for the specified FDCAN.
1834   * @param  sFilterConfig pointer to an FDCAN_FilterTypeDef structure that
1835   *         contains the filter configuration information
1836   * @retval HAL status
1837   */
1838 HAL_StatusTypeDef HAL_FDCAN_ConfigFilter(FDCAN_HandleTypeDef *hfdcan, const FDCAN_FilterTypeDef *sFilterConfig)
1839 {
1840   uint32_t FilterElementW1;
1841   uint32_t FilterElementW2;
1842   uint32_t *FilterAddress;
1843   HAL_FDCAN_StateTypeDef state = hfdcan->State;
1844 
1845   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
1846   {
1847     /* Check function parameters */
1848     assert_param(IS_FDCAN_ID_TYPE(sFilterConfig->IdType));
1849     assert_param(IS_FDCAN_FILTER_CFG(sFilterConfig->FilterConfig));
1850     if (sFilterConfig->FilterConfig == FDCAN_FILTER_TO_RXBUFFER)
1851     {
1852       assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->RxBufferIndex, 63U));
1853       assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->IsCalibrationMsg, 1U));
1854     }
1855 
1856     if (sFilterConfig->IdType == FDCAN_STANDARD_ID)
1857     {
1858       /* Check function parameters */
1859       assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterIndex, (hfdcan->Init.StdFiltersNbr - 1U)));
1860       assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterID1, 0x7FFU));
1861       if (sFilterConfig->FilterConfig != FDCAN_FILTER_TO_RXBUFFER)
1862       {
1863         assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterID2, 0x7FFU));
1864         assert_param(IS_FDCAN_STD_FILTER_TYPE(sFilterConfig->FilterType));
1865       }
1866 
1867       /* Build filter element */
1868       if (sFilterConfig->FilterConfig == FDCAN_FILTER_TO_RXBUFFER)
1869       {
1870         FilterElementW1 = ((FDCAN_FILTER_TO_RXBUFFER << 27U)       |
1871                            (sFilterConfig->FilterID1 << 16U)       |
1872                            (sFilterConfig->IsCalibrationMsg << 8U) |
1873                            sFilterConfig->RxBufferIndex);
1874       }
1875       else
1876       {
1877         FilterElementW1 = ((sFilterConfig->FilterType << 30U)   |
1878                            (sFilterConfig->FilterConfig << 27U) |
1879                            (sFilterConfig->FilterID1 << 16U)    |
1880                            sFilterConfig->FilterID2);
1881       }
1882 
1883       /* Calculate filter address */
1884       FilterAddress = (uint32_t *)(hfdcan->msgRam.StandardFilterSA + (sFilterConfig->FilterIndex * 4U));
1885 
1886       /* Write filter element to the message RAM */
1887       *FilterAddress = FilterElementW1;
1888     }
1889     else /* sFilterConfig->IdType == FDCAN_EXTENDED_ID */
1890     {
1891       /* Check function parameters */
1892       assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterIndex, (hfdcan->Init.ExtFiltersNbr - 1U)));
1893       assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterID1, 0x1FFFFFFFU));
1894       if (sFilterConfig->FilterConfig != FDCAN_FILTER_TO_RXBUFFER)
1895       {
1896         assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterID2, 0x1FFFFFFFU));
1897         assert_param(IS_FDCAN_EXT_FILTER_TYPE(sFilterConfig->FilterType));
1898       }
1899 
1900       /* Build first word of filter element */
1901       FilterElementW1 = ((sFilterConfig->FilterConfig << 29U) | sFilterConfig->FilterID1);
1902 
1903       /* Build second word of filter element */
1904       if (sFilterConfig->FilterConfig == FDCAN_FILTER_TO_RXBUFFER)
1905       {
1906         FilterElementW2 = sFilterConfig->RxBufferIndex;
1907       }
1908       else
1909       {
1910         FilterElementW2 = ((sFilterConfig->FilterType << 30U) | sFilterConfig->FilterID2);
1911       }
1912 
1913       /* Calculate filter address */
1914       FilterAddress = (uint32_t *)(hfdcan->msgRam.ExtendedFilterSA + (sFilterConfig->FilterIndex * 4U * 2U));
1915 
1916       /* Write filter element to the message RAM */
1917       *FilterAddress = FilterElementW1;
1918       FilterAddress++;
1919       *FilterAddress = FilterElementW2;
1920     }
1921 
1922     /* Return function status */
1923     return HAL_OK;
1924   }
1925   else
1926   {
1927     /* Update error code */
1928     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
1929 
1930     return HAL_ERROR;
1931   }
1932 }
1933 
1934 /**
1935   * @brief  Configure the FDCAN global filter.
1936   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1937   *         the configuration information for the specified FDCAN.
1938   * @param  NonMatchingStd Defines how received messages with 11-bit IDs that
1939   *         do not match any element of the filter list are treated.
1940   *         This parameter can be a value of @arg FDCAN_Non_Matching_Frames.
1941   * @param  NonMatchingExt Defines how received messages with 29-bit IDs that
1942   *         do not match any element of the filter list are treated.
1943   *         This parameter can be a value of @arg FDCAN_Non_Matching_Frames.
1944   * @param  RejectRemoteStd Filter or reject all the remote 11-bit IDs frames.
1945   *         This parameter can be a value of @arg FDCAN_Reject_Remote_Frames.
1946   * @param  RejectRemoteExt Filter or reject all the remote 29-bit IDs frames.
1947   *         This parameter can be a value of @arg FDCAN_Reject_Remote_Frames.
1948   * @retval HAL status
1949   */
1950 HAL_StatusTypeDef HAL_FDCAN_ConfigGlobalFilter(FDCAN_HandleTypeDef *hfdcan,
1951                                                uint32_t NonMatchingStd,
1952                                                uint32_t NonMatchingExt,
1953                                                uint32_t RejectRemoteStd,
1954                                                uint32_t RejectRemoteExt)
1955 {
1956   /* Check function parameters */
1957   assert_param(IS_FDCAN_NON_MATCHING(NonMatchingStd));
1958   assert_param(IS_FDCAN_NON_MATCHING(NonMatchingExt));
1959   assert_param(IS_FDCAN_REJECT_REMOTE(RejectRemoteStd));
1960   assert_param(IS_FDCAN_REJECT_REMOTE(RejectRemoteExt));
1961 
1962   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1963   {
1964     /* Configure global filter */
1965     hfdcan->Instance->GFC = ((NonMatchingStd << FDCAN_GFC_ANFS_Pos)  |
1966                              (NonMatchingExt << FDCAN_GFC_ANFE_Pos)  |
1967                              (RejectRemoteStd << FDCAN_GFC_RRFS_Pos) |
1968                              (RejectRemoteExt << FDCAN_GFC_RRFE_Pos));
1969 
1970     /* Return function status */
1971     return HAL_OK;
1972   }
1973   else
1974   {
1975     /* Update error code */
1976     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1977 
1978     return HAL_ERROR;
1979   }
1980 }
1981 
1982 /**
1983   * @brief  Configure the extended ID mask.
1984   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1985   *         the configuration information for the specified FDCAN.
1986   * @param  Mask Extended ID Mask.
1987   *         This parameter must be a number between 0 and 0x1FFFFFFF.
1988   * @retval HAL status
1989   */
1990 HAL_StatusTypeDef HAL_FDCAN_ConfigExtendedIdMask(FDCAN_HandleTypeDef *hfdcan, uint32_t Mask)
1991 {
1992   /* Check function parameters */
1993   assert_param(IS_FDCAN_MAX_VALUE(Mask, 0x1FFFFFFFU));
1994 
1995   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1996   {
1997     /* Configure the extended ID mask */
1998     hfdcan->Instance->XIDAM = Mask;
1999 
2000     /* Return function status */
2001     return HAL_OK;
2002   }
2003   else
2004   {
2005     /* Update error code */
2006     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2007 
2008     return HAL_ERROR;
2009   }
2010 }
2011 
2012 /**
2013   * @brief  Configure the Rx FIFO operation mode.
2014   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2015   *         the configuration information for the specified FDCAN.
2016   * @param  RxFifo Rx FIFO.
2017   *         This parameter can be one of the following values:
2018   *           @arg FDCAN_RX_FIFO0: Rx FIFO 0
2019   *           @arg FDCAN_RX_FIFO1: Rx FIFO 1
2020   * @param  OperationMode operation mode.
2021   *         This parameter can be a value of @arg FDCAN_Rx_FIFO_operation_mode.
2022   * @retval HAL status
2023   */
2024 HAL_StatusTypeDef HAL_FDCAN_ConfigRxFifoOverwrite(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo, uint32_t OperationMode)
2025 {
2026   /* Check function parameters */
2027   assert_param(IS_FDCAN_RX_FIFO(RxFifo));
2028   assert_param(IS_FDCAN_RX_FIFO_MODE(OperationMode));
2029 
2030   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2031   {
2032     if (RxFifo == FDCAN_RX_FIFO0)
2033     {
2034       /* Select FIFO 0 Operation Mode */
2035       MODIFY_REG(hfdcan->Instance->RXF0C, FDCAN_RXF0C_F0OM, (OperationMode << FDCAN_RXF0C_F0OM_Pos));
2036     }
2037     else /* RxFifo == FDCAN_RX_FIFO1 */
2038     {
2039       /* Select FIFO 1 Operation Mode */
2040       MODIFY_REG(hfdcan->Instance->RXF1C, FDCAN_RXF1C_F1OM, (OperationMode << FDCAN_RXF1C_F1OM_Pos));
2041     }
2042 
2043     /* Return function status */
2044     return HAL_OK;
2045   }
2046   else
2047   {
2048     /* Update error code */
2049     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2050 
2051     return HAL_ERROR;
2052   }
2053 }
2054 
2055 /**
2056   * @brief  Configure the FIFO watermark.
2057   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2058   *         the configuration information for the specified FDCAN.
2059   * @param  FIFO select the FIFO to be configured.
2060   *         This parameter can be a value of @arg FDCAN_FIFO_watermark.
2061   * @param  Watermark level for FIFO watermark interrupt.
2062   *         This parameter must be a number between:
2063   *           - 0 and 32, if FIFO is FDCAN_CFG_TX_EVENT_FIFO
2064   *           - 0 and 64, if FIFO is FDCAN_CFG_RX_FIFO0 or FDCAN_CFG_RX_FIFO1
2065   * @retval HAL status
2066   */
2067 HAL_StatusTypeDef HAL_FDCAN_ConfigFifoWatermark(FDCAN_HandleTypeDef *hfdcan, uint32_t FIFO, uint32_t Watermark)
2068 {
2069   /* Check function parameters */
2070   assert_param(IS_FDCAN_FIFO_WATERMARK(FIFO));
2071   if (FIFO == FDCAN_CFG_TX_EVENT_FIFO)
2072   {
2073     assert_param(IS_FDCAN_MAX_VALUE(Watermark, 32U));
2074   }
2075   else /* (FIFO == FDCAN_CFG_RX_FIFO0) || (FIFO == FDCAN_CFG_RX_FIFO1) */
2076   {
2077     assert_param(IS_FDCAN_MAX_VALUE(Watermark, 64U));
2078   }
2079 
2080   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2081   {
2082     /* Set the level for FIFO watermark interrupt */
2083     if (FIFO == FDCAN_CFG_TX_EVENT_FIFO)
2084     {
2085       MODIFY_REG(hfdcan->Instance->TXEFC, FDCAN_TXEFC_EFWM, (Watermark << FDCAN_TXEFC_EFWM_Pos));
2086     }
2087     else if (FIFO == FDCAN_CFG_RX_FIFO0)
2088     {
2089       MODIFY_REG(hfdcan->Instance->RXF0C, FDCAN_RXF0C_F0WM, (Watermark << FDCAN_RXF0C_F0WM_Pos));
2090     }
2091     else /* FIFO == FDCAN_CFG_RX_FIFO1 */
2092     {
2093       MODIFY_REG(hfdcan->Instance->RXF1C, FDCAN_RXF1C_F1WM, (Watermark << FDCAN_RXF1C_F1WM_Pos));
2094     }
2095 
2096     /* Return function status */
2097     return HAL_OK;
2098   }
2099   else
2100   {
2101     /* Update error code */
2102     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2103 
2104     return HAL_ERROR;
2105   }
2106 }
2107 
2108 /**
2109   * @brief  Configure the RAM watchdog.
2110   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2111   *         the configuration information for the specified FDCAN.
2112   * @param  CounterStartValue Start value of the Message RAM Watchdog Counter,
2113   *         This parameter must be a number between 0x00 and 0xFF,
2114   *         with the reset value of 0x00 the counter is disabled.
2115   * @retval HAL status
2116   */
2117 HAL_StatusTypeDef HAL_FDCAN_ConfigRamWatchdog(FDCAN_HandleTypeDef *hfdcan, uint32_t CounterStartValue)
2118 {
2119   /* Check function parameters */
2120   assert_param(IS_FDCAN_MAX_VALUE(CounterStartValue, 0xFFU));
2121 
2122   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2123   {
2124     /* Configure the RAM watchdog counter start value */
2125     MODIFY_REG(hfdcan->Instance->RWD, FDCAN_RWD_WDC, CounterStartValue);
2126 
2127     /* Return function status */
2128     return HAL_OK;
2129   }
2130   else
2131   {
2132     /* Update error code */
2133     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2134 
2135     return HAL_ERROR;
2136   }
2137 }
2138 
2139 /**
2140   * @brief  Configure the timestamp counter.
2141   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2142   *         the configuration information for the specified FDCAN.
2143   * @param  TimestampPrescaler Timestamp Counter Prescaler.
2144   *         This parameter can be a value of @arg FDCAN_Timestamp_Prescaler.
2145   * @retval HAL status
2146   */
2147 HAL_StatusTypeDef HAL_FDCAN_ConfigTimestampCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t TimestampPrescaler)
2148 {
2149   /* Check function parameters */
2150   assert_param(IS_FDCAN_TIMESTAMP_PRESCALER(TimestampPrescaler));
2151 
2152   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2153   {
2154     /* Configure prescaler */
2155     MODIFY_REG(hfdcan->Instance->TSCC, FDCAN_TSCC_TCP, TimestampPrescaler);
2156 
2157     /* Return function status */
2158     return HAL_OK;
2159   }
2160   else
2161   {
2162     /* Update error code */
2163     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2164 
2165     return HAL_ERROR;
2166   }
2167 }
2168 
2169 /**
2170   * @brief  Enable the timestamp counter.
2171   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2172   *         the configuration information for the specified FDCAN.
2173   * @param  TimestampOperation Timestamp counter operation.
2174   *         This parameter can be a value of @arg FDCAN_Timestamp.
2175   * @retval HAL status
2176   */
2177 HAL_StatusTypeDef HAL_FDCAN_EnableTimestampCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t TimestampOperation)
2178 {
2179   /* Check function parameters */
2180   assert_param(IS_FDCAN_TIMESTAMP(TimestampOperation));
2181 
2182   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2183   {
2184     /* Enable timestamp counter */
2185     MODIFY_REG(hfdcan->Instance->TSCC, FDCAN_TSCC_TSS, TimestampOperation);
2186 
2187     /* Return function status */
2188     return HAL_OK;
2189   }
2190   else
2191   {
2192     /* Update error code */
2193     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2194 
2195     return HAL_ERROR;
2196   }
2197 }
2198 
2199 /**
2200   * @brief  Disable the timestamp counter.
2201   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2202   *         the configuration information for the specified FDCAN.
2203   * @retval HAL status
2204   */
2205 HAL_StatusTypeDef HAL_FDCAN_DisableTimestampCounter(FDCAN_HandleTypeDef *hfdcan)
2206 {
2207   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2208   {
2209     /* Disable timestamp counter */
2210     CLEAR_BIT(hfdcan->Instance->TSCC, FDCAN_TSCC_TSS);
2211 
2212     /* Return function status */
2213     return HAL_OK;
2214   }
2215   else
2216   {
2217     /* Update error code */
2218     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2219 
2220     return HAL_ERROR;
2221   }
2222 }
2223 
2224 /**
2225   * @brief  Get the timestamp counter value.
2226   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2227   *         the configuration information for the specified FDCAN.
2228   * @retval Timestamp counter value
2229   */
2230 uint16_t HAL_FDCAN_GetTimestampCounter(const FDCAN_HandleTypeDef *hfdcan)
2231 {
2232   return (uint16_t)(hfdcan->Instance->TSCV);
2233 }
2234 
2235 /**
2236   * @brief  Reset the timestamp counter to zero.
2237   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2238   *         the configuration information for the specified FDCAN.
2239   * @retval HAL status
2240   */
2241 HAL_StatusTypeDef HAL_FDCAN_ResetTimestampCounter(FDCAN_HandleTypeDef *hfdcan)
2242 {
2243   if ((hfdcan->Instance->TSCC & FDCAN_TSCC_TSS) != FDCAN_TIMESTAMP_EXTERNAL)
2244   {
2245     /* Reset timestamp counter.
2246        Actually any write operation to TSCV clears the counter */
2247     CLEAR_REG(hfdcan->Instance->TSCV);
2248   }
2249   else
2250   {
2251     /* Update error code.
2252        Unable to reset external counter */
2253     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
2254 
2255     return HAL_ERROR;
2256   }
2257 
2258   /* Return function status */
2259   return HAL_OK;
2260 }
2261 
2262 /**
2263   * @brief  Configure the timeout counter.
2264   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2265   *         the configuration information for the specified FDCAN.
2266   * @param  TimeoutOperation Timeout counter operation.
2267   *         This parameter can be a value of @arg FDCAN_Timeout_Operation.
2268   * @param  TimeoutPeriod Start value of the timeout down-counter.
2269   *         This parameter must be a number between 0x0000 and 0xFFFF
2270   * @retval HAL status
2271   */
2272 HAL_StatusTypeDef HAL_FDCAN_ConfigTimeoutCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t TimeoutOperation,
2273                                                  uint32_t TimeoutPeriod)
2274 {
2275   /* Check function parameters */
2276   assert_param(IS_FDCAN_TIMEOUT(TimeoutOperation));
2277   assert_param(IS_FDCAN_MAX_VALUE(TimeoutPeriod, 0xFFFFU));
2278 
2279   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2280   {
2281     /* Select timeout operation and configure period */
2282     MODIFY_REG(hfdcan->Instance->TOCC,
2283                (FDCAN_TOCC_TOS | FDCAN_TOCC_TOP), (TimeoutOperation | (TimeoutPeriod << FDCAN_TOCC_TOP_Pos)));
2284 
2285     /* Return function status */
2286     return HAL_OK;
2287   }
2288   else
2289   {
2290     /* Update error code */
2291     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2292 
2293     return HAL_ERROR;
2294   }
2295 }
2296 
2297 /**
2298   * @brief  Enable the timeout counter.
2299   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2300   *         the configuration information for the specified FDCAN.
2301   * @retval HAL status
2302   */
2303 HAL_StatusTypeDef HAL_FDCAN_EnableTimeoutCounter(FDCAN_HandleTypeDef *hfdcan)
2304 {
2305   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2306   {
2307     /* Enable timeout counter */
2308     SET_BIT(hfdcan->Instance->TOCC, FDCAN_TOCC_ETOC);
2309 
2310     /* Return function status */
2311     return HAL_OK;
2312   }
2313   else
2314   {
2315     /* Update error code */
2316     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2317 
2318     return HAL_ERROR;
2319   }
2320 }
2321 
2322 /**
2323   * @brief  Disable the timeout counter.
2324   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2325   *         the configuration information for the specified FDCAN.
2326   * @retval HAL status
2327   */
2328 HAL_StatusTypeDef HAL_FDCAN_DisableTimeoutCounter(FDCAN_HandleTypeDef *hfdcan)
2329 {
2330   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2331   {
2332     /* Disable timeout counter */
2333     CLEAR_BIT(hfdcan->Instance->TOCC, FDCAN_TOCC_ETOC);
2334 
2335     /* Return function status */
2336     return HAL_OK;
2337   }
2338   else
2339   {
2340     /* Update error code */
2341     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2342 
2343     return HAL_ERROR;
2344   }
2345 }
2346 
2347 /**
2348   * @brief  Get the timeout counter value.
2349   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2350   *         the configuration information for the specified FDCAN.
2351   * @retval Timeout counter value
2352   */
2353 uint16_t HAL_FDCAN_GetTimeoutCounter(const FDCAN_HandleTypeDef *hfdcan)
2354 {
2355   return (uint16_t)(hfdcan->Instance->TOCV);
2356 }
2357 
2358 /**
2359   * @brief  Reset the timeout counter to its start value.
2360   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2361   *         the configuration information for the specified FDCAN.
2362   * @retval HAL status
2363   */
2364 HAL_StatusTypeDef HAL_FDCAN_ResetTimeoutCounter(FDCAN_HandleTypeDef *hfdcan)
2365 {
2366   if ((hfdcan->Instance->TOCC & FDCAN_TOCC_TOS) == FDCAN_TIMEOUT_CONTINUOUS)
2367   {
2368     /* Reset timeout counter to start value */
2369     CLEAR_REG(hfdcan->Instance->TOCV);
2370 
2371     /* Return function status */
2372     return HAL_OK;
2373   }
2374   else
2375   {
2376     /* Update error code.
2377        Unable to reset counter: controlled only by FIFO empty state */
2378     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
2379 
2380     return HAL_ERROR;
2381   }
2382 }
2383 
2384 /**
2385   * @brief  Configure the transmitter delay compensation.
2386   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2387   *         the configuration information for the specified FDCAN.
2388   * @param  TdcOffset Transmitter Delay Compensation Offset.
2389   *         This parameter must be a number between 0x00 and 0x7F.
2390   * @param  TdcFilter Transmitter Delay Compensation Filter Window Length.
2391   *         This parameter must be a number between 0x00 and 0x7F.
2392   * @retval HAL status
2393   */
2394 HAL_StatusTypeDef HAL_FDCAN_ConfigTxDelayCompensation(FDCAN_HandleTypeDef *hfdcan, uint32_t TdcOffset,
2395                                                       uint32_t TdcFilter)
2396 {
2397   /* Check function parameters */
2398   assert_param(IS_FDCAN_MAX_VALUE(TdcOffset, 0x7FU));
2399   assert_param(IS_FDCAN_MAX_VALUE(TdcFilter, 0x7FU));
2400 
2401   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2402   {
2403     /* Configure TDC offset and filter window */
2404     hfdcan->Instance->TDCR = ((TdcFilter << FDCAN_TDCR_TDCF_Pos) | (TdcOffset << FDCAN_TDCR_TDCO_Pos));
2405 
2406     /* Return function status */
2407     return HAL_OK;
2408   }
2409   else
2410   {
2411     /* Update error code */
2412     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2413 
2414     return HAL_ERROR;
2415   }
2416 }
2417 
2418 /**
2419   * @brief  Enable the transmitter delay compensation.
2420   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2421   *         the configuration information for the specified FDCAN.
2422   * @retval HAL status
2423   */
2424 HAL_StatusTypeDef HAL_FDCAN_EnableTxDelayCompensation(FDCAN_HandleTypeDef *hfdcan)
2425 {
2426   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2427   {
2428     /* Enable transmitter delay compensation */
2429     SET_BIT(hfdcan->Instance->DBTP, FDCAN_DBTP_TDC);
2430 
2431     /* Return function status */
2432     return HAL_OK;
2433   }
2434   else
2435   {
2436     /* Update error code */
2437     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2438 
2439     return HAL_ERROR;
2440   }
2441 }
2442 
2443 /**
2444   * @brief  Disable the transmitter delay compensation.
2445   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2446   *         the configuration information for the specified FDCAN.
2447   * @retval HAL status
2448   */
2449 HAL_StatusTypeDef HAL_FDCAN_DisableTxDelayCompensation(FDCAN_HandleTypeDef *hfdcan)
2450 {
2451   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2452   {
2453     /* Disable transmitter delay compensation */
2454     CLEAR_BIT(hfdcan->Instance->DBTP, FDCAN_DBTP_TDC);
2455 
2456     /* Return function status */
2457     return HAL_OK;
2458   }
2459   else
2460   {
2461     /* Update error code */
2462     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2463 
2464     return HAL_ERROR;
2465   }
2466 }
2467 
2468 /**
2469   * @brief  Enable ISO 11898-1 protocol mode.
2470   *         CAN FD frame format is according to ISO 11898-1 standard.
2471   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2472   *         the configuration information for the specified FDCAN.
2473   * @retval HAL status
2474   */
2475 HAL_StatusTypeDef HAL_FDCAN_EnableISOMode(FDCAN_HandleTypeDef *hfdcan)
2476 {
2477   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2478   {
2479     /* Disable Non ISO protocol mode */
2480     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_NISO);
2481 
2482     /* Return function status */
2483     return HAL_OK;
2484   }
2485   else
2486   {
2487     /* Update error code */
2488     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2489 
2490     return HAL_ERROR;
2491   }
2492 }
2493 
2494 /**
2495   * @brief  Disable ISO 11898-1 protocol mode.
2496   *         CAN FD frame format is according to Bosch CAN FD specification V1.0.
2497   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2498   *         the configuration information for the specified FDCAN.
2499   * @retval HAL status
2500   */
2501 HAL_StatusTypeDef HAL_FDCAN_DisableISOMode(FDCAN_HandleTypeDef *hfdcan)
2502 {
2503   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2504   {
2505     /* Enable Non ISO protocol mode */
2506     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_NISO);
2507 
2508     /* Return function status */
2509     return HAL_OK;
2510   }
2511   else
2512   {
2513     /* Update error code */
2514     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2515 
2516     return HAL_ERROR;
2517   }
2518 }
2519 
2520 /**
2521   * @brief  Enable edge filtering during bus integration.
2522   *         Two consecutive dominant tq are required to detect an edge for hard synchronization.
2523   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2524   *         the configuration information for the specified FDCAN.
2525   * @retval HAL status
2526   */
2527 HAL_StatusTypeDef HAL_FDCAN_EnableEdgeFiltering(FDCAN_HandleTypeDef *hfdcan)
2528 {
2529   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2530   {
2531     /* Enable edge filtering */
2532     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_EFBI);
2533 
2534     /* Return function status */
2535     return HAL_OK;
2536   }
2537   else
2538   {
2539     /* Update error code */
2540     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2541 
2542     return HAL_ERROR;
2543   }
2544 }
2545 
2546 /**
2547   * @brief  Disable edge filtering during bus integration.
2548   *         One dominant tq is required to detect an edge for hard synchronization.
2549   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2550   *         the configuration information for the specified FDCAN.
2551   * @retval HAL status
2552   */
2553 HAL_StatusTypeDef HAL_FDCAN_DisableEdgeFiltering(FDCAN_HandleTypeDef *hfdcan)
2554 {
2555   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2556   {
2557     /* Disable edge filtering */
2558     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_EFBI);
2559 
2560     /* Return function status */
2561     return HAL_OK;
2562   }
2563   else
2564   {
2565     /* Update error code */
2566     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2567 
2568     return HAL_ERROR;
2569   }
2570 }
2571 
2572 /**
2573   * @}
2574   */
2575 
2576 /** @defgroup FDCAN_Exported_Functions_Group3 Control functions
2577   * @ingroup RTEMSBSPsARMSTM32H7
2578   *  @brief    Control functions
2579   *
2580 @verbatim
2581   ==============================================================================
2582                           ##### Control functions #####
2583   ==============================================================================
2584     [..]  This section provides functions allowing to:
2585       (+) HAL_FDCAN_Start                         : Start the FDCAN module
2586       (+) HAL_FDCAN_Stop                          : Stop the FDCAN module and enable access to configuration registers
2587       (+) HAL_FDCAN_AddMessageToTxFifoQ           : Add a message to the Tx FIFO/Queue and activate the corresponding
2588                                                     transmission request
2589       (+) HAL_FDCAN_AddMessageToTxBuffer          : Add a message to a dedicated Tx buffer
2590       (+) HAL_FDCAN_EnableTxBufferRequest         : Enable transmission request
2591       (+) HAL_FDCAN_GetLatestTxFifoQRequestBuffer : Get Tx buffer index of latest Tx FIFO/Queue request
2592       (+) HAL_FDCAN_AbortTxRequest                : Abort transmission request
2593       (+) HAL_FDCAN_GetRxMessage                  : Get an FDCAN frame from the Rx Buffer/FIFO zone into the
2594                                                     message RAM
2595       (+) HAL_FDCAN_GetTxEvent                    : Get an FDCAN Tx event from the Tx Event FIFO zone
2596                                                     into the message RAM
2597       (+) HAL_FDCAN_GetHighPriorityMessageStatus  : Get high priority message status
2598       (+) HAL_FDCAN_GetProtocolStatus             : Get protocol status
2599       (+) HAL_FDCAN_GetErrorCounters              : Get error counter values
2600       (+) HAL_FDCAN_IsRxBufferMessageAvailable    : Check if a new message is received in the selected Rx buffer
2601       (+) HAL_FDCAN_IsTxBufferMessagePending      : Check if a transmission request is pending
2602                                                     on the selected Tx buffer
2603       (+) HAL_FDCAN_GetRxFifoFillLevel            : Return Rx FIFO fill level
2604       (+) HAL_FDCAN_GetTxFifoFreeLevel            : Return Tx FIFO free level
2605       (+) HAL_FDCAN_IsRestrictedOperationMode     : Check if the FDCAN peripheral entered Restricted Operation Mode
2606       (+) HAL_FDCAN_ExitRestrictedOperationMode   : Exit Restricted Operation Mode
2607 
2608 @endverbatim
2609   * @{
2610   */
2611 
2612 /**
2613   * @brief  Start the FDCAN module.
2614   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2615   *         the configuration information for the specified FDCAN.
2616   * @retval HAL status
2617   */
2618 HAL_StatusTypeDef HAL_FDCAN_Start(FDCAN_HandleTypeDef *hfdcan)
2619 {
2620   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2621   {
2622     /* Change FDCAN peripheral state */
2623     hfdcan->State = HAL_FDCAN_STATE_BUSY;
2624 
2625     /* Request leave initialisation */
2626     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT);
2627 
2628     /* Reset the FDCAN ErrorCode */
2629     hfdcan->ErrorCode = HAL_FDCAN_ERROR_NONE;
2630 
2631     /* Return function status */
2632     return HAL_OK;
2633   }
2634   else
2635   {
2636     /* Update error code */
2637     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2638 
2639     return HAL_ERROR;
2640   }
2641 }
2642 
2643 /**
2644   * @brief  Stop the FDCAN module and enable access to configuration registers.
2645   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2646   *         the configuration information for the specified FDCAN.
2647   * @retval HAL status
2648   */
2649 HAL_StatusTypeDef HAL_FDCAN_Stop(FDCAN_HandleTypeDef *hfdcan)
2650 {
2651   uint32_t Counter = 0U;
2652 
2653   if (hfdcan->State == HAL_FDCAN_STATE_BUSY)
2654   {
2655     /* Request initialisation */
2656     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT);
2657 
2658     /* Wait until the INIT bit into CCCR register is set */
2659     while ((hfdcan->Instance->CCCR & FDCAN_CCCR_INIT) == 0U)
2660     {
2661       /* Check for the Timeout */
2662       if (Counter > FDCAN_TIMEOUT_COUNT)
2663       {
2664         /* Update error code */
2665         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
2666 
2667         /* Change FDCAN state */
2668         hfdcan->State = HAL_FDCAN_STATE_ERROR;
2669 
2670         return HAL_ERROR;
2671       }
2672 
2673       /* Increment counter */
2674       Counter++;
2675     }
2676 
2677     /* Reset counter */
2678     Counter = 0U;
2679 
2680     /* Exit from Sleep mode */
2681     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CSR);
2682 
2683     /* Wait until FDCAN exits sleep mode */
2684     while ((hfdcan->Instance->CCCR & FDCAN_CCCR_CSA) == FDCAN_CCCR_CSA)
2685     {
2686       /* Check for the Timeout */
2687       if (Counter > FDCAN_TIMEOUT_COUNT)
2688       {
2689         /* Update error code */
2690         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
2691 
2692         /* Change FDCAN state */
2693         hfdcan->State = HAL_FDCAN_STATE_ERROR;
2694 
2695         return HAL_ERROR;
2696       }
2697 
2698       /* Increment counter */
2699       Counter++;
2700     }
2701 
2702     /* Enable configuration change */
2703     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CCE);
2704 
2705     /* Reset Latest Tx FIFO/Queue Request Buffer Index */
2706     hfdcan->LatestTxFifoQRequest = 0U;
2707 
2708     /* Change FDCAN peripheral state */
2709     hfdcan->State = HAL_FDCAN_STATE_READY;
2710 
2711     /* Return function status */
2712     return HAL_OK;
2713   }
2714   else
2715   {
2716     /* Update error code */
2717     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
2718 
2719     return HAL_ERROR;
2720   }
2721 }
2722 
2723 /**
2724   * @brief  Add a message to the Tx FIFO/Queue and activate the corresponding transmission request
2725   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2726   *         the configuration information for the specified FDCAN.
2727   * @param  pTxHeader pointer to a FDCAN_TxHeaderTypeDef structure.
2728   * @param  pTxData pointer to a buffer containing the payload of the Tx frame.
2729   * @retval HAL status
2730   */
2731 HAL_StatusTypeDef HAL_FDCAN_AddMessageToTxFifoQ(FDCAN_HandleTypeDef *hfdcan, const FDCAN_TxHeaderTypeDef *pTxHeader,
2732                                                 const uint8_t *pTxData)
2733 {
2734   uint32_t PutIndex;
2735 
2736   /* Check function parameters */
2737   assert_param(IS_FDCAN_ID_TYPE(pTxHeader->IdType));
2738   if (pTxHeader->IdType == FDCAN_STANDARD_ID)
2739   {
2740     assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->Identifier, 0x7FFU));
2741   }
2742   else /* pTxHeader->IdType == FDCAN_EXTENDED_ID */
2743   {
2744     assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->Identifier, 0x1FFFFFFFU));
2745   }
2746   assert_param(IS_FDCAN_FRAME_TYPE(pTxHeader->TxFrameType));
2747   assert_param(IS_FDCAN_DLC(pTxHeader->DataLength));
2748   assert_param(IS_FDCAN_ESI(pTxHeader->ErrorStateIndicator));
2749   assert_param(IS_FDCAN_BRS(pTxHeader->BitRateSwitch));
2750   assert_param(IS_FDCAN_FDF(pTxHeader->FDFormat));
2751   assert_param(IS_FDCAN_EFC(pTxHeader->TxEventFifoControl));
2752   assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->MessageMarker, 0xFFU));
2753 
2754   if (hfdcan->State == HAL_FDCAN_STATE_BUSY)
2755   {
2756     /* Check that the Tx FIFO/Queue has an allocated area into the RAM */
2757     if ((hfdcan->Instance->TXBC & FDCAN_TXBC_TFQS) == 0U)
2758     {
2759       /* Update error code */
2760       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
2761 
2762       return HAL_ERROR;
2763     }
2764 
2765     /* Check that the Tx FIFO/Queue is not full */
2766     if ((hfdcan->Instance->TXFQS & FDCAN_TXFQS_TFQF) != 0U)
2767     {
2768       /* Update error code */
2769       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_FULL;
2770 
2771       return HAL_ERROR;
2772     }
2773     else
2774     {
2775       /* Retrieve the Tx FIFO PutIndex */
2776       PutIndex = ((hfdcan->Instance->TXFQS & FDCAN_TXFQS_TFQPI) >> FDCAN_TXFQS_TFQPI_Pos);
2777 
2778       /* Add the message to the Tx FIFO/Queue */
2779       FDCAN_CopyMessageToRAM(hfdcan, pTxHeader, pTxData, PutIndex);
2780 
2781       /* Activate the corresponding transmission request */
2782       hfdcan->Instance->TXBAR = ((uint32_t)1 << PutIndex);
2783 
2784       /* Store the Latest Tx FIFO/Queue Request Buffer Index */
2785       hfdcan->LatestTxFifoQRequest = ((uint32_t)1 << PutIndex);
2786     }
2787 
2788     /* Return function status */
2789     return HAL_OK;
2790   }
2791   else
2792   {
2793     /* Update error code */
2794     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
2795 
2796     return HAL_ERROR;
2797   }
2798 }
2799 
2800 /**
2801   * @brief  Add a message to a dedicated Tx buffer
2802   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2803   *         the configuration information for the specified FDCAN.
2804   * @param  pTxHeader pointer to a FDCAN_TxHeaderTypeDef structure.
2805   * @param  pTxData pointer to a buffer containing the payload of the Tx frame.
2806   * @param  BufferIndex index of the buffer to be configured.
2807   *         This parameter can be a value of @arg FDCAN_Tx_location.
2808   * @retval HAL status
2809   */
2810 HAL_StatusTypeDef HAL_FDCAN_AddMessageToTxBuffer(FDCAN_HandleTypeDef *hfdcan, const FDCAN_TxHeaderTypeDef *pTxHeader,
2811                                                  const uint8_t *pTxData, uint32_t BufferIndex)
2812 {
2813   HAL_FDCAN_StateTypeDef state = hfdcan->State;
2814 
2815   /* Check function parameters */
2816   assert_param(IS_FDCAN_ID_TYPE(pTxHeader->IdType));
2817   if (pTxHeader->IdType == FDCAN_STANDARD_ID)
2818   {
2819     assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->Identifier, 0x7FFU));
2820   }
2821   else /* pTxHeader->IdType == FDCAN_EXTENDED_ID */
2822   {
2823     assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->Identifier, 0x1FFFFFFFU));
2824   }
2825   assert_param(IS_FDCAN_FRAME_TYPE(pTxHeader->TxFrameType));
2826   assert_param(IS_FDCAN_DLC(pTxHeader->DataLength));
2827   assert_param(IS_FDCAN_ESI(pTxHeader->ErrorStateIndicator));
2828   assert_param(IS_FDCAN_BRS(pTxHeader->BitRateSwitch));
2829   assert_param(IS_FDCAN_FDF(pTxHeader->FDFormat));
2830   assert_param(IS_FDCAN_EFC(pTxHeader->TxEventFifoControl));
2831   assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->MessageMarker, 0xFFU));
2832   assert_param(IS_FDCAN_TX_LOCATION(BufferIndex));
2833 
2834   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
2835   {
2836     /* Check that the selected buffer has an allocated area into the RAM */
2837     if (POSITION_VAL(BufferIndex) >= ((hfdcan->Instance->TXBC & FDCAN_TXBC_NDTB) >> FDCAN_TXBC_NDTB_Pos))
2838     {
2839       /* Update error code */
2840       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
2841 
2842       return HAL_ERROR;
2843     }
2844 
2845     /* Check that there is no transmission request pending for the selected buffer */
2846     if ((hfdcan->Instance->TXBRP & BufferIndex) != 0U)
2847     {
2848       /* Update error code */
2849       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PENDING;
2850 
2851       return HAL_ERROR;
2852     }
2853     else
2854     {
2855       /* Add the message to the Tx buffer */
2856       FDCAN_CopyMessageToRAM(hfdcan, pTxHeader, pTxData, POSITION_VAL(BufferIndex));
2857     }
2858 
2859     /* Return function status */
2860     return HAL_OK;
2861   }
2862   else
2863   {
2864     /* Update error code */
2865     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
2866 
2867     return HAL_ERROR;
2868   }
2869 }
2870 
2871 /**
2872   * @brief  Enable transmission request.
2873   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2874   *         the configuration information for the specified FDCAN.
2875   * @param  BufferIndex buffer index.
2876   *         This parameter can be any combination of @arg FDCAN_Tx_location.
2877   * @retval HAL status
2878   */
2879 HAL_StatusTypeDef HAL_FDCAN_EnableTxBufferRequest(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndex)
2880 {
2881   if (hfdcan->State == HAL_FDCAN_STATE_BUSY)
2882   {
2883     /* Add transmission request */
2884     hfdcan->Instance->TXBAR = BufferIndex;
2885 
2886     /* Return function status */
2887     return HAL_OK;
2888   }
2889   else
2890   {
2891     /* Update error code */
2892     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
2893 
2894     return HAL_ERROR;
2895   }
2896 }
2897 
2898 /**
2899   * @brief  Get Tx buffer index of latest Tx FIFO/Queue request
2900   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2901   *         the configuration information for the specified FDCAN.
2902   * @retval Tx buffer index of last Tx FIFO/Queue request
2903   *          - Any value of @arg FDCAN_Tx_location if Tx request has been submitted.
2904   *          - 0 if no Tx FIFO/Queue request have been submitted.
2905   */
2906 uint32_t HAL_FDCAN_GetLatestTxFifoQRequestBuffer(const FDCAN_HandleTypeDef *hfdcan)
2907 {
2908   /* Return Last Tx FIFO/Queue Request Buffer */
2909   return hfdcan->LatestTxFifoQRequest;
2910 }
2911 
2912 /**
2913   * @brief  Abort transmission request
2914   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2915   *         the configuration information for the specified FDCAN.
2916   * @param  BufferIndex buffer index.
2917   *         This parameter can be any combination of @arg FDCAN_Tx_location.
2918   * @retval HAL status
2919   */
2920 HAL_StatusTypeDef HAL_FDCAN_AbortTxRequest(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndex)
2921 {
2922   if (hfdcan->State == HAL_FDCAN_STATE_BUSY)
2923   {
2924     /* Add cancellation request */
2925     hfdcan->Instance->TXBCR = BufferIndex;
2926 
2927     /* Return function status */
2928     return HAL_OK;
2929   }
2930   else
2931   {
2932     /* Update error code */
2933     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
2934 
2935     return HAL_ERROR;
2936   }
2937 }
2938 
2939 /**
2940   * @brief  Get an FDCAN frame from the Rx Buffer/FIFO zone into the message RAM.
2941   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2942   *         the configuration information for the specified FDCAN.
2943   * @param  RxLocation Location of the received message to be read.
2944   *         This parameter can be a value of @arg FDCAN_Rx_location.
2945   * @param  pRxHeader pointer to a FDCAN_RxHeaderTypeDef structure.
2946   * @param  pRxData pointer to a buffer where the payload of the Rx frame will be stored.
2947   * @retval HAL status
2948   */
2949 HAL_StatusTypeDef HAL_FDCAN_GetRxMessage(FDCAN_HandleTypeDef *hfdcan, uint32_t RxLocation,
2950                                          FDCAN_RxHeaderTypeDef *pRxHeader, uint8_t *pRxData)
2951 {
2952   uint32_t *RxAddress;
2953   uint8_t  *pData;
2954   uint32_t ByteCounter;
2955   uint32_t GetIndex = 0;
2956   HAL_FDCAN_StateTypeDef state = hfdcan->State;
2957 
2958   if (state == HAL_FDCAN_STATE_BUSY)
2959   {
2960     if (RxLocation == FDCAN_RX_FIFO0) /* Rx element is assigned to the Rx FIFO 0 */
2961     {
2962       /* Check that the Rx FIFO 0 has an allocated area into the RAM */
2963       if ((hfdcan->Instance->RXF0C & FDCAN_RXF0C_F0S) == 0U)
2964       {
2965         /* Update error code */
2966         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
2967 
2968         return HAL_ERROR;
2969       }
2970 
2971       /* Check that the Rx FIFO 0 is not empty */
2972       if ((hfdcan->Instance->RXF0S & FDCAN_RXF0S_F0FL) == 0U)
2973       {
2974         /* Update error code */
2975         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_EMPTY;
2976 
2977         return HAL_ERROR;
2978       }
2979       else
2980       {
2981         /* Check that the Rx FIFO 0 is full & overwrite mode is on */
2982         if (((hfdcan->Instance->RXF0S & FDCAN_RXF0S_F0F) >> FDCAN_RXF0S_F0F_Pos) == 1U)
2983         {
2984           if (((hfdcan->Instance->RXF0C & FDCAN_RXF0C_F0OM) >> FDCAN_RXF0C_F0OM_Pos) == FDCAN_RX_FIFO_OVERWRITE)
2985           {
2986             /* When overwrite status is on discard first message in FIFO */
2987             GetIndex = 1U;
2988           }
2989         }
2990 
2991         /* Calculate Rx FIFO 0 element index */
2992         GetIndex += ((hfdcan->Instance->RXF0S & FDCAN_RXF0S_F0GI) >> FDCAN_RXF0S_F0GI_Pos);
2993 
2994         /* Calculate Rx FIFO 0 element address */
2995         RxAddress = (uint32_t *)(hfdcan->msgRam.RxFIFO0SA + (GetIndex * hfdcan->Init.RxFifo0ElmtSize * 4U));
2996       }
2997     }
2998     else if (RxLocation == FDCAN_RX_FIFO1) /* Rx element is assigned to the Rx FIFO 1 */
2999     {
3000       /* Check that the Rx FIFO 1 has an allocated area into the RAM */
3001       if ((hfdcan->Instance->RXF1C & FDCAN_RXF1C_F1S) == 0U)
3002       {
3003         /* Update error code */
3004         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
3005 
3006         return HAL_ERROR;
3007       }
3008 
3009       /* Check that the Rx FIFO 1 is not empty */
3010       if ((hfdcan->Instance->RXF1S & FDCAN_RXF1S_F1FL) == 0U)
3011       {
3012         /* Update error code */
3013         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_EMPTY;
3014 
3015         return HAL_ERROR;
3016       }
3017       else
3018       {
3019         /* Check that the Rx FIFO 1 is full & overwrite mode is on */
3020         if (((hfdcan->Instance->RXF1S & FDCAN_RXF1S_F1F) >> FDCAN_RXF1S_F1F_Pos) == 1U)
3021         {
3022           if (((hfdcan->Instance->RXF1C & FDCAN_RXF1C_F1OM) >> FDCAN_RXF1C_F1OM_Pos) == FDCAN_RX_FIFO_OVERWRITE)
3023           {
3024             /* When overwrite status is on discard first message in FIFO */
3025             GetIndex = 1U;
3026           }
3027         }
3028 
3029         /* Calculate Rx FIFO 1 element index */
3030         GetIndex += ((hfdcan->Instance->RXF1S & FDCAN_RXF1S_F1GI) >> FDCAN_RXF1S_F1GI_Pos);
3031 
3032         /* Calculate Rx FIFO 1 element address */
3033         RxAddress = (uint32_t *)(hfdcan->msgRam.RxFIFO1SA + (GetIndex * hfdcan->Init.RxFifo1ElmtSize * 4U));
3034       }
3035     }
3036     else /* Rx element is assigned to a dedicated Rx buffer */
3037     {
3038       /* Check that the selected buffer has an allocated area into the RAM */
3039       if (RxLocation >= hfdcan->Init.RxBuffersNbr)
3040       {
3041         /* Update error code */
3042         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
3043 
3044         return HAL_ERROR;
3045       }
3046       else
3047       {
3048         /* Calculate Rx buffer address */
3049         RxAddress = (uint32_t *)(hfdcan->msgRam.RxBufferSA + (RxLocation * hfdcan->Init.RxBufferSize * 4U));
3050       }
3051     }
3052 
3053     /* Retrieve IdType */
3054     pRxHeader->IdType = *RxAddress & FDCAN_ELEMENT_MASK_XTD;
3055 
3056     /* Retrieve Identifier */
3057     if (pRxHeader->IdType == FDCAN_STANDARD_ID) /* Standard ID element */
3058     {
3059       pRxHeader->Identifier = ((*RxAddress & FDCAN_ELEMENT_MASK_STDID) >> 18U);
3060     }
3061     else /* Extended ID element */
3062     {
3063       pRxHeader->Identifier = (*RxAddress & FDCAN_ELEMENT_MASK_EXTID);
3064     }
3065 
3066     /* Retrieve RxFrameType */
3067     pRxHeader->RxFrameType = (*RxAddress & FDCAN_ELEMENT_MASK_RTR);
3068 
3069     /* Retrieve ErrorStateIndicator */
3070     pRxHeader->ErrorStateIndicator = (*RxAddress & FDCAN_ELEMENT_MASK_ESI);
3071 
3072     /* Increment RxAddress pointer to second word of Rx FIFO element */
3073     RxAddress++;
3074 
3075     /* Retrieve RxTimestamp */
3076     pRxHeader->RxTimestamp = (*RxAddress & FDCAN_ELEMENT_MASK_TS);
3077 
3078     /* Retrieve DataLength */
3079     pRxHeader->DataLength = ((*RxAddress & FDCAN_ELEMENT_MASK_DLC) >> 16U);
3080 
3081     /* Retrieve BitRateSwitch */
3082     pRxHeader->BitRateSwitch = (*RxAddress & FDCAN_ELEMENT_MASK_BRS);
3083 
3084     /* Retrieve FDFormat */
3085     pRxHeader->FDFormat = (*RxAddress & FDCAN_ELEMENT_MASK_FDF);
3086 
3087     /* Retrieve FilterIndex */
3088     pRxHeader->FilterIndex = ((*RxAddress & FDCAN_ELEMENT_MASK_FIDX) >> 24U);
3089 
3090     /* Retrieve NonMatchingFrame */
3091     pRxHeader->IsFilterMatchingFrame = ((*RxAddress & FDCAN_ELEMENT_MASK_ANMF) >> 31U);
3092 
3093     /* Increment RxAddress pointer to payload of Rx FIFO element */
3094     RxAddress++;
3095 
3096     /* Retrieve Rx payload */
3097     pData = (uint8_t *)RxAddress;
3098     for (ByteCounter = 0; ByteCounter < DLCtoBytes[pRxHeader->DataLength]; ByteCounter++)
3099     {
3100       pRxData[ByteCounter] = pData[ByteCounter];
3101     }
3102 
3103     if (RxLocation == FDCAN_RX_FIFO0) /* Rx element is assigned to the Rx FIFO 0 */
3104     {
3105       /* Acknowledge the Rx FIFO 0 that the oldest element is read so that it increments the GetIndex */
3106       hfdcan->Instance->RXF0A = GetIndex;
3107     }
3108     else if (RxLocation == FDCAN_RX_FIFO1) /* Rx element is assigned to the Rx FIFO 1 */
3109     {
3110       /* Acknowledge the Rx FIFO 1 that the oldest element is read so that it increments the GetIndex */
3111       hfdcan->Instance->RXF1A = GetIndex;
3112     }
3113     else /* Rx element is assigned to a dedicated Rx buffer */
3114     {
3115       /* Clear the New Data flag of the current Rx buffer */
3116       if (RxLocation < FDCAN_RX_BUFFER32)
3117       {
3118         hfdcan->Instance->NDAT1 = ((uint32_t)1U << RxLocation);
3119       }
3120       else /* FDCAN_RX_BUFFER32 <= RxLocation <= FDCAN_RX_BUFFER63 */
3121       {
3122         hfdcan->Instance->NDAT2 = ((uint32_t)1U << (RxLocation & 0x1FU));
3123       }
3124     }
3125 
3126     /* Return function status */
3127     return HAL_OK;
3128   }
3129   else
3130   {
3131     /* Update error code */
3132     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
3133 
3134     return HAL_ERROR;
3135   }
3136 }
3137 
3138 /**
3139   * @brief  Get an FDCAN Tx event from the Tx Event FIFO zone into the message RAM.
3140   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3141   *         the configuration information for the specified FDCAN.
3142   * @param  pTxEvent pointer to a FDCAN_TxEventFifoTypeDef structure.
3143   * @retval HAL status
3144   */
3145 HAL_StatusTypeDef HAL_FDCAN_GetTxEvent(FDCAN_HandleTypeDef *hfdcan, FDCAN_TxEventFifoTypeDef *pTxEvent)
3146 {
3147   uint32_t *TxEventAddress;
3148   uint32_t GetIndex;
3149   HAL_FDCAN_StateTypeDef state = hfdcan->State;
3150 
3151   /* Check function parameters */
3152   assert_param(IS_FDCAN_MIN_VALUE(hfdcan->Init.TxEventsNbr, 1U));
3153 
3154   if (state == HAL_FDCAN_STATE_BUSY)
3155   {
3156     /* Check that the Tx Event FIFO has an allocated area into the RAM */
3157     if ((hfdcan->Instance->TXEFC & FDCAN_TXEFC_EFS) == 0U)
3158     {
3159       /* Update error code */
3160       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
3161 
3162       return HAL_ERROR;
3163     }
3164 
3165     /* Check that the Tx event FIFO is not empty */
3166     if ((hfdcan->Instance->TXEFS & FDCAN_TXEFS_EFFL) == 0U)
3167     {
3168       /* Update error code */
3169       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_EMPTY;
3170 
3171       return HAL_ERROR;
3172     }
3173 
3174     /* Calculate Tx event FIFO element address */
3175     GetIndex = ((hfdcan->Instance->TXEFS & FDCAN_TXEFS_EFGI) >> FDCAN_TXEFS_EFGI_Pos);
3176     TxEventAddress = (uint32_t *)(hfdcan->msgRam.TxEventFIFOSA + (GetIndex * 2U * 4U));
3177 
3178     /* Retrieve IdType */
3179     pTxEvent->IdType = *TxEventAddress & FDCAN_ELEMENT_MASK_XTD;
3180 
3181     /* Retrieve Identifier */
3182     if (pTxEvent->IdType == FDCAN_STANDARD_ID) /* Standard ID element */
3183     {
3184       pTxEvent->Identifier = ((*TxEventAddress & FDCAN_ELEMENT_MASK_STDID) >> 18U);
3185     }
3186     else /* Extended ID element */
3187     {
3188       pTxEvent->Identifier = (*TxEventAddress & FDCAN_ELEMENT_MASK_EXTID);
3189     }
3190 
3191     /* Retrieve TxFrameType */
3192     pTxEvent->TxFrameType = (*TxEventAddress & FDCAN_ELEMENT_MASK_RTR);
3193 
3194     /* Retrieve ErrorStateIndicator */
3195     pTxEvent->ErrorStateIndicator = (*TxEventAddress & FDCAN_ELEMENT_MASK_ESI);
3196 
3197     /* Increment TxEventAddress pointer to second word of Tx Event FIFO element */
3198     TxEventAddress++;
3199 
3200     /* Retrieve TxTimestamp */
3201     pTxEvent->TxTimestamp = (*TxEventAddress & FDCAN_ELEMENT_MASK_TS);
3202 
3203     /* Retrieve DataLength */
3204     pTxEvent->DataLength = ((*TxEventAddress & FDCAN_ELEMENT_MASK_DLC) >> 16U);
3205 
3206     /* Retrieve BitRateSwitch */
3207     pTxEvent->BitRateSwitch = (*TxEventAddress & FDCAN_ELEMENT_MASK_BRS);
3208 
3209     /* Retrieve FDFormat */
3210     pTxEvent->FDFormat = (*TxEventAddress & FDCAN_ELEMENT_MASK_FDF);
3211 
3212     /* Retrieve EventType */
3213     pTxEvent->EventType = (*TxEventAddress & FDCAN_ELEMENT_MASK_ET);
3214 
3215     /* Retrieve MessageMarker */
3216     pTxEvent->MessageMarker = ((*TxEventAddress & FDCAN_ELEMENT_MASK_MM) >> 24U);
3217 
3218     /* Acknowledge the Tx Event FIFO that the oldest element is read so that it increments the GetIndex */
3219     hfdcan->Instance->TXEFA = GetIndex;
3220 
3221     /* Return function status */
3222     return HAL_OK;
3223   }
3224   else
3225   {
3226     /* Update error code */
3227     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
3228 
3229     return HAL_ERROR;
3230   }
3231 }
3232 
3233 /**
3234   * @brief  Get high priority message status.
3235   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3236   *         the configuration information for the specified FDCAN.
3237   * @param  HpMsgStatus pointer to an FDCAN_HpMsgStatusTypeDef structure.
3238   * @retval HAL status
3239   */
3240 HAL_StatusTypeDef HAL_FDCAN_GetHighPriorityMessageStatus(const FDCAN_HandleTypeDef *hfdcan,
3241                                                          FDCAN_HpMsgStatusTypeDef *HpMsgStatus)
3242 {
3243   HpMsgStatus->FilterList = ((hfdcan->Instance->HPMS & FDCAN_HPMS_FLST) >> FDCAN_HPMS_FLST_Pos);
3244   HpMsgStatus->FilterIndex = ((hfdcan->Instance->HPMS & FDCAN_HPMS_FIDX) >> FDCAN_HPMS_FIDX_Pos);
3245   HpMsgStatus->MessageStorage = (hfdcan->Instance->HPMS & FDCAN_HPMS_MSI);
3246   HpMsgStatus->MessageIndex = (hfdcan->Instance->HPMS & FDCAN_HPMS_BIDX);
3247 
3248   /* Return function status */
3249   return HAL_OK;
3250 }
3251 
3252 /**
3253   * @brief  Get protocol status.
3254   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3255   *         the configuration information for the specified FDCAN.
3256   * @param  ProtocolStatus pointer to an FDCAN_ProtocolStatusTypeDef structure.
3257   * @retval HAL status
3258   */
3259 HAL_StatusTypeDef HAL_FDCAN_GetProtocolStatus(const FDCAN_HandleTypeDef *hfdcan,
3260                                               FDCAN_ProtocolStatusTypeDef *ProtocolStatus)
3261 {
3262   uint32_t StatusReg;
3263 
3264   /* Read the protocol status register */
3265   StatusReg = READ_REG(hfdcan->Instance->PSR);
3266 
3267   /* Fill the protocol status structure */
3268   ProtocolStatus->LastErrorCode = (StatusReg & FDCAN_PSR_LEC);
3269   ProtocolStatus->DataLastErrorCode = ((StatusReg & FDCAN_PSR_DLEC) >> FDCAN_PSR_DLEC_Pos);
3270   ProtocolStatus->Activity = (StatusReg & FDCAN_PSR_ACT);
3271   ProtocolStatus->ErrorPassive = ((StatusReg & FDCAN_PSR_EP) >> FDCAN_PSR_EP_Pos);
3272   ProtocolStatus->Warning = ((StatusReg & FDCAN_PSR_EW) >> FDCAN_PSR_EW_Pos);
3273   ProtocolStatus->BusOff = ((StatusReg & FDCAN_PSR_BO) >> FDCAN_PSR_BO_Pos);
3274   ProtocolStatus->RxESIflag = ((StatusReg & FDCAN_PSR_RESI) >> FDCAN_PSR_RESI_Pos);
3275   ProtocolStatus->RxBRSflag = ((StatusReg & FDCAN_PSR_RBRS) >> FDCAN_PSR_RBRS_Pos);
3276   ProtocolStatus->RxFDFflag = ((StatusReg & FDCAN_PSR_REDL) >> FDCAN_PSR_REDL_Pos);
3277   ProtocolStatus->ProtocolException = ((StatusReg & FDCAN_PSR_PXE) >> FDCAN_PSR_PXE_Pos);
3278   ProtocolStatus->TDCvalue = ((StatusReg & FDCAN_PSR_TDCV) >> FDCAN_PSR_TDCV_Pos);
3279 
3280   /* Return function status */
3281   return HAL_OK;
3282 }
3283 
3284 /**
3285   * @brief  Get error counter values.
3286   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3287   *         the configuration information for the specified FDCAN.
3288   * @param  ErrorCounters pointer to an FDCAN_ErrorCountersTypeDef structure.
3289   * @retval HAL status
3290   */
3291 HAL_StatusTypeDef HAL_FDCAN_GetErrorCounters(const FDCAN_HandleTypeDef *hfdcan,
3292                                              FDCAN_ErrorCountersTypeDef *ErrorCounters)
3293 {
3294   uint32_t CountersReg;
3295 
3296   /* Read the error counters register */
3297   CountersReg = READ_REG(hfdcan->Instance->ECR);
3298 
3299   /* Fill the error counters structure */
3300   ErrorCounters->TxErrorCnt = ((CountersReg & FDCAN_ECR_TEC) >> FDCAN_ECR_TEC_Pos);
3301   ErrorCounters->RxErrorCnt = ((CountersReg & FDCAN_ECR_REC) >> FDCAN_ECR_REC_Pos);
3302   ErrorCounters->RxErrorPassive = ((CountersReg & FDCAN_ECR_RP) >> FDCAN_ECR_RP_Pos);
3303   ErrorCounters->ErrorLogging = ((CountersReg & FDCAN_ECR_CEL) >> FDCAN_ECR_CEL_Pos);
3304 
3305   /* Return function status */
3306   return HAL_OK;
3307 }
3308 
3309 /**
3310   * @brief  Check if a new message is received in the selected Rx buffer.
3311   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3312   *         the configuration information for the specified FDCAN.
3313   * @param  RxBufferIndex Rx buffer index.
3314   *         This parameter must be a number between 0 and 63.
3315   * @retval Status
3316   *          - 0 : No new message on RxBufferIndex.
3317   *          - 1 : New message received on RxBufferIndex.
3318   */
3319 uint32_t HAL_FDCAN_IsRxBufferMessageAvailable(FDCAN_HandleTypeDef *hfdcan, uint32_t RxBufferIndex)
3320 {
3321   /* Check function parameters */
3322   assert_param(IS_FDCAN_MAX_VALUE(RxBufferIndex, 63U));
3323   uint32_t NewData1 = hfdcan->Instance->NDAT1;
3324   uint32_t NewData2 = hfdcan->Instance->NDAT2;
3325 
3326   /* Check new message reception on the selected buffer */
3327   if (((RxBufferIndex < 32U) && ((NewData1 & (uint32_t)((uint32_t)1 << RxBufferIndex)) == 0U)) ||
3328       ((RxBufferIndex >= 32U) && ((NewData2 & (uint32_t)((uint32_t)1 << (RxBufferIndex & 0x1FU))) == 0U)))
3329   {
3330     return 0;
3331   }
3332 
3333   /* Clear the New Data flag of the current Rx buffer */
3334   if (RxBufferIndex < 32U)
3335   {
3336     hfdcan->Instance->NDAT1 = ((uint32_t)1 << RxBufferIndex);
3337   }
3338   else /* 32 <= RxBufferIndex <= 63 */
3339   {
3340     hfdcan->Instance->NDAT2 = ((uint32_t)1 << (RxBufferIndex & 0x1FU));
3341   }
3342 
3343   return 1;
3344 }
3345 
3346 /**
3347   * @brief  Check if a transmission request is pending on the selected Tx buffer.
3348   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3349   *         the configuration information for the specified FDCAN.
3350   * @param  TxBufferIndex Tx buffer index.
3351   *         This parameter can be any combination of @arg FDCAN_Tx_location.
3352   * @retval Status
3353   *          - 0 : No pending transmission request on TxBufferIndex.
3354   *          - 1 : Pending transmission request on TxBufferIndex.
3355   */
3356 uint32_t HAL_FDCAN_IsTxBufferMessagePending(const FDCAN_HandleTypeDef *hfdcan, uint32_t TxBufferIndex)
3357 {
3358   /* Check pending transmission request on the selected buffer */
3359   if ((hfdcan->Instance->TXBRP & TxBufferIndex) == 0U)
3360   {
3361     return 0;
3362   }
3363   return 1;
3364 }
3365 
3366 /**
3367   * @brief  Return Rx FIFO fill level.
3368   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3369   *         the configuration information for the specified FDCAN.
3370   * @param  RxFifo Rx FIFO.
3371   *         This parameter can be one of the following values:
3372   *           @arg FDCAN_RX_FIFO0: Rx FIFO 0
3373   *           @arg FDCAN_RX_FIFO1: Rx FIFO 1
3374   * @retval Rx FIFO fill level.
3375   */
3376 uint32_t HAL_FDCAN_GetRxFifoFillLevel(const FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo)
3377 {
3378   uint32_t FillLevel;
3379 
3380   /* Check function parameters */
3381   assert_param(IS_FDCAN_RX_FIFO(RxFifo));
3382 
3383   if (RxFifo == FDCAN_RX_FIFO0)
3384   {
3385     FillLevel = hfdcan->Instance->RXF0S & FDCAN_RXF0S_F0FL;
3386   }
3387   else /* RxFifo == FDCAN_RX_FIFO1 */
3388   {
3389     FillLevel = hfdcan->Instance->RXF1S & FDCAN_RXF1S_F1FL;
3390   }
3391 
3392   /* Return Rx FIFO fill level */
3393   return FillLevel;
3394 }
3395 
3396 /**
3397   * @brief  Return Tx FIFO free level: number of consecutive free Tx FIFO
3398   *         elements starting from Tx FIFO GetIndex.
3399   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3400   *         the configuration information for the specified FDCAN.
3401   * @retval Tx FIFO free level.
3402   */
3403 uint32_t HAL_FDCAN_GetTxFifoFreeLevel(const FDCAN_HandleTypeDef *hfdcan)
3404 {
3405   uint32_t FreeLevel;
3406 
3407   FreeLevel = hfdcan->Instance->TXFQS & FDCAN_TXFQS_TFFL;
3408 
3409   /* Return Tx FIFO free level */
3410   return FreeLevel;
3411 }
3412 
3413 /**
3414   * @brief  Check if the FDCAN peripheral entered Restricted Operation Mode.
3415   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3416   *         the configuration information for the specified FDCAN.
3417   * @retval Status
3418   *          - 0 : Normal FDCAN operation.
3419   *          - 1 : Restricted Operation Mode active.
3420   */
3421 uint32_t HAL_FDCAN_IsRestrictedOperationMode(const FDCAN_HandleTypeDef *hfdcan)
3422 {
3423   uint32_t OperationMode;
3424 
3425   /* Get Operation Mode */
3426   OperationMode = ((hfdcan->Instance->CCCR & FDCAN_CCCR_ASM) >> FDCAN_CCCR_ASM_Pos);
3427 
3428   return OperationMode;
3429 }
3430 
3431 /**
3432   * @brief  Exit Restricted Operation Mode.
3433   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3434   *         the configuration information for the specified FDCAN.
3435   * @retval HAL status
3436   */
3437 HAL_StatusTypeDef HAL_FDCAN_ExitRestrictedOperationMode(FDCAN_HandleTypeDef *hfdcan)
3438 {
3439   HAL_FDCAN_StateTypeDef state = hfdcan->State;
3440 
3441   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3442   {
3443     /* Exit Restricted Operation mode */
3444     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_ASM);
3445 
3446     /* Return function status */
3447     return HAL_OK;
3448   }
3449   else
3450   {
3451     /* Update error code */
3452     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3453 
3454     return HAL_ERROR;
3455   }
3456 }
3457 
3458 /**
3459   * @}
3460   */
3461 
3462 /** @defgroup FDCAN_Exported_Functions_Group4 TT Configuration and control functions
3463   * @ingroup RTEMSBSPsARMSTM32H7
3464   *  @brief    TT Configuration and control functions
3465   *
3466 @verbatim
3467   ==============================================================================
3468               ##### TT Configuration and control functions #####
3469   ==============================================================================
3470     [..]  This section provides functions allowing to:
3471       (+) HAL_FDCAN_TT_ConfigOperation                  : Initialize TT operation parameters
3472       (+) HAL_FDCAN_TT_ConfigReferenceMessage           : Configure the reference message
3473       (+) HAL_FDCAN_TT_ConfigTrigger                    : Configure the FDCAN trigger
3474       (+) HAL_FDCAN_TT_SetGlobalTime                    : Schedule global time adjustment
3475       (+) HAL_FDCAN_TT_SetClockSynchronization          : Schedule TUR numerator update
3476       (+) HAL_FDCAN_TT_ConfigStopWatch                  : Configure stop watch source and polarity
3477       (+) HAL_FDCAN_TT_ConfigRegisterTimeMark           : Configure register time mark pulse generation
3478         (+) HAL_FDCAN_TT_EnableRegisterTimeMarkPulse      : Enable register time mark pulse generation
3479         (+) HAL_FDCAN_TT_DisableRegisterTimeMarkPulse     : Disable register time mark pulse generation
3480       (+) HAL_FDCAN_TT_EnableTriggerTimeMarkPulse       : Enable trigger time mark pulse generation
3481       (+) HAL_FDCAN_TT_DisableTriggerTimeMarkPulse      : Disable trigger time mark pulse generation
3482       (+) HAL_FDCAN_TT_EnableHardwareGapControl         : Enable gap control by input pin fdcan1_evt
3483       (+) HAL_FDCAN_TT_DisableHardwareGapControl        : Disable gap control by input pin fdcan1_evt
3484       (+) HAL_FDCAN_TT_EnableTimeMarkGapControl         : Enable gap control (finish only) by register time mark IT
3485       (+) HAL_FDCAN_TT_DisableTimeMarkGapControl        : Disable gap control by register time mark interrupt
3486       (+) HAL_FDCAN_TT_SetNextIsGap                     : Transmit next reference message with Next_is_Gap = "1"
3487       (+) HAL_FDCAN_TT_SetEndOfGap                      : Finish a Gap by requesting start of reference message
3488       (+) HAL_FDCAN_TT_ConfigExternalSyncPhase          : Configure target phase used for external synchronization
3489         (+) HAL_FDCAN_TT_EnableExternalSynchronization    : Synchronize the phase of the FDCAN schedule to an external
3490                                                             schedule
3491         (+) HAL_FDCAN_TT_DisableExternalSynchronization   : Disable external schedule synchronization
3492       (+) HAL_FDCAN_TT_GetOperationStatus               : Get TT operation status
3493 
3494 @endverbatim
3495   * @{
3496   */
3497 
3498 /**
3499   * @brief  Initialize TT operation parameters.
3500   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3501   *         the configuration information for the specified FDCAN.
3502   * @param  pTTParams pointer to a FDCAN_TT_ConfigTypeDef structure.
3503   * @retval HAL status
3504   */
3505 HAL_StatusTypeDef HAL_FDCAN_TT_ConfigOperation(FDCAN_HandleTypeDef *hfdcan, const FDCAN_TT_ConfigTypeDef *pTTParams)
3506 {
3507   uint32_t tickstart;
3508   uint32_t RAMcounter;
3509   uint32_t StartAddress;
3510 
3511   /* Check function parameters */
3512   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3513   assert_param(IS_FDCAN_TT_TUR_NUMERATOR(pTTParams->TURNumerator));
3514   assert_param(IS_FDCAN_TT_TUR_DENOMINATOR(pTTParams->TURDenominator));
3515   assert_param(IS_FDCAN_TT_TIME_MASTER(pTTParams->TimeMaster));
3516   assert_param(IS_FDCAN_MAX_VALUE(pTTParams->SyncDevLimit, 7U));
3517   assert_param(IS_FDCAN_MAX_VALUE(pTTParams->InitRefTrigOffset, 127U));
3518   assert_param(IS_FDCAN_MAX_VALUE(pTTParams->TriggerMemoryNbr, 64U));
3519   assert_param(IS_FDCAN_TT_CYCLE_START_SYNC(pTTParams->CycleStartSync));
3520   assert_param(IS_FDCAN_TT_STOP_WATCH_TRIGGER(pTTParams->StopWatchTrigSel));
3521   assert_param(IS_FDCAN_TT_EVENT_TRIGGER(pTTParams->EventTrigSel));
3522   if (pTTParams->TimeMaster == FDCAN_TT_POTENTIAL_MASTER)
3523   {
3524     assert_param(IS_FDCAN_TT_BASIC_CYCLES_NUMBER(pTTParams->BasicCyclesNbr));
3525   }
3526   if (pTTParams->OperationMode != FDCAN_TT_COMMUNICATION_LEVEL0)
3527   {
3528     assert_param(IS_FDCAN_TT_OPERATION(pTTParams->GapEnable));
3529     assert_param(IS_FDCAN_MAX_VALUE(pTTParams->AppWdgLimit, 255U));
3530     assert_param(IS_FDCAN_TT_EVENT_TRIGGER_POLARITY(pTTParams->EvtTrigPolarity));
3531     assert_param(IS_FDCAN_TT_TX_ENABLE_WINDOW(pTTParams->TxEnableWindow));
3532     assert_param(IS_FDCAN_MAX_VALUE(pTTParams->ExpTxTrigNbr, 4095U));
3533   }
3534   if (pTTParams->OperationMode != FDCAN_TT_COMMUNICATION_LEVEL1)
3535   {
3536     assert_param(IS_FDCAN_TT_TUR_LEVEL_0_2(pTTParams->TURNumerator, pTTParams->TURDenominator));
3537     assert_param(IS_FDCAN_TT_EXTERNAL_CLK_SYNC(pTTParams->ExternalClkSync));
3538     assert_param(IS_FDCAN_TT_GLOBAL_TIME_FILTERING(pTTParams->GlobalTimeFilter));
3539     assert_param(IS_FDCAN_TT_AUTO_CLK_CALIBRATION(pTTParams->ClockCalibration));
3540   }
3541   else
3542   {
3543     assert_param(IS_FDCAN_TT_TUR_LEVEL_1(pTTParams->TURNumerator, pTTParams->TURDenominator));
3544   }
3545 
3546   if (hfdcan->State == HAL_FDCAN_STATE_READY)
3547   {
3548     /* Stop local time in order to enable write access to the other bits of TURCF register */
3549     CLEAR_BIT(hfdcan->ttcan->TURCF, FDCAN_TURCF_ELT);
3550 
3551     /* Get tick */
3552     tickstart = HAL_GetTick();
3553 
3554     /* Wait until the ELT bit into TURCF register is reset */
3555     while ((hfdcan->ttcan->TURCF & FDCAN_TURCF_ELT) != 0U)
3556     {
3557       /* Check for the Timeout */
3558       if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE)
3559       {
3560         /* Update error code */
3561         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3562 
3563         /* Change FDCAN state */
3564         hfdcan->State = HAL_FDCAN_STATE_ERROR;
3565 
3566         return HAL_ERROR;
3567       }
3568     }
3569 
3570     /* Configure TUR (Time Unit Ratio) */
3571     MODIFY_REG(hfdcan->ttcan->TURCF,
3572                (FDCAN_TURCF_NCL | FDCAN_TURCF_DC),
3573                (((pTTParams->TURNumerator - 0x10000U) << FDCAN_TURCF_NCL_Pos) |
3574                 (pTTParams->TURDenominator << FDCAN_TURCF_DC_Pos)));
3575 
3576     /* Enable local time */
3577     SET_BIT(hfdcan->ttcan->TURCF, FDCAN_TURCF_ELT);
3578 
3579     /* Configure TT operation */
3580     MODIFY_REG(hfdcan->ttcan->TTOCF,
3581                (FDCAN_TTOCF_OM | FDCAN_TTOCF_TM | FDCAN_TTOCF_LDSDL | FDCAN_TTOCF_IRTO),
3582                (pTTParams->OperationMode                           | \
3583                 pTTParams->TimeMaster                              | \
3584                 (pTTParams->SyncDevLimit << FDCAN_TTOCF_LDSDL_Pos) | \
3585                 (pTTParams->InitRefTrigOffset << FDCAN_TTOCF_IRTO_Pos)));
3586     if (pTTParams->OperationMode != FDCAN_TT_COMMUNICATION_LEVEL0)
3587     {
3588       MODIFY_REG(hfdcan->ttcan->TTOCF,
3589                  (FDCAN_TTOCF_GEN | FDCAN_TTOCF_AWL | FDCAN_TTOCF_EVTP),
3590                  (pTTParams->GapEnable                            | \
3591                   (pTTParams->AppWdgLimit << FDCAN_TTOCF_AWL_Pos) | \
3592                   pTTParams->EvtTrigPolarity));
3593     }
3594     if (pTTParams->OperationMode != FDCAN_TT_COMMUNICATION_LEVEL1)
3595     {
3596       MODIFY_REG(hfdcan->ttcan->TTOCF,
3597                  (FDCAN_TTOCF_EECS | FDCAN_TTOCF_EGTF | FDCAN_TTOCF_ECC),
3598                  (pTTParams->ExternalClkSync  | \
3599                   pTTParams->GlobalTimeFilter | \
3600                   pTTParams->ClockCalibration));
3601     }
3602 
3603     /* Configure system matrix limits */
3604     MODIFY_REG(hfdcan->ttcan->TTMLM, FDCAN_TTMLM_CSS, pTTParams->CycleStartSync);
3605     if (pTTParams->OperationMode != FDCAN_TT_COMMUNICATION_LEVEL0)
3606     {
3607       MODIFY_REG(hfdcan->ttcan->TTMLM,
3608                  (FDCAN_TTMLM_TXEW | FDCAN_TTMLM_ENTT),
3609                  (((pTTParams->TxEnableWindow - 1U) << FDCAN_TTMLM_TXEW_Pos) |
3610                   (pTTParams->ExpTxTrigNbr << FDCAN_TTMLM_ENTT_Pos)));
3611     }
3612     if (pTTParams->TimeMaster == FDCAN_TT_POTENTIAL_MASTER)
3613     {
3614       MODIFY_REG(hfdcan->ttcan->TTMLM, FDCAN_TTMLM_CCM, pTTParams->BasicCyclesNbr);
3615     }
3616 
3617     /* Configure input triggers: Stop watch and Event */
3618     MODIFY_REG(hfdcan->ttcan->TTTS,
3619                (FDCAN_TTTS_SWTSEL | FDCAN_TTTS_EVTSEL),
3620                (pTTParams->StopWatchTrigSel | pTTParams->EventTrigSel));
3621 
3622     /* Configure trigger memory start address */
3623     StartAddress = (hfdcan->msgRam.EndAddress - SRAMCAN_BASE) / 4U;
3624     MODIFY_REG(hfdcan->ttcan->TTTMC, FDCAN_TTTMC_TMSA, (StartAddress << FDCAN_TTTMC_TMSA_Pos));
3625 
3626     /* Trigger memory elements number */
3627     MODIFY_REG(hfdcan->ttcan->TTTMC, FDCAN_TTTMC_TME, (pTTParams->TriggerMemoryNbr << FDCAN_TTTMC_TME_Pos));
3628 
3629     /* Recalculate End Address */
3630     hfdcan->msgRam.TTMemorySA = hfdcan->msgRam.EndAddress;
3631     hfdcan->msgRam.EndAddress = hfdcan->msgRam.TTMemorySA + (pTTParams->TriggerMemoryNbr * 2U * 4U);
3632 
3633     if (hfdcan->msgRam.EndAddress > FDCAN_MESSAGE_RAM_END_ADDRESS) /* Last address of the Message RAM */
3634     {
3635       /* Update error code.
3636          Message RAM overflow */
3637       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
3638 
3639       return HAL_ERROR;
3640     }
3641     else
3642     {
3643       /* Flush the allocated Message RAM area */
3644       for (RAMcounter = hfdcan->msgRam.TTMemorySA; RAMcounter < hfdcan->msgRam.EndAddress; RAMcounter += 4U)
3645       {
3646         *(uint32_t *)(RAMcounter) = 0x00000000;
3647       }
3648     }
3649 
3650     /* Return function status */
3651     return HAL_OK;
3652   }
3653   else
3654   {
3655     /* Update error code */
3656     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
3657 
3658     return HAL_ERROR;
3659   }
3660 }
3661 
3662 /**
3663   * @brief  Configure the reference message.
3664   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3665   *         the configuration information for the specified FDCAN.
3666   * @param  IdType Identifier Type.
3667   *         This parameter can be a value of @arg FDCAN_id_type.
3668   * @param  Identifier Reference Identifier.
3669   *         This parameter must be a number between:
3670   *           - 0 and 0x7FF, if IdType is FDCAN_STANDARD_ID
3671   *           - 0 and 0x1FFFFFFF, if IdType is FDCAN_EXTENDED_ID
3672   * @param  Payload Enable or disable the additional payload.
3673   *         This parameter can be a value of @arg FDCAN_TT_Reference_Message_Payload.
3674   *         This parameter is ignored in case of time slaves.
3675   *         If this parameter is set to FDCAN_TT_REF_MESSAGE_ADD_PAYLOAD, the
3676   *         following elements are taken from Tx Buffer 0:
3677   *          - MessageMarker
3678   *          - TxEventFifoControl
3679   *          - DataLength
3680   *          - Data Bytes (payload):
3681   *             - bytes 2-8, for Level 1
3682   *             - bytes 5-8, for Level 0 and Level 2
3683   * @retval HAL status
3684   */
3685 HAL_StatusTypeDef HAL_FDCAN_TT_ConfigReferenceMessage(FDCAN_HandleTypeDef *hfdcan, uint32_t IdType,
3686                                                       uint32_t Identifier, uint32_t Payload)
3687 {
3688   /* Check function parameters */
3689   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3690   assert_param(IS_FDCAN_ID_TYPE(IdType));
3691   if (IdType == FDCAN_STANDARD_ID)
3692   {
3693     assert_param(IS_FDCAN_MAX_VALUE(Identifier, 0x7FFU));
3694   }
3695   else /* IdType == FDCAN_EXTENDED_ID */
3696   {
3697     assert_param(IS_FDCAN_MAX_VALUE(Identifier, 0x1FFFFFFFU));
3698   }
3699   assert_param(IS_FDCAN_TT_REFERENCE_MESSAGE_PAYLOAD(Payload));
3700 
3701   if (hfdcan->State == HAL_FDCAN_STATE_READY)
3702   {
3703     /* Configure reference message identifier type, identifier and payload */
3704     if (IdType == FDCAN_EXTENDED_ID)
3705     {
3706       MODIFY_REG(hfdcan->ttcan->TTRMC, (FDCAN_TTRMC_RID | FDCAN_TTRMC_XTD | FDCAN_TTRMC_RMPS),
3707                  (Payload | IdType | Identifier));
3708     }
3709     else /* IdType == FDCAN_STANDARD_ID */
3710     {
3711       MODIFY_REG(hfdcan->ttcan->TTRMC, (FDCAN_TTRMC_RID | FDCAN_TTRMC_XTD | FDCAN_TTRMC_RMPS),
3712                  (Payload | IdType | (Identifier << 18)));
3713     }
3714 
3715     /* Return function status */
3716     return HAL_OK;
3717   }
3718   else
3719   {
3720     /* Update error code */
3721     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
3722 
3723     return HAL_ERROR;
3724   }
3725 }
3726 
3727 /**
3728   * @brief  Configure the FDCAN trigger according to the specified
3729   *         parameters in the FDCAN_TriggerTypeDef structure.
3730   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3731   *         the configuration information for the specified FDCAN.
3732   * @param  sTriggerConfig pointer to an FDCAN_TriggerTypeDef structure that
3733   *         contains the trigger configuration information
3734   * @retval HAL status
3735   */
3736 HAL_StatusTypeDef HAL_FDCAN_TT_ConfigTrigger(FDCAN_HandleTypeDef *hfdcan, const FDCAN_TriggerTypeDef *sTriggerConfig)
3737 {
3738   uint32_t CycleCode;
3739   uint32_t MessageNumber;
3740   uint32_t TriggerElementW1;
3741   uint32_t TriggerElementW2;
3742   uint32_t *TriggerAddress;
3743 
3744   /* Check function parameters */
3745   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3746   assert_param(IS_FDCAN_MAX_VALUE(sTriggerConfig->TriggerIndex, 63U));
3747   assert_param(IS_FDCAN_MAX_VALUE(sTriggerConfig->TimeMark, 0xFFFFU));
3748   assert_param(IS_FDCAN_TT_REPEAT_FACTOR(sTriggerConfig->RepeatFactor));
3749   if (sTriggerConfig->RepeatFactor != FDCAN_TT_REPEAT_EVERY_CYCLE)
3750   {
3751     assert_param(IS_FDCAN_MAX_VALUE(sTriggerConfig->StartCycle, (sTriggerConfig->RepeatFactor - 1U)));
3752   }
3753   assert_param(IS_FDCAN_TT_TM_EVENT_INTERNAL(sTriggerConfig->TmEventInt));
3754   assert_param(IS_FDCAN_TT_TM_EVENT_EXTERNAL(sTriggerConfig->TmEventExt));
3755   assert_param(IS_FDCAN_TT_TRIGGER_TYPE(sTriggerConfig->TriggerType));
3756   assert_param(IS_FDCAN_ID_TYPE(sTriggerConfig->FilterType));
3757   if ((sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_SINGLE) ||
3758       (sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_CONTINUOUS) ||
3759       (sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_ARBITRATION) ||
3760       (sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_MERGED))
3761   {
3762     assert_param(IS_FDCAN_TX_LOCATION(sTriggerConfig->TxBufferIndex));
3763   }
3764   if (sTriggerConfig->TriggerType == FDCAN_TT_RX_TRIGGER)
3765   {
3766     if (sTriggerConfig->FilterType == FDCAN_STANDARD_ID)
3767     {
3768       assert_param(IS_FDCAN_MAX_VALUE(sTriggerConfig->FilterIndex, 63U));
3769     }
3770     else /* sTriggerConfig->FilterType == FDCAN_EXTENDED_ID */
3771     {
3772       assert_param(IS_FDCAN_MAX_VALUE(sTriggerConfig->FilterIndex, 127U));
3773     }
3774   }
3775 
3776   if (hfdcan->State == HAL_FDCAN_STATE_READY)
3777   {
3778     /* Calculate cycle code */
3779     if (sTriggerConfig->RepeatFactor == FDCAN_TT_REPEAT_EVERY_CYCLE)
3780     {
3781       CycleCode = FDCAN_TT_REPEAT_EVERY_CYCLE;
3782     }
3783     else /* sTriggerConfig->RepeatFactor != FDCAN_TT_REPEAT_EVERY_CYCLE */
3784     {
3785       CycleCode = sTriggerConfig->RepeatFactor + sTriggerConfig->StartCycle;
3786     }
3787 
3788     /* Build first word of trigger element */
3789     TriggerElementW1 = ((sTriggerConfig->TimeMark << 16) | \
3790                         (CycleCode << 8)                 | \
3791                         sTriggerConfig->TmEventInt       | \
3792                         sTriggerConfig->TmEventExt       | \
3793                         sTriggerConfig->TriggerType);
3794 
3795     /* Select message number depending on trigger type (transmission or reception) */
3796     if (sTriggerConfig->TriggerType == FDCAN_TT_RX_TRIGGER)
3797     {
3798       MessageNumber = sTriggerConfig->FilterIndex;
3799     }
3800     else if ((sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_SINGLE) ||
3801              (sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_CONTINUOUS) ||
3802              (sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_ARBITRATION) ||
3803              (sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_MERGED))
3804     {
3805       MessageNumber = POSITION_VAL(sTriggerConfig->TxBufferIndex);
3806     }
3807     else
3808     {
3809       MessageNumber = 0U;
3810     }
3811 
3812     /* Build second word of trigger element */
3813     TriggerElementW2 = ((sTriggerConfig->FilterType >> 7) | (MessageNumber << 16));
3814 
3815     /* Calculate trigger address */
3816     TriggerAddress = (uint32_t *)(hfdcan->msgRam.TTMemorySA + (sTriggerConfig->TriggerIndex * 4U * 2U));
3817 
3818     /* Write trigger element to the message RAM */
3819     *TriggerAddress = TriggerElementW1;
3820     TriggerAddress++;
3821     *TriggerAddress = TriggerElementW2;
3822 
3823     /* Return function status */
3824     return HAL_OK;
3825   }
3826   else
3827   {
3828     /* Update error code */
3829     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
3830 
3831     return HAL_ERROR;
3832   }
3833 }
3834 
3835 /**
3836   * @brief  Schedule global time adjustment for the next reference message.
3837   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3838   *         the configuration information for the specified FDCAN.
3839   * @param  TimePreset time preset value.
3840   *         This parameter must be a number between:
3841   *           - 0x0000 and 0x7FFF, Next_Master_Ref_Mark = Current_Master_Ref_Mark + TimePreset
3842   *           or
3843   *           - 0x8001 and 0xFFFF, Next_Master_Ref_Mark = Current_Master_Ref_Mark - (0x10000 - TimePreset)
3844   * @retval HAL status
3845   */
3846 HAL_StatusTypeDef HAL_FDCAN_TT_SetGlobalTime(FDCAN_HandleTypeDef *hfdcan, uint32_t TimePreset)
3847 {
3848   uint32_t Counter = 0U;
3849   HAL_FDCAN_StateTypeDef state = hfdcan->State;
3850 
3851   /* Check function parameters */
3852   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3853   assert_param(IS_FDCAN_TT_TIME_PRESET(TimePreset));
3854 
3855   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3856   {
3857     /* Check that the external clock synchronization is enabled */
3858     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_EECS) != FDCAN_TTOCF_EECS)
3859     {
3860       /* Update error code */
3861       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
3862 
3863       return HAL_ERROR;
3864     }
3865 
3866     /* Check that no global time preset is pending */
3867     if ((hfdcan->ttcan->TTOST & FDCAN_TTOST_WGTD) == FDCAN_TTOST_WGTD)
3868     {
3869       /* Update error code */
3870       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PENDING;
3871 
3872       return HAL_ERROR;
3873     }
3874 
3875     /* Configure time preset */
3876     MODIFY_REG(hfdcan->ttcan->TTGTP, FDCAN_TTGTP_TP, (TimePreset << FDCAN_TTGTP_TP_Pos));
3877 
3878     /* Wait until the LCKC bit into TTOCN register is reset */
3879     while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
3880     {
3881       /* Check for the Timeout */
3882       if (Counter > FDCAN_TIMEOUT_COUNT)
3883       {
3884         /* Update error code */
3885         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3886 
3887         /* Change FDCAN state */
3888         hfdcan->State = HAL_FDCAN_STATE_ERROR;
3889 
3890         return HAL_ERROR;
3891       }
3892 
3893       /* Increment counter */
3894       Counter++;
3895     }
3896 
3897     /* Schedule time preset to take effect by the next reference message */
3898     SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_SGT);
3899 
3900     /* Return function status */
3901     return HAL_OK;
3902   }
3903   else
3904   {
3905     /* Update error code */
3906     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3907 
3908     return HAL_ERROR;
3909   }
3910 }
3911 
3912 /**
3913   * @brief  Schedule TUR numerator update for the next reference message.
3914   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3915   *         the configuration information for the specified FDCAN.
3916   * @param  NewTURNumerator new value of the TUR numerator.
3917   *         This parameter must be a number between 0x10000 and 0x1FFFF.
3918   * @retval HAL status
3919   */
3920 HAL_StatusTypeDef HAL_FDCAN_TT_SetClockSynchronization(FDCAN_HandleTypeDef *hfdcan, uint32_t NewTURNumerator)
3921 {
3922   uint32_t Counter = 0U;
3923   HAL_FDCAN_StateTypeDef state = hfdcan->State;
3924 
3925   /* Check function parameters */
3926   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3927   assert_param(IS_FDCAN_TT_TUR_NUMERATOR(NewTURNumerator));
3928 
3929   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3930   {
3931     /* Check that the external clock synchronization is enabled */
3932     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_EECS) != FDCAN_TTOCF_EECS)
3933     {
3934       /* Update error code */
3935       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
3936 
3937       return HAL_ERROR;
3938     }
3939 
3940     /* Check that no external clock synchronization is pending */
3941     if ((hfdcan->ttcan->TTOST & FDCAN_TTOST_WECS) == FDCAN_TTOST_WECS)
3942     {
3943       /* Update error code */
3944       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PENDING;
3945 
3946       return HAL_ERROR;
3947     }
3948 
3949     /* Configure new TUR numerator */
3950     MODIFY_REG(hfdcan->ttcan->TURCF, FDCAN_TURCF_NCL, (NewTURNumerator - 0x10000U));
3951 
3952     /* Wait until the LCKC bit into TTOCN register is reset */
3953     while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
3954     {
3955       /* Check for the Timeout */
3956       if (Counter > FDCAN_TIMEOUT_COUNT)
3957       {
3958         /* Update error code */
3959         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3960 
3961         /* Change FDCAN state */
3962         hfdcan->State = HAL_FDCAN_STATE_ERROR;
3963 
3964         return HAL_ERROR;
3965       }
3966 
3967       /* Increment counter */
3968       Counter++;
3969     }
3970 
3971     /* Schedule TUR numerator update by the next reference message */
3972     SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_ECS);
3973 
3974     /* Return function status */
3975     return HAL_OK;
3976   }
3977   else
3978   {
3979     /* Update error code */
3980     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3981 
3982     return HAL_ERROR;
3983   }
3984 }
3985 
3986 /**
3987   * @brief  Configure stop watch source and polarity.
3988   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3989   *         the configuration information for the specified FDCAN.
3990   * @param  Source stop watch source.
3991   *         This parameter can be a value of @arg FDCAN_TT_stop_watch_source.
3992   * @param  Polarity stop watch polarity.
3993   *         This parameter can be a value of @arg FDCAN_TT_stop_watch_polarity.
3994   * @retval HAL status
3995   */
3996 HAL_StatusTypeDef HAL_FDCAN_TT_ConfigStopWatch(FDCAN_HandleTypeDef *hfdcan, uint32_t Source, uint32_t Polarity)
3997 {
3998   uint32_t Counter = 0U;
3999   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4000 
4001   /* Check function parameters */
4002   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4003   assert_param(IS_FDCAN_TT_STOP_WATCH_SOURCE(Source));
4004   assert_param(IS_FDCAN_TT_STOP_WATCH_POLARITY(Polarity));
4005 
4006   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4007   {
4008     /* Wait until the LCKC bit into TTOCN register is reset */
4009     while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4010     {
4011       /* Check for the Timeout */
4012       if (Counter > FDCAN_TIMEOUT_COUNT)
4013       {
4014         /* Update error code */
4015         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4016 
4017         /* Change FDCAN state */
4018         hfdcan->State = HAL_FDCAN_STATE_ERROR;
4019 
4020         return HAL_ERROR;
4021       }
4022 
4023       /* Increment counter */
4024       Counter++;
4025     }
4026 
4027     /* Select stop watch source and polarity */
4028     MODIFY_REG(hfdcan->ttcan->TTOCN, (FDCAN_TTOCN_SWS | FDCAN_TTOCN_SWP), (Source | Polarity));
4029 
4030     /* Return function status */
4031     return HAL_OK;
4032   }
4033   else
4034   {
4035     /* Update error code */
4036     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4037 
4038     return HAL_ERROR;
4039   }
4040 }
4041 
4042 /**
4043   * @brief  Configure register time mark pulse generation.
4044   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4045   *         the configuration information for the specified FDCAN.
4046   * @param  TimeMarkSource time mark source.
4047   *         This parameter can be a value of @arg FDCAN_TT_time_mark_source.
4048   * @param  TimeMarkValue time mark value (reference).
4049   *         This parameter must be a number between 0 and 0xFFFF.
4050   * @param  RepeatFactor repeat factor of the cycle for which the time mark is valid.
4051   *         This parameter can be a value of @arg FDCAN_TT_Repeat_Factor.
4052   * @param  StartCycle index of the first cycle in which the time mark becomes valid.
4053   *         This parameter is ignored if RepeatFactor is set to FDCAN_TT_REPEAT_EVERY_CYCLE.
4054   *         This parameter must be a number between 0 and RepeatFactor.
4055   * @retval HAL status
4056   */
4057 HAL_StatusTypeDef HAL_FDCAN_TT_ConfigRegisterTimeMark(FDCAN_HandleTypeDef *hfdcan,
4058                                                       uint32_t TimeMarkSource, uint32_t TimeMarkValue,
4059                                                       uint32_t RepeatFactor, uint32_t StartCycle)
4060 {
4061   uint32_t Counter = 0U;
4062   uint32_t CycleCode;
4063   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4064 
4065   /* Check function parameters */
4066   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4067   assert_param(IS_FDCAN_TT_REGISTER_TIME_MARK_SOURCE(TimeMarkSource));
4068   assert_param(IS_FDCAN_MAX_VALUE(TimeMarkValue, 0xFFFFU));
4069   assert_param(IS_FDCAN_TT_REPEAT_FACTOR(RepeatFactor));
4070   if (RepeatFactor != FDCAN_TT_REPEAT_EVERY_CYCLE)
4071   {
4072     assert_param(IS_FDCAN_MAX_VALUE(StartCycle, (RepeatFactor - 1U)));
4073   }
4074 
4075   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4076   {
4077     /* Wait until the LCKC bit into TTOCN register is reset */
4078     while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4079     {
4080       /* Check for the Timeout */
4081       if (Counter > FDCAN_TIMEOUT_COUNT)
4082       {
4083         /* Update error code */
4084         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4085 
4086         /* Change FDCAN state */
4087         hfdcan->State = HAL_FDCAN_STATE_ERROR;
4088 
4089         return HAL_ERROR;
4090       }
4091 
4092       /* Increment counter */
4093       Counter++;
4094     }
4095 
4096     /* Disable the time mark compare function */
4097     CLEAR_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_TMC);
4098 
4099     if (TimeMarkSource != FDCAN_TT_REG_TIMEMARK_DIABLED)
4100     {
4101       /* Calculate cycle code */
4102       if (RepeatFactor == FDCAN_TT_REPEAT_EVERY_CYCLE)
4103       {
4104         CycleCode = FDCAN_TT_REPEAT_EVERY_CYCLE;
4105       }
4106       else /* RepeatFactor != FDCAN_TT_REPEAT_EVERY_CYCLE */
4107       {
4108         CycleCode = RepeatFactor + StartCycle;
4109       }
4110 
4111       Counter = 0U;
4112 
4113       /* Wait until the LCKM bit into TTTMK register is reset */
4114       while ((hfdcan->ttcan->TTTMK & FDCAN_TTTMK_LCKM) != 0U)
4115       {
4116         /* Check for the Timeout */
4117         if (Counter > FDCAN_TIMEOUT_COUNT)
4118         {
4119           /* Update error code */
4120           hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4121 
4122           /* Change FDCAN state */
4123           hfdcan->State = HAL_FDCAN_STATE_ERROR;
4124 
4125           return HAL_ERROR;
4126         }
4127 
4128         /* Increment counter */
4129         Counter++;
4130       }
4131 
4132       /* Configure time mark value and cycle code */
4133       hfdcan->ttcan->TTTMK = ((TimeMarkValue << FDCAN_TTTMK_TM_Pos) | (CycleCode << FDCAN_TTTMK_TICC_Pos));
4134 
4135       Counter = 0U;
4136 
4137       /* Wait until the LCKC bit into TTOCN register is reset */
4138       while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4139       {
4140         /* Check for the Timeout */
4141         if (Counter > FDCAN_TIMEOUT_COUNT)
4142         {
4143           /* Update error code */
4144           hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4145 
4146           /* Change FDCAN state */
4147           hfdcan->State = HAL_FDCAN_STATE_ERROR;
4148 
4149           return HAL_ERROR;
4150         }
4151 
4152         /* Increment counter */
4153         Counter++;
4154       }
4155 
4156       /* Update the register time mark compare source */
4157       MODIFY_REG(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_TMC, TimeMarkSource);
4158     }
4159 
4160     /* Return function status */
4161     return HAL_OK;
4162   }
4163   else
4164   {
4165     /* Update error code */
4166     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4167 
4168     return HAL_ERROR;
4169   }
4170 }
4171 
4172 /**
4173   * @brief  Enable register time mark pulse generation.
4174   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4175   *         the configuration information for the specified FDCAN.
4176   * @retval HAL status
4177   */
4178 HAL_StatusTypeDef HAL_FDCAN_TT_EnableRegisterTimeMarkPulse(FDCAN_HandleTypeDef *hfdcan)
4179 {
4180   uint32_t Counter = 0U;
4181   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4182 
4183   /* Check function parameters */
4184   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4185 
4186   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4187   {
4188     /* Wait until the LCKC bit into TTOCN register is reset */
4189     while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4190     {
4191       /* Check for the Timeout */
4192       if (Counter > FDCAN_TIMEOUT_COUNT)
4193       {
4194         /* Update error code */
4195         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4196 
4197         /* Change FDCAN state */
4198         hfdcan->State = HAL_FDCAN_STATE_ERROR;
4199 
4200         return HAL_ERROR;
4201       }
4202 
4203       /* Increment counter */
4204       Counter++;
4205     }
4206 
4207     /* Enable Register Time Mark Interrupt output on fdcan1_rtp */
4208     SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_RTIE);
4209 
4210     /* Return function status */
4211     return HAL_OK;
4212   }
4213   else
4214   {
4215     /* Update error code */
4216     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4217 
4218     return HAL_ERROR;
4219   }
4220 }
4221 
4222 /**
4223   * @brief  Disable register time mark pulse generation.
4224   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4225   *         the configuration information for the specified FDCAN.
4226   * @retval HAL status
4227   */
4228 HAL_StatusTypeDef HAL_FDCAN_TT_DisableRegisterTimeMarkPulse(FDCAN_HandleTypeDef *hfdcan)
4229 {
4230   uint32_t Counter = 0U;
4231   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4232 
4233   /* Check function parameters */
4234   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4235 
4236   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4237   {
4238     /* Wait until the LCKC bit into TTOCN register is reset */
4239     while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4240     {
4241       /* Check for the Timeout */
4242       if (Counter > FDCAN_TIMEOUT_COUNT)
4243       {
4244         /* Update error code */
4245         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4246 
4247         /* Change FDCAN state */
4248         hfdcan->State = HAL_FDCAN_STATE_ERROR;
4249 
4250         return HAL_ERROR;
4251       }
4252 
4253       /* Increment counter */
4254       Counter++;
4255     }
4256 
4257     /* Disable Register Time Mark Interrupt output on fdcan1_rtp */
4258     CLEAR_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_RTIE);
4259 
4260     /* Return function status */
4261     return HAL_OK;
4262   }
4263   else
4264   {
4265     /* Update error code */
4266     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4267 
4268     return HAL_ERROR;
4269   }
4270 }
4271 
4272 /**
4273   * @brief  Enable trigger time mark pulse generation.
4274   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4275   *         the configuration information for the specified FDCAN.
4276   * @retval HAL status
4277   */
4278 HAL_StatusTypeDef HAL_FDCAN_TT_EnableTriggerTimeMarkPulse(FDCAN_HandleTypeDef *hfdcan)
4279 {
4280   uint32_t Counter = 0U;
4281   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4282 
4283   /* Check function parameters */
4284   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4285 
4286   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4287   {
4288     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
4289     {
4290       /* Wait until the LCKC bit into TTOCN register is reset */
4291       while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4292       {
4293         /* Check for the Timeout */
4294         if (Counter > FDCAN_TIMEOUT_COUNT)
4295         {
4296           /* Update error code */
4297           hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4298 
4299           /* Change FDCAN state */
4300           hfdcan->State = HAL_FDCAN_STATE_ERROR;
4301 
4302           return HAL_ERROR;
4303         }
4304 
4305         /* Increment counter */
4306         Counter++;
4307       }
4308 
4309       /* Enable Trigger Time Mark Interrupt output on fdcan1_tmp */
4310       SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_TTIE);
4311 
4312       /* Return function status */
4313       return HAL_OK;
4314     }
4315     else
4316     {
4317       /* Update error code.
4318          Feature not supported for TT Level 0 */
4319       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
4320 
4321       return HAL_ERROR;
4322     }
4323   }
4324   else
4325   {
4326     /* Update error code */
4327     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4328 
4329     return HAL_ERROR;
4330   }
4331 }
4332 
4333 /**
4334   * @brief  Disable trigger time mark pulse generation.
4335   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4336   *         the configuration information for the specified FDCAN.
4337   * @retval HAL status
4338   */
4339 HAL_StatusTypeDef HAL_FDCAN_TT_DisableTriggerTimeMarkPulse(FDCAN_HandleTypeDef *hfdcan)
4340 {
4341   uint32_t Counter = 0U;
4342   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4343 
4344   /* Check function parameters */
4345   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4346 
4347   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4348   {
4349     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
4350     {
4351       /* Wait until the LCKC bit into TTOCN register is reset */
4352       while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4353       {
4354         /* Check for the Timeout */
4355         if (Counter > FDCAN_TIMEOUT_COUNT)
4356         {
4357           /* Update error code */
4358           hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4359 
4360           /* Change FDCAN state */
4361           hfdcan->State = HAL_FDCAN_STATE_ERROR;
4362 
4363           return HAL_ERROR;
4364         }
4365 
4366         /* Increment counter */
4367         Counter++;
4368       }
4369 
4370       /* Disable Trigger Time Mark Interrupt output on fdcan1_rtp */
4371       CLEAR_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_TTIE);
4372 
4373       /* Return function status */
4374       return HAL_OK;
4375     }
4376     else
4377     {
4378       /* Update error code.
4379          Feature not supported for TT Level 0 */
4380       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
4381 
4382       return HAL_ERROR;
4383     }
4384   }
4385   else
4386   {
4387     /* Update error code */
4388     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4389 
4390     return HAL_ERROR;
4391   }
4392 }
4393 
4394 /**
4395   * @brief  Enable gap control by input pin fdcan1_evt.
4396   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4397   *         the configuration information for the specified FDCAN.
4398   * @retval HAL status
4399   */
4400 HAL_StatusTypeDef HAL_FDCAN_TT_EnableHardwareGapControl(FDCAN_HandleTypeDef *hfdcan)
4401 {
4402   uint32_t Counter = 0U;
4403   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4404 
4405   /* Check function parameters */
4406   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4407 
4408   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4409   {
4410     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
4411     {
4412       /* Wait until the LCKC bit into TTOCN register is reset */
4413       while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4414       {
4415         /* Check for the Timeout */
4416         if (Counter > FDCAN_TIMEOUT_COUNT)
4417         {
4418           /* Update error code */
4419           hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4420 
4421           /* Change FDCAN state */
4422           hfdcan->State = HAL_FDCAN_STATE_ERROR;
4423 
4424           return HAL_ERROR;
4425         }
4426 
4427         /* Increment counter */
4428         Counter++;
4429       }
4430 
4431       /* Enable gap control by pin fdcan1_evt */
4432       SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_GCS);
4433 
4434       /* Return function status */
4435       return HAL_OK;
4436     }
4437     else
4438     {
4439       /* Update error code.
4440          Feature not supported for TT Level 0 */
4441       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
4442 
4443       return HAL_ERROR;
4444     }
4445   }
4446   else
4447   {
4448     /* Update error code */
4449     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4450 
4451     return HAL_ERROR;
4452   }
4453 }
4454 
4455 /**
4456   * @brief  Disable gap control by input pin fdcan1_evt.
4457   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4458   *         the configuration information for the specified FDCAN.
4459   * @retval HAL status
4460   */
4461 HAL_StatusTypeDef HAL_FDCAN_TT_DisableHardwareGapControl(FDCAN_HandleTypeDef *hfdcan)
4462 {
4463   uint32_t Counter = 0U;
4464   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4465 
4466   /* Check function parameters */
4467   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4468 
4469   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4470   {
4471     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
4472     {
4473       /* Wait until the LCKC bit into TTOCN register is reset */
4474       while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4475       {
4476         /* Check for the Timeout */
4477         if (Counter > FDCAN_TIMEOUT_COUNT)
4478         {
4479           /* Update error code */
4480           hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4481 
4482           /* Change FDCAN state */
4483           hfdcan->State = HAL_FDCAN_STATE_ERROR;
4484 
4485           return HAL_ERROR;
4486         }
4487 
4488         /* Increment counter */
4489         Counter++;
4490       }
4491 
4492       /* Disable gap control by pin fdcan1_evt */
4493       CLEAR_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_GCS);
4494 
4495       /* Return function status */
4496       return HAL_OK;
4497     }
4498     else
4499     {
4500       /* Update error code.
4501          Feature not supported for TT Level 0 */
4502       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
4503 
4504       return HAL_ERROR;
4505     }
4506   }
4507   else
4508   {
4509     /* Update error code */
4510     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4511 
4512     return HAL_ERROR;
4513   }
4514 }
4515 
4516 /**
4517   * @brief  Enable gap control (finish only) by register time mark interrupt.
4518   *         The next register time mark interrupt (TTIR.RTMI = "1") will finish
4519   *         the Gap and start the reference message.
4520   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4521   *         the configuration information for the specified FDCAN.
4522   * @retval HAL status
4523   */
4524 HAL_StatusTypeDef HAL_FDCAN_TT_EnableTimeMarkGapControl(FDCAN_HandleTypeDef *hfdcan)
4525 {
4526   uint32_t Counter = 0U;
4527   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4528 
4529   /* Check function parameters */
4530   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4531 
4532   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4533   {
4534     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
4535     {
4536       /* Wait until the LCKC bit into TTOCN register is reset */
4537       while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4538       {
4539         /* Check for the Timeout */
4540         if (Counter > FDCAN_TIMEOUT_COUNT)
4541         {
4542           /* Update error code */
4543           hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4544 
4545           /* Change FDCAN state */
4546           hfdcan->State = HAL_FDCAN_STATE_ERROR;
4547 
4548           return HAL_ERROR;
4549         }
4550 
4551         /* Increment counter */
4552         Counter++;
4553       }
4554 
4555       /* Enable gap control by register time mark interrupt */
4556       SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_TMG);
4557 
4558       /* Return function status */
4559       return HAL_OK;
4560     }
4561     else
4562     {
4563       /* Update error code.
4564          Feature not supported for TT Level 0 */
4565       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
4566 
4567       return HAL_ERROR;
4568     }
4569   }
4570   else
4571   {
4572     /* Update error code */
4573     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4574 
4575     return HAL_ERROR;
4576   }
4577 }
4578 
4579 /**
4580   * @brief  Disable gap control by register time mark interrupt.
4581   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4582   *         the configuration information for the specified FDCAN.
4583   * @retval HAL status
4584   */
4585 HAL_StatusTypeDef HAL_FDCAN_TT_DisableTimeMarkGapControl(FDCAN_HandleTypeDef *hfdcan)
4586 {
4587   uint32_t Counter = 0U;
4588   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4589 
4590   /* Check function parameters */
4591   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4592 
4593   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4594   {
4595     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
4596     {
4597       /* Wait until the LCKC bit into TTOCN register is reset */
4598       while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4599       {
4600         /* Check for the Timeout */
4601         if (Counter > FDCAN_TIMEOUT_COUNT)
4602         {
4603           /* Update error code */
4604           hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4605 
4606           /* Change FDCAN state */
4607           hfdcan->State = HAL_FDCAN_STATE_ERROR;
4608 
4609           return HAL_ERROR;
4610         }
4611 
4612         /* Increment counter */
4613         Counter++;
4614       }
4615 
4616       /* Disable gap control by register time mark interrupt */
4617       CLEAR_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_TMG);
4618 
4619       /* Return function status */
4620       return HAL_OK;
4621     }
4622     else
4623     {
4624       /* Update error code.
4625          Feature not supported for TT Level 0 */
4626       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
4627 
4628       return HAL_ERROR;
4629     }
4630   }
4631   else
4632   {
4633     /* Update error code */
4634     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4635 
4636     return HAL_ERROR;
4637   }
4638 }
4639 
4640 /**
4641   * @brief  Transmit next reference message with Next_is_Gap = "1".
4642   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4643   *         the configuration information for the specified FDCAN.
4644   * @retval HAL status
4645   */
4646 HAL_StatusTypeDef HAL_FDCAN_TT_SetNextIsGap(FDCAN_HandleTypeDef *hfdcan)
4647 {
4648   uint32_t Counter = 0U;
4649   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4650 
4651   /* Check function parameters */
4652   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4653 
4654   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4655   {
4656     /* Check that the node is configured for external event-synchronized TT operation */
4657     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_GEN) != FDCAN_TTOCF_GEN)
4658     {
4659       /* Update error code */
4660       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
4661 
4662       return HAL_ERROR;
4663     }
4664 
4665     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
4666     {
4667       /* Wait until the LCKC bit into TTOCN register is reset */
4668       while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4669       {
4670         /* Check for the Timeout */
4671         if (Counter > FDCAN_TIMEOUT_COUNT)
4672         {
4673           /* Update error code */
4674           hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4675 
4676           /* Change FDCAN state */
4677           hfdcan->State = HAL_FDCAN_STATE_ERROR;
4678 
4679           return HAL_ERROR;
4680         }
4681 
4682         /* Increment counter */
4683         Counter++;
4684       }
4685 
4686       /* Set Next is Gap */
4687       SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_NIG);
4688 
4689       /* Return function status */
4690       return HAL_OK;
4691     }
4692     else
4693     {
4694       /* Update error code.
4695          Feature not supported for TT Level 0 */
4696       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
4697 
4698       return HAL_ERROR;
4699     }
4700   }
4701   else
4702   {
4703     /* Update error code */
4704     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4705 
4706     return HAL_ERROR;
4707   }
4708 }
4709 
4710 /**
4711   * @brief  Finish a Gap by requesting start of reference message.
4712   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4713   *         the configuration information for the specified FDCAN.
4714   * @retval HAL status
4715   */
4716 HAL_StatusTypeDef HAL_FDCAN_TT_SetEndOfGap(FDCAN_HandleTypeDef *hfdcan)
4717 {
4718   uint32_t Counter = 0U;
4719   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4720 
4721   /* Check function parameters */
4722   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4723 
4724   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4725   {
4726     /* Check that the node is configured for external event-synchronized TT operation */
4727     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_GEN) != FDCAN_TTOCF_GEN)
4728     {
4729       /* Update error code */
4730       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
4731 
4732       return HAL_ERROR;
4733     }
4734 
4735     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
4736     {
4737       /* Wait until the LCKC bit into TTOCN register is reset */
4738       while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4739       {
4740         /* Check for the Timeout */
4741         if (Counter > FDCAN_TIMEOUT_COUNT)
4742         {
4743           /* Update error code */
4744           hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4745 
4746           /* Change FDCAN state */
4747           hfdcan->State = HAL_FDCAN_STATE_ERROR;
4748 
4749           return HAL_ERROR;
4750         }
4751 
4752         /* Increment counter */
4753         Counter++;
4754       }
4755 
4756       /* Set Finish Gap */
4757       SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_FGP);
4758 
4759       /* Return function status */
4760       return HAL_OK;
4761     }
4762     else
4763     {
4764       /* Update error code.
4765          Feature not supported for TT Level 0 */
4766       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
4767 
4768       return HAL_ERROR;
4769     }
4770   }
4771   else
4772   {
4773     /* Update error code */
4774     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4775 
4776     return HAL_ERROR;
4777   }
4778 }
4779 
4780 /**
4781   * @brief  Configure target phase used for external synchronization by event
4782   *         trigger input pin fdcan1_evt.
4783   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4784   *         the configuration information for the specified FDCAN.
4785   * @param  TargetPhase defines target value of cycle time when a rising edge
4786   *         of fdcan1_evt is expected.
4787   *         This parameter must be a number between 0 and 0xFFFF.
4788   * @retval HAL status
4789   */
4790 HAL_StatusTypeDef HAL_FDCAN_TT_ConfigExternalSyncPhase(FDCAN_HandleTypeDef *hfdcan, uint32_t TargetPhase)
4791 {
4792   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4793 
4794   /* Check function parameters */
4795   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4796   assert_param(IS_FDCAN_MAX_VALUE(TargetPhase, 0xFFFFU));
4797 
4798   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4799   {
4800     /* Check that no external schedule synchronization is pending */
4801     if ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_ESCN) == FDCAN_TTOCN_ESCN)
4802     {
4803       /* Update error code */
4804       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PENDING;
4805 
4806       return HAL_ERROR;
4807     }
4808 
4809     /* Configure cycle time target phase */
4810     MODIFY_REG(hfdcan->ttcan->TTGTP, FDCAN_TTGTP_CTP, (TargetPhase << FDCAN_TTGTP_CTP_Pos));
4811 
4812     /* Return function status */
4813     return HAL_OK;
4814   }
4815   else
4816   {
4817     /* Update error code */
4818     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4819 
4820     return HAL_ERROR;
4821   }
4822 }
4823 
4824 /**
4825   * @brief  Synchronize the phase of the FDCAN schedule to an external schedule
4826   *         using event trigger input pin fdcan1_evt.
4827   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4828   *         the configuration information for the specified FDCAN.
4829   * @retval HAL status
4830   */
4831 HAL_StatusTypeDef HAL_FDCAN_TT_EnableExternalSynchronization(FDCAN_HandleTypeDef *hfdcan)
4832 {
4833   uint32_t Counter = 0U;
4834   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4835 
4836   /* Check function parameters */
4837   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4838 
4839   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4840   {
4841     /* Wait until the LCKC bit into TTOCN register is reset */
4842     while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4843     {
4844       /* Check for the Timeout */
4845       if (Counter > FDCAN_TIMEOUT_COUNT)
4846       {
4847         /* Update error code */
4848         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4849 
4850         /* Change FDCAN state */
4851         hfdcan->State = HAL_FDCAN_STATE_ERROR;
4852 
4853         return HAL_ERROR;
4854       }
4855 
4856       /* Increment counter */
4857       Counter++;
4858     }
4859 
4860     /* Enable external synchronization */
4861     SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_ESCN);
4862 
4863     /* Return function status */
4864     return HAL_OK;
4865   }
4866   else
4867   {
4868     /* Update error code */
4869     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4870 
4871     return HAL_ERROR;
4872   }
4873 }
4874 
4875 /**
4876   * @brief  Disable external schedule synchronization.
4877   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4878   *         the configuration information for the specified FDCAN.
4879   * @retval HAL status
4880   */
4881 HAL_StatusTypeDef HAL_FDCAN_TT_DisableExternalSynchronization(FDCAN_HandleTypeDef *hfdcan)
4882 {
4883   uint32_t Counter = 0U;
4884   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4885 
4886   /* Check function parameters */
4887   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4888 
4889   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4890   {
4891     /* Wait until the LCKC bit into TTOCN register is reset */
4892     while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4893     {
4894       /* Check for the Timeout */
4895       if (Counter > FDCAN_TIMEOUT_COUNT)
4896       {
4897         /* Update error code */
4898         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4899 
4900         /* Change FDCAN state */
4901         hfdcan->State = HAL_FDCAN_STATE_ERROR;
4902 
4903         return HAL_ERROR;
4904       }
4905 
4906       /* Increment counter */
4907       Counter++;
4908     }
4909 
4910     /* Disable external synchronization */
4911     CLEAR_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_ESCN);
4912 
4913     /* Return function status */
4914     return HAL_OK;
4915   }
4916   else
4917   {
4918     /* Update error code */
4919     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4920 
4921     return HAL_ERROR;
4922   }
4923 }
4924 
4925 /**
4926   * @brief  Get TT operation status.
4927   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4928   *         the configuration information for the specified FDCAN.
4929   * @param  TTOpStatus pointer to an FDCAN_TTOperationStatusTypeDef structure.
4930   * @retval HAL status
4931   */
4932 HAL_StatusTypeDef HAL_FDCAN_TT_GetOperationStatus(const FDCAN_HandleTypeDef *hfdcan,
4933                                                   FDCAN_TTOperationStatusTypeDef *TTOpStatus)
4934 {
4935   uint32_t TTStatusReg;
4936 
4937   /* Check function parameters */
4938   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4939 
4940   /* Read the TT operation status register */
4941   TTStatusReg = READ_REG(hfdcan->ttcan->TTOST);
4942 
4943   /* Fill the TT operation status structure */
4944   TTOpStatus->ErrorLevel = (TTStatusReg & FDCAN_TTOST_EL);
4945   TTOpStatus->MasterState = (TTStatusReg & FDCAN_TTOST_MS);
4946   TTOpStatus->SyncState = (TTStatusReg & FDCAN_TTOST_SYS);
4947   TTOpStatus->GTimeQuality = ((TTStatusReg & FDCAN_TTOST_QGTP) >> FDCAN_TTOST_QGTP_Pos);
4948   TTOpStatus->ClockQuality = ((TTStatusReg & FDCAN_TTOST_QCS) >> FDCAN_TTOST_QCS_Pos);
4949   TTOpStatus->RefTrigOffset = ((TTStatusReg & FDCAN_TTOST_RTO) >> FDCAN_TTOST_RTO_Pos);
4950   TTOpStatus->GTimeDiscPending = ((TTStatusReg & FDCAN_TTOST_WGTD) >> FDCAN_TTOST_WGTD_Pos);
4951   TTOpStatus->GapFinished = ((TTStatusReg & FDCAN_TTOST_GFI) >> FDCAN_TTOST_GFI_Pos);
4952   TTOpStatus->MasterPriority = ((TTStatusReg & FDCAN_TTOST_TMP) >> FDCAN_TTOST_TMP_Pos);
4953   TTOpStatus->GapStarted = ((TTStatusReg & FDCAN_TTOST_GSI) >> FDCAN_TTOST_GSI_Pos);
4954   TTOpStatus->WaitForEvt = ((TTStatusReg & FDCAN_TTOST_WFE) >> FDCAN_TTOST_WFE_Pos);
4955   TTOpStatus->AppWdgEvt = ((TTStatusReg & FDCAN_TTOST_AWE) >> FDCAN_TTOST_AWE_Pos);
4956   TTOpStatus->ECSPending = ((TTStatusReg & FDCAN_TTOST_WECS) >> FDCAN_TTOST_WECS_Pos);
4957   TTOpStatus->PhaseLock = ((TTStatusReg & FDCAN_TTOST_SPL) >> FDCAN_TTOST_SPL_Pos);
4958 
4959   /* Return function status */
4960   return HAL_OK;
4961 }
4962 
4963 /**
4964   * @}
4965   */
4966 
4967 /** @defgroup FDCAN_Exported_Functions_Group5 Interrupts management
4968   * @ingroup RTEMSBSPsARMSTM32H7
4969   *  @brief    Interrupts management
4970   *
4971 @verbatim
4972   ==============================================================================
4973                        ##### Interrupts management #####
4974   ==============================================================================
4975     [..]  This section provides functions allowing to:
4976       (+) HAL_FDCAN_ConfigInterruptLines      : Assign interrupts to either Interrupt line 0 or 1
4977       (+) HAL_FDCAN_TT_ConfigInterruptLines   : Assign TT interrupts to either Interrupt line 0 or 1
4978       (+) HAL_FDCAN_ActivateNotification      : Enable interrupts
4979       (+) HAL_FDCAN_DeactivateNotification    : Disable interrupts
4980       (+) HAL_FDCAN_TT_ActivateNotification   : Enable TT interrupts
4981       (+) HAL_FDCAN_TT_DeactivateNotification : Disable TT interrupts
4982       (+) HAL_FDCAN_IRQHandler                : Handles FDCAN interrupt request
4983 
4984 @endverbatim
4985   * @{
4986   */
4987 
4988 /**
4989   * @brief  Assign interrupts to either Interrupt line 0 or 1.
4990   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4991   *         the configuration information for the specified FDCAN.
4992   * @param  ITList indicates which interrupts will be assigned to the selected interrupt line.
4993   *         This parameter can be any combination of @arg FDCAN_Interrupts.
4994   * @param  InterruptLine Interrupt line.
4995   *         This parameter can be a value of @arg FDCAN_Interrupt_Line.
4996   * @retval HAL status
4997   */
4998 HAL_StatusTypeDef HAL_FDCAN_ConfigInterruptLines(FDCAN_HandleTypeDef *hfdcan, uint32_t ITList, uint32_t InterruptLine)
4999 {
5000   HAL_FDCAN_StateTypeDef state = hfdcan->State;
5001 
5002   /* Check function parameters */
5003   assert_param(IS_FDCAN_IT(ITList));
5004   assert_param(IS_FDCAN_IT_LINE(InterruptLine));
5005 
5006   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
5007   {
5008     /* Assign list of interrupts to the selected line */
5009     if (InterruptLine == FDCAN_INTERRUPT_LINE0)
5010     {
5011       CLEAR_BIT(hfdcan->Instance->ILS, ITList);
5012     }
5013     else /* InterruptLine == FDCAN_INTERRUPT_LINE1 */
5014     {
5015       SET_BIT(hfdcan->Instance->ILS, ITList);
5016     }
5017 
5018     /* Return function status */
5019     return HAL_OK;
5020   }
5021   else
5022   {
5023     /* Update error code */
5024     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
5025 
5026     return HAL_ERROR;
5027   }
5028 }
5029 
5030 /**
5031   * @brief  Assign TT interrupts to either Interrupt line 0 or 1.
5032   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5033   *         the configuration information for the specified FDCAN.
5034   * @param  TTITList indicates which interrupts will be assigned to the selected interrupt line.
5035   *         This parameter can be any combination of @arg FDCAN_TTInterrupts.
5036   * @param  InterruptLine Interrupt line.
5037   *         This parameter can be a value of @arg FDCAN_Interrupt_Line.
5038   * @retval HAL status
5039   */
5040 HAL_StatusTypeDef HAL_FDCAN_TT_ConfigInterruptLines(FDCAN_HandleTypeDef *hfdcan, uint32_t TTITList,
5041                                                     uint32_t InterruptLine)
5042 {
5043   HAL_FDCAN_StateTypeDef state = hfdcan->State;
5044 
5045   /* Check function parameters */
5046   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
5047   assert_param(IS_FDCAN_TT_IT(TTITList));
5048   assert_param(IS_FDCAN_IT_LINE(InterruptLine));
5049 
5050   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
5051   {
5052     /* Assign list of interrupts to the selected line */
5053     if (InterruptLine == FDCAN_INTERRUPT_LINE0)
5054     {
5055       CLEAR_BIT(hfdcan->ttcan->TTILS, TTITList);
5056     }
5057     else /* InterruptLine == FDCAN_INTERRUPT_LINE1 */
5058     {
5059       SET_BIT(hfdcan->ttcan->TTILS, TTITList);
5060     }
5061 
5062     /* Return function status */
5063     return HAL_OK;
5064   }
5065   else
5066   {
5067     /* Update error code */
5068     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
5069 
5070     return HAL_ERROR;
5071   }
5072 }
5073 
5074 /**
5075   * @brief  Enable interrupts.
5076   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5077   *         the configuration information for the specified FDCAN.
5078   * @param  ActiveITs indicates which interrupts will be enabled.
5079   *         This parameter can be any combination of @arg FDCAN_Interrupts.
5080   * @param  BufferIndexes Tx Buffer Indexes.
5081   *         This parameter can be any combination of @arg FDCAN_Tx_location.
5082   *         This parameter is ignored if ActiveITs does not include one of the following:
5083   *           - FDCAN_IT_TX_COMPLETE
5084   *           - FDCAN_IT_TX_ABORT_COMPLETE
5085   * @retval HAL status
5086   */
5087 HAL_StatusTypeDef HAL_FDCAN_ActivateNotification(FDCAN_HandleTypeDef *hfdcan, uint32_t ActiveITs,
5088                                                  uint32_t BufferIndexes)
5089 {
5090   HAL_FDCAN_StateTypeDef state = hfdcan->State;
5091 
5092   /* Check function parameters */
5093   assert_param(IS_FDCAN_IT(ActiveITs));
5094 
5095   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
5096   {
5097     /* Enable Interrupt lines */
5098     if ((ActiveITs & hfdcan->Instance->ILS) == 0U)
5099     {
5100       /* Enable Interrupt line 0 */
5101       SET_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE0);
5102     }
5103     else if ((ActiveITs & hfdcan->Instance->ILS) == ActiveITs)
5104     {
5105       /* Enable Interrupt line 1 */
5106       SET_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE1);
5107     }
5108     else
5109     {
5110       /* Enable Interrupt lines 0 and 1 */
5111       hfdcan->Instance->ILE = (FDCAN_INTERRUPT_LINE0 | FDCAN_INTERRUPT_LINE1);
5112     }
5113 
5114     if ((ActiveITs & FDCAN_IT_TX_COMPLETE) != 0U)
5115     {
5116       /* Enable Tx Buffer Transmission Interrupt to set TC flag in IR register,
5117          but interrupt will only occur if TC is enabled in IE register */
5118       SET_BIT(hfdcan->Instance->TXBTIE, BufferIndexes);
5119     }
5120 
5121     if ((ActiveITs & FDCAN_IT_TX_ABORT_COMPLETE) != 0U)
5122     {
5123       /* Enable Tx Buffer Cancellation Finished Interrupt to set TCF flag in IR register,
5124          but interrupt will only occur if TCF is enabled in IE register */
5125       SET_BIT(hfdcan->Instance->TXBCIE, BufferIndexes);
5126     }
5127 
5128     /* Enable the selected interrupts */
5129     __HAL_FDCAN_ENABLE_IT(hfdcan, ActiveITs);
5130 
5131     /* Return function status */
5132     return HAL_OK;
5133   }
5134   else
5135   {
5136     /* Update error code */
5137     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
5138 
5139     return HAL_ERROR;
5140   }
5141 }
5142 
5143 /**
5144   * @brief  Disable interrupts.
5145   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5146   *         the configuration information for the specified FDCAN.
5147   * @param  InactiveITs indicates which interrupts will be disabled.
5148   *         This parameter can be any combination of @arg FDCAN_Interrupts.
5149   * @retval HAL status
5150   */
5151 HAL_StatusTypeDef HAL_FDCAN_DeactivateNotification(FDCAN_HandleTypeDef *hfdcan, uint32_t InactiveITs)
5152 {
5153   uint32_t ITLineSelection;
5154   HAL_FDCAN_StateTypeDef state = hfdcan->State;
5155 
5156   /* Check function parameters */
5157   assert_param(IS_FDCAN_IT(InactiveITs));
5158 
5159   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
5160   {
5161     /* Disable the selected interrupts */
5162     __HAL_FDCAN_DISABLE_IT(hfdcan, InactiveITs);
5163 
5164     if ((InactiveITs & FDCAN_IT_TX_COMPLETE) != 0U)
5165     {
5166       /* Disable Tx Buffer Transmission Interrupts */
5167       CLEAR_REG(hfdcan->Instance->TXBTIE);
5168     }
5169 
5170     if ((InactiveITs & FDCAN_IT_TX_ABORT_COMPLETE) != 0U)
5171     {
5172       /* Disable Tx Buffer Cancellation Finished Interrupt */
5173       CLEAR_REG(hfdcan->Instance->TXBCIE);
5174     }
5175 
5176     ITLineSelection = hfdcan->Instance->ILS;
5177 
5178     if ((hfdcan->Instance->IE | ITLineSelection) == ITLineSelection)
5179     {
5180       /* Disable Interrupt line 0 */
5181       CLEAR_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE0);
5182     }
5183 
5184     if ((hfdcan->Instance->IE & ITLineSelection) == 0U)
5185     {
5186       /* Disable Interrupt line 1 */
5187       CLEAR_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE1);
5188     }
5189 
5190     /* Return function status */
5191     return HAL_OK;
5192   }
5193   else
5194   {
5195     /* Update error code */
5196     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
5197 
5198     return HAL_ERROR;
5199   }
5200 }
5201 
5202 /**
5203   * @brief  Enable TT interrupts.
5204   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5205   *         the configuration information for the specified FDCAN.
5206   * @param  ActiveTTITs indicates which TT interrupts will be enabled.
5207   *         This parameter can be any combination of @arg FDCAN_TTInterrupts.
5208   * @retval HAL status
5209   */
5210 HAL_StatusTypeDef HAL_FDCAN_TT_ActivateNotification(FDCAN_HandleTypeDef *hfdcan, uint32_t ActiveTTITs)
5211 {
5212   HAL_FDCAN_StateTypeDef state = hfdcan->State;
5213 
5214   /* Check function parameters */
5215   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
5216   assert_param(IS_FDCAN_TT_IT(ActiveTTITs));
5217 
5218   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
5219   {
5220     /* Enable Interrupt lines */
5221     if ((ActiveTTITs & hfdcan->ttcan->TTILS) == 0U)
5222     {
5223       /* Enable Interrupt line 0 */
5224       SET_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE0);
5225     }
5226     else if ((ActiveTTITs & hfdcan->ttcan->TTILS) == ActiveTTITs)
5227     {
5228       /* Enable Interrupt line 1 */
5229       SET_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE1);
5230     }
5231     else
5232     {
5233       /* Enable Interrupt lines 0 and 1 */
5234       hfdcan->Instance->ILE = (FDCAN_INTERRUPT_LINE0 | FDCAN_INTERRUPT_LINE1);
5235     }
5236 
5237     /* Enable the selected TT interrupts */
5238     __HAL_FDCAN_TT_ENABLE_IT(hfdcan, ActiveTTITs);
5239 
5240     /* Return function status */
5241     return HAL_OK;
5242   }
5243   else
5244   {
5245     /* Update error code */
5246     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
5247 
5248     return HAL_ERROR;
5249   }
5250 }
5251 
5252 /**
5253   * @brief  Disable TT interrupts.
5254   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5255   *         the configuration information for the specified FDCAN.
5256   * @param  InactiveTTITs indicates which TT interrupts will be disabled.
5257   *         This parameter can be any combination of @arg FDCAN_TTInterrupts.
5258   * @retval HAL status
5259   */
5260 HAL_StatusTypeDef HAL_FDCAN_TT_DeactivateNotification(FDCAN_HandleTypeDef *hfdcan, uint32_t InactiveTTITs)
5261 {
5262   uint32_t ITLineSelection;
5263   HAL_FDCAN_StateTypeDef state = hfdcan->State;
5264 
5265   /* Check function parameters */
5266   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
5267   assert_param(IS_FDCAN_TT_IT(InactiveTTITs));
5268 
5269   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
5270   {
5271     /* Disable the selected TT interrupts */
5272     __HAL_FDCAN_TT_DISABLE_IT(hfdcan, InactiveTTITs);
5273 
5274     ITLineSelection = hfdcan->ttcan->TTILS;
5275 
5276     if ((hfdcan->ttcan->TTIE | ITLineSelection) == ITLineSelection)
5277     {
5278       /* Disable Interrupt line 0 */
5279       CLEAR_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE0);
5280     }
5281 
5282     if ((hfdcan->ttcan->TTIE & ITLineSelection) == 0U)
5283     {
5284       /* Disable interrupt line 1 */
5285       CLEAR_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE1);
5286     }
5287 
5288     /* Return function status */
5289     return HAL_OK;
5290   }
5291   else
5292   {
5293     /* Update error code */
5294     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
5295 
5296     return HAL_ERROR;
5297   }
5298 }
5299 
5300 /**
5301   * @brief  Handles FDCAN interrupt request.
5302   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5303   *         the configuration information for the specified FDCAN.
5304   * @retval HAL status
5305   */
5306 void HAL_FDCAN_IRQHandler(FDCAN_HandleTypeDef *hfdcan)
5307 {
5308   uint32_t ClkCalibrationITs;
5309   uint32_t TxEventFifoITs;
5310   uint32_t RxFifo0ITs;
5311   uint32_t RxFifo1ITs;
5312   uint32_t Errors;
5313   uint32_t ErrorStatusITs;
5314   uint32_t TransmittedBuffers;
5315   uint32_t AbortedBuffers;
5316   uint32_t TTSchedSyncITs;
5317   uint32_t TTTimeMarkITs;
5318   uint32_t TTGlobTimeITs;
5319   uint32_t TTDistErrors;
5320   uint32_t TTFatalErrors;
5321   uint32_t SWTime;
5322   uint32_t SWCycleCount;
5323   uint32_t itsourceIE;
5324   uint32_t itsourceTTIE;
5325   uint32_t itflagIR;
5326   uint32_t itflagTTIR;
5327 
5328   ClkCalibrationITs = (FDCAN_CCU->IR << 30);
5329   ClkCalibrationITs &= (FDCAN_CCU->IE << 30);
5330   TxEventFifoITs = hfdcan->Instance->IR & FDCAN_TX_EVENT_FIFO_MASK;
5331   TxEventFifoITs &= hfdcan->Instance->IE;
5332   RxFifo0ITs = hfdcan->Instance->IR & FDCAN_RX_FIFO0_MASK;
5333   RxFifo0ITs &= hfdcan->Instance->IE;
5334   RxFifo1ITs = hfdcan->Instance->IR & FDCAN_RX_FIFO1_MASK;
5335   RxFifo1ITs &= hfdcan->Instance->IE;
5336   Errors = hfdcan->Instance->IR & FDCAN_ERROR_MASK;
5337   Errors &= hfdcan->Instance->IE;
5338   ErrorStatusITs = hfdcan->Instance->IR & FDCAN_ERROR_STATUS_MASK;
5339   ErrorStatusITs &= hfdcan->Instance->IE;
5340   itsourceIE = hfdcan->Instance->IE;
5341   itflagIR = hfdcan->Instance->IR;
5342 
5343   /* High Priority Message interrupt management *******************************/
5344   if (FDCAN_CHECK_IT_SOURCE(itsourceIE, FDCAN_IT_RX_HIGH_PRIORITY_MSG) != RESET)
5345   {
5346     if (FDCAN_CHECK_FLAG(itflagIR, FDCAN_FLAG_RX_HIGH_PRIORITY_MSG) != RESET)
5347     {
5348       /* Clear the High Priority Message flag */
5349       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_RX_HIGH_PRIORITY_MSG);
5350 
5351 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5352       /* Call registered callback*/
5353       hfdcan->HighPriorityMessageCallback(hfdcan);
5354 #else
5355       /* High Priority Message Callback */
5356       HAL_FDCAN_HighPriorityMessageCallback(hfdcan);
5357 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5358     }
5359   }
5360 
5361   /* Transmission Abort interrupt management **********************************/
5362   if (FDCAN_CHECK_IT_SOURCE(itsourceIE, FDCAN_IT_TX_ABORT_COMPLETE) != RESET)
5363   {
5364     if (FDCAN_CHECK_FLAG(itflagIR, FDCAN_FLAG_TX_ABORT_COMPLETE) != RESET)
5365     {
5366       /* List of aborted monitored buffers */
5367       AbortedBuffers = hfdcan->Instance->TXBCF;
5368       AbortedBuffers &= hfdcan->Instance->TXBCIE;
5369 
5370       /* Clear the Transmission Cancellation flag */
5371       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TX_ABORT_COMPLETE);
5372 
5373 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5374       /* Call registered callback*/
5375       hfdcan->TxBufferAbortCallback(hfdcan, AbortedBuffers);
5376 #else
5377       /* Transmission Cancellation Callback */
5378       HAL_FDCAN_TxBufferAbortCallback(hfdcan, AbortedBuffers);
5379 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5380     }
5381   }
5382 
5383   /* Clock calibration unit interrupts management *****************************/
5384   if (ClkCalibrationITs != 0U)
5385   {
5386     /* Clear the Clock Calibration flags */
5387     __HAL_FDCAN_CLEAR_FLAG(hfdcan, ClkCalibrationITs);
5388 
5389 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5390     /* Call registered callback*/
5391     hfdcan->ClockCalibrationCallback(hfdcan, ClkCalibrationITs);
5392 #else
5393     /* Clock Calibration Callback */
5394     HAL_FDCAN_ClockCalibrationCallback(hfdcan, ClkCalibrationITs);
5395 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5396   }
5397 
5398   /* Tx event FIFO interrupts management **************************************/
5399   if (TxEventFifoITs != 0U)
5400   {
5401     /* Clear the Tx Event FIFO flags */
5402     __HAL_FDCAN_CLEAR_FLAG(hfdcan, TxEventFifoITs);
5403 
5404 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5405     /* Call registered callback*/
5406     hfdcan->TxEventFifoCallback(hfdcan, TxEventFifoITs);
5407 #else
5408     /* Tx Event FIFO Callback */
5409     HAL_FDCAN_TxEventFifoCallback(hfdcan, TxEventFifoITs);
5410 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5411   }
5412 
5413   /* Rx FIFO 0 interrupts management ******************************************/
5414   if (RxFifo0ITs != 0U)
5415   {
5416     /* Clear the Rx FIFO 0 flags */
5417     __HAL_FDCAN_CLEAR_FLAG(hfdcan, RxFifo0ITs);
5418 
5419 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5420     /* Call registered callback*/
5421     hfdcan->RxFifo0Callback(hfdcan, RxFifo0ITs);
5422 #else
5423     /* Rx FIFO 0 Callback */
5424     HAL_FDCAN_RxFifo0Callback(hfdcan, RxFifo0ITs);
5425 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5426   }
5427 
5428   /* Rx FIFO 1 interrupts management ******************************************/
5429   if (RxFifo1ITs != 0U)
5430   {
5431     /* Clear the Rx FIFO 1 flags */
5432     __HAL_FDCAN_CLEAR_FLAG(hfdcan, RxFifo1ITs);
5433 
5434 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5435     /* Call registered callback*/
5436     hfdcan->RxFifo1Callback(hfdcan, RxFifo1ITs);
5437 #else
5438     /* Rx FIFO 1 Callback */
5439     HAL_FDCAN_RxFifo1Callback(hfdcan, RxFifo1ITs);
5440 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5441   }
5442 
5443   /* Tx FIFO empty interrupt management ***************************************/
5444   if (FDCAN_CHECK_IT_SOURCE(itsourceIE, FDCAN_IT_TX_FIFO_EMPTY) != RESET)
5445   {
5446     if (FDCAN_CHECK_FLAG(itflagIR, FDCAN_FLAG_TX_FIFO_EMPTY) != RESET)
5447     {
5448       /* Clear the Tx FIFO empty flag */
5449       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TX_FIFO_EMPTY);
5450 
5451 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5452       /* Call registered callback*/
5453       hfdcan->TxFifoEmptyCallback(hfdcan);
5454 #else
5455       /* Tx FIFO empty Callback */
5456       HAL_FDCAN_TxFifoEmptyCallback(hfdcan);
5457 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5458     }
5459   }
5460 
5461   /* Transmission Complete interrupt management *******************************/
5462   if (FDCAN_CHECK_IT_SOURCE(itsourceIE, FDCAN_IT_TX_COMPLETE) != RESET)
5463   {
5464     if (FDCAN_CHECK_FLAG(itflagIR, FDCAN_FLAG_TX_COMPLETE) != RESET)
5465     {
5466       /* List of transmitted monitored buffers */
5467       TransmittedBuffers = hfdcan->Instance->TXBTO;
5468       TransmittedBuffers &= hfdcan->Instance->TXBTIE;
5469 
5470       /* Clear the Transmission Complete flag */
5471       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TX_COMPLETE);
5472 
5473 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5474       /* Call registered callback*/
5475       hfdcan->TxBufferCompleteCallback(hfdcan, TransmittedBuffers);
5476 #else
5477       /* Transmission Complete Callback */
5478       HAL_FDCAN_TxBufferCompleteCallback(hfdcan, TransmittedBuffers);
5479 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5480     }
5481   }
5482 
5483   /* Rx Buffer New Message interrupt management *******************************/
5484   if (FDCAN_CHECK_IT_SOURCE(itsourceIE, FDCAN_IT_RX_BUFFER_NEW_MESSAGE) != RESET)
5485   {
5486     if (FDCAN_CHECK_FLAG(itflagIR, FDCAN_FLAG_RX_BUFFER_NEW_MESSAGE) != RESET)
5487     {
5488       /* Clear the Rx Buffer New Message flag */
5489       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_RX_BUFFER_NEW_MESSAGE);
5490 
5491 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5492       /* Call registered callback*/
5493       hfdcan->RxBufferNewMessageCallback(hfdcan);
5494 #else
5495       /* Rx Buffer New Message Callback */
5496       HAL_FDCAN_RxBufferNewMessageCallback(hfdcan);
5497 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5498     }
5499   }
5500 
5501   /* Timestamp Wraparound interrupt management ********************************/
5502   if (FDCAN_CHECK_IT_SOURCE(itsourceIE, FDCAN_IT_TIMESTAMP_WRAPAROUND) != RESET)
5503   {
5504     if (FDCAN_CHECK_FLAG(itflagIR, FDCAN_FLAG_TIMESTAMP_WRAPAROUND) != RESET)
5505     {
5506       /* Clear the Timestamp Wraparound flag */
5507       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TIMESTAMP_WRAPAROUND);
5508 
5509 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5510       /* Call registered callback*/
5511       hfdcan->TimestampWraparoundCallback(hfdcan);
5512 #else
5513       /* Timestamp Wraparound Callback */
5514       HAL_FDCAN_TimestampWraparoundCallback(hfdcan);
5515 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5516     }
5517   }
5518 
5519   /* Timeout Occurred interrupt management ************************************/
5520   if (FDCAN_CHECK_IT_SOURCE(itsourceIE, FDCAN_IT_TIMEOUT_OCCURRED) != RESET)
5521   {
5522     if (FDCAN_CHECK_FLAG(itflagIR, FDCAN_FLAG_TIMEOUT_OCCURRED) != RESET)
5523     {
5524       /* Clear the Timeout Occurred flag */
5525       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TIMEOUT_OCCURRED);
5526 
5527 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5528       /* Call registered callback*/
5529       hfdcan->TimeoutOccurredCallback(hfdcan);
5530 #else
5531       /* Timeout Occurred Callback */
5532       HAL_FDCAN_TimeoutOccurredCallback(hfdcan);
5533 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5534     }
5535   }
5536 
5537   /* Message RAM access failure interrupt management **************************/
5538   if (FDCAN_CHECK_IT_SOURCE(itsourceIE, FDCAN_IT_RAM_ACCESS_FAILURE) != RESET)
5539   {
5540     if (FDCAN_CHECK_FLAG(itflagIR, FDCAN_FLAG_RAM_ACCESS_FAILURE) != RESET)
5541     {
5542       /* Clear the Message RAM access failure flag */
5543       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_RAM_ACCESS_FAILURE);
5544 
5545       /* Update error code */
5546       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_RAM_ACCESS;
5547     }
5548   }
5549 
5550   /* Error Status interrupts management ***************************************/
5551   if (ErrorStatusITs != 0U)
5552   {
5553     /* Clear the Error flags */
5554     __HAL_FDCAN_CLEAR_FLAG(hfdcan, ErrorStatusITs);
5555 
5556 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5557     /* Call registered callback*/
5558     hfdcan->ErrorStatusCallback(hfdcan, ErrorStatusITs);
5559 #else
5560     /* Error Status Callback */
5561     HAL_FDCAN_ErrorStatusCallback(hfdcan, ErrorStatusITs);
5562 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5563   }
5564 
5565   /* Error interrupts management **********************************************/
5566   if (Errors != 0U)
5567   {
5568     /* Clear the Error flags */
5569     __HAL_FDCAN_CLEAR_FLAG(hfdcan, Errors);
5570 
5571     /* Update error code */
5572     hfdcan->ErrorCode |= Errors;
5573   }
5574 
5575   if (hfdcan->Instance == FDCAN1)
5576   {
5577     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != 0U)
5578     {
5579       TTSchedSyncITs = hfdcan->ttcan->TTIR & FDCAN_TT_SCHEDULE_SYNC_MASK;
5580       TTSchedSyncITs &= hfdcan->ttcan->TTIE;
5581       TTTimeMarkITs = hfdcan->ttcan->TTIR & FDCAN_TT_TIME_MARK_MASK;
5582       TTTimeMarkITs &= hfdcan->ttcan->TTIE;
5583       TTGlobTimeITs = hfdcan->ttcan->TTIR & FDCAN_TT_GLOBAL_TIME_MASK;
5584       TTGlobTimeITs &= hfdcan->ttcan->TTIE;
5585       TTDistErrors = hfdcan->ttcan->TTIR & FDCAN_TT_DISTURBING_ERROR_MASK;
5586       TTDistErrors &= hfdcan->ttcan->TTIE;
5587       TTFatalErrors = hfdcan->ttcan->TTIR & FDCAN_TT_FATAL_ERROR_MASK;
5588       TTFatalErrors &= hfdcan->ttcan->TTIE;
5589       itsourceTTIE = hfdcan->ttcan->TTIE;
5590       itflagTTIR = hfdcan->ttcan->TTIR;
5591 
5592       /* TT Schedule Synchronization interrupts management **********************/
5593       if (TTSchedSyncITs != 0U)
5594       {
5595         /* Clear the TT Schedule Synchronization flags */
5596         __HAL_FDCAN_TT_CLEAR_FLAG(hfdcan, TTSchedSyncITs);
5597 
5598 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5599         /* Call registered callback*/
5600         hfdcan->TT_ScheduleSyncCallback(hfdcan, TTSchedSyncITs);
5601 #else
5602         /* TT Schedule Synchronization Callback */
5603         HAL_FDCAN_TT_ScheduleSyncCallback(hfdcan, TTSchedSyncITs);
5604 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5605       }
5606 
5607       /* TT Time Mark interrupts management *************************************/
5608       if (TTTimeMarkITs != 0U)
5609       {
5610         /* Clear the TT Time Mark flags */
5611         __HAL_FDCAN_TT_CLEAR_FLAG(hfdcan, TTTimeMarkITs);
5612 
5613 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5614         /* Call registered callback*/
5615         hfdcan->TT_TimeMarkCallback(hfdcan, TTTimeMarkITs);
5616 #else
5617         /* TT Time Mark Callback */
5618         HAL_FDCAN_TT_TimeMarkCallback(hfdcan, TTTimeMarkITs);
5619 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5620       }
5621 
5622       /* TT Stop Watch interrupt management *************************************/
5623       if (FDCAN_CHECK_IT_SOURCE(itsourceTTIE, FDCAN_TT_IT_STOP_WATCH) != RESET)
5624       {
5625         if (FDCAN_CHECK_FLAG(itflagTTIR, FDCAN_TT_FLAG_STOP_WATCH) != RESET)
5626         {
5627           /* Retrieve Stop watch Time and Cycle count */
5628           SWTime = ((hfdcan->ttcan->TTCPT & FDCAN_TTCPT_SWV) >> FDCAN_TTCPT_SWV_Pos);
5629           SWCycleCount = ((hfdcan->ttcan->TTCPT & FDCAN_TTCPT_CCV) >> FDCAN_TTCPT_CCV_Pos);
5630 
5631           /* Clear the TT Stop Watch flag */
5632           __HAL_FDCAN_TT_CLEAR_FLAG(hfdcan, FDCAN_TT_FLAG_STOP_WATCH);
5633 
5634 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5635           /* Call registered callback*/
5636           hfdcan->TT_StopWatchCallback(hfdcan, SWTime, SWCycleCount);
5637 #else
5638           /* TT Stop Watch Callback */
5639           HAL_FDCAN_TT_StopWatchCallback(hfdcan, SWTime, SWCycleCount);
5640 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5641         }
5642       }
5643 
5644       /* TT Global Time interrupts management ***********************************/
5645       if (TTGlobTimeITs != 0U)
5646       {
5647         /* Clear the TT Global Time flags */
5648         __HAL_FDCAN_TT_CLEAR_FLAG(hfdcan, TTGlobTimeITs);
5649 
5650 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5651         /* Call registered callback*/
5652         hfdcan->TT_GlobalTimeCallback(hfdcan, TTGlobTimeITs);
5653 #else
5654         /* TT Global Time Callback */
5655         HAL_FDCAN_TT_GlobalTimeCallback(hfdcan, TTGlobTimeITs);
5656 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5657       }
5658 
5659       /* TT Disturbing Error interrupts management ******************************/
5660       if (TTDistErrors != 0U)
5661       {
5662         /* Clear the TT Disturbing Error flags */
5663         __HAL_FDCAN_TT_CLEAR_FLAG(hfdcan, TTDistErrors);
5664 
5665         /* Update error code */
5666         hfdcan->ErrorCode |= TTDistErrors;
5667       }
5668 
5669       /* TT Fatal Error interrupts management ***********************************/
5670       if (TTFatalErrors != 0U)
5671       {
5672         /* Clear the TT Fatal Error flags */
5673         __HAL_FDCAN_TT_CLEAR_FLAG(hfdcan, TTFatalErrors);
5674 
5675         /* Update error code */
5676         hfdcan->ErrorCode |= TTFatalErrors;
5677       }
5678     }
5679   }
5680 
5681   if (hfdcan->ErrorCode != HAL_FDCAN_ERROR_NONE)
5682   {
5683 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5684     /* Call registered callback*/
5685     hfdcan->ErrorCallback(hfdcan);
5686 #else
5687     /* Error Callback */
5688     HAL_FDCAN_ErrorCallback(hfdcan);
5689 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5690   }
5691 }
5692 
5693 /**
5694   * @}
5695   */
5696 
5697 /** @defgroup FDCAN_Exported_Functions_Group6 Callback functions
5698   * @ingroup RTEMSBSPsARMSTM32H7
5699   *  @brief   FDCAN Callback functions
5700   *
5701 @verbatim
5702   ==============================================================================
5703                           ##### Callback functions #####
5704   ==============================================================================
5705     [..]
5706     This subsection provides the following callback functions:
5707       (+) HAL_FDCAN_ClockCalibrationCallback
5708       (+) HAL_FDCAN_TxEventFifoCallback
5709       (+) HAL_FDCAN_RxFifo0Callback
5710       (+) HAL_FDCAN_RxFifo1Callback
5711       (+) HAL_FDCAN_TxFifoEmptyCallback
5712       (+) HAL_FDCAN_TxBufferCompleteCallback
5713       (+) HAL_FDCAN_TxBufferAbortCallback
5714       (+) HAL_FDCAN_RxBufferNewMessageCallback
5715       (+) HAL_FDCAN_HighPriorityMessageCallback
5716       (+) HAL_FDCAN_TimestampWraparoundCallback
5717       (+) HAL_FDCAN_TimeoutOccurredCallback
5718       (+) HAL_FDCAN_ErrorCallback
5719       (+) HAL_FDCAN_ErrorStatusCallback
5720       (+) HAL_FDCAN_TT_ScheduleSyncCallback
5721       (+) HAL_FDCAN_TT_TimeMarkCallback
5722       (+) HAL_FDCAN_TT_StopWatchCallback
5723       (+) HAL_FDCAN_TT_GlobalTimeCallback
5724 
5725 @endverbatim
5726   * @{
5727   */
5728 
5729 /**
5730   * @brief  Clock Calibration callback.
5731   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5732   *         the configuration information for the specified FDCAN.
5733   * @param  ClkCalibrationITs indicates which Clock Calibration interrupts are signaled.
5734   *         This parameter can be any combination of @arg FDCAN_Clock_Calibration_Interrupts.
5735   * @retval None
5736   */
5737 __weak void HAL_FDCAN_ClockCalibrationCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t ClkCalibrationITs)
5738 {
5739   /* Prevent unused argument(s) compilation warning */
5740   UNUSED(hfdcan);
5741   UNUSED(ClkCalibrationITs);
5742 
5743   /* NOTE: This function Should not be modified, when the callback is needed,
5744             the HAL_FDCAN_ClockCalibrationCallback could be implemented in the user file
5745    */
5746 }
5747 
5748 /**
5749   * @brief  Tx Event callback.
5750   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5751   *         the configuration information for the specified FDCAN.
5752   * @param  TxEventFifoITs indicates which Tx Event FIFO interrupts are signaled.
5753   *         This parameter can be any combination of @arg FDCAN_Tx_Event_Fifo_Interrupts.
5754   * @retval None
5755   */
5756 __weak void HAL_FDCAN_TxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t TxEventFifoITs)
5757 {
5758   /* Prevent unused argument(s) compilation warning */
5759   UNUSED(hfdcan);
5760   UNUSED(TxEventFifoITs);
5761 
5762   /* NOTE: This function Should not be modified, when the callback is needed,
5763             the HAL_FDCAN_TxEventFifoCallback could be implemented in the user file
5764    */
5765 }
5766 
5767 /**
5768   * @brief  Rx FIFO 0 callback.
5769   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5770   *         the configuration information for the specified FDCAN.
5771   * @param  RxFifo0ITs indicates which Rx FIFO 0 interrupts are signaled.
5772   *         This parameter can be any combination of @arg FDCAN_Rx_Fifo0_Interrupts.
5773   * @retval None
5774   */
5775 __weak void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
5776 {
5777   /* Prevent unused argument(s) compilation warning */
5778   UNUSED(hfdcan);
5779   UNUSED(RxFifo0ITs);
5780 
5781   /* NOTE: This function Should not be modified, when the callback is needed,
5782             the HAL_FDCAN_RxFifo0Callback could be implemented in the user file
5783    */
5784 }
5785 
5786 /**
5787   * @brief  Rx FIFO 1 callback.
5788   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5789   *         the configuration information for the specified FDCAN.
5790   * @param  RxFifo1ITs indicates which Rx FIFO 1 interrupts are signaled.
5791   *         This parameter can be any combination of @arg FDCAN_Rx_Fifo1_Interrupts.
5792   * @retval None
5793   */
5794 __weak void HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo1ITs)
5795 {
5796   /* Prevent unused argument(s) compilation warning */
5797   UNUSED(hfdcan);
5798   UNUSED(RxFifo1ITs);
5799 
5800   /* NOTE: This function Should not be modified, when the callback is needed,
5801             the HAL_FDCAN_RxFifo1Callback could be implemented in the user file
5802    */
5803 }
5804 
5805 /**
5806   * @brief  Tx FIFO Empty callback.
5807   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5808   *         the configuration information for the specified FDCAN.
5809   * @retval None
5810   */
5811 __weak void HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef *hfdcan)
5812 {
5813   /* Prevent unused argument(s) compilation warning */
5814   UNUSED(hfdcan);
5815 
5816   /* NOTE: This function Should not be modified, when the callback is needed,
5817             the HAL_FDCAN_TxFifoEmptyCallback could be implemented in the user file
5818    */
5819 }
5820 
5821 /**
5822   * @brief  Transmission Complete callback.
5823   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5824   *         the configuration information for the specified FDCAN.
5825   * @param  BufferIndexes Indexes of the transmitted buffers.
5826   *         This parameter can be any combination of @arg FDCAN_Tx_location.
5827   * @retval None
5828   */
5829 __weak void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes)
5830 {
5831   /* Prevent unused argument(s) compilation warning */
5832   UNUSED(hfdcan);
5833   UNUSED(BufferIndexes);
5834 
5835   /* NOTE: This function Should not be modified, when the callback is needed,
5836             the HAL_FDCAN_TxBufferCompleteCallback could be implemented in the user file
5837    */
5838 }
5839 
5840 /**
5841   * @brief  Transmission Cancellation callback.
5842   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5843   *         the configuration information for the specified FDCAN.
5844   * @param  BufferIndexes Indexes of the aborted buffers.
5845   *         This parameter can be any combination of @arg FDCAN_Tx_location.
5846   * @retval None
5847   */
5848 __weak void HAL_FDCAN_TxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes)
5849 {
5850   /* Prevent unused argument(s) compilation warning */
5851   UNUSED(hfdcan);
5852   UNUSED(BufferIndexes);
5853 
5854   /* NOTE: This function Should not be modified, when the callback is needed,
5855             the HAL_FDCAN_TxBufferAbortCallback could be implemented in the user file
5856    */
5857 }
5858 
5859 /**
5860   * @brief  Rx Buffer New Message callback.
5861   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5862   *         the configuration information for the specified FDCAN.
5863   * @retval None
5864   */
5865 __weak void HAL_FDCAN_RxBufferNewMessageCallback(FDCAN_HandleTypeDef *hfdcan)
5866 {
5867   /* Prevent unused argument(s) compilation warning */
5868   UNUSED(hfdcan);
5869 
5870   /* NOTE: This function Should not be modified, when the callback is needed,
5871             the HAL_FDCAN_RxBufferNewMessageCallback could be implemented in the user file
5872    */
5873 }
5874 
5875 /**
5876   * @brief  Timestamp Wraparound callback.
5877   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5878   *         the configuration information for the specified FDCAN.
5879   * @retval None
5880   */
5881 __weak void HAL_FDCAN_TimestampWraparoundCallback(FDCAN_HandleTypeDef *hfdcan)
5882 {
5883   /* Prevent unused argument(s) compilation warning */
5884   UNUSED(hfdcan);
5885 
5886   /* NOTE: This function Should not be modified, when the callback is needed,
5887             the HAL_FDCAN_TimestampWraparoundCallback could be implemented in the user file
5888    */
5889 }
5890 
5891 /**
5892   * @brief  Timeout Occurred callback.
5893   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5894   *         the configuration information for the specified FDCAN.
5895   * @retval None
5896   */
5897 __weak void HAL_FDCAN_TimeoutOccurredCallback(FDCAN_HandleTypeDef *hfdcan)
5898 {
5899   /* Prevent unused argument(s) compilation warning */
5900   UNUSED(hfdcan);
5901 
5902   /* NOTE: This function Should not be modified, when the callback is needed,
5903             the HAL_FDCAN_TimeoutOccurredCallback could be implemented in the user file
5904    */
5905 }
5906 
5907 /**
5908   * @brief  High Priority Message callback.
5909   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5910   *         the configuration information for the specified FDCAN.
5911   * @retval None
5912   */
5913 __weak void HAL_FDCAN_HighPriorityMessageCallback(FDCAN_HandleTypeDef *hfdcan)
5914 {
5915   /* Prevent unused argument(s) compilation warning */
5916   UNUSED(hfdcan);
5917 
5918   /* NOTE: This function Should not be modified, when the callback is needed,
5919             the HAL_FDCAN_HighPriorityMessageCallback could be implemented in the user file
5920    */
5921 }
5922 
5923 /**
5924   * @brief  Error callback.
5925   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5926   *         the configuration information for the specified FDCAN.
5927   * @retval None
5928   */
5929 __weak void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan)
5930 {
5931   /* Prevent unused argument(s) compilation warning */
5932   UNUSED(hfdcan);
5933 
5934   /* NOTE: This function Should not be modified, when the callback is needed,
5935             the HAL_FDCAN_ErrorCallback could be implemented in the user file
5936    */
5937 }
5938 
5939 /**
5940   * @brief  Error status callback.
5941   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5942   *         the configuration information for the specified FDCAN.
5943   * @param  ErrorStatusITs indicates which Error Status interrupts are signaled.
5944   *         This parameter can be any combination of @arg FDCAN_Error_Status_Interrupts.
5945   * @retval None
5946   */
5947 __weak void HAL_FDCAN_ErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t ErrorStatusITs)
5948 {
5949   /* Prevent unused argument(s) compilation warning */
5950   UNUSED(hfdcan);
5951   UNUSED(ErrorStatusITs);
5952 
5953   /* NOTE: This function Should not be modified, when the callback is needed,
5954             the HAL_FDCAN_ErrorStatusCallback could be implemented in the user file
5955    */
5956 }
5957 
5958 /**
5959   * @brief  TT Schedule Synchronization callback.
5960   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5961   *         the configuration information for the specified FDCAN.
5962   * @param  TTSchedSyncITs indicates which TT Schedule Synchronization interrupts are signaled.
5963   *         This parameter can be any combination of @arg FDCAN_TTScheduleSynchronization_Interrupts.
5964   * @retval None
5965   */
5966 __weak void HAL_FDCAN_TT_ScheduleSyncCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t TTSchedSyncITs)
5967 {
5968   /* Prevent unused argument(s) compilation warning */
5969   UNUSED(hfdcan);
5970   UNUSED(TTSchedSyncITs);
5971 
5972   /* NOTE: This function Should not be modified, when the callback is needed,
5973             the HAL_FDCAN_TT_ScheduleSyncCallback could be implemented in the user file
5974    */
5975 }
5976 
5977 /**
5978   * @brief  TT Time Mark callback.
5979   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5980   *         the configuration information for the specified FDCAN.
5981   * @param  TTTimeMarkITs indicates which TT Schedule Synchronization interrupts are signaled.
5982   *         This parameter can be any combination of @arg FDCAN_TTTimeMark_Interrupts.
5983   * @retval None
5984   */
5985 __weak void HAL_FDCAN_TT_TimeMarkCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t TTTimeMarkITs)
5986 {
5987   /* Prevent unused argument(s) compilation warning */
5988   UNUSED(hfdcan);
5989   UNUSED(TTTimeMarkITs);
5990 
5991   /* NOTE: This function Should not be modified, when the callback is needed,
5992             the HAL_FDCAN_TT_TimeMarkCallback could be implemented in the user file
5993    */
5994 }
5995 
5996 /**
5997   * @brief  TT Stop Watch callback.
5998   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5999   *         the configuration information for the specified FDCAN.
6000   * @param  SWTime Time Value captured at the Stop Watch Trigger pin (fdcan1_swt) falling/rising
6001   *         edge (as configured via HAL_FDCAN_TTConfigStopWatch).
6002   *         This parameter is a number between 0 and 0xFFFF.
6003   * @param  SWCycleCount Cycle count value captured together with SWTime.
6004   *         This parameter is a number between 0 and 0x3F.
6005   * @retval None
6006   */
6007 __weak void HAL_FDCAN_TT_StopWatchCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t SWTime, uint32_t SWCycleCount)
6008 {
6009   /* Prevent unused argument(s) compilation warning */
6010   UNUSED(hfdcan);
6011   UNUSED(SWTime);
6012   UNUSED(SWCycleCount);
6013 
6014   /* NOTE: This function Should not be modified, when the callback is needed,
6015             the HAL_FDCAN_TT_StopWatchCallback could be implemented in the user file
6016    */
6017 }
6018 
6019 /**
6020   * @brief  TT Global Time callback.
6021   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
6022   *         the configuration information for the specified FDCAN.
6023   * @param  TTGlobTimeITs indicates which TT Global Time interrupts are signaled.
6024   *         This parameter can be any combination of @arg FDCAN_TTGlobalTime_Interrupts.
6025   * @retval None
6026   */
6027 __weak void HAL_FDCAN_TT_GlobalTimeCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t TTGlobTimeITs)
6028 {
6029   /* Prevent unused argument(s) compilation warning */
6030   UNUSED(hfdcan);
6031   UNUSED(TTGlobTimeITs);
6032 
6033   /* NOTE: This function Should not be modified, when the callback is needed,
6034             the HAL_FDCAN_TT_GlobalTimeCallback could be implemented in the user file
6035    */
6036 }
6037 
6038 /**
6039   * @}
6040   */
6041 
6042 /** @defgroup FDCAN_Exported_Functions_Group7 Peripheral State functions
6043   * @ingroup RTEMSBSPsARMSTM32H7
6044   *  @brief   FDCAN Peripheral State functions
6045   *
6046 @verbatim
6047   ==============================================================================
6048                       ##### Peripheral State functions #####
6049   ==============================================================================
6050     [..]
6051     This subsection provides functions allowing to :
6052       (+) HAL_FDCAN_GetState()  : Return the FDCAN state.
6053       (+) HAL_FDCAN_GetError()  : Return the FDCAN error code if any.
6054 
6055 @endverbatim
6056   * @{
6057   */
6058 /**
6059   * @brief  Return the FDCAN state
6060   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
6061   *         the configuration information for the specified FDCAN.
6062   * @retval HAL state
6063   */
6064 HAL_FDCAN_StateTypeDef HAL_FDCAN_GetState(const FDCAN_HandleTypeDef *hfdcan)
6065 {
6066   /* Return FDCAN state */
6067   return hfdcan->State;
6068 }
6069 
6070 /**
6071   * @brief  Return the FDCAN error code
6072   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
6073   *         the configuration information for the specified FDCAN.
6074   * @retval FDCAN Error Code
6075   */
6076 uint32_t HAL_FDCAN_GetError(const FDCAN_HandleTypeDef *hfdcan)
6077 {
6078   /* Return FDCAN error code */
6079   return hfdcan->ErrorCode;
6080 }
6081 
6082 /**
6083   * @}
6084   */
6085 
6086 /**
6087   * @}
6088   */
6089 
6090 /** @defgroup FDCAN_Private_Functions FDCAN Private Functions
6091   * @{
6092   */
6093 
6094 /**
6095   * @brief  Calculate each RAM block start address and size
6096   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
6097   *         the configuration information for the specified FDCAN.
6098   * @retval HAL status
6099  */
6100 static HAL_StatusTypeDef FDCAN_CalcultateRamBlockAddresses(FDCAN_HandleTypeDef *hfdcan)
6101 {
6102   uint32_t RAMcounter;
6103   uint32_t StartAddress;
6104 
6105   StartAddress = hfdcan->Init.MessageRAMOffset;
6106 
6107   /* Standard filter list start address */
6108   MODIFY_REG(hfdcan->Instance->SIDFC, FDCAN_SIDFC_FLSSA, (StartAddress << FDCAN_SIDFC_FLSSA_Pos));
6109 
6110   /* Standard filter elements number */
6111   MODIFY_REG(hfdcan->Instance->SIDFC, FDCAN_SIDFC_LSS, (hfdcan->Init.StdFiltersNbr << FDCAN_SIDFC_LSS_Pos));
6112 
6113   /* Extended filter list start address */
6114   StartAddress += hfdcan->Init.StdFiltersNbr;
6115   MODIFY_REG(hfdcan->Instance->XIDFC, FDCAN_XIDFC_FLESA, (StartAddress << FDCAN_XIDFC_FLESA_Pos));
6116 
6117   /* Extended filter elements number */
6118   MODIFY_REG(hfdcan->Instance->XIDFC, FDCAN_XIDFC_LSE, (hfdcan->Init.ExtFiltersNbr << FDCAN_XIDFC_LSE_Pos));
6119 
6120   /* Rx FIFO 0 start address */
6121   StartAddress += (hfdcan->Init.ExtFiltersNbr * 2U);
6122   MODIFY_REG(hfdcan->Instance->RXF0C, FDCAN_RXF0C_F0SA, (StartAddress << FDCAN_RXF0C_F0SA_Pos));
6123 
6124   /* Rx FIFO 0 elements number */
6125   MODIFY_REG(hfdcan->Instance->RXF0C, FDCAN_RXF0C_F0S, (hfdcan->Init.RxFifo0ElmtsNbr << FDCAN_RXF0C_F0S_Pos));
6126 
6127   /* Rx FIFO 1 start address */
6128   StartAddress += (hfdcan->Init.RxFifo0ElmtsNbr * hfdcan->Init.RxFifo0ElmtSize);
6129   MODIFY_REG(hfdcan->Instance->RXF1C, FDCAN_RXF1C_F1SA, (StartAddress << FDCAN_RXF1C_F1SA_Pos));
6130 
6131   /* Rx FIFO 1 elements number */
6132   MODIFY_REG(hfdcan->Instance->RXF1C, FDCAN_RXF1C_F1S, (hfdcan->Init.RxFifo1ElmtsNbr << FDCAN_RXF1C_F1S_Pos));
6133 
6134   /* Rx buffer list start address */
6135   StartAddress += (hfdcan->Init.RxFifo1ElmtsNbr * hfdcan->Init.RxFifo1ElmtSize);
6136   MODIFY_REG(hfdcan->Instance->RXBC, FDCAN_RXBC_RBSA, (StartAddress << FDCAN_RXBC_RBSA_Pos));
6137 
6138   /* Tx event FIFO start address */
6139   StartAddress += (hfdcan->Init.RxBuffersNbr * hfdcan->Init.RxBufferSize);
6140   MODIFY_REG(hfdcan->Instance->TXEFC, FDCAN_TXEFC_EFSA, (StartAddress << FDCAN_TXEFC_EFSA_Pos));
6141 
6142   /* Tx event FIFO elements number */
6143   MODIFY_REG(hfdcan->Instance->TXEFC, FDCAN_TXEFC_EFS, (hfdcan->Init.TxEventsNbr << FDCAN_TXEFC_EFS_Pos));
6144 
6145   /* Tx buffer list start address */
6146   StartAddress += (hfdcan->Init.TxEventsNbr * 2U);
6147   MODIFY_REG(hfdcan->Instance->TXBC, FDCAN_TXBC_TBSA, (StartAddress << FDCAN_TXBC_TBSA_Pos));
6148 
6149   /* Dedicated Tx buffers number */
6150   MODIFY_REG(hfdcan->Instance->TXBC, FDCAN_TXBC_NDTB, (hfdcan->Init.TxBuffersNbr << FDCAN_TXBC_NDTB_Pos));
6151 
6152   /* Tx FIFO/queue elements number */
6153   MODIFY_REG(hfdcan->Instance->TXBC, FDCAN_TXBC_TFQS, (hfdcan->Init.TxFifoQueueElmtsNbr << FDCAN_TXBC_TFQS_Pos));
6154 
6155   hfdcan->msgRam.StandardFilterSA = SRAMCAN_BASE + (hfdcan->Init.MessageRAMOffset * 4U);
6156   hfdcan->msgRam.ExtendedFilterSA = hfdcan->msgRam.StandardFilterSA + (hfdcan->Init.StdFiltersNbr * 4U);
6157   hfdcan->msgRam.RxFIFO0SA = hfdcan->msgRam.ExtendedFilterSA + (hfdcan->Init.ExtFiltersNbr * 2U * 4U);
6158   hfdcan->msgRam.RxFIFO1SA = hfdcan->msgRam.RxFIFO0SA +
6159                              (hfdcan->Init.RxFifo0ElmtsNbr * hfdcan->Init.RxFifo0ElmtSize * 4U);
6160   hfdcan->msgRam.RxBufferSA = hfdcan->msgRam.RxFIFO1SA +
6161                               (hfdcan->Init.RxFifo1ElmtsNbr * hfdcan->Init.RxFifo1ElmtSize * 4U);
6162   hfdcan->msgRam.TxEventFIFOSA = hfdcan->msgRam.RxBufferSA +
6163                                  (hfdcan->Init.RxBuffersNbr * hfdcan->Init.RxBufferSize * 4U);
6164   hfdcan->msgRam.TxBufferSA = hfdcan->msgRam.TxEventFIFOSA + (hfdcan->Init.TxEventsNbr * 2U * 4U);
6165   hfdcan->msgRam.TxFIFOQSA = hfdcan->msgRam.TxBufferSA + (hfdcan->Init.TxBuffersNbr * hfdcan->Init.TxElmtSize * 4U);
6166 
6167   hfdcan->msgRam.EndAddress = hfdcan->msgRam.TxFIFOQSA +
6168                               (hfdcan->Init.TxFifoQueueElmtsNbr * hfdcan->Init.TxElmtSize * 4U);
6169 
6170   if (hfdcan->msgRam.EndAddress > FDCAN_MESSAGE_RAM_END_ADDRESS) /* Last address of the Message RAM */
6171   {
6172     /* Update error code.
6173        Message RAM overflow */
6174     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
6175 
6176     /* Change FDCAN state */
6177     hfdcan->State = HAL_FDCAN_STATE_ERROR;
6178 
6179     return HAL_ERROR;
6180   }
6181   else
6182   {
6183     /* Flush the allocated Message RAM area */
6184     for (RAMcounter = hfdcan->msgRam.StandardFilterSA; RAMcounter < hfdcan->msgRam.EndAddress; RAMcounter += 4U)
6185     {
6186       *(uint32_t *)(RAMcounter) = 0x00000000;
6187     }
6188   }
6189 
6190   /* Return function status */
6191   return HAL_OK;
6192 }
6193 
6194 /**
6195   * @brief  Copy Tx message to the message RAM.
6196   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
6197   *         the configuration information for the specified FDCAN.
6198   * @param  pTxHeader pointer to a FDCAN_TxHeaderTypeDef structure.
6199   * @param  pTxData pointer to a buffer containing the payload of the Tx frame.
6200   * @param  BufferIndex index of the buffer to be configured.
6201   * @retval none
6202  */
6203 static void FDCAN_CopyMessageToRAM(const FDCAN_HandleTypeDef *hfdcan, const FDCAN_TxHeaderTypeDef *pTxHeader,
6204                                    const uint8_t *pTxData, uint32_t BufferIndex)
6205 {
6206   uint32_t TxElementW1;
6207   uint32_t TxElementW2;
6208   uint32_t *TxAddress;
6209   uint32_t ByteCounter;
6210 
6211   /* Build first word of Tx header element */
6212   if (pTxHeader->IdType == FDCAN_STANDARD_ID)
6213   {
6214     TxElementW1 = (pTxHeader->ErrorStateIndicator |
6215                    FDCAN_STANDARD_ID |
6216                    pTxHeader->TxFrameType |
6217                    (pTxHeader->Identifier << 18U));
6218   }
6219   else /* pTxHeader->IdType == FDCAN_EXTENDED_ID */
6220   {
6221     TxElementW1 = (pTxHeader->ErrorStateIndicator |
6222                    FDCAN_EXTENDED_ID |
6223                    pTxHeader->TxFrameType |
6224                    pTxHeader->Identifier);
6225   }
6226 
6227   /* Build second word of Tx header element */
6228   TxElementW2 = ((pTxHeader->MessageMarker << 24U) |
6229                  pTxHeader->TxEventFifoControl |
6230                  pTxHeader->FDFormat |
6231                  pTxHeader->BitRateSwitch |
6232                  (pTxHeader->DataLength << 16U));
6233 
6234   /* Calculate Tx element address */
6235   TxAddress = (uint32_t *)(hfdcan->msgRam.TxBufferSA + (BufferIndex * hfdcan->Init.TxElmtSize * 4U));
6236 
6237   /* Write Tx element header to the message RAM */
6238   *TxAddress = TxElementW1;
6239   TxAddress++;
6240   *TxAddress = TxElementW2;
6241   TxAddress++;
6242 
6243   /* Write Tx payload to the message RAM */
6244   for (ByteCounter = 0; ByteCounter < DLCtoBytes[pTxHeader->DataLength]; ByteCounter += 4U)
6245   {
6246     *TxAddress = (((uint32_t)pTxData[ByteCounter + 3U] << 24U) |
6247                   ((uint32_t)pTxData[ByteCounter + 2U] << 16U) |
6248                   ((uint32_t)pTxData[ByteCounter + 1U] << 8U)  |
6249                   (uint32_t)pTxData[ByteCounter]);
6250     TxAddress++;
6251   }
6252 }
6253 
6254 /**
6255   * @}
6256   */
6257 #endif /* HAL_FDCAN_MODULE_ENABLED */
6258 /**
6259   * @}
6260   */
6261 
6262 /**
6263   * @}
6264   */
6265 
6266 #endif /* FDCAN1 */