1 /**
2   ******************************************************************************
3   * @file    stm32h7xx_hal_fdcan.c
4   * @author  MCD Application Team
5   * @brief   FDCAN HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Flexible DataRate Controller Area Network
8   *          (FDCAN) peripheral:
9   *           + Initialization and de-initialization functions
10   *           + IO operation functions
11   *           + Peripheral Configuration and Control functions
12   *           + Peripheral State and Error functions
13   *
14   @verbatim
15   ==============================================================================
16                         ##### How to use this driver #####
17   ==============================================================================
18     [..]
19       (#) Initialize the FDCAN peripheral using HAL_FDCAN_Init function.
20 
21       (#) If needed , configure the reception filters and optional features using
22           the following configuration functions:
23             (++) HAL_FDCAN_ConfigClockCalibration
24             (++) HAL_FDCAN_ConfigFilter
25             (++) HAL_FDCAN_ConfigGlobalFilter
26             (++) HAL_FDCAN_ConfigExtendedIdMask
27             (++) HAL_FDCAN_ConfigRxFifoOverwrite
28             (++) HAL_FDCAN_ConfigFifoWatermark
29             (++) HAL_FDCAN_ConfigRamWatchdog
30             (++) HAL_FDCAN_ConfigTimestampCounter
31             (++) HAL_FDCAN_EnableTimestampCounter
32             (++) HAL_FDCAN_DisableTimestampCounter
33             (++) HAL_FDCAN_ConfigTimeoutCounter
34             (++) HAL_FDCAN_EnableTimeoutCounter
35             (++) HAL_FDCAN_DisableTimeoutCounter
36             (++) HAL_FDCAN_ConfigTxDelayCompensation
37             (++) HAL_FDCAN_EnableTxDelayCompensation
38             (++) HAL_FDCAN_DisableTxDelayCompensation
39             (++) HAL_FDCAN_EnableISOMode
40             (++) HAL_FDCAN_DisableISOMode
41             (++) HAL_FDCAN_EnableEdgeFiltering
42             (++) HAL_FDCAN_DisableEdgeFiltering
43             (++) HAL_FDCAN_TT_ConfigOperation
44             (++) HAL_FDCAN_TT_ConfigReferenceMessage
45             (++) HAL_FDCAN_TT_ConfigTrigger
46 
47       (#) Start the FDCAN module using HAL_FDCAN_Start function. At this level
48           the node is active on the bus: it can send and receive messages.
49 
50       (#) The following Tx control functions can only be called when the FDCAN
51           module is started:
52             (++) HAL_FDCAN_AddMessageToTxFifoQ
53             (++) HAL_FDCAN_EnableTxBufferRequest
54             (++) HAL_FDCAN_AbortTxRequest
55 
56       (#) After having submitted a Tx request in Tx Fifo or Queue, it is possible to
57           get Tx buffer location used to place the Tx request thanks to
58           HAL_FDCAN_GetLatestTxFifoQRequestBuffer API.
59           It is then possible to abort later on the corresponding Tx Request using
60           HAL_FDCAN_AbortTxRequest API.
61 
62       (#) When a message is received into the FDCAN message RAM, it can be
63           retrieved using the HAL_FDCAN_GetRxMessage function.
64 
65       (#) Calling the HAL_FDCAN_Stop function stops the FDCAN module by entering
66           it to initialization mode and re-enabling access to configuration
67           registers through the configuration functions listed here above.
68 
69       (#) All other control functions can be called any time after initialization
70           phase, no matter if the FDCAN module is started or stopped.
71 
72       *** Polling mode operation ***
73       ==============================
74 
75     [..]
76         (#) Reception and transmission states can be monitored via the following
77             functions:
78               (++) HAL_FDCAN_IsRxBufferMessageAvailable
79               (++) HAL_FDCAN_IsTxBufferMessagePending
80               (++) HAL_FDCAN_GetRxFifoFillLevel
81               (++) HAL_FDCAN_GetTxFifoFreeLevel
82 
83       *** Interrupt mode operation ***
84       ================================
85       [..]
86         (#) There are two interrupt lines: line 0 and 1.
87             By default, all interrupts are assigned to line 0. Interrupt lines
88             can be configured using HAL_FDCAN_ConfigInterruptLines function.
89 
90         (#) Notifications are activated using HAL_FDCAN_ActivateNotification
91             function. Then, the process can be controlled through one of the
92             available user callbacks: HAL_FDCAN_xxxCallback.
93 
94   *** Callback registration ***
95   =============================================
96 
97   The compilation define USE_HAL_FDCAN_REGISTER_CALLBACKS when set to 1
98   allows the user to configure dynamically the driver callbacks.
99   Use Function @ref HAL_FDCAN_RegisterCallback() or HAL_FDCAN_RegisterXXXCallback()
100   to register an interrupt callback.
101 
102   Function @ref HAL_FDCAN_RegisterCallback() allows to register following callbacks:
103     (+) TxFifoEmptyCallback          : Tx Fifo Empty Callback.
104     (+) RxBufferNewMessageCallback   : Rx Buffer New Message Callback.
105     (+) HighPriorityMessageCallback  : High Priority Message Callback.
106     (+) TimestampWraparoundCallback  : Timestamp Wraparound Callback.
107     (+) TimeoutOccurredCallback      : Timeout Occurred Callback.
108     (+) ErrorCallback                : Error Callback.
109     (+) MspInitCallback              : FDCAN MspInit.
110     (+) MspDeInitCallback            : FDCAN MspDeInit.
111   This function takes as parameters the HAL peripheral handle, the Callback ID
112   and a pointer to the user callback function.
113 
114   For specific callbacks ClockCalibrationCallback, TxEventFifoCallback, RxFifo0Callback, RxFifo1Callback,
115   TxBufferCompleteCallback, TxBufferAbortCallback, ErrorStatusCallback, TT_ScheduleSyncCallback, TT_TimeMarkCallback,
116   TT_StopWatchCallback and TT_GlobalTimeCallback, use dedicated register callbacks :
117   respectively @ref HAL_FDCAN_RegisterClockCalibrationCallback(), @ref HAL_FDCAN_RegisterTxEventFifoCallback(),
118   @ref HAL_FDCAN_RegisterRxFifo0Callback(), @ref HAL_FDCAN_RegisterRxFifo1Callback(),
119   @ref HAL_FDCAN_RegisterTxBufferCompleCallback(), @ref HAL_FDCAN_RegisterTxBufferAbortCallback(),
120   @ref HAL_FDCAN_RegisterErrorStatusCallback(), @ref HAL_FDCAN_TT_RegisterScheduleSyncCallback(),
121   @ref HAL_FDCAN_TT_RegisterTimeMarkCallback(), @ref HAL_FDCAN_TT_RegisterStopWatchCallback() and
122   @ref HAL_FDCAN_TT_RegisterGlobalTimeCallback().
123 
124   Use function @ref HAL_FDCAN_UnRegisterCallback() to reset a callback to the default
125   weak function.
126   @ref HAL_FDCAN_UnRegisterCallback takes as parameters the HAL peripheral handle,
127   and the Callback ID.
128   This function allows to reset following callbacks:
129     (+) TxFifoEmptyCallback          : Tx Fifo Empty Callback.
130     (+) RxBufferNewMessageCallback   : Rx Buffer New Message Callback.
131     (+) HighPriorityMessageCallback  : High Priority Message Callback.
132     (+) TimestampWraparoundCallback  : Timestamp Wraparound Callback.
133     (+) TimeoutOccurredCallback      : Timeout Occurred Callback.
134     (+) ErrorCallback                : Error Callback.
135     (+) MspInitCallback              : FDCAN MspInit.
136     (+) MspDeInitCallback            : FDCAN MspDeInit.
137 
138   For specific callbacks ClockCalibrationCallback, TxEventFifoCallback, RxFifo0Callback,
139   RxFifo1Callback, TxBufferCompleteCallback, TxBufferAbortCallback, TT_ScheduleSyncCallback,
140   TT_TimeMarkCallback, TT_StopWatchCallback and TT_GlobalTimeCallback, use dedicated
141   register callbacks : respectively @ref HAL_FDCAN_UnRegisterClockCalibrationCallback(),
142   @ref HAL_FDCAN_UnRegisterTxEventFifoCallback(), @ref HAL_FDCAN_UnRegisterRxFifo0Callback(),
143   @ref HAL_FDCAN_UnRegisterRxFifo1Callback(), @ref HAL_FDCAN_UnRegisterTxBufferCompleCallback(),
144   @ref HAL_FDCAN_UnRegisterTxBufferAbortCallback(), @ref HAL_FDCAN_UnRegisterErrorStatusCallback(),
145   @ref HAL_FDCAN_TT_UnRegisterScheduleSyncCallback(), @ref HAL_FDCAN_TT_UnRegisterTimeMarkCallback(),
146   @ref HAL_FDCAN_TT_UnRegisterStopWatchCallback() and @ref HAL_FDCAN_TT_UnRegisterGlobalTimeCallback().
147 
148   By default, after the @ref HAL_FDCAN_Init() and when the state is HAL_FDCAN_STATE_RESET,
149   all callbacks are set to the corresponding weak functions:
150   examples @ref HAL_FDCAN_ErrorCallback().
151   Exception done for MspInit and MspDeInit functions that are
152   reset to the legacy weak function in the @ref HAL_FDCAN_Init()/ @ref HAL_FDCAN_DeInit() only when
153   these callbacks are null (not registered beforehand).
154   if not, MspInit or MspDeInit are not null, the @ref HAL_FDCAN_Init()/ @ref HAL_FDCAN_DeInit()
155   keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
156 
157   Callbacks can be registered/unregistered in HAL_FDCAN_STATE_READY state only.
158   Exception done MspInit/MspDeInit that can be registered/unregistered
159   in HAL_FDCAN_STATE_READY or HAL_FDCAN_STATE_RESET state,
160   thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
161   In that case first register the MspInit/MspDeInit user callbacks
162   using @ref HAL_FDCAN_RegisterCallback() before calling @ref HAL_FDCAN_DeInit()
163   or @ref HAL_FDCAN_Init() function.
164 
165   When The compilation define USE_HAL_FDCAN_REGISTER_CALLBACKS is set to 0 or
166   not defined, the callback registration feature is not available and all callbacks
167   are set to the corresponding weak functions.
168 
169   @endverbatim
170 
171   ******************************************************************************
172   * @attention
173   *
174   * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
175   * All rights reserved.</center></h2>
176   *
177   * This software component is licensed by ST under BSD 3-Clause license,
178   * the "License"; You may not use this file except in compliance with the
179   * License. You may obtain a copy of the License at:
180   *                        opensource.org/licenses/BSD-3-Clause
181   *
182   ******************************************************************************
183   */
184 
185 /* Includes ------------------------------------------------------------------*/
186 #include "stm32h7xx_hal.h"
187 
188 #if defined(FDCAN1)
189 
190 /** @addtogroup STM32H7xx_HAL_Driver
191   * @{
192   */
193 
194 /** @defgroup FDCAN FDCAN
195   * @brief FDCAN HAL module driver
196   * @{
197   */
198 
199 #ifdef HAL_FDCAN_MODULE_ENABLED
200 
201 /* Private typedef -----------------------------------------------------------*/
202 /* Private define ------------------------------------------------------------*/
203 /** @addtogroup FDCAN_Private_Constants
204   * @{
205   */
206 #define FDCAN_TIMEOUT_VALUE 10U
207 #define FDCAN_TIMEOUT_COUNT 50U
208 
209 #define FDCAN_TX_EVENT_FIFO_MASK (FDCAN_IR_TEFL | FDCAN_IR_TEFF | FDCAN_IR_TEFW | FDCAN_IR_TEFN)
210 #define FDCAN_RX_FIFO0_MASK (FDCAN_IR_RF0L | FDCAN_IR_RF0F | FDCAN_IR_RF0W | FDCAN_IR_RF0N)
211 #define FDCAN_RX_FIFO1_MASK (FDCAN_IR_RF1L | FDCAN_IR_RF1F | FDCAN_IR_RF1W | FDCAN_IR_RF1N)
212 #define FDCAN_ERROR_MASK (FDCAN_IR_ELO | FDCAN_IR_WDI | FDCAN_IR_PEA | FDCAN_IR_PED | FDCAN_IR_ARA)
213 #define FDCAN_ERROR_STATUS_MASK (FDCAN_IR_EP | FDCAN_IR_EW | FDCAN_IR_BO)
214 #define FDCAN_TT_SCHEDULE_SYNC_MASK (FDCAN_TTIR_SBC | FDCAN_TTIR_SMC | FDCAN_TTIR_CSM | FDCAN_TTIR_SOG)
215 #define FDCAN_TT_TIME_MARK_MASK (FDCAN_TTIR_RTMI | FDCAN_TTIR_TTMI)
216 #define FDCAN_TT_GLOBAL_TIME_MASK (FDCAN_TTIR_GTW | FDCAN_TTIR_GTD)
217 #define FDCAN_TT_DISTURBING_ERROR_MASK (FDCAN_TTIR_GTE | FDCAN_TTIR_TXU | FDCAN_TTIR_TXO | \
218                                         FDCAN_TTIR_SE1 | FDCAN_TTIR_SE2 | FDCAN_TTIR_ELC)
219 #define FDCAN_TT_FATAL_ERROR_MASK (FDCAN_TTIR_IWT | FDCAN_TTIR_WT | FDCAN_TTIR_AW | FDCAN_TTIR_CER)
220 
221 #define FDCAN_ELEMENT_MASK_STDID ((uint32_t)0x1FFC0000U) /* Standard Identifier         */
222 #define FDCAN_ELEMENT_MASK_EXTID ((uint32_t)0x1FFFFFFFU) /* Extended Identifier         */
223 #define FDCAN_ELEMENT_MASK_RTR   ((uint32_t)0x20000000U) /* Remote Transmission Request */
224 #define FDCAN_ELEMENT_MASK_XTD   ((uint32_t)0x40000000U) /* Extended Identifier         */
225 #define FDCAN_ELEMENT_MASK_ESI   ((uint32_t)0x80000000U) /* Error State Indicator       */
226 #define FDCAN_ELEMENT_MASK_TS    ((uint32_t)0x0000FFFFU) /* Timestamp                   */
227 #define FDCAN_ELEMENT_MASK_DLC   ((uint32_t)0x000F0000U) /* Data Length Code            */
228 #define FDCAN_ELEMENT_MASK_BRS   ((uint32_t)0x00100000U) /* Bit Rate Switch             */
229 #define FDCAN_ELEMENT_MASK_FDF   ((uint32_t)0x00200000U) /* FD Format                   */
230 #define FDCAN_ELEMENT_MASK_EFC   ((uint32_t)0x00800000U) /* Event FIFO Control          */
231 #define FDCAN_ELEMENT_MASK_MM    ((uint32_t)0xFF000000U) /* Message Marker              */
232 #define FDCAN_ELEMENT_MASK_FIDX  ((uint32_t)0x7F000000U) /* Filter Index                */
233 #define FDCAN_ELEMENT_MASK_ANMF  ((uint32_t)0x80000000U) /* Accepted Non-matching Frame */
234 #define FDCAN_ELEMENT_MASK_ET    ((uint32_t)0x00C00000U) /* Event type                  */
235 
236 #define FDCAN_MESSAGE_RAM_SIZE 0x2800U
237 #define FDCAN_MESSAGE_RAM_END_ADDRESS (SRAMCAN_BASE + FDCAN_MESSAGE_RAM_SIZE - 0x4U) /* The Message RAM has a width of 4 Bytes */
238 
239 /**
240   * @}
241   */
242 
243 /* Private macro -------------------------------------------------------------*/
244 /* Private variables ---------------------------------------------------------*/
245 static const uint8_t DLCtoBytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64};
246 
247 /* Private function prototypes -----------------------------------------------*/
248 /** @addtogroup FDCAN_Private_Functions_Prototypes
249   * @{
250   */
251 static HAL_StatusTypeDef FDCAN_CalcultateRamBlockAddresses(FDCAN_HandleTypeDef *hfdcan);
252 static void FDCAN_CopyMessageToRAM(FDCAN_HandleTypeDef *hfdcan, FDCAN_TxHeaderTypeDef *pTxHeader, uint8_t *pTxData, uint32_t BufferIndex);
253 /**
254   * @}
255   */
256 
257 /* Exported functions --------------------------------------------------------*/
258 /** @defgroup FDCAN_Exported_Functions FDCAN Exported Functions
259   * @{
260   */
261 
262 /** @defgroup FDCAN_Exported_Functions_Group1 Initialization and de-initialization functions
263  *  @brief    Initialization and Configuration functions
264  *
265 @verbatim
266   ==============================================================================
267               ##### Initialization and de-initialization functions #####
268   ==============================================================================
269     [..]  This section provides functions allowing to:
270       (+) Initialize and configure the FDCAN.
271       (+) De-initialize the FDCAN.
272       (+) Enter FDCAN peripheral in power down mode.
273       (+) Exit power down mode.
274       (+) Register callbacks.
275       (+) Unregister callbacks.
276 
277 @endverbatim
278   * @{
279   */
280 
281 /**
282   * @brief  Initializes the FDCAN peripheral according to the specified
283   *         parameters in the FDCAN_InitTypeDef structure.
284   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
285   *         the configuration information for the specified FDCAN.
286   * @retval HAL status
287   */
HAL_FDCAN_Init(FDCAN_HandleTypeDef * hfdcan)288 HAL_StatusTypeDef HAL_FDCAN_Init(FDCAN_HandleTypeDef *hfdcan)
289 {
290   uint32_t tickstart;
291   HAL_StatusTypeDef status;
292   const uint32_t CvtEltSize[] = {0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7};
293 
294   /* Check FDCAN handle */
295   if (hfdcan == NULL)
296   {
297     return HAL_ERROR;
298   }
299 
300   /* Check FDCAN instance */
301   if (hfdcan->Instance == FDCAN1)
302   {
303     hfdcan->ttcan = (TTCAN_TypeDef *)((uint32_t)hfdcan->Instance + 0x100U);
304   }
305 
306   /* Check function parameters */
307   assert_param(IS_FDCAN_ALL_INSTANCE(hfdcan->Instance));
308   assert_param(IS_FDCAN_FRAME_FORMAT(hfdcan->Init.FrameFormat));
309   assert_param(IS_FDCAN_MODE(hfdcan->Init.Mode));
310   assert_param(IS_FUNCTIONAL_STATE(hfdcan->Init.AutoRetransmission));
311   assert_param(IS_FUNCTIONAL_STATE(hfdcan->Init.TransmitPause));
312   assert_param(IS_FUNCTIONAL_STATE(hfdcan->Init.ProtocolException));
313   assert_param(IS_FDCAN_NOMINAL_PRESCALER(hfdcan->Init.NominalPrescaler));
314   assert_param(IS_FDCAN_NOMINAL_SJW(hfdcan->Init.NominalSyncJumpWidth));
315   assert_param(IS_FDCAN_NOMINAL_TSEG1(hfdcan->Init.NominalTimeSeg1));
316   assert_param(IS_FDCAN_NOMINAL_TSEG2(hfdcan->Init.NominalTimeSeg2));
317   if (hfdcan->Init.FrameFormat == FDCAN_FRAME_FD_BRS)
318   {
319     assert_param(IS_FDCAN_DATA_PRESCALER(hfdcan->Init.DataPrescaler));
320     assert_param(IS_FDCAN_DATA_SJW(hfdcan->Init.DataSyncJumpWidth));
321     assert_param(IS_FDCAN_DATA_TSEG1(hfdcan->Init.DataTimeSeg1));
322     assert_param(IS_FDCAN_DATA_TSEG2(hfdcan->Init.DataTimeSeg2));
323   }
324   assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.StdFiltersNbr, 128U));
325   assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.ExtFiltersNbr, 64U));
326   assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.RxFifo0ElmtsNbr, 64U));
327   if (hfdcan->Init.RxFifo0ElmtsNbr > 0U)
328   {
329     assert_param(IS_FDCAN_DATA_SIZE(hfdcan->Init.RxFifo0ElmtSize));
330   }
331   assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.RxFifo1ElmtsNbr, 64U));
332   if (hfdcan->Init.RxFifo1ElmtsNbr > 0U)
333   {
334     assert_param(IS_FDCAN_DATA_SIZE(hfdcan->Init.RxFifo1ElmtSize));
335   }
336   assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.RxBuffersNbr, 64U));
337   if (hfdcan->Init.RxBuffersNbr > 0U)
338   {
339     assert_param(IS_FDCAN_DATA_SIZE(hfdcan->Init.RxBufferSize));
340   }
341   assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.TxEventsNbr, 32U));
342   assert_param(IS_FDCAN_MAX_VALUE((hfdcan->Init.TxBuffersNbr + hfdcan->Init.TxFifoQueueElmtsNbr), 32U));
343   if (hfdcan->Init.TxFifoQueueElmtsNbr > 0U)
344   {
345     assert_param(IS_FDCAN_TX_FIFO_QUEUE_MODE(hfdcan->Init.TxFifoQueueMode));
346   }
347   if ((hfdcan->Init.TxBuffersNbr + hfdcan->Init.TxFifoQueueElmtsNbr) > 0U)
348   {
349     assert_param(IS_FDCAN_DATA_SIZE(hfdcan->Init.TxElmtSize));
350   }
351 
352 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
353   if (hfdcan->State == HAL_FDCAN_STATE_RESET)
354   {
355     /* Allocate lock resource and initialize it */
356     hfdcan->Lock = HAL_UNLOCKED;
357 
358     /* Reset callbacks to legacy functions */
359     hfdcan->ClockCalibrationCallback    = HAL_FDCAN_ClockCalibrationCallback;    /* Legacy weak ClockCalibrationCallback    */
360     hfdcan->TxEventFifoCallback         = HAL_FDCAN_TxEventFifoCallback;         /* Legacy weak TxEventFifoCallback         */
361     hfdcan->RxFifo0Callback             = HAL_FDCAN_RxFifo0Callback;             /* Legacy weak RxFifo0Callback             */
362     hfdcan->RxFifo1Callback             = HAL_FDCAN_RxFifo1Callback;             /* Legacy weak RxFifo1Callback             */
363     hfdcan->TxFifoEmptyCallback         = HAL_FDCAN_TxFifoEmptyCallback;         /* Legacy weak TxFifoEmptyCallback         */
364     hfdcan->TxBufferCompleteCallback    = HAL_FDCAN_TxBufferCompleteCallback;    /* Legacy weak TxBufferCompleteCallback    */
365     hfdcan->TxBufferAbortCallback       = HAL_FDCAN_TxBufferAbortCallback;       /* Legacy weak TxBufferAbortCallback       */
366     hfdcan->RxBufferNewMessageCallback  = HAL_FDCAN_RxBufferNewMessageCallback;  /* Legacy weak RxBufferNewMessageCallback  */
367     hfdcan->HighPriorityMessageCallback = HAL_FDCAN_HighPriorityMessageCallback; /* Legacy weak HighPriorityMessageCallback */
368     hfdcan->TimestampWraparoundCallback = HAL_FDCAN_TimestampWraparoundCallback; /* Legacy weak TimestampWraparoundCallback */
369     hfdcan->TimeoutOccurredCallback     = HAL_FDCAN_TimeoutOccurredCallback;     /* Legacy weak TimeoutOccurredCallback     */
370     hfdcan->ErrorCallback               = HAL_FDCAN_ErrorCallback;               /* Legacy weak ErrorCallback               */
371     hfdcan->ErrorStatusCallback         = HAL_FDCAN_ErrorStatusCallback;         /* Legacy weak ErrorStatusCallback         */
372     hfdcan->TT_ScheduleSyncCallback     = HAL_FDCAN_TT_ScheduleSyncCallback;     /* Legacy weak TT_ScheduleSyncCallback     */
373     hfdcan->TT_TimeMarkCallback         = HAL_FDCAN_TT_TimeMarkCallback;         /* Legacy weak TT_TimeMarkCallback         */
374     hfdcan->TT_StopWatchCallback        = HAL_FDCAN_TT_StopWatchCallback;        /* Legacy weak TT_StopWatchCallback        */
375     hfdcan->TT_GlobalTimeCallback       = HAL_FDCAN_TT_GlobalTimeCallback;       /* Legacy weak TT_GlobalTimeCallback       */
376 
377     if (hfdcan->MspInitCallback == NULL)
378     {
379       hfdcan->MspInitCallback = HAL_FDCAN_MspInit;  /* Legacy weak MspInit */
380     }
381 
382     /* Init the low level hardware: CLOCK, NVIC */
383     hfdcan->MspInitCallback(hfdcan);
384   }
385 #else
386   if (hfdcan->State == HAL_FDCAN_STATE_RESET)
387   {
388     /* Allocate lock resource and initialize it */
389     hfdcan->Lock = HAL_UNLOCKED;
390 
391     /* Init the low level hardware: CLOCK, NVIC */
392     HAL_FDCAN_MspInit(hfdcan);
393   }
394 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
395 
396   /* Exit from Sleep mode */
397   CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CSR);
398 
399   /* Get tick */
400   tickstart = HAL_GetTick();
401 
402   /* Check Sleep mode acknowledge */
403   while ((hfdcan->Instance->CCCR & FDCAN_CCCR_CSA) == FDCAN_CCCR_CSA)
404   {
405     if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE)
406     {
407       /* Update error code */
408       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
409 
410       /* Change FDCAN state */
411       hfdcan->State = HAL_FDCAN_STATE_ERROR;
412 
413       return HAL_ERROR;
414     }
415   }
416 
417   /* Request initialisation */
418   SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT);
419 
420   /* Get tick */
421   tickstart = HAL_GetTick();
422 
423   /* Wait until the INIT bit into CCCR register is set */
424   while ((hfdcan->Instance->CCCR & FDCAN_CCCR_INIT) == 0U)
425   {
426     /* Check for the Timeout */
427     if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE)
428     {
429       /* Update error code */
430       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
431 
432       /* Change FDCAN state */
433       hfdcan->State = HAL_FDCAN_STATE_ERROR;
434 
435       return HAL_ERROR;
436     }
437   }
438 
439   /* Enable configuration change */
440   SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CCE);
441 
442   /* Set the no automatic retransmission */
443   if (hfdcan->Init.AutoRetransmission == ENABLE)
444   {
445     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_DAR);
446   }
447   else
448   {
449     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_DAR);
450   }
451 
452   /* Set the transmit pause feature */
453   if (hfdcan->Init.TransmitPause == ENABLE)
454   {
455     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_TXP);
456   }
457   else
458   {
459     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_TXP);
460   }
461 
462   /* Set the Protocol Exception Handling */
463   if (hfdcan->Init.ProtocolException == ENABLE)
464   {
465     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_PXHD);
466   }
467   else
468   {
469     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_PXHD);
470   }
471 
472   /* Set FDCAN Frame Format */
473   MODIFY_REG(hfdcan->Instance->CCCR, FDCAN_FRAME_FD_BRS, hfdcan->Init.FrameFormat);
474 
475   /* Reset FDCAN Operation Mode */
476   CLEAR_BIT(hfdcan->Instance->CCCR, (FDCAN_CCCR_TEST | FDCAN_CCCR_MON | FDCAN_CCCR_ASM));
477   CLEAR_BIT(hfdcan->Instance->TEST, FDCAN_TEST_LBCK);
478 
479   /* Set FDCAN Operating Mode:
480                | Normal | Restricted |    Bus     | Internal | External
481                |        | Operation  | Monitoring | LoopBack | LoopBack
482      CCCR.TEST |   0    |     0      |     0      |    1     |    1
483      CCCR.MON  |   0    |     0      |     1      |    1     |    0
484      TEST.LBCK |   0    |     0      |     0      |    1     |    1
485      CCCR.ASM  |   0    |     1      |     0      |    0     |    0
486   */
487   if (hfdcan->Init.Mode == FDCAN_MODE_RESTRICTED_OPERATION)
488   {
489     /* Enable Restricted Operation mode */
490     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_ASM);
491   }
492   else if (hfdcan->Init.Mode != FDCAN_MODE_NORMAL)
493   {
494     if (hfdcan->Init.Mode != FDCAN_MODE_BUS_MONITORING)
495     {
496       /* Enable write access to TEST register */
497       SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_TEST);
498 
499       /* Enable LoopBack mode */
500       SET_BIT(hfdcan->Instance->TEST, FDCAN_TEST_LBCK);
501 
502       if (hfdcan->Init.Mode == FDCAN_MODE_INTERNAL_LOOPBACK)
503       {
504         SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_MON);
505       }
506     }
507     else
508     {
509       /* Enable bus monitoring mode */
510       SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_MON);
511     }
512   }
513   else
514   {
515     /* Nothing to do: normal mode */
516   }
517 
518   /* Set the nominal bit timing register */
519   hfdcan->Instance->NBTP = ((((uint32_t)hfdcan->Init.NominalSyncJumpWidth - 1U) << FDCAN_NBTP_NSJW_Pos) | \
520                             (((uint32_t)hfdcan->Init.NominalTimeSeg1 - 1U) << FDCAN_NBTP_NTSEG1_Pos)    | \
521                             (((uint32_t)hfdcan->Init.NominalTimeSeg2 - 1U) << FDCAN_NBTP_NTSEG2_Pos)    | \
522                             (((uint32_t)hfdcan->Init.NominalPrescaler - 1U) << FDCAN_NBTP_NBRP_Pos));
523 
524   /* If FD operation with BRS is selected, set the data bit timing register */
525   if (hfdcan->Init.FrameFormat == FDCAN_FRAME_FD_BRS)
526   {
527     hfdcan->Instance->DBTP = ((((uint32_t)hfdcan->Init.DataSyncJumpWidth - 1U) << FDCAN_DBTP_DSJW_Pos) | \
528                               (((uint32_t)hfdcan->Init.DataTimeSeg1 - 1U) << FDCAN_DBTP_DTSEG1_Pos)    | \
529                               (((uint32_t)hfdcan->Init.DataTimeSeg2 - 1U) << FDCAN_DBTP_DTSEG2_Pos)    | \
530                               (((uint32_t)hfdcan->Init.DataPrescaler - 1U) << FDCAN_DBTP_DBRP_Pos));
531   }
532 
533   if (hfdcan->Init.TxFifoQueueElmtsNbr > 0U)
534   {
535     /* Select between Tx FIFO and Tx Queue operation modes */
536     SET_BIT(hfdcan->Instance->TXBC, hfdcan->Init.TxFifoQueueMode);
537   }
538 
539   /* Configure Tx element size */
540   if ((hfdcan->Init.TxBuffersNbr + hfdcan->Init.TxFifoQueueElmtsNbr) > 0U)
541   {
542     MODIFY_REG(hfdcan->Instance->TXESC, FDCAN_TXESC_TBDS, CvtEltSize[hfdcan->Init.TxElmtSize]);
543   }
544 
545   /* Configure Rx FIFO 0 element size */
546   if (hfdcan->Init.RxFifo0ElmtsNbr > 0U)
547   {
548     MODIFY_REG(hfdcan->Instance->RXESC, FDCAN_RXESC_F0DS, (CvtEltSize[hfdcan->Init.RxFifo0ElmtSize] << FDCAN_RXESC_F0DS_Pos));
549   }
550 
551   /* Configure Rx FIFO 1 element size */
552   if (hfdcan->Init.RxFifo1ElmtsNbr > 0U)
553   {
554     MODIFY_REG(hfdcan->Instance->RXESC, FDCAN_RXESC_F1DS, (CvtEltSize[hfdcan->Init.RxFifo1ElmtSize] << FDCAN_RXESC_F1DS_Pos));
555   }
556 
557   /* Configure Rx buffer element size */
558   if (hfdcan->Init.RxBuffersNbr > 0U)
559   {
560     MODIFY_REG(hfdcan->Instance->RXESC, FDCAN_RXESC_RBDS, (CvtEltSize[hfdcan->Init.RxBufferSize] << FDCAN_RXESC_RBDS_Pos));
561   }
562 
563   /* By default operation mode is set to Event-driven communication.
564      If Time-triggered communication is needed, user should call the
565      HAL_FDCAN_TT_ConfigOperation function just after the HAL_FDCAN_Init */
566   if (hfdcan->Instance == FDCAN1)
567   {
568     CLEAR_BIT(hfdcan->ttcan->TTOCF, FDCAN_TTOCF_OM);
569   }
570 
571   /* Initialize the Latest Tx FIFO/Queue request buffer index */
572   hfdcan->LatestTxFifoQRequest = 0U;
573 
574   /* Initialize the error code */
575   hfdcan->ErrorCode = HAL_FDCAN_ERROR_NONE;
576 
577   /* Initialize the FDCAN state */
578   hfdcan->State = HAL_FDCAN_STATE_READY;
579 
580   /* Calculate each RAM block address */
581   status = FDCAN_CalcultateRamBlockAddresses(hfdcan);
582 
583   /* Return function status */
584   return status;
585 }
586 
587 /**
588   * @brief  Deinitializes the FDCAN peripheral registers to their default reset values.
589   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
590   *         the configuration information for the specified FDCAN.
591   * @retval HAL status
592   */
HAL_FDCAN_DeInit(FDCAN_HandleTypeDef * hfdcan)593 HAL_StatusTypeDef HAL_FDCAN_DeInit(FDCAN_HandleTypeDef *hfdcan)
594 {
595   /* Check FDCAN handle */
596   if (hfdcan == NULL)
597   {
598     return HAL_ERROR;
599   }
600 
601   /* Check function parameters */
602   assert_param(IS_FDCAN_ALL_INSTANCE(hfdcan->Instance));
603 
604   /* Stop the FDCAN module: return value is voluntary ignored */
605   (void)HAL_FDCAN_Stop(hfdcan);
606 
607   /* Disable Interrupt lines */
608   CLEAR_BIT(hfdcan->Instance->ILE, (FDCAN_INTERRUPT_LINE0 | FDCAN_INTERRUPT_LINE1));
609 
610 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
611   if (hfdcan->MspDeInitCallback == NULL)
612   {
613     hfdcan->MspDeInitCallback = HAL_FDCAN_MspDeInit; /* Legacy weak MspDeInit */
614   }
615 
616   /* DeInit the low level hardware: CLOCK, NVIC */
617   hfdcan->MspDeInitCallback(hfdcan);
618 #else
619   /* DeInit the low level hardware: CLOCK, NVIC */
620   HAL_FDCAN_MspDeInit(hfdcan);
621 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
622 
623   /* Reset the FDCAN ErrorCode */
624   hfdcan->ErrorCode = HAL_FDCAN_ERROR_NONE;
625 
626   /* Change FDCAN state */
627   hfdcan->State = HAL_FDCAN_STATE_RESET;
628 
629   /* Return function status */
630   return HAL_OK;
631 }
632 
633 /**
634   * @brief  Initializes the FDCAN MSP.
635   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
636   *         the configuration information for the specified FDCAN.
637   * @retval None
638   */
HAL_FDCAN_MspInit(FDCAN_HandleTypeDef * hfdcan)639 __weak void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef *hfdcan)
640 {
641   /* Prevent unused argument(s) compilation warning */
642   UNUSED(hfdcan);
643   /* NOTE : This function Should not be modified, when the callback is needed,
644             the HAL_FDCAN_MspInit could be implemented in the user file
645    */
646 }
647 
648 /**
649   * @brief  DeInitializes the FDCAN MSP.
650   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
651   *         the configuration information for the specified FDCAN.
652   * @retval None
653   */
HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef * hfdcan)654 __weak void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef *hfdcan)
655 {
656   /* Prevent unused argument(s) compilation warning */
657   UNUSED(hfdcan);
658   /* NOTE : This function Should not be modified, when the callback is needed,
659             the HAL_FDCAN_MspDeInit could be implemented in the user file
660    */
661 }
662 
663 /**
664   * @brief  Enter FDCAN peripheral in sleep mode.
665   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
666   *         the configuration information for the specified FDCAN.
667   * @retval HAL status
668   */
HAL_FDCAN_EnterPowerDownMode(FDCAN_HandleTypeDef * hfdcan)669 HAL_StatusTypeDef HAL_FDCAN_EnterPowerDownMode(FDCAN_HandleTypeDef *hfdcan)
670 {
671   uint32_t tickstart;
672 
673   /* Request clock stop */
674   SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CSR);
675 
676   /* Get tick */
677   tickstart = HAL_GetTick();
678 
679   /* Wait until FDCAN is ready for power down */
680   while ((hfdcan->Instance->CCCR & FDCAN_CCCR_CSA) == 0U)
681   {
682     if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE)
683     {
684       /* Update error code */
685       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
686 
687       /* Change FDCAN state */
688       hfdcan->State = HAL_FDCAN_STATE_ERROR;
689 
690       return HAL_ERROR;
691     }
692   }
693 
694   /* Return function status */
695   return HAL_OK;
696 }
697 
698 /**
699   * @brief  Exit power down mode.
700   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
701   *         the configuration information for the specified FDCAN.
702   * @retval HAL status
703   */
HAL_FDCAN_ExitPowerDownMode(FDCAN_HandleTypeDef * hfdcan)704 HAL_StatusTypeDef HAL_FDCAN_ExitPowerDownMode(FDCAN_HandleTypeDef *hfdcan)
705 {
706   uint32_t tickstart;
707 
708   /* Reset clock stop request */
709   CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CSR);
710 
711   /* Get tick */
712   tickstart = HAL_GetTick();
713 
714   /* Wait until FDCAN exits sleep mode */
715   while ((hfdcan->Instance->CCCR & FDCAN_CCCR_CSA) == FDCAN_CCCR_CSA)
716   {
717     if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE)
718     {
719       /* Update error code */
720       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
721 
722       /* Change FDCAN state */
723       hfdcan->State = HAL_FDCAN_STATE_ERROR;
724 
725       return HAL_ERROR;
726     }
727   }
728 
729   /* Enter normal operation */
730   CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT);
731 
732   /* Return function status */
733   return HAL_OK;
734 }
735 
736 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
737 /**
738   * @brief  Register a FDCAN CallBack.
739   *         To be used instead of the weak predefined callback
740   * @param  hfdcan pointer to a FDCAN_HandleTypeDef structure that contains
741   *         the configuration information for FDCAN module
742   * @param  CallbackID ID of the callback to be registered
743   *         This parameter can be one of the following values:
744   *           @arg @ref HAL_FDCAN_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty callback ID
745   *           @arg @ref HAL_FDCAN_RX_BUFFER_NEW_MSG_CB_ID Rx buffer new message callback ID
746   *           @arg @ref HAL_FDCAN_HIGH_PRIO_MESSAGE_CB_ID High priority message callback ID
747   *           @arg @ref HAL_FDCAN_TIMESTAMP_WRAPAROUND_CB_ID Timestamp wraparound callback ID
748   *           @arg @ref HAL_FDCAN_TIMEOUT_OCCURRED_CB_ID Timeout occurred callback ID
749   *           @arg @ref HAL_FDCAN_ERROR_CALLBACK_CB_ID Error callback ID
750   *           @arg @ref HAL_FDCAN_MSPINIT_CB_ID MspInit callback ID
751   *           @arg @ref HAL_FDCAN_MSPDEINIT_CB_ID MspDeInit callback ID
752   * @param  pCallback pointer to the Callback function
753   * @retval HAL status
754   */
HAL_FDCAN_RegisterCallback(FDCAN_HandleTypeDef * hfdcan,HAL_FDCAN_CallbackIDTypeDef CallbackID,void (* pCallback)(FDCAN_HandleTypeDef * _hFDCAN))755 HAL_StatusTypeDef HAL_FDCAN_RegisterCallback(FDCAN_HandleTypeDef *hfdcan, HAL_FDCAN_CallbackIDTypeDef CallbackID, void (* pCallback)(FDCAN_HandleTypeDef *_hFDCAN))
756 {
757   HAL_StatusTypeDef status = HAL_OK;
758 
759   if (pCallback == NULL)
760   {
761     /* Update the error code */
762     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
763 
764     return HAL_ERROR;
765   }
766 
767   if (hfdcan->State == HAL_FDCAN_STATE_READY)
768   {
769     switch (CallbackID)
770     {
771       case HAL_FDCAN_TX_FIFO_EMPTY_CB_ID :
772         hfdcan->TxFifoEmptyCallback = pCallback;
773         break;
774 
775       case HAL_FDCAN_RX_BUFFER_NEW_MSG_CB_ID :
776         hfdcan->RxBufferNewMessageCallback = pCallback;
777         break;
778 
779       case HAL_FDCAN_HIGH_PRIO_MESSAGE_CB_ID :
780         hfdcan->HighPriorityMessageCallback = pCallback;
781         break;
782 
783       case HAL_FDCAN_TIMESTAMP_WRAPAROUND_CB_ID :
784         hfdcan->TimestampWraparoundCallback = pCallback;
785         break;
786 
787       case HAL_FDCAN_TIMEOUT_OCCURRED_CB_ID :
788         hfdcan->TimeoutOccurredCallback = pCallback;
789         break;
790 
791       case HAL_FDCAN_ERROR_CALLBACK_CB_ID :
792         hfdcan->ErrorCallback = pCallback;
793         break;
794 
795       case HAL_FDCAN_MSPINIT_CB_ID :
796         hfdcan->MspInitCallback = pCallback;
797         break;
798 
799       case HAL_FDCAN_MSPDEINIT_CB_ID :
800         hfdcan->MspDeInitCallback = pCallback;
801         break;
802 
803       default :
804         /* Update the error code */
805         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
806 
807         /* Return error status */
808         status =  HAL_ERROR;
809         break;
810     }
811   }
812   else if (hfdcan->State == HAL_FDCAN_STATE_RESET)
813   {
814     switch (CallbackID)
815     {
816       case HAL_FDCAN_MSPINIT_CB_ID :
817         hfdcan->MspInitCallback = pCallback;
818         break;
819 
820       case HAL_FDCAN_MSPDEINIT_CB_ID :
821         hfdcan->MspDeInitCallback = pCallback;
822         break;
823 
824       default :
825         /* Update the error code */
826         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
827 
828         /* Return error status */
829         status =  HAL_ERROR;
830         break;
831     }
832   }
833   else
834   {
835     /* Update the error code */
836     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
837 
838     /* Return error status */
839     status =  HAL_ERROR;
840   }
841 
842   return status;
843 }
844 
845 /**
846   * @brief  Unregister a FDCAN CallBack.
847   *         FDCAN callback is redirected to the weak predefined callback
848   * @param  hfdcan pointer to a FDCAN_HandleTypeDef structure that contains
849   *         the configuration information for FDCAN module
850   * @param  CallbackID ID of the callback to be unregistered
851   *         This parameter can be one of the following values:
852   *           @arg @ref HAL_FDCAN_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty callback ID
853   *           @arg @ref HAL_FDCAN_RX_BUFFER_NEW_MSG_CB_ID Rx buffer new message callback ID
854   *           @arg @ref HAL_FDCAN_HIGH_PRIO_MESSAGE_CB_ID High priority message callback ID
855   *           @arg @ref HAL_FDCAN_TIMESTAMP_WRAPAROUND_CB_ID Timestamp wraparound callback ID
856   *           @arg @ref HAL_FDCAN_TIMEOUT_OCCURRED_CB_ID Timeout occurred callback ID
857   *           @arg @ref HAL_FDCAN_ERROR_CALLBACK_CB_ID Error callback ID
858   *           @arg @ref HAL_FDCAN_MSPINIT_CB_ID MspInit callback ID
859   *           @arg @ref HAL_FDCAN_MSPDEINIT_CB_ID MspDeInit callback ID
860   * @retval HAL status
861   */
HAL_FDCAN_UnRegisterCallback(FDCAN_HandleTypeDef * hfdcan,HAL_FDCAN_CallbackIDTypeDef CallbackID)862 HAL_StatusTypeDef HAL_FDCAN_UnRegisterCallback(FDCAN_HandleTypeDef *hfdcan, HAL_FDCAN_CallbackIDTypeDef CallbackID)
863 {
864   HAL_StatusTypeDef status = HAL_OK;
865 
866   if (hfdcan->State == HAL_FDCAN_STATE_READY)
867   {
868     switch (CallbackID)
869     {
870       case HAL_FDCAN_TX_FIFO_EMPTY_CB_ID :
871         hfdcan->TxFifoEmptyCallback = HAL_FDCAN_TxFifoEmptyCallback;
872         break;
873 
874       case HAL_FDCAN_RX_BUFFER_NEW_MSG_CB_ID :
875         hfdcan->RxBufferNewMessageCallback = HAL_FDCAN_RxBufferNewMessageCallback;
876         break;
877 
878       case HAL_FDCAN_HIGH_PRIO_MESSAGE_CB_ID :
879         hfdcan->HighPriorityMessageCallback = HAL_FDCAN_HighPriorityMessageCallback;
880         break;
881 
882       case HAL_FDCAN_TIMESTAMP_WRAPAROUND_CB_ID :
883         hfdcan->TimestampWraparoundCallback = HAL_FDCAN_TimestampWraparoundCallback;
884         break;
885 
886       case HAL_FDCAN_TIMEOUT_OCCURRED_CB_ID :
887         hfdcan->TimeoutOccurredCallback = HAL_FDCAN_TimeoutOccurredCallback;
888         break;
889 
890       case HAL_FDCAN_ERROR_CALLBACK_CB_ID :
891         hfdcan->ErrorCallback = HAL_FDCAN_ErrorCallback;
892         break;
893 
894       case HAL_FDCAN_MSPINIT_CB_ID :
895         hfdcan->MspInitCallback = HAL_FDCAN_MspInit;
896         break;
897 
898       case HAL_FDCAN_MSPDEINIT_CB_ID :
899         hfdcan->MspDeInitCallback = HAL_FDCAN_MspDeInit;
900         break;
901 
902       default :
903         /* Update the error code */
904         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
905 
906         /* Return error status */
907         status =  HAL_ERROR;
908         break;
909     }
910   }
911   else if (hfdcan->State == HAL_FDCAN_STATE_RESET)
912   {
913     switch (CallbackID)
914     {
915       case HAL_FDCAN_MSPINIT_CB_ID :
916         hfdcan->MspInitCallback = HAL_FDCAN_MspInit;
917         break;
918 
919       case HAL_FDCAN_MSPDEINIT_CB_ID :
920         hfdcan->MspDeInitCallback = HAL_FDCAN_MspDeInit;
921         break;
922 
923       default :
924         /* Update the error code */
925         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
926 
927         /* Return error status */
928         status =  HAL_ERROR;
929         break;
930     }
931   }
932   else
933   {
934     /* Update the error code */
935     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
936 
937     /* Return error status */
938     status =  HAL_ERROR;
939   }
940 
941   return status;
942 }
943 
944 /**
945   * @brief  Register Clock Calibration FDCAN Callback
946   *         To be used instead of the weak HAL_FDCAN_ClockCalibrationCallback() predefined callback
947   * @param  hfdcan FDCAN handle
948   * @param  pCallback pointer to the Clock Calibration Callback function
949   * @retval HAL status
950   */
HAL_FDCAN_RegisterClockCalibrationCallback(FDCAN_HandleTypeDef * hfdcan,pFDCAN_ClockCalibrationCallbackTypeDef pCallback)951 HAL_StatusTypeDef HAL_FDCAN_RegisterClockCalibrationCallback(FDCAN_HandleTypeDef *hfdcan, pFDCAN_ClockCalibrationCallbackTypeDef pCallback)
952 {
953   HAL_StatusTypeDef status = HAL_OK;
954 
955   if (pCallback == NULL)
956   {
957     /* Update the error code */
958     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
959     return HAL_ERROR;
960   }
961 
962   if (hfdcan->State == HAL_FDCAN_STATE_READY)
963   {
964     hfdcan->ClockCalibrationCallback = pCallback;
965   }
966   else
967   {
968     /* Update the error code */
969     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
970 
971     /* Return error status */
972     status =  HAL_ERROR;
973   }
974 
975   return status;
976 }
977 
978 /**
979   * @brief  UnRegister the Clock Calibration FDCAN Callback
980   *         Clock Calibration FDCAN Callback is redirected to the weak HAL_FDCAN_ClockCalibrationCallback() predefined callback
981   * @param  hfdcan FDCAN handle
982   * @retval HAL status
983   */
HAL_FDCAN_UnRegisterClockCalibrationCallback(FDCAN_HandleTypeDef * hfdcan)984 HAL_StatusTypeDef HAL_FDCAN_UnRegisterClockCalibrationCallback(FDCAN_HandleTypeDef *hfdcan)
985 {
986   HAL_StatusTypeDef status = HAL_OK;
987 
988   if (hfdcan->State == HAL_FDCAN_STATE_READY)
989   {
990     hfdcan->ClockCalibrationCallback = HAL_FDCAN_ClockCalibrationCallback; /* Legacy weak ClockCalibrationCallback  */
991   }
992   else
993   {
994     /* Update the error code */
995     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
996 
997     /* Return error status */
998     status =  HAL_ERROR;
999   }
1000 
1001   return status;
1002 }
1003 
1004 /**
1005   * @brief  Register Tx Event Fifo FDCAN Callback
1006   *         To be used instead of the weak HAL_FDCAN_TxEventFifoCallback() predefined callback
1007   * @param  hfdcan FDCAN handle
1008   * @param  pCallback pointer to the Tx Event Fifo Callback function
1009   * @retval HAL status
1010   */
HAL_FDCAN_RegisterTxEventFifoCallback(FDCAN_HandleTypeDef * hfdcan,pFDCAN_TxEventFifoCallbackTypeDef pCallback)1011 HAL_StatusTypeDef HAL_FDCAN_RegisterTxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan, pFDCAN_TxEventFifoCallbackTypeDef pCallback)
1012 {
1013   HAL_StatusTypeDef status = HAL_OK;
1014 
1015   if (pCallback == NULL)
1016   {
1017     /* Update the error code */
1018     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1019     return HAL_ERROR;
1020   }
1021 
1022   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1023   {
1024     hfdcan->TxEventFifoCallback = pCallback;
1025   }
1026   else
1027   {
1028     /* Update the error code */
1029     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1030 
1031     /* Return error status */
1032     status =  HAL_ERROR;
1033   }
1034 
1035   return status;
1036 }
1037 
1038 /**
1039   * @brief  UnRegister the Tx Event Fifo FDCAN Callback
1040   *         Tx Event Fifo FDCAN Callback is redirected to the weak HAL_FDCAN_TxEventFifoCallback() predefined callback
1041   * @param  hfdcan FDCAN handle
1042   * @retval HAL status
1043   */
HAL_FDCAN_UnRegisterTxEventFifoCallback(FDCAN_HandleTypeDef * hfdcan)1044 HAL_StatusTypeDef HAL_FDCAN_UnRegisterTxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan)
1045 {
1046   HAL_StatusTypeDef status = HAL_OK;
1047 
1048   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1049   {
1050     hfdcan->TxEventFifoCallback = HAL_FDCAN_TxEventFifoCallback; /* Legacy weak TxEventFifoCallback  */
1051   }
1052   else
1053   {
1054     /* Update the error code */
1055     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1056 
1057     /* Return error status */
1058     status =  HAL_ERROR;
1059   }
1060 
1061   return status;
1062 }
1063 
1064 /**
1065   * @brief  Register Rx Fifo 0 FDCAN Callback
1066   *         To be used instead of the weak HAL_FDCAN_RxFifo0Callback() predefined callback
1067   * @param  hfdcan FDCAN handle
1068   * @param  pCallback pointer to the Rx Fifo 0 Callback function
1069   * @retval HAL status
1070   */
HAL_FDCAN_RegisterRxFifo0Callback(FDCAN_HandleTypeDef * hfdcan,pFDCAN_RxFifo0CallbackTypeDef pCallback)1071 HAL_StatusTypeDef HAL_FDCAN_RegisterRxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, pFDCAN_RxFifo0CallbackTypeDef pCallback)
1072 {
1073   HAL_StatusTypeDef status = HAL_OK;
1074 
1075   if (pCallback == NULL)
1076   {
1077     /* Update the error code */
1078     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1079     return HAL_ERROR;
1080   }
1081 
1082   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1083   {
1084     hfdcan->RxFifo0Callback = pCallback;
1085   }
1086   else
1087   {
1088     /* Update the error code */
1089     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1090 
1091     /* Return error status */
1092     status =  HAL_ERROR;
1093   }
1094 
1095   return status;
1096 }
1097 
1098 /**
1099   * @brief  UnRegister the Rx Fifo 0 FDCAN Callback
1100   *         Rx Fifo 0 FDCAN Callback is redirected to the weak HAL_FDCAN_RxFifo0Callback() predefined callback
1101   * @param  hfdcan FDCAN handle
1102   * @retval HAL status
1103   */
HAL_FDCAN_UnRegisterRxFifo0Callback(FDCAN_HandleTypeDef * hfdcan)1104 HAL_StatusTypeDef HAL_FDCAN_UnRegisterRxFifo0Callback(FDCAN_HandleTypeDef *hfdcan)
1105 {
1106   HAL_StatusTypeDef status = HAL_OK;
1107 
1108   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1109   {
1110     hfdcan->RxFifo0Callback = HAL_FDCAN_RxFifo0Callback; /* Legacy weak RxFifo0Callback  */
1111   }
1112   else
1113   {
1114     /* Update the error code */
1115     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1116 
1117     /* Return error status */
1118     status =  HAL_ERROR;
1119   }
1120 
1121   return status;
1122 }
1123 
1124 /**
1125   * @brief  Register Rx Fifo 1 FDCAN Callback
1126   *         To be used instead of the weak HAL_FDCAN_RxFifo1Callback() predefined callback
1127   * @param  hfdcan FDCAN handle
1128   * @param  pCallback pointer to the Rx Fifo 1 Callback function
1129   * @retval HAL status
1130   */
HAL_FDCAN_RegisterRxFifo1Callback(FDCAN_HandleTypeDef * hfdcan,pFDCAN_RxFifo1CallbackTypeDef pCallback)1131 HAL_StatusTypeDef HAL_FDCAN_RegisterRxFifo1Callback(FDCAN_HandleTypeDef *hfdcan, pFDCAN_RxFifo1CallbackTypeDef pCallback)
1132 {
1133   HAL_StatusTypeDef status = HAL_OK;
1134 
1135   if (pCallback == NULL)
1136   {
1137     /* Update the error code */
1138     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1139     return HAL_ERROR;
1140   }
1141 
1142   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1143   {
1144     hfdcan->RxFifo1Callback = pCallback;
1145   }
1146   else
1147   {
1148     /* Update the error code */
1149     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1150 
1151     /* Return error status */
1152     status =  HAL_ERROR;
1153   }
1154 
1155   return status;
1156 }
1157 
1158 /**
1159   * @brief  UnRegister the Rx Fifo 1 FDCAN Callback
1160   *         Rx Fifo 1 FDCAN Callback is redirected to the weak HAL_FDCAN_RxFifo1Callback() predefined callback
1161   * @param  hfdcan FDCAN handle
1162   * @retval HAL status
1163   */
HAL_FDCAN_UnRegisterRxFifo1Callback(FDCAN_HandleTypeDef * hfdcan)1164 HAL_StatusTypeDef HAL_FDCAN_UnRegisterRxFifo1Callback(FDCAN_HandleTypeDef *hfdcan)
1165 {
1166   HAL_StatusTypeDef status = HAL_OK;
1167 
1168   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1169   {
1170     hfdcan->RxFifo1Callback = HAL_FDCAN_RxFifo1Callback; /* Legacy weak RxFifo1Callback  */
1171   }
1172   else
1173   {
1174     /* Update the error code */
1175     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1176 
1177     /* Return error status */
1178     status =  HAL_ERROR;
1179   }
1180 
1181   return status;
1182 }
1183 
1184 /**
1185   * @brief  Register Tx Buffer Complete FDCAN Callback
1186   *         To be used instead of the weak HAL_FDCAN_TxBufferCompleteCallback() predefined callback
1187   * @param  hfdcan FDCAN handle
1188   * @param  pCallback pointer to the Tx Buffer Complete Callback function
1189   * @retval HAL status
1190   */
HAL_FDCAN_RegisterTxBufferCompleteCallback(FDCAN_HandleTypeDef * hfdcan,pFDCAN_TxBufferCompleteCallbackTypeDef pCallback)1191 HAL_StatusTypeDef HAL_FDCAN_RegisterTxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, pFDCAN_TxBufferCompleteCallbackTypeDef pCallback)
1192 {
1193   HAL_StatusTypeDef status = HAL_OK;
1194 
1195   if (pCallback == NULL)
1196   {
1197     /* Update the error code */
1198     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1199     return HAL_ERROR;
1200   }
1201 
1202   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1203   {
1204     hfdcan->TxBufferCompleteCallback = pCallback;
1205   }
1206   else
1207   {
1208     /* Update the error code */
1209     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1210 
1211     /* Return error status */
1212     status =  HAL_ERROR;
1213   }
1214 
1215   return status;
1216 }
1217 
1218 /**
1219   * @brief  UnRegister the Tx Buffer Complete FDCAN Callback
1220   *         Tx Buffer Complete FDCAN Callback is redirected to the weak HAL_FDCAN_TxBufferCompleteCallback() predefined callback
1221   * @param  hfdcan FDCAN handle
1222   * @retval HAL status
1223   */
HAL_FDCAN_UnRegisterTxBufferCompleteCallback(FDCAN_HandleTypeDef * hfdcan)1224 HAL_StatusTypeDef HAL_FDCAN_UnRegisterTxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan)
1225 {
1226   HAL_StatusTypeDef status = HAL_OK;
1227 
1228   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1229   {
1230     hfdcan->TxBufferCompleteCallback = HAL_FDCAN_TxBufferCompleteCallback; /* Legacy weak TxBufferCompleteCallback  */
1231   }
1232   else
1233   {
1234     /* Update the error code */
1235     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1236 
1237     /* Return error status */
1238     status =  HAL_ERROR;
1239   }
1240 
1241   return status;
1242 }
1243 
1244 /**
1245   * @brief  Register Tx Buffer Abort FDCAN Callback
1246   *         To be used instead of the weak HAL_FDCAN_TxBufferAbortCallback() predefined callback
1247   * @param  hfdcan FDCAN handle
1248   * @param  pCallback pointer to the Tx Buffer Abort Callback function
1249   * @retval HAL status
1250   */
HAL_FDCAN_RegisterTxBufferAbortCallback(FDCAN_HandleTypeDef * hfdcan,pFDCAN_TxBufferAbortCallbackTypeDef pCallback)1251 HAL_StatusTypeDef HAL_FDCAN_RegisterTxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan, pFDCAN_TxBufferAbortCallbackTypeDef pCallback)
1252 {
1253   HAL_StatusTypeDef status = HAL_OK;
1254 
1255   if (pCallback == NULL)
1256   {
1257     /* Update the error code */
1258     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1259     return HAL_ERROR;
1260   }
1261 
1262   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1263   {
1264     hfdcan->TxBufferAbortCallback = pCallback;
1265   }
1266   else
1267   {
1268     /* Update the error code */
1269     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1270 
1271     /* Return error status */
1272     status =  HAL_ERROR;
1273   }
1274 
1275   return status;
1276 }
1277 
1278 /**
1279   * @brief  UnRegister the Tx Buffer Abort FDCAN Callback
1280   *         Tx Buffer Abort FDCAN Callback is redirected to the weak HAL_FDCAN_TxBufferAbortCallback() predefined callback
1281   * @param  hfdcan FDCAN handle
1282   * @retval HAL status
1283   */
HAL_FDCAN_UnRegisterTxBufferAbortCallback(FDCAN_HandleTypeDef * hfdcan)1284 HAL_StatusTypeDef HAL_FDCAN_UnRegisterTxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan)
1285 {
1286   HAL_StatusTypeDef status = HAL_OK;
1287 
1288   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1289   {
1290     hfdcan->TxBufferAbortCallback = HAL_FDCAN_TxBufferAbortCallback; /* Legacy weak TxBufferAbortCallback  */
1291   }
1292   else
1293   {
1294     /* Update the error code */
1295     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1296 
1297     /* Return error status */
1298     status =  HAL_ERROR;
1299   }
1300 
1301   return status;
1302 }
1303 
1304 /**
1305   * @brief  Register Error Status FDCAN Callback
1306   *         To be used instead of the weak HAL_FDCAN_ErrorStatusCallback() predefined callback
1307   * @param  hfdcan FDCAN handle
1308   * @param  pCallback pointer to the Error Status Callback function
1309   * @retval HAL status
1310   */
HAL_FDCAN_RegisterErrorStatusCallback(FDCAN_HandleTypeDef * hfdcan,pFDCAN_ErrorStatusCallbackTypeDef pCallback)1311 HAL_StatusTypeDef HAL_FDCAN_RegisterErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan, pFDCAN_ErrorStatusCallbackTypeDef pCallback)
1312 {
1313   HAL_StatusTypeDef status = HAL_OK;
1314 
1315   if (pCallback == NULL)
1316   {
1317     /* Update the error code */
1318     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1319     return HAL_ERROR;
1320   }
1321 
1322   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1323   {
1324     hfdcan->ErrorStatusCallback = pCallback;
1325   }
1326   else
1327   {
1328     /* Update the error code */
1329     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1330 
1331     /* Return error status */
1332     status =  HAL_ERROR;
1333   }
1334 
1335   return status;
1336 }
1337 
1338 /**
1339   * @brief  UnRegister the Error Status FDCAN Callback
1340   *         Error Status FDCAN Callback is redirected to the weak HAL_FDCAN_ErrorStatusCallback() predefined callback
1341   * @param  hfdcan FDCAN handle
1342   * @retval HAL status
1343   */
HAL_FDCAN_UnRegisterErrorStatusCallback(FDCAN_HandleTypeDef * hfdcan)1344 HAL_StatusTypeDef HAL_FDCAN_UnRegisterErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan)
1345 {
1346   HAL_StatusTypeDef status = HAL_OK;
1347 
1348   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1349   {
1350     hfdcan->ErrorStatusCallback = HAL_FDCAN_ErrorStatusCallback; /* Legacy weak ErrorStatusCallback  */
1351   }
1352   else
1353   {
1354     /* Update the error code */
1355     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1356 
1357     /* Return error status */
1358     status =  HAL_ERROR;
1359   }
1360 
1361   return status;
1362 }
1363 
1364 /**
1365   * @brief  Register TT Schedule Synchronization FDCAN Callback
1366   *         To be used instead of the weak HAL_FDCAN_TT_ScheduleSyncCallback() predefined callback
1367   * @param  hfdcan FDCAN handle
1368   * @param  pCallback pointer to the TT Schedule Synchronization Callback function
1369   * @retval HAL status
1370   */
HAL_FDCAN_RegisterTTScheduleSyncCallback(FDCAN_HandleTypeDef * hfdcan,pFDCAN_TT_ScheduleSyncCallbackTypeDef pCallback)1371 HAL_StatusTypeDef HAL_FDCAN_RegisterTTScheduleSyncCallback(FDCAN_HandleTypeDef *hfdcan, pFDCAN_TT_ScheduleSyncCallbackTypeDef pCallback)
1372 {
1373   HAL_StatusTypeDef status = HAL_OK;
1374 
1375   if (pCallback == NULL)
1376   {
1377     /* Update the error code */
1378     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1379     return HAL_ERROR;
1380   }
1381 
1382   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1383   {
1384     hfdcan->TT_ScheduleSyncCallback = pCallback;
1385   }
1386   else
1387   {
1388     /* Update the error code */
1389     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1390 
1391     /* Return error status */
1392     status =  HAL_ERROR;
1393   }
1394 
1395   return status;
1396 }
1397 
1398 /**
1399   * @brief  UnRegister the TT Schedule Synchronization FDCAN Callback
1400   *         TT Schedule Synchronization Callback is redirected to the weak HAL_FDCAN_TT_ScheduleSyncCallback() predefined callback
1401   * @param  hfdcan FDCAN handle
1402   * @retval HAL status
1403   */
HAL_FDCAN_UnRegisterTTScheduleSyncCallback(FDCAN_HandleTypeDef * hfdcan)1404 HAL_StatusTypeDef HAL_FDCAN_UnRegisterTTScheduleSyncCallback(FDCAN_HandleTypeDef *hfdcan)
1405 {
1406   HAL_StatusTypeDef status = HAL_OK;
1407 
1408   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1409   {
1410     hfdcan->TT_ScheduleSyncCallback = HAL_FDCAN_TT_ScheduleSyncCallback; /* Legacy weak TT_ScheduleSyncCallback  */
1411   }
1412   else
1413   {
1414     /* Update the error code */
1415     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1416 
1417     /* Return error status */
1418     status =  HAL_ERROR;
1419   }
1420 
1421   return status;
1422 }
1423 
1424 /**
1425   * @brief  Register TT Time Mark FDCAN Callback
1426   *         To be used instead of the weak HAL_FDCAN_TT_TimeMarkCallback() predefined callback
1427   * @param  hfdcan FDCAN handle
1428   * @param  pCallback pointer to the TT Time Mark Callback function
1429   * @retval HAL status
1430   */
HAL_FDCAN_RegisterTTTimeMarkCallback(FDCAN_HandleTypeDef * hfdcan,pFDCAN_TT_TimeMarkCallbackTypeDef pCallback)1431 HAL_StatusTypeDef HAL_FDCAN_RegisterTTTimeMarkCallback(FDCAN_HandleTypeDef *hfdcan, pFDCAN_TT_TimeMarkCallbackTypeDef pCallback)
1432 {
1433   HAL_StatusTypeDef status = HAL_OK;
1434 
1435   if (pCallback == NULL)
1436   {
1437     /* Update the error code */
1438     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1439     return HAL_ERROR;
1440   }
1441 
1442   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1443   {
1444     hfdcan->TT_TimeMarkCallback = pCallback;
1445   }
1446   else
1447   {
1448     /* Update the error code */
1449     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1450 
1451     /* Return error status */
1452     status =  HAL_ERROR;
1453   }
1454 
1455   return status;
1456 }
1457 
1458 /**
1459   * @brief  UnRegister the TT Time Mark FDCAN Callback
1460   *         TT Time Mark Callback is redirected to the weak HAL_FDCAN_TT_TimeMarkCallback() predefined callback
1461   * @param  hfdcan FDCAN handle
1462   * @retval HAL status
1463   */
HAL_FDCAN_UnRegisterTTTimeMarkCallback(FDCAN_HandleTypeDef * hfdcan)1464 HAL_StatusTypeDef HAL_FDCAN_UnRegisterTTTimeMarkCallback(FDCAN_HandleTypeDef *hfdcan)
1465 {
1466   HAL_StatusTypeDef status = HAL_OK;
1467 
1468   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1469   {
1470     hfdcan->TT_TimeMarkCallback = HAL_FDCAN_TT_TimeMarkCallback; /* Legacy weak TT_TimeMarkCallback  */
1471   }
1472   else
1473   {
1474     /* Update the error code */
1475     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1476 
1477     /* Return error status */
1478     status =  HAL_ERROR;
1479   }
1480 
1481   return status;
1482 }
1483 
1484 /**
1485   * @brief  Register TT Stop Watch FDCAN Callback
1486   *         To be used instead of the weak HAL_FDCAN_TT_StopWatchCallback() predefined callback
1487   * @param  hfdcan FDCAN handle
1488   * @param  pCallback pointer to the TT Stop Watch Callback function
1489   * @retval HAL status
1490   */
HAL_FDCAN_RegisterTTStopWatchCallback(FDCAN_HandleTypeDef * hfdcan,pFDCAN_TT_StopWatchCallbackTypeDef pCallback)1491 HAL_StatusTypeDef HAL_FDCAN_RegisterTTStopWatchCallback(FDCAN_HandleTypeDef *hfdcan, pFDCAN_TT_StopWatchCallbackTypeDef pCallback)
1492 {
1493   HAL_StatusTypeDef status = HAL_OK;
1494 
1495   if (pCallback == NULL)
1496   {
1497     /* Update the error code */
1498     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1499     return HAL_ERROR;
1500   }
1501 
1502   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1503   {
1504     hfdcan->TT_StopWatchCallback = pCallback;
1505   }
1506   else
1507   {
1508     /* Update the error code */
1509     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1510 
1511     /* Return error status */
1512     status =  HAL_ERROR;
1513   }
1514 
1515   return status;
1516 }
1517 
1518 /**
1519   * @brief  UnRegister the TT Stop Watch FDCAN Callback
1520   *         TT Stop Watch Callback is redirected to the weak HAL_FDCAN_TT_StopWatchCallback() predefined callback
1521   * @param  hfdcan FDCAN handle
1522   * @retval HAL status
1523   */
HAL_FDCAN_UnRegisterTTStopWatchCallback(FDCAN_HandleTypeDef * hfdcan)1524 HAL_StatusTypeDef HAL_FDCAN_UnRegisterTTStopWatchCallback(FDCAN_HandleTypeDef *hfdcan)
1525 {
1526   HAL_StatusTypeDef status = HAL_OK;
1527 
1528   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1529   {
1530     hfdcan->TT_StopWatchCallback = HAL_FDCAN_TT_StopWatchCallback; /* Legacy weak TT_StopWatchCallback  */
1531   }
1532   else
1533   {
1534     /* Update the error code */
1535     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1536 
1537     /* Return error status */
1538     status =  HAL_ERROR;
1539   }
1540 
1541   return status;
1542 }
1543 
1544 /**
1545   * @brief  Register TT Global Time FDCAN Callback
1546   *         To be used instead of the weak HAL_FDCAN_TT_GlobalTimeCallback() predefined callback
1547   * @param  hfdcan FDCAN handle
1548   * @param  pCallback pointer to the TT Global Time Callback function
1549   * @retval HAL status
1550   */
HAL_FDCAN_RegisterTTGlobalTimeCallback(FDCAN_HandleTypeDef * hfdcan,pFDCAN_TT_GlobalTimeCallbackTypeDef pCallback)1551 HAL_StatusTypeDef HAL_FDCAN_RegisterTTGlobalTimeCallback(FDCAN_HandleTypeDef *hfdcan, pFDCAN_TT_GlobalTimeCallbackTypeDef pCallback)
1552 {
1553   HAL_StatusTypeDef status = HAL_OK;
1554 
1555   if (pCallback == NULL)
1556   {
1557     /* Update the error code */
1558     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1559     return HAL_ERROR;
1560   }
1561 
1562   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1563   {
1564     hfdcan->TT_GlobalTimeCallback = pCallback;
1565   }
1566   else
1567   {
1568     /* Update the error code */
1569     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1570 
1571     /* Return error status */
1572     status =  HAL_ERROR;
1573   }
1574 
1575   return status;
1576 }
1577 
1578 /**
1579   * @brief  UnRegister the TT Global Time FDCAN Callback
1580   *         TT Global Time Callback is redirected to the weak HAL_FDCAN_TT_GlobalTimeCallback() predefined callback
1581   * @param  hfdcan FDCAN handle
1582   * @retval HAL status
1583   */
HAL_FDCAN_UnRegisterTTGlobalTimeCallback(FDCAN_HandleTypeDef * hfdcan)1584 HAL_StatusTypeDef HAL_FDCAN_UnRegisterTTGlobalTimeCallback(FDCAN_HandleTypeDef *hfdcan)
1585 {
1586   HAL_StatusTypeDef status = HAL_OK;
1587 
1588   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1589   {
1590     hfdcan->TT_GlobalTimeCallback = HAL_FDCAN_TT_GlobalTimeCallback; /* Legacy weak TT_GlobalTimeCallback  */
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 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
1605 
1606 /**
1607   * @}
1608   */
1609 
1610 /** @defgroup FDCAN_Exported_Functions_Group2 Configuration functions
1611  *  @brief    FDCAN Configuration functions.
1612  *
1613 @verbatim
1614   ==============================================================================
1615               ##### Configuration functions #####
1616   ==============================================================================
1617     [..]  This section provides functions allowing to:
1618       (+) HAL_FDCAN_ConfigClockCalibration        : Configure the FDCAN clock calibration unit
1619         (+) HAL_FDCAN_GetClockCalibrationState      : Get the clock calibration state
1620         (+) HAL_FDCAN_ResetClockCalibrationState    : Reset the clock calibration state
1621         (+) HAL_FDCAN_GetClockCalibrationCounter    : Get the clock calibration counters values
1622       (+) HAL_FDCAN_ConfigFilter                  : Configure the FDCAN reception filters
1623       (+) HAL_FDCAN_ConfigGlobalFilter            : Configure the FDCAN global filter
1624       (+) HAL_FDCAN_ConfigExtendedIdMask          : Configure the extended ID mask
1625       (+) HAL_FDCAN_ConfigRxFifoOverwrite         : Configure the Rx FIFO operation mode
1626       (+) HAL_FDCAN_ConfigFifoWatermark           : Configure the FIFO watermark
1627       (+) HAL_FDCAN_ConfigRamWatchdog             : Configure the RAM watchdog
1628       (+) HAL_FDCAN_ConfigTimestampCounter        : Configure the timestamp counter
1629         (+) HAL_FDCAN_EnableTimestampCounter        : Enable the timestamp counter
1630         (+) HAL_FDCAN_DisableTimestampCounter       : Disable the timestamp counter
1631         (+) HAL_FDCAN_GetTimestampCounter           : Get the timestamp counter value
1632         (+) HAL_FDCAN_ResetTimestampCounter         : Reset the timestamp counter to zero
1633       (+) HAL_FDCAN_ConfigTimeoutCounter          : Configure the timeout counter
1634         (+) HAL_FDCAN_EnableTimeoutCounter          : Enable the timeout counter
1635         (+) HAL_FDCAN_DisableTimeoutCounter         : Disable the timeout counter
1636         (+) HAL_FDCAN_GetTimeoutCounter             : Get the timeout counter value
1637         (+) HAL_FDCAN_ResetTimeoutCounter           : Reset the timeout counter to its start value
1638       (+) HAL_FDCAN_ConfigTxDelayCompensation     : Configure the transmitter delay compensation
1639         (+) HAL_FDCAN_EnableTxDelayCompensation     : Enable the transmitter delay compensation
1640         (+) HAL_FDCAN_DisableTxDelayCompensation    : Disable the transmitter delay compensation
1641       (+) HAL_FDCAN_EnableISOMode                 : Enable ISO 11898-1 protocol mode
1642       (+) HAL_FDCAN_DisableISOMode                : Disable ISO 11898-1 protocol mode
1643       (+) HAL_FDCAN_EnableEdgeFiltering           : Enable edge filtering during bus integration
1644       (+) HAL_FDCAN_DisableEdgeFiltering          : Disable edge filtering during bus integration
1645 
1646 @endverbatim
1647   * @{
1648   */
1649 
1650 /**
1651   * @brief  Configure the FDCAN clock calibration unit according to the specified
1652   *         parameters in the FDCAN_ClkCalUnitTypeDef structure.
1653   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1654   *         the configuration information for the specified FDCAN.
1655   * @param  sCcuConfig pointer to an FDCAN_ClkCalUnitTypeDef structure that
1656   *         contains the clock calibration information
1657   * @retval HAL status
1658   */
HAL_FDCAN_ConfigClockCalibration(FDCAN_HandleTypeDef * hfdcan,FDCAN_ClkCalUnitTypeDef * sCcuConfig)1659 HAL_StatusTypeDef HAL_FDCAN_ConfigClockCalibration(FDCAN_HandleTypeDef *hfdcan, FDCAN_ClkCalUnitTypeDef *sCcuConfig)
1660 {
1661   /* Check function parameters */
1662   assert_param(IS_FDCAN_CLOCK_CALIBRATION(sCcuConfig->ClockCalibration));
1663   if (sCcuConfig->ClockCalibration == FDCAN_CLOCK_CALIBRATION_DISABLE)
1664   {
1665     assert_param(IS_FDCAN_CKDIV(sCcuConfig->ClockDivider));
1666   }
1667   else
1668   {
1669     assert_param(IS_FDCAN_MAX_VALUE(sCcuConfig->MinOscClkPeriods, 0xFFU));
1670     assert_param(IS_FDCAN_CALIBRATION_FIELD_LENGTH(sCcuConfig->CalFieldLength));
1671     assert_param(IS_FDCAN_MIN_VALUE(sCcuConfig->TimeQuantaPerBitTime, 4U));
1672     assert_param(IS_FDCAN_MAX_VALUE(sCcuConfig->TimeQuantaPerBitTime, 0x25U));
1673     assert_param(IS_FDCAN_MAX_VALUE(sCcuConfig->WatchdogStartValue, 0xFFFFU));
1674   }
1675 
1676   /* FDCAN1 should be initialized in order to use clock calibration */
1677   if (hfdcan->Instance != FDCAN1)
1678   {
1679     /* Update error code */
1680     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
1681 
1682     return HAL_ERROR;
1683   }
1684 
1685   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1686   {
1687     if (sCcuConfig->ClockCalibration == FDCAN_CLOCK_CALIBRATION_DISABLE)
1688     {
1689       /* Bypass clock calibration */
1690       SET_BIT(FDCAN_CCU->CCFG, FDCANCCU_CCFG_BCC);
1691 
1692       /* Configure clock divider */
1693       MODIFY_REG(FDCAN_CCU->CCFG, FDCANCCU_CCFG_CDIV, sCcuConfig->ClockDivider);
1694     }
1695     else /* sCcuConfig->ClockCalibration == ENABLE */
1696     {
1697       /* Clock calibration unit generates time quanta clock */
1698       CLEAR_BIT(FDCAN_CCU->CCFG, FDCANCCU_CCFG_BCC);
1699 
1700       /* Configure clock calibration unit */
1701       MODIFY_REG(FDCAN_CCU->CCFG,
1702                  (FDCANCCU_CCFG_TQBT | FDCANCCU_CCFG_CFL | FDCANCCU_CCFG_OCPM),
1703                  ((sCcuConfig->TimeQuantaPerBitTime << FDCANCCU_CCFG_TQBT_Pos) | sCcuConfig->CalFieldLength | (sCcuConfig->MinOscClkPeriods << FDCANCCU_CCFG_OCPM_Pos)));
1704 
1705       /* Configure the start value of the calibration watchdog counter */
1706       MODIFY_REG(FDCAN_CCU->CWD, FDCANCCU_CWD_WDC, sCcuConfig->WatchdogStartValue);
1707     }
1708 
1709     /* Return function status */
1710     return HAL_OK;
1711   }
1712   else
1713   {
1714     /* Update error code */
1715     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1716 
1717     return HAL_ERROR;
1718   }
1719 }
1720 
1721 /**
1722   * @brief  Get the clock calibration state.
1723   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1724   *         the configuration information for the specified FDCAN.
1725   * @retval State clock calibration state (can be a value of @arg FDCAN_calibration_state)
1726   */
HAL_FDCAN_GetClockCalibrationState(FDCAN_HandleTypeDef * hfdcan)1727 uint32_t HAL_FDCAN_GetClockCalibrationState(FDCAN_HandleTypeDef *hfdcan)
1728 {
1729   /* Prevent unused argument(s) compilation warning */
1730   UNUSED(hfdcan);
1731 
1732   return (FDCAN_CCU->CSTAT & FDCANCCU_CSTAT_CALS);
1733 }
1734 
1735 /**
1736   * @brief  Reset the clock calibration state.
1737   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1738   *         the configuration information for the specified FDCAN.
1739   * @retval HAL status
1740   */
HAL_FDCAN_ResetClockCalibrationState(FDCAN_HandleTypeDef * hfdcan)1741 HAL_StatusTypeDef HAL_FDCAN_ResetClockCalibrationState(FDCAN_HandleTypeDef *hfdcan)
1742 {
1743   /* FDCAN1 should be initialized in order to use clock calibration */
1744   if (hfdcan->Instance != FDCAN1)
1745   {
1746     /* Update error code */
1747     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
1748 
1749     return HAL_ERROR;
1750   }
1751 
1752   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1753   {
1754     /* Calibration software reset */
1755     SET_BIT(FDCAN_CCU->CCFG, FDCANCCU_CCFG_SWR);
1756 
1757     /* Return function status */
1758     return HAL_OK;
1759   }
1760   else
1761   {
1762     /* Update error code */
1763     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1764 
1765     return HAL_ERROR;
1766   }
1767 }
1768 
1769 /**
1770   * @brief  Get the clock calibration counter value.
1771   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1772   *         the configuration information for the specified FDCAN.
1773   * @param  Counter clock calibration counter.
1774   *         This parameter can be a value of @arg FDCAN_calibration_counter.
1775   * @retval Value clock calibration counter value
1776   */
HAL_FDCAN_GetClockCalibrationCounter(FDCAN_HandleTypeDef * hfdcan,uint32_t Counter)1777 uint32_t HAL_FDCAN_GetClockCalibrationCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t Counter)
1778 {
1779   /* Prevent unused argument(s) compilation warning */
1780   UNUSED(hfdcan);
1781 
1782   /* Check function parameters */
1783   assert_param(IS_FDCAN_CALIBRATION_COUNTER(Counter));
1784 
1785   if (Counter == FDCAN_CALIB_TIME_QUANTA_COUNTER)
1786   {
1787     return ((FDCAN_CCU->CSTAT & FDCANCCU_CSTAT_TQC) >> FDCANCCU_CSTAT_TQC_Pos);
1788   }
1789   else if (Counter == FDCAN_CALIB_CLOCK_PERIOD_COUNTER)
1790   {
1791     return (FDCAN_CCU->CSTAT & FDCANCCU_CSTAT_OCPC);
1792   }
1793   else /* Counter == FDCAN_CALIB_WATCHDOG_COUNTER */
1794   {
1795     return ((FDCAN_CCU->CWD & FDCANCCU_CWD_WDV) >> FDCANCCU_CWD_WDV_Pos);
1796   }
1797 }
1798 
1799 /**
1800   * @brief  Configure the FDCAN reception filter according to the specified
1801   *         parameters in the FDCAN_FilterTypeDef structure.
1802   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1803   *         the configuration information for the specified FDCAN.
1804   * @param  sFilterConfig pointer to an FDCAN_FilterTypeDef structure that
1805   *         contains the filter configuration information
1806   * @retval HAL status
1807   */
HAL_FDCAN_ConfigFilter(FDCAN_HandleTypeDef * hfdcan,FDCAN_FilterTypeDef * sFilterConfig)1808 HAL_StatusTypeDef HAL_FDCAN_ConfigFilter(FDCAN_HandleTypeDef *hfdcan, FDCAN_FilterTypeDef *sFilterConfig)
1809 {
1810   uint32_t FilterElementW1;
1811   uint32_t FilterElementW2;
1812   uint32_t *FilterAddress;
1813   HAL_FDCAN_StateTypeDef state = hfdcan->State;
1814 
1815   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
1816   {
1817     /* Check function parameters */
1818     assert_param(IS_FDCAN_ID_TYPE(sFilterConfig->IdType));
1819     assert_param(IS_FDCAN_FILTER_CFG(sFilterConfig->FilterConfig));
1820     if (sFilterConfig->FilterConfig == FDCAN_FILTER_TO_RXBUFFER)
1821     {
1822       assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->RxBufferIndex, 63U));
1823       assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->IsCalibrationMsg, 1U));
1824     }
1825 
1826     if (sFilterConfig->IdType == FDCAN_STANDARD_ID)
1827     {
1828       /* Check function parameters */
1829       assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterIndex, (hfdcan->Init.StdFiltersNbr - 1U)));
1830       assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterID1, 0x7FFU));
1831       if (sFilterConfig->FilterConfig != FDCAN_FILTER_TO_RXBUFFER)
1832       {
1833         assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterID2, 0x7FFU));
1834         assert_param(IS_FDCAN_STD_FILTER_TYPE(sFilterConfig->FilterType));
1835       }
1836 
1837       /* Build filter element */
1838       if (sFilterConfig->FilterConfig == FDCAN_FILTER_TO_RXBUFFER)
1839       {
1840         FilterElementW1 = ((FDCAN_FILTER_TO_RXBUFFER << 27U)       |
1841                            (sFilterConfig->FilterID1 << 16U)       |
1842                            (sFilterConfig->IsCalibrationMsg << 8U) |
1843                            sFilterConfig->RxBufferIndex);
1844       }
1845       else
1846       {
1847         FilterElementW1 = ((sFilterConfig->FilterType << 30U)   |
1848                            (sFilterConfig->FilterConfig << 27U) |
1849                            (sFilterConfig->FilterID1 << 16U)    |
1850                            sFilterConfig->FilterID2);
1851       }
1852 
1853       /* Calculate filter address */
1854       FilterAddress = (uint32_t *)(hfdcan->msgRam.StandardFilterSA + (sFilterConfig->FilterIndex * 4U));
1855 
1856       /* Write filter element to the message RAM */
1857       *FilterAddress = FilterElementW1;
1858     }
1859     else /* sFilterConfig->IdType == FDCAN_EXTENDED_ID */
1860     {
1861       /* Check function parameters */
1862       assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterIndex, (hfdcan->Init.ExtFiltersNbr - 1U)));
1863       assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterID1, 0x1FFFFFFFU));
1864       if (sFilterConfig->FilterConfig != FDCAN_FILTER_TO_RXBUFFER)
1865       {
1866         assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterID2, 0x1FFFFFFFU));
1867         assert_param(IS_FDCAN_EXT_FILTER_TYPE(sFilterConfig->FilterType));
1868       }
1869 
1870       /* Build first word of filter element */
1871       FilterElementW1 = ((sFilterConfig->FilterConfig << 29U) | sFilterConfig->FilterID1);
1872 
1873       /* Build second word of filter element */
1874       if (sFilterConfig->FilterConfig == FDCAN_FILTER_TO_RXBUFFER)
1875       {
1876         FilterElementW2 = sFilterConfig->RxBufferIndex;
1877       }
1878       else
1879       {
1880         FilterElementW2 = ((sFilterConfig->FilterType << 30U) | sFilterConfig->FilterID2);
1881       }
1882 
1883       /* Calculate filter address */
1884       FilterAddress = (uint32_t *)(hfdcan->msgRam.ExtendedFilterSA + (sFilterConfig->FilterIndex * 4U * 2U));
1885 
1886       /* Write filter element to the message RAM */
1887       *FilterAddress = FilterElementW1;
1888       FilterAddress++;
1889       *FilterAddress = FilterElementW2;
1890     }
1891 
1892     /* Return function status */
1893     return HAL_OK;
1894   }
1895   else
1896   {
1897     /* Update error code */
1898     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
1899 
1900     return HAL_ERROR;
1901   }
1902 }
1903 
1904 /**
1905   * @brief  Configure the FDCAN global filter.
1906   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1907   *         the configuration information for the specified FDCAN.
1908   * @param  NonMatchingStd Defines how received messages with 11-bit IDs that
1909   *         do not match any element of the filter list are treated.
1910   *         This parameter can be a value of @arg FDCAN_Non_Matching_Frames.
1911   * @param  NonMatchingExt Defines how received messages with 29-bit IDs that
1912   *         do not match any element of the filter list are treated.
1913   *         This parameter can be a value of @arg FDCAN_Non_Matching_Frames.
1914   * @param  RejectRemoteStd Filter or reject all the remote 11-bit IDs frames.
1915   *         This parameter can be a value of @arg FDCAN_Reject_Remote_Frames.
1916   * @param  RejectRemoteExt Filter or reject all the remote 29-bit IDs frames.
1917   *         This parameter can be a value of @arg FDCAN_Reject_Remote_Frames.
1918   * @retval HAL status
1919   */
HAL_FDCAN_ConfigGlobalFilter(FDCAN_HandleTypeDef * hfdcan,uint32_t NonMatchingStd,uint32_t NonMatchingExt,uint32_t RejectRemoteStd,uint32_t RejectRemoteExt)1920 HAL_StatusTypeDef HAL_FDCAN_ConfigGlobalFilter(FDCAN_HandleTypeDef *hfdcan,
1921                                                uint32_t NonMatchingStd,
1922                                                uint32_t NonMatchingExt,
1923                                                uint32_t RejectRemoteStd,
1924                                                uint32_t RejectRemoteExt)
1925 {
1926   /* Check function parameters */
1927   assert_param(IS_FDCAN_NON_MATCHING(NonMatchingStd));
1928   assert_param(IS_FDCAN_NON_MATCHING(NonMatchingExt));
1929   assert_param(IS_FDCAN_REJECT_REMOTE(RejectRemoteStd));
1930   assert_param(IS_FDCAN_REJECT_REMOTE(RejectRemoteExt));
1931 
1932   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1933   {
1934     /* Configure global filter */
1935     hfdcan->Instance->GFC = ((NonMatchingStd << FDCAN_GFC_ANFS_Pos)  |
1936                              (NonMatchingExt << FDCAN_GFC_ANFE_Pos)  |
1937                              (RejectRemoteStd << FDCAN_GFC_RRFS_Pos) |
1938                              (RejectRemoteExt << FDCAN_GFC_RRFE_Pos));
1939 
1940     /* Return function status */
1941     return HAL_OK;
1942   }
1943   else
1944   {
1945     /* Update error code */
1946     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1947 
1948     return HAL_ERROR;
1949   }
1950 }
1951 
1952 /**
1953   * @brief  Configure the extended ID mask.
1954   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1955   *         the configuration information for the specified FDCAN.
1956   * @param  Mask Extended ID Mask.
1957   *         This parameter must be a number between 0 and 0x1FFFFFFF
1958   * @retval HAL status
1959   */
HAL_FDCAN_ConfigExtendedIdMask(FDCAN_HandleTypeDef * hfdcan,uint32_t Mask)1960 HAL_StatusTypeDef HAL_FDCAN_ConfigExtendedIdMask(FDCAN_HandleTypeDef *hfdcan, uint32_t Mask)
1961 {
1962   /* Check function parameters */
1963   assert_param(IS_FDCAN_MAX_VALUE(Mask, 0x1FFFFFFFU));
1964 
1965   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1966   {
1967     /* Configure the extended ID mask */
1968     hfdcan->Instance->XIDAM = Mask;
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 Rx FIFO operation mode.
1984   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1985   *         the configuration information for the specified FDCAN.
1986   * @param  RxFifo Rx FIFO.
1987   *         This parameter can be one of the following values:
1988   *           @arg FDCAN_RX_FIFO0: Rx FIFO 0
1989   *           @arg FDCAN_RX_FIFO1: Rx FIFO 1
1990   * @param  OperationMode operation mode.
1991   *         This parameter can be a value of @arg FDCAN_Rx_FIFO_operation_mode.
1992   * @retval HAL status
1993   */
HAL_FDCAN_ConfigRxFifoOverwrite(FDCAN_HandleTypeDef * hfdcan,uint32_t RxFifo,uint32_t OperationMode)1994 HAL_StatusTypeDef HAL_FDCAN_ConfigRxFifoOverwrite(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo, uint32_t OperationMode)
1995 {
1996   /* Check function parameters */
1997   assert_param(IS_FDCAN_RX_FIFO(RxFifo));
1998   assert_param(IS_FDCAN_RX_FIFO_MODE(OperationMode));
1999 
2000   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2001   {
2002     if (RxFifo == FDCAN_RX_FIFO0)
2003     {
2004       /* Select FIFO 0 Operation Mode */
2005       MODIFY_REG(hfdcan->Instance->RXF0C, FDCAN_RXF0C_F0OM, OperationMode);
2006     }
2007     else /* RxFifo == FDCAN_RX_FIFO1 */
2008     {
2009       /* Select FIFO 1 Operation Mode */
2010       MODIFY_REG(hfdcan->Instance->RXF1C, FDCAN_RXF1C_F1OM, OperationMode);
2011     }
2012 
2013     /* Return function status */
2014     return HAL_OK;
2015   }
2016   else
2017   {
2018     /* Update error code */
2019     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2020 
2021     return HAL_ERROR;
2022   }
2023 }
2024 
2025 /**
2026   * @brief  Configure the FIFO watermark.
2027   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2028   *         the configuration information for the specified FDCAN.
2029   * @param  FIFO select the FIFO to be configured.
2030   *         This parameter can be a value of @arg FDCAN_FIFO_watermark.
2031   * @param  Watermark level for FIFO watermark interrupt.
2032   *         This parameter must be a number between:
2033   *           - 0 and 32, if FIFO is FDCAN_CFG_TX_EVENT_FIFO
2034   *           - 0 and 64, if FIFO is FDCAN_CFG_RX_FIFO0 or FDCAN_CFG_RX_FIFO1
2035   * @retval HAL status
2036   */
HAL_FDCAN_ConfigFifoWatermark(FDCAN_HandleTypeDef * hfdcan,uint32_t FIFO,uint32_t Watermark)2037 HAL_StatusTypeDef HAL_FDCAN_ConfigFifoWatermark(FDCAN_HandleTypeDef *hfdcan, uint32_t FIFO, uint32_t Watermark)
2038 {
2039   /* Check function parameters */
2040   assert_param(IS_FDCAN_FIFO_WATERMARK(FIFO));
2041   if (FIFO == FDCAN_CFG_TX_EVENT_FIFO)
2042   {
2043     assert_param(IS_FDCAN_MAX_VALUE(Watermark, 32U));
2044   }
2045   else /* (FIFO == FDCAN_CFG_RX_FIFO0) || (FIFO == FDCAN_CFG_RX_FIFO1) */
2046   {
2047     assert_param(IS_FDCAN_MAX_VALUE(Watermark, 64U));
2048   }
2049 
2050   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2051   {
2052     /* Set the level for FIFO watermark interrupt */
2053     if (FIFO == FDCAN_CFG_TX_EVENT_FIFO)
2054     {
2055       MODIFY_REG(hfdcan->Instance->TXEFC, FDCAN_TXEFC_EFWM, (Watermark << FDCAN_TXEFC_EFWM_Pos));
2056     }
2057     else if (FIFO == FDCAN_CFG_RX_FIFO0)
2058     {
2059       MODIFY_REG(hfdcan->Instance->RXF0C, FDCAN_RXF0C_F0WM, (Watermark << FDCAN_RXF0C_F0WM_Pos));
2060     }
2061     else /* FIFO == FDCAN_CFG_RX_FIFO1 */
2062     {
2063       MODIFY_REG(hfdcan->Instance->RXF1C, FDCAN_RXF1C_F1WM, (Watermark << FDCAN_RXF1C_F1WM_Pos));
2064     }
2065 
2066     /* Return function status */
2067     return HAL_OK;
2068   }
2069   else
2070   {
2071     /* Update error code */
2072     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2073 
2074     return HAL_ERROR;
2075   }
2076 }
2077 
2078 /**
2079   * @brief  Configure the RAM watchdog.
2080   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2081   *         the configuration information for the specified FDCAN.
2082   * @param  CounterStartValue Start value of the Message RAM Watchdog Counter,
2083   *         This parameter must be a number between 0x00 and 0xFF,
2084   *         with the reset value of 0x00 the counter is disabled.
2085   * @retval HAL status
2086   */
HAL_FDCAN_ConfigRamWatchdog(FDCAN_HandleTypeDef * hfdcan,uint32_t CounterStartValue)2087 HAL_StatusTypeDef HAL_FDCAN_ConfigRamWatchdog(FDCAN_HandleTypeDef *hfdcan, uint32_t CounterStartValue)
2088 {
2089   /* Check function parameters */
2090   assert_param(IS_FDCAN_MAX_VALUE(CounterStartValue, 0xFFU));
2091 
2092   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2093   {
2094     /* Configure the RAM watchdog counter start value */
2095     MODIFY_REG(hfdcan->Instance->RWD, FDCAN_RWD_WDC, CounterStartValue);
2096 
2097     /* Return function status */
2098     return HAL_OK;
2099   }
2100   else
2101   {
2102     /* Update error code */
2103     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2104 
2105     return HAL_ERROR;
2106   }
2107 }
2108 
2109 /**
2110   * @brief  Configure the timestamp counter.
2111   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2112   *         the configuration information for the specified FDCAN.
2113   * @param  TimestampPrescaler Timestamp Counter Prescaler.
2114   *         This parameter can be a value of @arg FDCAN_Timestamp_Prescaler.
2115   * @retval HAL status
2116   */
HAL_FDCAN_ConfigTimestampCounter(FDCAN_HandleTypeDef * hfdcan,uint32_t TimestampPrescaler)2117 HAL_StatusTypeDef HAL_FDCAN_ConfigTimestampCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t TimestampPrescaler)
2118 {
2119   /* Check function parameters */
2120   assert_param(IS_FDCAN_TIMESTAMP_PRESCALER(TimestampPrescaler));
2121 
2122   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2123   {
2124     /* Configure prescaler */
2125     MODIFY_REG(hfdcan->Instance->TSCC, FDCAN_TSCC_TCP, TimestampPrescaler);
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  Enable the timestamp counter.
2141   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2142   *         the configuration information for the specified FDCAN.
2143   * @param  TimestampOperation Timestamp counter operation.
2144   *         This parameter can be a value of @arg FDCAN_Timestamp.
2145   * @retval HAL status
2146   */
HAL_FDCAN_EnableTimestampCounter(FDCAN_HandleTypeDef * hfdcan,uint32_t TimestampOperation)2147 HAL_StatusTypeDef HAL_FDCAN_EnableTimestampCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t TimestampOperation)
2148 {
2149   /* Check function parameters */
2150   assert_param(IS_FDCAN_TIMESTAMP(TimestampOperation));
2151 
2152   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2153   {
2154     /* Enable timestamp counter */
2155     MODIFY_REG(hfdcan->Instance->TSCC, FDCAN_TSCC_TSS, TimestampOperation);
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  Disable the timestamp counter.
2171   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2172   *         the configuration information for the specified FDCAN.
2173   * @retval HAL status
2174   */
HAL_FDCAN_DisableTimestampCounter(FDCAN_HandleTypeDef * hfdcan)2175 HAL_StatusTypeDef HAL_FDCAN_DisableTimestampCounter(FDCAN_HandleTypeDef *hfdcan)
2176 {
2177   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2178   {
2179     /* Disable timestamp counter */
2180     CLEAR_BIT(hfdcan->Instance->TSCC, FDCAN_TSCC_TSS);
2181 
2182     /* Return function status */
2183     return HAL_OK;
2184   }
2185   else
2186   {
2187     /* Update error code */
2188     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2189 
2190     return HAL_ERROR;
2191   }
2192 }
2193 
2194 /**
2195   * @brief  Get the timestamp counter value.
2196   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2197   *         the configuration information for the specified FDCAN.
2198   * @retval Value Timestamp counter value
2199   */
HAL_FDCAN_GetTimestampCounter(FDCAN_HandleTypeDef * hfdcan)2200 uint16_t HAL_FDCAN_GetTimestampCounter(FDCAN_HandleTypeDef *hfdcan)
2201 {
2202   return (uint16_t)(hfdcan->Instance->TSCV);
2203 }
2204 
2205 /**
2206   * @brief  Reset the timestamp counter to zero.
2207   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2208   *         the configuration information for the specified FDCAN.
2209   * @retval HAL status
2210   */
HAL_FDCAN_ResetTimestampCounter(FDCAN_HandleTypeDef * hfdcan)2211 HAL_StatusTypeDef HAL_FDCAN_ResetTimestampCounter(FDCAN_HandleTypeDef *hfdcan)
2212 {
2213   if ((hfdcan->Instance->TSCC & FDCAN_TSCC_TSS) != FDCAN_TIMESTAMP_EXTERNAL)
2214   {
2215     /* Reset timestamp counter.
2216        Actually any write operation to TSCV clears the counter */
2217     CLEAR_REG(hfdcan->Instance->TSCV);
2218   }
2219   else
2220   {
2221     /* Update error code.
2222        Unable to reset external counter */
2223     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
2224 
2225     return HAL_ERROR;
2226   }
2227 
2228   /* Return function status */
2229   return HAL_OK;
2230 }
2231 
2232 /**
2233   * @brief  Configure the timeout counter.
2234   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2235   *         the configuration information for the specified FDCAN.
2236   * @param  TimeoutOperation Timeout counter operation.
2237   *         This parameter can be a value of @arg FDCAN_Timeout_Operation.
2238   * @param  TimeoutPeriod Start value of the timeout down-counter.
2239   *         This parameter must be a number between 0x0000 and 0xFFFF
2240   * @retval HAL status
2241   */
HAL_FDCAN_ConfigTimeoutCounter(FDCAN_HandleTypeDef * hfdcan,uint32_t TimeoutOperation,uint32_t TimeoutPeriod)2242 HAL_StatusTypeDef HAL_FDCAN_ConfigTimeoutCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t TimeoutOperation, uint32_t TimeoutPeriod)
2243 {
2244   /* Check function parameters */
2245   assert_param(IS_FDCAN_TIMEOUT(TimeoutOperation));
2246   assert_param(IS_FDCAN_MAX_VALUE(TimeoutPeriod, 0xFFFFU));
2247 
2248   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2249   {
2250     /* Select timeout operation and configure period */
2251     MODIFY_REG(hfdcan->Instance->TOCC, (FDCAN_TOCC_TOS | FDCAN_TOCC_TOP), (TimeoutOperation | (TimeoutPeriod << FDCAN_TOCC_TOP_Pos)));
2252 
2253     /* Return function status */
2254     return HAL_OK;
2255   }
2256   else
2257   {
2258     /* Update error code */
2259     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2260 
2261     return HAL_ERROR;
2262   }
2263 }
2264 
2265 /**
2266   * @brief  Enable the timeout counter.
2267   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2268   *         the configuration information for the specified FDCAN.
2269   * @retval HAL status
2270   */
HAL_FDCAN_EnableTimeoutCounter(FDCAN_HandleTypeDef * hfdcan)2271 HAL_StatusTypeDef HAL_FDCAN_EnableTimeoutCounter(FDCAN_HandleTypeDef *hfdcan)
2272 {
2273   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2274   {
2275     /* Enable timeout counter */
2276     SET_BIT(hfdcan->Instance->TOCC, FDCAN_TOCC_ETOC);
2277 
2278     /* Return function status */
2279     return HAL_OK;
2280   }
2281   else
2282   {
2283     /* Update error code */
2284     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2285 
2286     return HAL_ERROR;
2287   }
2288 }
2289 
2290 /**
2291   * @brief  Disable the timeout counter.
2292   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2293   *         the configuration information for the specified FDCAN.
2294   * @retval HAL status
2295   */
HAL_FDCAN_DisableTimeoutCounter(FDCAN_HandleTypeDef * hfdcan)2296 HAL_StatusTypeDef HAL_FDCAN_DisableTimeoutCounter(FDCAN_HandleTypeDef *hfdcan)
2297 {
2298   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2299   {
2300     /* Disable timeout counter */
2301     CLEAR_BIT(hfdcan->Instance->TOCC, FDCAN_TOCC_ETOC);
2302 
2303     /* Return function status */
2304     return HAL_OK;
2305   }
2306   else
2307   {
2308     /* Update error code */
2309     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2310 
2311     return HAL_ERROR;
2312   }
2313 }
2314 
2315 /**
2316   * @brief  Get the timeout counter value.
2317   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2318   *         the configuration information for the specified FDCAN.
2319   * @retval Value Timeout counter value
2320   */
HAL_FDCAN_GetTimeoutCounter(FDCAN_HandleTypeDef * hfdcan)2321 uint16_t HAL_FDCAN_GetTimeoutCounter(FDCAN_HandleTypeDef *hfdcan)
2322 {
2323   return (uint16_t)(hfdcan->Instance->TOCV);
2324 }
2325 
2326 /**
2327   * @brief  Reset the timeout counter to its start value.
2328   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2329   *         the configuration information for the specified FDCAN.
2330   * @retval HAL status
2331   */
HAL_FDCAN_ResetTimeoutCounter(FDCAN_HandleTypeDef * hfdcan)2332 HAL_StatusTypeDef HAL_FDCAN_ResetTimeoutCounter(FDCAN_HandleTypeDef *hfdcan)
2333 {
2334   if ((hfdcan->Instance->TOCC & FDCAN_TOCC_TOS) == FDCAN_TIMEOUT_CONTINUOUS)
2335   {
2336     /* Reset timeout counter to start value */
2337     CLEAR_REG(hfdcan->Instance->TOCV);
2338 
2339     /* Return function status */
2340     return HAL_OK;
2341   }
2342   else
2343   {
2344     /* Update error code.
2345        Unable to reset counter: controlled only by FIFO empty state */
2346     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
2347 
2348     return HAL_ERROR;
2349   }
2350 }
2351 
2352 /**
2353   * @brief  Configure the transmitter delay compensation.
2354   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2355   *         the configuration information for the specified FDCAN.
2356   * @param  TdcOffset Transmitter Delay Compensation Offset.
2357   *         This parameter must be a number between 0x00 and 0x7F.
2358   * @param  TdcFilter Transmitter Delay Compensation Filter Window Length.
2359   *         This parameter must be a number between 0x00 and 0x7F.
2360   * @retval HAL status
2361   */
HAL_FDCAN_ConfigTxDelayCompensation(FDCAN_HandleTypeDef * hfdcan,uint32_t TdcOffset,uint32_t TdcFilter)2362 HAL_StatusTypeDef HAL_FDCAN_ConfigTxDelayCompensation(FDCAN_HandleTypeDef *hfdcan, uint32_t TdcOffset, uint32_t TdcFilter)
2363 {
2364   /* Check function parameters */
2365   assert_param(IS_FDCAN_MAX_VALUE(TdcOffset, 0x7FU));
2366   assert_param(IS_FDCAN_MAX_VALUE(TdcFilter, 0x7FU));
2367 
2368   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2369   {
2370     /* Configure TDC offset and filter window */
2371     hfdcan->Instance->TDCR = ((TdcFilter << FDCAN_TDCR_TDCF_Pos) | (TdcOffset << FDCAN_TDCR_TDCO_Pos));
2372 
2373     /* Return function status */
2374     return HAL_OK;
2375   }
2376   else
2377   {
2378     /* Update error code */
2379     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2380 
2381     return HAL_ERROR;
2382   }
2383 }
2384 
2385 /**
2386   * @brief  Enable the transmitter delay compensation.
2387   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2388   *         the configuration information for the specified FDCAN.
2389   * @retval HAL status
2390   */
HAL_FDCAN_EnableTxDelayCompensation(FDCAN_HandleTypeDef * hfdcan)2391 HAL_StatusTypeDef HAL_FDCAN_EnableTxDelayCompensation(FDCAN_HandleTypeDef *hfdcan)
2392 {
2393   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2394   {
2395     /* Enable transmitter delay compensation */
2396     SET_BIT(hfdcan->Instance->DBTP, FDCAN_DBTP_TDC);
2397 
2398     /* Return function status */
2399     return HAL_OK;
2400   }
2401   else
2402   {
2403     /* Update error code */
2404     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2405 
2406     return HAL_ERROR;
2407   }
2408 }
2409 
2410 /**
2411   * @brief  Disable the transmitter delay compensation.
2412   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2413   *         the configuration information for the specified FDCAN.
2414   * @retval HAL status
2415   */
HAL_FDCAN_DisableTxDelayCompensation(FDCAN_HandleTypeDef * hfdcan)2416 HAL_StatusTypeDef HAL_FDCAN_DisableTxDelayCompensation(FDCAN_HandleTypeDef *hfdcan)
2417 {
2418   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2419   {
2420     /* Disable transmitter delay compensation */
2421     CLEAR_BIT(hfdcan->Instance->DBTP, FDCAN_DBTP_TDC);
2422 
2423     /* Return function status */
2424     return HAL_OK;
2425   }
2426   else
2427   {
2428     /* Update error code */
2429     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2430 
2431     return HAL_ERROR;
2432   }
2433 }
2434 
2435 /**
2436   * @brief  Enable ISO 11898-1 protocol mode.
2437   *         CAN FD frame format is according to ISO 11898-1 standard.
2438   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2439   *         the configuration information for the specified FDCAN.
2440   * @retval HAL status
2441   */
HAL_FDCAN_EnableISOMode(FDCAN_HandleTypeDef * hfdcan)2442 HAL_StatusTypeDef HAL_FDCAN_EnableISOMode(FDCAN_HandleTypeDef *hfdcan)
2443 {
2444   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2445   {
2446     /* Disable Non ISO protocol mode */
2447     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_NISO);
2448 
2449     /* Return function status */
2450     return HAL_OK;
2451   }
2452   else
2453   {
2454     /* Update error code */
2455     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2456 
2457     return HAL_ERROR;
2458   }
2459 }
2460 
2461 /**
2462   * @brief  Disable ISO 11898-1 protocol mode.
2463   *         CAN FD frame format is according to Bosch CAN FD specification V1.0.
2464   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2465   *         the configuration information for the specified FDCAN.
2466   * @retval HAL status
2467   */
HAL_FDCAN_DisableISOMode(FDCAN_HandleTypeDef * hfdcan)2468 HAL_StatusTypeDef HAL_FDCAN_DisableISOMode(FDCAN_HandleTypeDef *hfdcan)
2469 {
2470   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2471   {
2472     /* Enable Non ISO protocol mode */
2473     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_NISO);
2474 
2475     /* Return function status */
2476     return HAL_OK;
2477   }
2478   else
2479   {
2480     /* Update error code */
2481     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2482 
2483     return HAL_ERROR;
2484   }
2485 }
2486 
2487 /**
2488   * @brief  Enable edge filtering during bus integration.
2489   *         Two consecutive dominant tq are required to detect an edge for hard synchronization.
2490   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2491   *         the configuration information for the specified FDCAN.
2492   * @retval HAL status
2493   */
HAL_FDCAN_EnableEdgeFiltering(FDCAN_HandleTypeDef * hfdcan)2494 HAL_StatusTypeDef HAL_FDCAN_EnableEdgeFiltering(FDCAN_HandleTypeDef *hfdcan)
2495 {
2496   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2497   {
2498     /* Enable edge filtering */
2499     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_EFBI);
2500 
2501     /* Return function status */
2502     return HAL_OK;
2503   }
2504   else
2505   {
2506     /* Update error code */
2507     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2508 
2509     return HAL_ERROR;
2510   }
2511 }
2512 
2513 /**
2514   * @brief  Disable edge filtering during bus integration.
2515   *         One dominant tq is required to detect an edge for hard synchronization.
2516   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2517   *         the configuration information for the specified FDCAN.
2518   * @retval HAL status
2519   */
HAL_FDCAN_DisableEdgeFiltering(FDCAN_HandleTypeDef * hfdcan)2520 HAL_StatusTypeDef HAL_FDCAN_DisableEdgeFiltering(FDCAN_HandleTypeDef *hfdcan)
2521 {
2522   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2523   {
2524     /* Disable edge filtering */
2525     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_EFBI);
2526 
2527     /* Return function status */
2528     return HAL_OK;
2529   }
2530   else
2531   {
2532     /* Update error code */
2533     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2534 
2535     return HAL_ERROR;
2536   }
2537 }
2538 
2539 /**
2540   * @}
2541   */
2542 
2543 /** @defgroup FDCAN_Exported_Functions_Group3 Control functions
2544  *  @brief    Control functions
2545  *
2546 @verbatim
2547   ==============================================================================
2548                           ##### Control functions #####
2549   ==============================================================================
2550     [..]  This section provides functions allowing to:
2551       (+) HAL_FDCAN_Start                         : Start the FDCAN module
2552       (+) HAL_FDCAN_Stop                          : Stop the FDCAN module and enable access to configuration registers
2553       (+) HAL_FDCAN_AddMessageToTxFifoQ           : Add a message to the Tx FIFO/Queue and activate the corresponding transmission request
2554       (+) HAL_FDCAN_AddMessageToTxBuffer          : Add a message to a dedicated Tx buffer
2555       (+) HAL_FDCAN_EnableTxBufferRequest         : Enable transmission request
2556       (+) HAL_FDCAN_GetLatestTxFifoQRequestBuffer : Get Tx buffer index of latest Tx FIFO/Queue request
2557       (+) HAL_FDCAN_AbortTxRequest                : Abort transmission request
2558       (+) HAL_FDCAN_GetRxMessage                  : Get an FDCAN frame from the Rx Buffer/FIFO zone into the message RAM
2559       (+) HAL_FDCAN_GetTxEvent                    : Get an FDCAN Tx event from the Tx Event FIFO zone into the message RAM
2560       (+) HAL_FDCAN_GetHighPriorityMessageStatus  : Get high priority message status
2561       (+) HAL_FDCAN_GetProtocolStatus             : Get protocol status
2562       (+) HAL_FDCAN_GetErrorCounters              : Get error counter values
2563       (+) HAL_FDCAN_IsRxBufferMessageAvailable    : Check if a new message is received in the selected Rx buffer
2564       (+) HAL_FDCAN_IsTxBufferMessagePending      : Check if a transmission request is pending on the selected Tx buffer
2565       (+) HAL_FDCAN_GetRxFifoFillLevel            : Return Rx FIFO fill level
2566       (+) HAL_FDCAN_GetTxFifoFreeLevel            : Return Tx FIFO free level
2567       (+) HAL_FDCAN_IsRestrictedOperationMode     : Check if the FDCAN peripheral entered Restricted Operation Mode
2568       (+) HAL_FDCAN_ExitRestrictedOperationMode   : Exit Restricted Operation Mode
2569 
2570 @endverbatim
2571   * @{
2572   */
2573 
2574 /**
2575   * @brief  Start the FDCAN module.
2576   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2577   *         the configuration information for the specified FDCAN.
2578   * @retval HAL status
2579   */
HAL_FDCAN_Start(FDCAN_HandleTypeDef * hfdcan)2580 HAL_StatusTypeDef HAL_FDCAN_Start(FDCAN_HandleTypeDef *hfdcan)
2581 {
2582   if (hfdcan->State == HAL_FDCAN_STATE_READY)
2583   {
2584     /* Change FDCAN peripheral state */
2585     hfdcan->State = HAL_FDCAN_STATE_BUSY;
2586 
2587     /* Request leave initialisation */
2588     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT);
2589 
2590     /* Reset the FDCAN ErrorCode */
2591     hfdcan->ErrorCode = HAL_FDCAN_ERROR_NONE;
2592 
2593     /* Return function status */
2594     return HAL_OK;
2595   }
2596   else
2597   {
2598     /* Update error code */
2599     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2600 
2601     return HAL_ERROR;
2602   }
2603 }
2604 
2605 /**
2606   * @brief  Stop the FDCAN module and enable access to configuration registers.
2607   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2608   *         the configuration information for the specified FDCAN.
2609   * @retval HAL status
2610   */
HAL_FDCAN_Stop(FDCAN_HandleTypeDef * hfdcan)2611 HAL_StatusTypeDef HAL_FDCAN_Stop(FDCAN_HandleTypeDef *hfdcan)
2612 {
2613   uint32_t Counter = 0U;
2614 
2615   if (hfdcan->State == HAL_FDCAN_STATE_BUSY)
2616   {
2617     /* Request initialisation */
2618     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT);
2619 
2620     /* Wait until the INIT bit into CCCR register is set */
2621     while ((hfdcan->Instance->CCCR & FDCAN_CCCR_INIT) == 0U)
2622     {
2623       /* Check for the Timeout */
2624       if (Counter > FDCAN_TIMEOUT_COUNT)
2625       {
2626         /* Update error code */
2627         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
2628 
2629         /* Change FDCAN state */
2630         hfdcan->State = HAL_FDCAN_STATE_ERROR;
2631 
2632         return HAL_ERROR;
2633       }
2634 
2635       /* Increment counter */
2636       Counter++;
2637     }
2638 
2639     /* Reset counter */
2640     Counter = 0U;
2641 
2642     /* Exit from Sleep mode */
2643     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CSR);
2644 
2645     /* Wait until FDCAN exits sleep mode */
2646     while ((hfdcan->Instance->CCCR & FDCAN_CCCR_CSA) == FDCAN_CCCR_CSA)
2647     {
2648       /* Check for the Timeout */
2649       if (Counter > FDCAN_TIMEOUT_COUNT)
2650       {
2651         /* Update error code */
2652         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
2653 
2654         /* Change FDCAN state */
2655         hfdcan->State = HAL_FDCAN_STATE_ERROR;
2656 
2657         return HAL_ERROR;
2658       }
2659 
2660       /* Increment counter */
2661       Counter++;
2662     }
2663 
2664     /* Enable configuration change */
2665     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CCE);
2666 
2667     /* Reset Latest Tx FIFO/Queue Request Buffer Index */
2668     hfdcan->LatestTxFifoQRequest = 0U;
2669 
2670     /* Change FDCAN peripheral state */
2671     hfdcan->State = HAL_FDCAN_STATE_READY;
2672 
2673     /* Return function status */
2674     return HAL_OK;
2675   }
2676   else
2677   {
2678     /* Update error code */
2679     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
2680 
2681     return HAL_ERROR;
2682   }
2683 }
2684 
2685 /**
2686   * @brief  Add a message to the Tx FIFO/Queue and activate the corresponding transmission request
2687   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2688   *         the configuration information for the specified FDCAN.
2689   * @param  pTxHeader pointer to a FDCAN_TxHeaderTypeDef structure.
2690   * @param  pTxData pointer to a buffer containing the payload of the Tx frame.
2691   * @retval HAL status
2692   */
HAL_FDCAN_AddMessageToTxFifoQ(FDCAN_HandleTypeDef * hfdcan,FDCAN_TxHeaderTypeDef * pTxHeader,uint8_t * pTxData)2693 HAL_StatusTypeDef HAL_FDCAN_AddMessageToTxFifoQ(FDCAN_HandleTypeDef *hfdcan, FDCAN_TxHeaderTypeDef *pTxHeader, uint8_t *pTxData)
2694 {
2695   uint32_t PutIndex;
2696 
2697   /* Check function parameters */
2698   assert_param(IS_FDCAN_ID_TYPE(pTxHeader->IdType));
2699   if (pTxHeader->IdType == FDCAN_STANDARD_ID)
2700   {
2701     assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->Identifier, 0x7FFU));
2702   }
2703   else /* pTxHeader->IdType == FDCAN_EXTENDED_ID */
2704   {
2705     assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->Identifier, 0x1FFFFFFFU));
2706   }
2707   assert_param(IS_FDCAN_FRAME_TYPE(pTxHeader->TxFrameType));
2708   assert_param(IS_FDCAN_DLC(pTxHeader->DataLength));
2709   assert_param(IS_FDCAN_ESI(pTxHeader->ErrorStateIndicator));
2710   assert_param(IS_FDCAN_BRS(pTxHeader->BitRateSwitch));
2711   assert_param(IS_FDCAN_FDF(pTxHeader->FDFormat));
2712   assert_param(IS_FDCAN_EFC(pTxHeader->TxEventFifoControl));
2713   assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->MessageMarker, 0xFFU));
2714 
2715   if (hfdcan->State == HAL_FDCAN_STATE_BUSY)
2716   {
2717     /* Check that the Tx FIFO/Queue has an allocated area into the RAM */
2718     if ((hfdcan->Instance->TXBC & FDCAN_TXBC_TFQS) == 0U)
2719     {
2720       /* Update error code */
2721       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
2722 
2723       return HAL_ERROR;
2724     }
2725 
2726     /* Check that the Tx FIFO/Queue is not full */
2727     if ((hfdcan->Instance->TXFQS & FDCAN_TXFQS_TFQF) != 0U)
2728     {
2729       /* Update error code */
2730       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_FULL;
2731 
2732       return HAL_ERROR;
2733     }
2734     else
2735     {
2736       /* Retrieve the Tx FIFO PutIndex */
2737       PutIndex = ((hfdcan->Instance->TXFQS & FDCAN_TXFQS_TFQPI) >> FDCAN_TXFQS_TFQPI_Pos);
2738 
2739       /* Add the message to the Tx FIFO/Queue */
2740       FDCAN_CopyMessageToRAM(hfdcan, pTxHeader, pTxData, PutIndex);
2741 
2742       /* Activate the corresponding transmission request */
2743       hfdcan->Instance->TXBAR = ((uint32_t)1 << PutIndex);
2744 
2745       /* Store the Latest Tx FIFO/Queue Request Buffer Index */
2746       hfdcan->LatestTxFifoQRequest = ((uint32_t)1 << PutIndex);
2747     }
2748 
2749     /* Return function status */
2750     return HAL_OK;
2751   }
2752   else
2753   {
2754     /* Update error code */
2755     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
2756 
2757     return HAL_ERROR;
2758   }
2759 }
2760 
2761 /**
2762   * @brief  Add a message to a dedicated Tx buffer
2763   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2764   *         the configuration information for the specified FDCAN.
2765   * @param  pTxHeader pointer to a FDCAN_TxHeaderTypeDef structure.
2766   * @param  pTxData pointer to a buffer containing the payload of the Tx frame.
2767   * @param  BufferIndex index of the buffer to be configured.
2768   *         This parameter can be a value of @arg FDCAN_Tx_location.
2769   * @retval HAL status
2770   */
HAL_FDCAN_AddMessageToTxBuffer(FDCAN_HandleTypeDef * hfdcan,FDCAN_TxHeaderTypeDef * pTxHeader,uint8_t * pTxData,uint32_t BufferIndex)2771 HAL_StatusTypeDef HAL_FDCAN_AddMessageToTxBuffer(FDCAN_HandleTypeDef *hfdcan, FDCAN_TxHeaderTypeDef *pTxHeader, uint8_t *pTxData, uint32_t BufferIndex)
2772 {
2773   HAL_FDCAN_StateTypeDef state = hfdcan->State;
2774 
2775   /* Check function parameters */
2776   assert_param(IS_FDCAN_ID_TYPE(pTxHeader->IdType));
2777   if (pTxHeader->IdType == FDCAN_STANDARD_ID)
2778   {
2779     assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->Identifier, 0x7FFU));
2780   }
2781   else /* pTxHeader->IdType == FDCAN_EXTENDED_ID */
2782   {
2783     assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->Identifier, 0x1FFFFFFFU));
2784   }
2785   assert_param(IS_FDCAN_FRAME_TYPE(pTxHeader->TxFrameType));
2786   assert_param(IS_FDCAN_DLC(pTxHeader->DataLength));
2787   assert_param(IS_FDCAN_ESI(pTxHeader->ErrorStateIndicator));
2788   assert_param(IS_FDCAN_BRS(pTxHeader->BitRateSwitch));
2789   assert_param(IS_FDCAN_FDF(pTxHeader->FDFormat));
2790   assert_param(IS_FDCAN_EFC(pTxHeader->TxEventFifoControl));
2791   assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->MessageMarker, 0xFFU));
2792   assert_param(IS_FDCAN_TX_LOCATION(BufferIndex));
2793 
2794   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
2795   {
2796     /* Check that the selected buffer has an allocated area into the RAM */
2797     if (POSITION_VAL(BufferIndex) >= ((hfdcan->Instance->TXBC & FDCAN_TXBC_NDTB) >> FDCAN_TXBC_NDTB_Pos))
2798     {
2799       /* Update error code */
2800       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
2801 
2802       return HAL_ERROR;
2803     }
2804 
2805     /* Check that there is no transmission request pending for the selected buffer */
2806     if ((hfdcan->Instance->TXBRP & BufferIndex) != 0U)
2807     {
2808       /* Update error code */
2809       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PENDING;
2810 
2811       return HAL_ERROR;
2812     }
2813     else
2814     {
2815       /* Add the message to the Tx buffer */
2816       FDCAN_CopyMessageToRAM(hfdcan, pTxHeader, pTxData, POSITION_VAL(BufferIndex));
2817     }
2818 
2819     /* Return function status */
2820     return HAL_OK;
2821   }
2822   else
2823   {
2824     /* Update error code */
2825     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
2826 
2827     return HAL_ERROR;
2828   }
2829 }
2830 
2831 /**
2832   * @brief  Enable transmission request.
2833   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2834   *         the configuration information for the specified FDCAN.
2835   * @param  BufferIndex buffer index.
2836   *         This parameter can be any combination of @arg FDCAN_Tx_location.
2837   * @retval HAL status
2838   */
HAL_FDCAN_EnableTxBufferRequest(FDCAN_HandleTypeDef * hfdcan,uint32_t BufferIndex)2839 HAL_StatusTypeDef HAL_FDCAN_EnableTxBufferRequest(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndex)
2840 {
2841   if (hfdcan->State == HAL_FDCAN_STATE_BUSY)
2842   {
2843     /* Add transmission request */
2844     hfdcan->Instance->TXBAR = BufferIndex;
2845 
2846     /* Return function status */
2847     return HAL_OK;
2848   }
2849   else
2850   {
2851     /* Update error code */
2852     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
2853 
2854     return HAL_ERROR;
2855   }
2856 }
2857 
2858 /**
2859   * @brief  Get Tx buffer index of latest Tx FIFO/Queue request
2860   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2861   *         the configuration information for the specified FDCAN.
2862   * @retval Tx buffer index of last Tx FIFO/Queue request
2863   *          - Any value of @arg FDCAN_Tx_location if Tx request has been submitted.
2864   *          - 0 if no Tx FIFO/Queue request have been submitted.
2865   */
HAL_FDCAN_GetLatestTxFifoQRequestBuffer(FDCAN_HandleTypeDef * hfdcan)2866 uint32_t HAL_FDCAN_GetLatestTxFifoQRequestBuffer(FDCAN_HandleTypeDef *hfdcan)
2867 {
2868   /* Return Last Tx FIFO/Queue Request Buffer */
2869   return hfdcan->LatestTxFifoQRequest;
2870 }
2871 
2872 /**
2873   * @brief  Abort transmission request
2874   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2875   *         the configuration information for the specified FDCAN.
2876   * @param  BufferIndex buffer index.
2877   *         This parameter can be any combination of @arg FDCAN_Tx_location.
2878   * @retval HAL status
2879   */
HAL_FDCAN_AbortTxRequest(FDCAN_HandleTypeDef * hfdcan,uint32_t BufferIndex)2880 HAL_StatusTypeDef HAL_FDCAN_AbortTxRequest(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndex)
2881 {
2882   if (hfdcan->State == HAL_FDCAN_STATE_BUSY)
2883   {
2884     /* Add cancellation request */
2885     hfdcan->Instance->TXBCR = BufferIndex;
2886 
2887     /* Return function status */
2888     return HAL_OK;
2889   }
2890   else
2891   {
2892     /* Update error code */
2893     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
2894 
2895     return HAL_ERROR;
2896   }
2897 }
2898 
2899 /**
2900   * @brief  Get an FDCAN frame from the Rx Buffer/FIFO zone into the message RAM.
2901   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2902   *         the configuration information for the specified FDCAN.
2903   * @param  RxLocation Location of the received message to be read.
2904   *         This parameter can be a value of @arg FDCAN_Rx_location.
2905   * @param  pRxHeader pointer to a FDCAN_RxHeaderTypeDef structure.
2906   * @param  pRxData pointer to a buffer where the payload of the Rx frame will be stored.
2907   * @retval HAL status
2908   */
HAL_FDCAN_GetRxMessage(FDCAN_HandleTypeDef * hfdcan,uint32_t RxLocation,FDCAN_RxHeaderTypeDef * pRxHeader,uint8_t * pRxData)2909 HAL_StatusTypeDef HAL_FDCAN_GetRxMessage(FDCAN_HandleTypeDef *hfdcan, uint32_t RxLocation, FDCAN_RxHeaderTypeDef *pRxHeader, uint8_t *pRxData)
2910 {
2911   uint32_t *RxAddress;
2912   uint8_t  *pData;
2913   uint32_t ByteCounter;
2914   uint32_t GetIndex = 0;
2915   HAL_FDCAN_StateTypeDef state = hfdcan->State;
2916 
2917   if (state == HAL_FDCAN_STATE_BUSY)
2918   {
2919     if (RxLocation == FDCAN_RX_FIFO0) /* Rx element is assigned to the Rx FIFO 0 */
2920     {
2921       /* Check that the Rx FIFO 0 has an allocated area into the RAM */
2922       if ((hfdcan->Instance->RXF0C & FDCAN_RXF0C_F0S) == 0U)
2923       {
2924         /* Update error code */
2925         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
2926 
2927         return HAL_ERROR;
2928       }
2929 
2930       /* Check that the Rx FIFO 0 is not empty */
2931       if ((hfdcan->Instance->RXF0S & FDCAN_RXF0S_F0FL) == 0U)
2932       {
2933         /* Update error code */
2934         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_EMPTY;
2935 
2936         return HAL_ERROR;
2937       }
2938       else
2939       {
2940         /* Check that the Rx FIFO 0 is full & overwrite mode is on*/
2941         if(((hfdcan->Instance->RXF0S & FDCAN_RXF0S_F0F) >> FDCAN_RXF0S_F0F_Pos) == 1U)
2942         {
2943           if(((hfdcan->Instance->RXF0C & FDCAN_RXF0C_F0OM) >> FDCAN_RXF0C_F0OM_Pos) == FDCAN_RX_FIFO_OVERWRITE)
2944           {
2945             /* When overwrite status is on discard first message in FIFO */
2946             GetIndex = 1U;
2947           }
2948         }
2949 
2950         /* Calculate Rx FIFO 0 element index*/
2951         GetIndex += ((hfdcan->Instance->RXF0S & FDCAN_RXF0S_F0GI) >> FDCAN_RXF0S_F0GI_Pos);
2952 
2953         /* Calculate Rx FIFO 0 element address */
2954         RxAddress = (uint32_t *)(hfdcan->msgRam.RxFIFO0SA + (GetIndex * hfdcan->Init.RxFifo0ElmtSize * 4U));
2955       }
2956     }
2957     else if (RxLocation == FDCAN_RX_FIFO1) /* Rx element is assigned to the Rx FIFO 1 */
2958     {
2959       /* Check that the Rx FIFO 1 has an allocated area into the RAM */
2960       if ((hfdcan->Instance->RXF1C & FDCAN_RXF1C_F1S) == 0U)
2961       {
2962         /* Update error code */
2963         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
2964 
2965         return HAL_ERROR;
2966       }
2967 
2968       /* Check that the Rx FIFO 0 is not empty */
2969       if ((hfdcan->Instance->RXF1S & FDCAN_RXF1S_F1FL) == 0U)
2970       {
2971         /* Update error code */
2972         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_EMPTY;
2973 
2974         return HAL_ERROR;
2975       }
2976       else
2977       {
2978         /* Check that the Rx FIFO 1 is full & overwrite mode is on*/
2979         if(((hfdcan->Instance->RXF1S & FDCAN_RXF1S_F1F) >> FDCAN_RXF1S_F1F_Pos) == 1U)
2980         {
2981           if(((hfdcan->Instance->RXF1C & FDCAN_RXF1C_F1OM) >> FDCAN_RXF1C_F1OM_Pos) == FDCAN_RX_FIFO_OVERWRITE)
2982           {
2983             /* When overwrite status is on discard first message in FIFO */
2984             GetIndex = 1U;
2985           }
2986         }
2987 
2988         /* Calculate Rx FIFO 1 element index*/
2989         GetIndex += ((hfdcan->Instance->RXF1S & FDCAN_RXF1S_F1GI) >> FDCAN_RXF1S_F1GI_Pos);
2990 
2991         /* Calculate Rx FIFO 1 element address */
2992         RxAddress = (uint32_t *)(hfdcan->msgRam.RxFIFO1SA + (GetIndex * hfdcan->Init.RxFifo1ElmtSize * 4U));
2993       }
2994     }
2995     else /* Rx element is assigned to a dedicated Rx buffer */
2996     {
2997       /* Check that the selected buffer has an allocated area into the RAM */
2998       if (RxLocation >= hfdcan->Init.RxBuffersNbr)
2999       {
3000         /* Update error code */
3001         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
3002 
3003         return HAL_ERROR;
3004       }
3005       else
3006       {
3007         /* Calculate Rx buffer address */
3008         RxAddress = (uint32_t *)(hfdcan->msgRam.RxBufferSA + (RxLocation * hfdcan->Init.RxBufferSize * 4U));
3009       }
3010     }
3011 
3012     /* Retrieve IdType */
3013     pRxHeader->IdType = *RxAddress & FDCAN_ELEMENT_MASK_XTD;
3014 
3015     /* Retrieve Identifier */
3016     if (pRxHeader->IdType == FDCAN_STANDARD_ID) /* Standard ID element */
3017     {
3018       pRxHeader->Identifier = ((*RxAddress & FDCAN_ELEMENT_MASK_STDID) >> 18);
3019     }
3020     else /* Extended ID element */
3021     {
3022       pRxHeader->Identifier = (*RxAddress & FDCAN_ELEMENT_MASK_EXTID);
3023     }
3024 
3025     /* Retrieve RxFrameType */
3026     pRxHeader->RxFrameType = (*RxAddress & FDCAN_ELEMENT_MASK_RTR);
3027 
3028     /* Retrieve ErrorStateIndicator */
3029     pRxHeader->ErrorStateIndicator = (*RxAddress & FDCAN_ELEMENT_MASK_ESI);
3030 
3031     /* Increment RxAddress pointer to second word of Rx FIFO element */
3032     RxAddress++;
3033 
3034     /* Retrieve RxTimestamp */
3035     pRxHeader->RxTimestamp = (*RxAddress & FDCAN_ELEMENT_MASK_TS);
3036 
3037     /* Retrieve DataLength */
3038     pRxHeader->DataLength = (*RxAddress & FDCAN_ELEMENT_MASK_DLC);
3039 
3040     /* Retrieve BitRateSwitch */
3041     pRxHeader->BitRateSwitch = (*RxAddress & FDCAN_ELEMENT_MASK_BRS);
3042 
3043     /* Retrieve FDFormat */
3044     pRxHeader->FDFormat = (*RxAddress & FDCAN_ELEMENT_MASK_FDF);
3045 
3046     /* Retrieve FilterIndex */
3047     pRxHeader->FilterIndex = ((*RxAddress & FDCAN_ELEMENT_MASK_FIDX) >> 24);
3048 
3049     /* Retrieve NonMatchingFrame */
3050     pRxHeader->IsFilterMatchingFrame = ((*RxAddress & FDCAN_ELEMENT_MASK_ANMF) >> 31);
3051 
3052     /* Increment RxAddress pointer to payload of Rx FIFO element */
3053     RxAddress++;
3054 
3055     /* Retrieve Rx payload */
3056     pData = (uint8_t *)RxAddress;
3057     for (ByteCounter = 0; ByteCounter < DLCtoBytes[pRxHeader->DataLength >> 16]; ByteCounter++)
3058     {
3059       pRxData[ByteCounter] = pData[ByteCounter];
3060     }
3061 
3062     if (RxLocation == FDCAN_RX_FIFO0) /* Rx element is assigned to the Rx FIFO 0 */
3063     {
3064       /* Acknowledge the Rx FIFO 0 that the oldest element is read so that it increments the GetIndex */
3065       hfdcan->Instance->RXF0A = GetIndex;
3066     }
3067     else if (RxLocation == FDCAN_RX_FIFO1) /* Rx element is assigned to the Rx FIFO 1 */
3068     {
3069       /* Acknowledge the Rx FIFO 1 that the oldest element is read so that it increments the GetIndex */
3070       hfdcan->Instance->RXF1A = GetIndex;
3071     }
3072     else /* Rx element is assigned to a dedicated Rx buffer */
3073     {
3074       /* Clear the New Data flag of the current Rx buffer */
3075       if (RxLocation < FDCAN_RX_BUFFER32)
3076       {
3077         hfdcan->Instance->NDAT1 = ((uint32_t)1 << RxLocation);
3078       }
3079       else /* FDCAN_RX_BUFFER32 <= RxLocation <= FDCAN_RX_BUFFER63 */
3080       {
3081         hfdcan->Instance->NDAT2 = ((uint32_t)1 << (RxLocation & 0x1FU));
3082       }
3083     }
3084 
3085     /* Return function status */
3086     return HAL_OK;
3087   }
3088   else
3089   {
3090     /* Update error code */
3091     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
3092 
3093     return HAL_ERROR;
3094   }
3095 }
3096 
3097 /**
3098   * @brief  Get an FDCAN Tx event from the Tx Event FIFO zone into the message RAM.
3099   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3100   *         the configuration information for the specified FDCAN.
3101   * @param  pTxEvent pointer to a FDCAN_TxEventFifoTypeDef structure.
3102   * @retval HAL status
3103   */
HAL_FDCAN_GetTxEvent(FDCAN_HandleTypeDef * hfdcan,FDCAN_TxEventFifoTypeDef * pTxEvent)3104 HAL_StatusTypeDef HAL_FDCAN_GetTxEvent(FDCAN_HandleTypeDef *hfdcan, FDCAN_TxEventFifoTypeDef *pTxEvent)
3105 {
3106   uint32_t *TxEventAddress;
3107   uint32_t GetIndex;
3108   HAL_FDCAN_StateTypeDef state = hfdcan->State;
3109 
3110   /* Check function parameters */
3111   assert_param(IS_FDCAN_MIN_VALUE(hfdcan->Init.TxEventsNbr, 1U));
3112 
3113   if (state == HAL_FDCAN_STATE_BUSY)
3114   {
3115     /* Check that the Tx Event FIFO has an allocated area into the RAM */
3116     if ((hfdcan->Instance->TXEFC & FDCAN_TXEFC_EFS) == 0U)
3117     {
3118       /* Update error code */
3119       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
3120 
3121       return HAL_ERROR;
3122     }
3123 
3124     /* Check that the Tx event FIFO is not empty */
3125     if ((hfdcan->Instance->TXEFS & FDCAN_TXEFS_EFFL) == 0U)
3126     {
3127       /* Update error code */
3128       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_EMPTY;
3129 
3130       return HAL_ERROR;
3131     }
3132 
3133     /* Calculate Tx event FIFO element address */
3134     GetIndex = ((hfdcan->Instance->TXEFS & FDCAN_TXEFS_EFGI) >> FDCAN_TXEFS_EFGI_Pos);
3135     TxEventAddress = (uint32_t *)(hfdcan->msgRam.TxEventFIFOSA + (GetIndex * 2U * 4U));
3136 
3137     /* Retrieve IdType */
3138     pTxEvent->IdType = *TxEventAddress & FDCAN_ELEMENT_MASK_XTD;
3139 
3140     /* Retrieve Identifier */
3141     if (pTxEvent->IdType == FDCAN_STANDARD_ID) /* Standard ID element */
3142     {
3143       pTxEvent->Identifier = ((*TxEventAddress & FDCAN_ELEMENT_MASK_STDID) >> 18U);
3144     }
3145     else /* Extended ID element */
3146     {
3147       pTxEvent->Identifier = (*TxEventAddress & FDCAN_ELEMENT_MASK_EXTID);
3148     }
3149 
3150     /* Retrieve TxFrameType */
3151     pTxEvent->TxFrameType = (*TxEventAddress & FDCAN_ELEMENT_MASK_RTR);
3152 
3153     /* Retrieve ErrorStateIndicator */
3154     pTxEvent->ErrorStateIndicator = (*TxEventAddress & FDCAN_ELEMENT_MASK_ESI);
3155 
3156     /* Increment TxEventAddress pointer to second word of Tx Event FIFO element */
3157     TxEventAddress++;
3158 
3159     /* Retrieve TxTimestamp */
3160     pTxEvent->TxTimestamp = (*TxEventAddress & FDCAN_ELEMENT_MASK_TS);
3161 
3162     /* Retrieve DataLength */
3163     pTxEvent->DataLength = (*TxEventAddress & FDCAN_ELEMENT_MASK_DLC);
3164 
3165     /* Retrieve BitRateSwitch */
3166     pTxEvent->BitRateSwitch = (*TxEventAddress & FDCAN_ELEMENT_MASK_BRS);
3167 
3168     /* Retrieve FDFormat */
3169     pTxEvent->FDFormat = (*TxEventAddress & FDCAN_ELEMENT_MASK_FDF);
3170 
3171     /* Retrieve EventType */
3172     pTxEvent->EventType = (*TxEventAddress & FDCAN_ELEMENT_MASK_ET);
3173 
3174     /* Retrieve MessageMarker */
3175     pTxEvent->MessageMarker = ((*TxEventAddress & FDCAN_ELEMENT_MASK_MM) >> 24);
3176 
3177     /* Acknowledge the Tx Event FIFO that the oldest element is read so that it increments the GetIndex */
3178     hfdcan->Instance->TXEFA = GetIndex;
3179 
3180     /* Return function status */
3181     return HAL_OK;
3182   }
3183   else
3184   {
3185     /* Update error code */
3186     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
3187 
3188     return HAL_ERROR;
3189   }
3190 }
3191 
3192 /**
3193   * @brief  Get high priority message status.
3194   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3195   *         the configuration information for the specified FDCAN.
3196   * @param  HpMsgStatus pointer to an FDCAN_HpMsgStatusTypeDef structure.
3197   * @retval HAL status
3198   */
HAL_FDCAN_GetHighPriorityMessageStatus(FDCAN_HandleTypeDef * hfdcan,FDCAN_HpMsgStatusTypeDef * HpMsgStatus)3199 HAL_StatusTypeDef HAL_FDCAN_GetHighPriorityMessageStatus(FDCAN_HandleTypeDef *hfdcan, FDCAN_HpMsgStatusTypeDef *HpMsgStatus)
3200 {
3201   HpMsgStatus->FilterList = ((hfdcan->Instance->HPMS & FDCAN_HPMS_FLST) >> FDCAN_HPMS_FLST_Pos);
3202   HpMsgStatus->FilterIndex = ((hfdcan->Instance->HPMS & FDCAN_HPMS_FIDX) >> FDCAN_HPMS_FIDX_Pos);
3203   HpMsgStatus->MessageStorage = (hfdcan->Instance->HPMS & FDCAN_HPMS_MSI);
3204   HpMsgStatus->MessageIndex = (hfdcan->Instance->HPMS & FDCAN_HPMS_BIDX);
3205 
3206   /* Return function status */
3207   return HAL_OK;
3208 }
3209 
3210 /**
3211   * @brief  Get protocol status.
3212   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3213   *         the configuration information for the specified FDCAN.
3214   * @param  ProtocolStatus pointer to an FDCAN_ProtocolStatusTypeDef structure.
3215   * @retval HAL status
3216   */
HAL_FDCAN_GetProtocolStatus(FDCAN_HandleTypeDef * hfdcan,FDCAN_ProtocolStatusTypeDef * ProtocolStatus)3217 HAL_StatusTypeDef HAL_FDCAN_GetProtocolStatus(FDCAN_HandleTypeDef *hfdcan, FDCAN_ProtocolStatusTypeDef *ProtocolStatus)
3218 {
3219   uint32_t StatusReg;
3220 
3221   /* Read the protocol status register */
3222   StatusReg = READ_REG(hfdcan->Instance->PSR);
3223 
3224   /* Fill the protocol status structure */
3225   ProtocolStatus->LastErrorCode = (StatusReg & FDCAN_PSR_LEC);
3226   ProtocolStatus->DataLastErrorCode = ((StatusReg & FDCAN_PSR_DLEC) >> FDCAN_PSR_DLEC_Pos);
3227   ProtocolStatus->Activity = (StatusReg & FDCAN_PSR_ACT);
3228   ProtocolStatus->ErrorPassive = ((StatusReg & FDCAN_PSR_EP) >> FDCAN_PSR_EP_Pos);
3229   ProtocolStatus->Warning = ((StatusReg & FDCAN_PSR_EW) >> FDCAN_PSR_EW_Pos);
3230   ProtocolStatus->BusOff = ((StatusReg & FDCAN_PSR_BO) >> FDCAN_PSR_BO_Pos);
3231   ProtocolStatus->RxESIflag = ((StatusReg & FDCAN_PSR_RESI) >> FDCAN_PSR_RESI_Pos);
3232   ProtocolStatus->RxBRSflag = ((StatusReg & FDCAN_PSR_RBRS) >> FDCAN_PSR_RBRS_Pos);
3233   ProtocolStatus->RxFDFflag = ((StatusReg & FDCAN_PSR_REDL) >> FDCAN_PSR_REDL_Pos);
3234   ProtocolStatus->ProtocolException = ((StatusReg & FDCAN_PSR_PXE) >> FDCAN_PSR_PXE_Pos);
3235   ProtocolStatus->TDCvalue = ((StatusReg & FDCAN_PSR_TDCV) >> FDCAN_PSR_TDCV_Pos);
3236 
3237   /* Return function status */
3238   return HAL_OK;
3239 }
3240 
3241 /**
3242   * @brief  Get error counter values.
3243   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3244   *         the configuration information for the specified FDCAN.
3245   * @param  ErrorCounters pointer to an FDCAN_ErrorCountersTypeDef structure.
3246   * @retval HAL status
3247   */
HAL_FDCAN_GetErrorCounters(FDCAN_HandleTypeDef * hfdcan,FDCAN_ErrorCountersTypeDef * ErrorCounters)3248 HAL_StatusTypeDef HAL_FDCAN_GetErrorCounters(FDCAN_HandleTypeDef *hfdcan, FDCAN_ErrorCountersTypeDef *ErrorCounters)
3249 {
3250   uint32_t CountersReg;
3251 
3252   /* Read the error counters register */
3253   CountersReg = READ_REG(hfdcan->Instance->ECR);
3254 
3255   /* Fill the error counters structure */
3256   ErrorCounters->TxErrorCnt = ((CountersReg & FDCAN_ECR_TEC) >> FDCAN_ECR_TEC_Pos);
3257   ErrorCounters->RxErrorCnt = ((CountersReg & FDCAN_ECR_REC) >> FDCAN_ECR_REC_Pos);
3258   ErrorCounters->RxErrorPassive = ((CountersReg & FDCAN_ECR_RP) >> FDCAN_ECR_RP_Pos);
3259   ErrorCounters->ErrorLogging = ((CountersReg & FDCAN_ECR_CEL) >> FDCAN_ECR_CEL_Pos);
3260 
3261   /* Return function status */
3262   return HAL_OK;
3263 }
3264 
3265 /**
3266   * @brief  Check if a new message is received in the selected Rx buffer.
3267   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3268   *         the configuration information for the specified FDCAN.
3269   * @param  RxBufferIndex Rx buffer index.
3270   *         This parameter must be a number between 0 and 63.
3271   * @retval Status
3272   *          - 0 : No new message on RxBufferIndex.
3273   *          - 1 : New message received on RxBufferIndex.
3274   */
HAL_FDCAN_IsRxBufferMessageAvailable(FDCAN_HandleTypeDef * hfdcan,uint32_t RxBufferIndex)3275 uint32_t HAL_FDCAN_IsRxBufferMessageAvailable(FDCAN_HandleTypeDef *hfdcan, uint32_t RxBufferIndex)
3276 {
3277   /* Check function parameters */
3278   assert_param(IS_FDCAN_MAX_VALUE(RxBufferIndex, 63U));
3279   uint32_t NewData1 = hfdcan->Instance->NDAT1;
3280   uint32_t NewData2 = hfdcan->Instance->NDAT2;
3281 
3282   /* Check new message reception on the selected buffer */
3283   if (((RxBufferIndex < 32U) && ((NewData1 & (uint32_t)((uint32_t)1 << RxBufferIndex)) == 0U)) ||
3284       ((RxBufferIndex >= 32U) && ((NewData2 & (uint32_t)((uint32_t)1 << (RxBufferIndex & 0x1FU))) == 0U)))
3285   {
3286     return 0;
3287   }
3288 
3289   /* Clear the New Data flag of the current Rx buffer */
3290   if (RxBufferIndex < 32U)
3291   {
3292     hfdcan->Instance->NDAT1 = ((uint32_t)1 << RxBufferIndex);
3293   }
3294   else /* 32 <= RxBufferIndex <= 63 */
3295   {
3296     hfdcan->Instance->NDAT2 = ((uint32_t)1 << (RxBufferIndex & 0x1FU));
3297   }
3298 
3299   return 1;
3300 }
3301 
3302 /**
3303   * @brief  Check if a transmission request is pending on the selected Tx buffer.
3304   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3305   *         the configuration information for the specified FDCAN.
3306   * @param  TxBufferIndex Tx buffer index.
3307   *         This parameter can be any combination of @arg FDCAN_Tx_location.
3308   * @retval Status
3309   *          - 0 : No pending transmission request on TxBufferIndex.
3310   *          - 1 : Pending transmission request on TxBufferIndex.
3311   */
HAL_FDCAN_IsTxBufferMessagePending(FDCAN_HandleTypeDef * hfdcan,uint32_t TxBufferIndex)3312 uint32_t HAL_FDCAN_IsTxBufferMessagePending(FDCAN_HandleTypeDef *hfdcan, uint32_t TxBufferIndex)
3313 {
3314   /* Check pending transmission request on the selected buffer */
3315   if ((hfdcan->Instance->TXBRP & TxBufferIndex) == 0U)
3316   {
3317     return 0;
3318   }
3319   return 1;
3320 }
3321 
3322 /**
3323   * @brief  Return Rx FIFO fill level.
3324   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3325   *         the configuration information for the specified FDCAN.
3326   * @param  RxFifo Rx FIFO.
3327   *         This parameter can be one of the following values:
3328   *           @arg FDCAN_RX_FIFO0: Rx FIFO 0
3329   *           @arg FDCAN_RX_FIFO1: Rx FIFO 1
3330   * @retval Level Rx FIFO fill level.
3331   */
HAL_FDCAN_GetRxFifoFillLevel(FDCAN_HandleTypeDef * hfdcan,uint32_t RxFifo)3332 uint32_t HAL_FDCAN_GetRxFifoFillLevel(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo)
3333 {
3334   uint32_t FillLevel;
3335 
3336   /* Check function parameters */
3337   assert_param(IS_FDCAN_RX_FIFO(RxFifo));
3338 
3339   if (RxFifo == FDCAN_RX_FIFO0)
3340   {
3341     FillLevel = hfdcan->Instance->RXF0S & FDCAN_RXF0S_F0FL;
3342   }
3343   else /* RxFifo == FDCAN_RX_FIFO1 */
3344   {
3345     FillLevel = hfdcan->Instance->RXF1S & FDCAN_RXF1S_F1FL;
3346   }
3347 
3348   /* Return Rx FIFO fill level */
3349   return FillLevel;
3350 }
3351 
3352 /**
3353   * @brief  Return Tx FIFO free level: number of consecutive free Tx FIFO
3354   *         elements starting from Tx FIFO GetIndex.
3355   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3356   *         the configuration information for the specified FDCAN.
3357   * @retval Level Tx FIFO free level.
3358   */
HAL_FDCAN_GetTxFifoFreeLevel(FDCAN_HandleTypeDef * hfdcan)3359 uint32_t HAL_FDCAN_GetTxFifoFreeLevel(FDCAN_HandleTypeDef *hfdcan)
3360 {
3361   uint32_t FreeLevel;
3362 
3363   FreeLevel = hfdcan->Instance->TXFQS & FDCAN_TXFQS_TFFL;
3364 
3365   /* Return Tx FIFO free level */
3366   return FreeLevel;
3367 }
3368 
3369 /**
3370   * @brief  Check if the FDCAN peripheral entered Restricted Operation Mode.
3371   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3372   *         the configuration information for the specified FDCAN.
3373   * @retval Status
3374   *          - 0 : Normal FDCAN operation.
3375   *          - 1 : Restricted Operation Mode active.
3376   */
HAL_FDCAN_IsRestrictedOperationMode(FDCAN_HandleTypeDef * hfdcan)3377 uint32_t HAL_FDCAN_IsRestrictedOperationMode(FDCAN_HandleTypeDef *hfdcan)
3378 {
3379   uint32_t OperationMode;
3380 
3381   /* Get Operation Mode */
3382   OperationMode = ((hfdcan->Instance->CCCR & FDCAN_CCCR_ASM) >> FDCAN_CCCR_ASM_Pos);
3383 
3384   return OperationMode;
3385 }
3386 
3387 /**
3388   * @brief  Exit Restricted Operation Mode.
3389   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3390   *         the configuration information for the specified FDCAN.
3391   * @retval HAL status
3392   */
HAL_FDCAN_ExitRestrictedOperationMode(FDCAN_HandleTypeDef * hfdcan)3393 HAL_StatusTypeDef HAL_FDCAN_ExitRestrictedOperationMode(FDCAN_HandleTypeDef *hfdcan)
3394 {
3395   HAL_FDCAN_StateTypeDef state = hfdcan->State;
3396 
3397   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3398   {
3399     /* Exit Restricted Operation mode */
3400     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_ASM);
3401 
3402     /* Return function status */
3403     return HAL_OK;
3404   }
3405   else
3406   {
3407     /* Update error code */
3408     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3409 
3410     return HAL_ERROR;
3411   }
3412 }
3413 
3414 /**
3415   * @}
3416   */
3417 
3418 /** @defgroup FDCAN_Exported_Functions_Group4 TT Configuration and control functions
3419  *  @brief    TT Configuration and control functions
3420  *
3421 @verbatim
3422   ==============================================================================
3423               ##### TT Configuration and control functions #####
3424   ==============================================================================
3425     [..]  This section provides functions allowing to:
3426       (+) HAL_FDCAN_TT_ConfigOperation                  : Initialize TT operation parameters
3427       (+) HAL_FDCAN_TT_ConfigReferenceMessage           : Configure the reference message
3428       (+) HAL_FDCAN_TT_ConfigTrigger                    : Configure the FDCAN trigger
3429       (+) HAL_FDCAN_TT_SetGlobalTime                    : Schedule global time adjustment
3430       (+) HAL_FDCAN_TT_SetClockSynchronization          : Schedule TUR numerator update
3431       (+) HAL_FDCAN_TT_ConfigStopWatch                  : Configure stop watch source and polarity
3432       (+) HAL_FDCAN_TT_ConfigRegisterTimeMark           : Configure register time mark pulse generation
3433         (+) HAL_FDCAN_TT_EnableRegisterTimeMarkPulse      : Enable register time mark pulse generation
3434         (+) HAL_FDCAN_TT_DisableRegisterTimeMarkPulse     : Disable register time mark pulse generation
3435       (+) HAL_FDCAN_TT_EnableTriggerTimeMarkPulse       : Enable trigger time mark pulse generation
3436       (+) HAL_FDCAN_TT_DisableTriggerTimeMarkPulse      : Disable trigger time mark pulse generation
3437       (+) HAL_FDCAN_TT_EnableHardwareGapControl         : Enable gap control by input pin fdcan1_evt
3438       (+) HAL_FDCAN_TT_DisableHardwareGapControl        : Disable gap control by input pin fdcan1_evt
3439       (+) HAL_FDCAN_TT_EnableTimeMarkGapControl         : Enable gap control (finish only) by register time mark interrupt
3440       (+) HAL_FDCAN_TT_DisableTimeMarkGapControl        : Disable gap control by register time mark interrupt
3441       (+) HAL_FDCAN_TT_SetNextIsGap                     : Transmit next reference message with Next_is_Gap = "1"
3442       (+) HAL_FDCAN_TT_SetEndOfGap                      : Finish a Gap by requesting start of reference message
3443       (+) HAL_FDCAN_TT_ConfigExternalSyncPhase          : Configure target phase used for external synchronization
3444         (+) HAL_FDCAN_TT_EnableExternalSynchronization    : Synchronize the phase of the FDCAN schedule to an external schedule
3445         (+) HAL_FDCAN_TT_DisableExternalSynchronization   : Disable external schedule synchronization
3446       (+) HAL_FDCAN_TT_GetOperationStatus               : Get TT operation status
3447 
3448 @endverbatim
3449   * @{
3450   */
3451 
3452 /**
3453   * @brief  Initialize TT operation parameters.
3454   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3455   *         the configuration information for the specified FDCAN.
3456   * @param  pTTParams pointer to a FDCAN_TT_ConfigTypeDef structure.
3457   * @retval HAL status
3458   */
HAL_FDCAN_TT_ConfigOperation(FDCAN_HandleTypeDef * hfdcan,FDCAN_TT_ConfigTypeDef * pTTParams)3459 HAL_StatusTypeDef HAL_FDCAN_TT_ConfigOperation(FDCAN_HandleTypeDef *hfdcan, FDCAN_TT_ConfigTypeDef *pTTParams)
3460 {
3461   uint32_t tickstart;
3462   uint32_t RAMcounter;
3463   uint32_t StartAddress;
3464 
3465   /* Check function parameters */
3466   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3467   assert_param(IS_FDCAN_TT_TUR_NUMERATOR(pTTParams->TURNumerator));
3468   assert_param(IS_FDCAN_TT_TUR_DENOMINATOR(pTTParams->TURDenominator));
3469   assert_param(IS_FDCAN_TT_TIME_MASTER(pTTParams->TimeMaster));
3470   assert_param(IS_FDCAN_MAX_VALUE(pTTParams->SyncDevLimit, 7U));
3471   assert_param(IS_FDCAN_MAX_VALUE(pTTParams->InitRefTrigOffset, 127U));
3472   assert_param(IS_FDCAN_MAX_VALUE(pTTParams->TriggerMemoryNbr, 64U));
3473   assert_param(IS_FDCAN_TT_CYCLE_START_SYNC(pTTParams->CycleStartSync));
3474   assert_param(IS_FDCAN_TT_STOP_WATCH_TRIGGER(pTTParams->StopWatchTrigSel));
3475   assert_param(IS_FDCAN_TT_EVENT_TRIGGER(pTTParams->EventTrigSel));
3476   if (pTTParams->TimeMaster == FDCAN_TT_POTENTIAL_MASTER)
3477   {
3478     assert_param(IS_FDCAN_TT_BASIC_CYCLES_NUMBER(pTTParams->BasicCyclesNbr));
3479   }
3480   if (pTTParams->OperationMode != FDCAN_TT_COMMUNICATION_LEVEL0)
3481   {
3482     assert_param(IS_FDCAN_TT_OPERATION(pTTParams->GapEnable));
3483     assert_param(IS_FDCAN_MAX_VALUE(pTTParams->AppWdgLimit, 255U));
3484     assert_param(IS_FDCAN_TT_EVENT_TRIGGER_POLARITY(pTTParams->EvtTrigPolarity));
3485     assert_param(IS_FDCAN_TT_TX_ENABLE_WINDOW(pTTParams->TxEnableWindow));
3486     assert_param(IS_FDCAN_MAX_VALUE(pTTParams->ExpTxTrigNbr, 4095U));
3487   }
3488   if (pTTParams->OperationMode != FDCAN_TT_COMMUNICATION_LEVEL1)
3489   {
3490     assert_param(IS_FDCAN_TT_TUR_LEVEL_0_2(pTTParams->TURNumerator, pTTParams->TURDenominator));
3491     assert_param(IS_FDCAN_TT_EXTERNAL_CLK_SYNC(pTTParams->ExternalClkSync));
3492     assert_param(IS_FDCAN_TT_GLOBAL_TIME_FILTERING(pTTParams->GlobalTimeFilter));
3493     assert_param(IS_FDCAN_TT_AUTO_CLK_CALIBRATION(pTTParams->ClockCalibration));
3494   }
3495   else
3496   {
3497     assert_param(IS_FDCAN_TT_TUR_LEVEL_1(pTTParams->TURNumerator, pTTParams->TURDenominator));
3498   }
3499 
3500   if (hfdcan->State == HAL_FDCAN_STATE_READY)
3501   {
3502     /* Stop local time in order to enable write access to the other bits of TURCF register */
3503     CLEAR_BIT(hfdcan->ttcan->TURCF, FDCAN_TURCF_ELT);
3504 
3505     /* Get tick */
3506     tickstart = HAL_GetTick();
3507 
3508     /* Wait until the ELT bit into TURCF register is reset */
3509     while ((hfdcan->ttcan->TURCF & FDCAN_TURCF_ELT) != 0U)
3510     {
3511       /* Check for the Timeout */
3512       if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE)
3513       {
3514         /* Update error code */
3515         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3516 
3517         /* Change FDCAN state */
3518         hfdcan->State = HAL_FDCAN_STATE_ERROR;
3519 
3520         return HAL_ERROR;
3521       }
3522     }
3523 
3524     /* Configure TUR (Time Unit Ratio) */
3525     MODIFY_REG(hfdcan->ttcan->TURCF,
3526                (FDCAN_TURCF_NCL | FDCAN_TURCF_DC),
3527                (((pTTParams->TURNumerator - 0x10000U) << FDCAN_TURCF_NCL_Pos) | (pTTParams->TURDenominator << FDCAN_TURCF_DC_Pos)));
3528 
3529     /* Enable local time */
3530     SET_BIT(hfdcan->ttcan->TURCF, FDCAN_TURCF_ELT);
3531 
3532     /* Configure TT operation */
3533     MODIFY_REG(hfdcan->ttcan->TTOCF,
3534                (FDCAN_TTOCF_OM | FDCAN_TTOCF_TM | FDCAN_TTOCF_LDSDL | FDCAN_TTOCF_IRTO),
3535                (pTTParams->OperationMode                           | \
3536                 pTTParams->TimeMaster                              | \
3537                 (pTTParams->SyncDevLimit << FDCAN_TTOCF_LDSDL_Pos) | \
3538                 (pTTParams->InitRefTrigOffset << FDCAN_TTOCF_IRTO_Pos)));
3539     if (pTTParams->OperationMode != FDCAN_TT_COMMUNICATION_LEVEL0)
3540     {
3541       MODIFY_REG(hfdcan->ttcan->TTOCF,
3542                  (FDCAN_TTOCF_GEN | FDCAN_TTOCF_AWL | FDCAN_TTOCF_EVTP),
3543                  (pTTParams->GapEnable                            | \
3544                   (pTTParams->AppWdgLimit << FDCAN_TTOCF_AWL_Pos) | \
3545                   pTTParams->EvtTrigPolarity));
3546     }
3547     if (pTTParams->OperationMode != FDCAN_TT_COMMUNICATION_LEVEL1)
3548     {
3549       MODIFY_REG(hfdcan->ttcan->TTOCF,
3550                  (FDCAN_TTOCF_EECS | FDCAN_TTOCF_EGTF | FDCAN_TTOCF_ECC),
3551                  (pTTParams->ExternalClkSync  | \
3552                   pTTParams->GlobalTimeFilter | \
3553                   pTTParams->ClockCalibration));
3554     }
3555 
3556     /* Configure system matrix limits */
3557     MODIFY_REG(hfdcan->ttcan->TTMLM, FDCAN_TTMLM_CSS, pTTParams->CycleStartSync);
3558     if (pTTParams->OperationMode != FDCAN_TT_COMMUNICATION_LEVEL0)
3559     {
3560       MODIFY_REG(hfdcan->ttcan->TTMLM,
3561                  (FDCAN_TTMLM_TXEW | FDCAN_TTMLM_ENTT),
3562                  (((pTTParams->TxEnableWindow - 1U) << FDCAN_TTMLM_TXEW_Pos) | (pTTParams->ExpTxTrigNbr << FDCAN_TTMLM_ENTT_Pos)));
3563     }
3564     if (pTTParams->TimeMaster == FDCAN_TT_POTENTIAL_MASTER)
3565     {
3566       MODIFY_REG(hfdcan->ttcan->TTMLM, FDCAN_TTMLM_CCM, pTTParams->BasicCyclesNbr);
3567     }
3568 
3569     /* Configure input triggers: Stop watch and Event */
3570     MODIFY_REG(hfdcan->ttcan->TTTS,
3571                (FDCAN_TTTS_SWTSEL | FDCAN_TTTS_EVTSEL),
3572                (pTTParams->StopWatchTrigSel | pTTParams->EventTrigSel));
3573 
3574     /* Configure trigger memory start address */
3575     StartAddress = (hfdcan->msgRam.EndAddress - SRAMCAN_BASE) / 4U;
3576     MODIFY_REG(hfdcan->ttcan->TTTMC, FDCAN_TTTMC_TMSA, (StartAddress << FDCAN_TTTMC_TMSA_Pos));
3577 
3578     /* Trigger memory elements number */
3579     MODIFY_REG(hfdcan->ttcan->TTTMC, FDCAN_TTTMC_TME, (pTTParams->TriggerMemoryNbr << FDCAN_TTTMC_TME_Pos));
3580 
3581     /* Recalculate End Address */
3582     hfdcan->msgRam.TTMemorySA = hfdcan->msgRam.EndAddress;
3583     hfdcan->msgRam.EndAddress = hfdcan->msgRam.TTMemorySA + (pTTParams->TriggerMemoryNbr * 2U * 4U);
3584 
3585     if (hfdcan->msgRam.EndAddress > FDCAN_MESSAGE_RAM_END_ADDRESS) /* Last address of the Message RAM */
3586     {
3587       /* Update error code.
3588          Message RAM overflow */
3589       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
3590 
3591       return HAL_ERROR;
3592     }
3593     else
3594     {
3595       /* Flush the allocated Message RAM area */
3596       for (RAMcounter = hfdcan->msgRam.TTMemorySA; RAMcounter < hfdcan->msgRam.EndAddress; RAMcounter += 4U)
3597       {
3598         *(uint32_t *)(RAMcounter) = 0x00000000;
3599       }
3600     }
3601 
3602     /* Return function status */
3603     return HAL_OK;
3604   }
3605   else
3606   {
3607     /* Update error code */
3608     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
3609 
3610     return HAL_ERROR;
3611   }
3612 }
3613 
3614 /**
3615   * @brief  Configure the reference message.
3616   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3617   *         the configuration information for the specified FDCAN.
3618   * @param  IdType Identifier Type.
3619   *         This parameter can be a value of @arg FDCAN_id_type.
3620   * @param  Identifier Reference Identifier.
3621   *         This parameter must be a number between:
3622   *           - 0 and 0x7FF, if IdType is FDCAN_STANDARD_ID
3623   *           - 0 and 0x1FFFFFFF, if IdType is FDCAN_EXTENDED_ID
3624   * @param  Payload Enable or disable the additional payload.
3625   *         This parameter can be a value of @arg FDCAN_TT_Reference_Message_Payload.
3626   *         This parameter is ignored in case of time slaves.
3627   *         If this parameter is set to FDCAN_TT_REF_MESSAGE_ADD_PAYLOAD, the
3628   *         following elements are taken from Tx Buffer 0:
3629   *          - MessageMarker
3630   *          - TxEventFifoControl
3631   *          - DataLength
3632   *          - Data Bytes (payload):
3633   *             - bytes 2-8, for Level 1
3634   *             - bytes 5-8, for Level 0 and Level 2
3635   * @retval HAL status
3636   */
HAL_FDCAN_TT_ConfigReferenceMessage(FDCAN_HandleTypeDef * hfdcan,uint32_t IdType,uint32_t Identifier,uint32_t Payload)3637 HAL_StatusTypeDef HAL_FDCAN_TT_ConfigReferenceMessage(FDCAN_HandleTypeDef *hfdcan, uint32_t IdType, uint32_t Identifier, uint32_t Payload)
3638 {
3639   /* Check function parameters */
3640   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3641   assert_param(IS_FDCAN_ID_TYPE(IdType));
3642   if (IdType == FDCAN_STANDARD_ID)
3643   {
3644     assert_param(IS_FDCAN_MAX_VALUE(Identifier, 0x7FFU));
3645   }
3646   else /* IdType == FDCAN_EXTENDED_ID */
3647   {
3648     assert_param(IS_FDCAN_MAX_VALUE(Identifier, 0x1FFFFFFFU));
3649   }
3650   assert_param(IS_FDCAN_TT_REFERENCE_MESSAGE_PAYLOAD(Payload));
3651 
3652   if (hfdcan->State == HAL_FDCAN_STATE_READY)
3653   {
3654     /* Configure reference message identifier type, identifier and payload */
3655     if (IdType == FDCAN_EXTENDED_ID)
3656     {
3657       MODIFY_REG(hfdcan->ttcan->TTRMC, (FDCAN_TTRMC_RID | FDCAN_TTRMC_XTD | FDCAN_TTRMC_RMPS), (Payload | IdType | Identifier));
3658     }
3659     else /* IdType == FDCAN_STANDARD_ID */
3660     {
3661       MODIFY_REG(hfdcan->ttcan->TTRMC, (FDCAN_TTRMC_RID | FDCAN_TTRMC_XTD | FDCAN_TTRMC_RMPS), (Payload | IdType | (Identifier << 18)));
3662     }
3663 
3664     /* Return function status */
3665     return HAL_OK;
3666   }
3667   else
3668   {
3669     /* Update error code */
3670     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
3671 
3672     return HAL_ERROR;
3673   }
3674 }
3675 
3676 /**
3677   * @brief  Configure the FDCAN trigger according to the specified
3678   *         parameters in the FDCAN_TriggerTypeDef structure.
3679   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3680   *         the configuration information for the specified FDCAN.
3681   * @param  sTriggerConfig pointer to an FDCAN_TriggerTypeDef structure that
3682   *         contains the trigger configuration information
3683   * @retval HAL status
3684   */
HAL_FDCAN_TT_ConfigTrigger(FDCAN_HandleTypeDef * hfdcan,FDCAN_TriggerTypeDef * sTriggerConfig)3685 HAL_StatusTypeDef HAL_FDCAN_TT_ConfigTrigger(FDCAN_HandleTypeDef *hfdcan, FDCAN_TriggerTypeDef *sTriggerConfig)
3686 {
3687   uint32_t CycleCode;
3688   uint32_t MessageNumber;
3689   uint32_t TriggerElementW1;
3690   uint32_t TriggerElementW2;
3691   uint32_t *TriggerAddress;
3692 
3693   /* Check function parameters */
3694   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3695   assert_param(IS_FDCAN_MAX_VALUE(sTriggerConfig->TriggerIndex, 63U));
3696   assert_param(IS_FDCAN_MAX_VALUE(sTriggerConfig->TimeMark, 0xFFFFU));
3697   assert_param(IS_FDCAN_TT_REPEAT_FACTOR(sTriggerConfig->RepeatFactor));
3698   if (sTriggerConfig->RepeatFactor != FDCAN_TT_REPEAT_EVERY_CYCLE)
3699   {
3700     assert_param(IS_FDCAN_MAX_VALUE(sTriggerConfig->StartCycle, (sTriggerConfig->RepeatFactor - 1U)));
3701   }
3702   assert_param(IS_FDCAN_TT_TM_EVENT_INTERNAL(sTriggerConfig->TmEventInt));
3703   assert_param(IS_FDCAN_TT_TM_EVENT_EXTERNAL(sTriggerConfig->TmEventExt));
3704   assert_param(IS_FDCAN_TT_TRIGGER_TYPE(sTriggerConfig->TriggerType));
3705   assert_param(IS_FDCAN_ID_TYPE(sTriggerConfig->FilterType));
3706   if ((sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_SINGLE) ||
3707       (sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_CONTINUOUS) ||
3708       (sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_ARBITRATION) ||
3709       (sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_MERGED))
3710   {
3711     assert_param(IS_FDCAN_TX_LOCATION(sTriggerConfig->TxBufferIndex));
3712   }
3713   if (sTriggerConfig->TriggerType == FDCAN_TT_RX_TRIGGER)
3714   {
3715     if (sTriggerConfig->FilterType == FDCAN_STANDARD_ID)
3716     {
3717       assert_param(IS_FDCAN_MAX_VALUE(sTriggerConfig->FilterIndex, 63U));
3718     }
3719     else /* sTriggerConfig->FilterType == FDCAN_EXTENDED_ID */
3720     {
3721       assert_param(IS_FDCAN_MAX_VALUE(sTriggerConfig->FilterIndex, 127U));
3722     }
3723   }
3724 
3725   if (hfdcan->State == HAL_FDCAN_STATE_READY)
3726   {
3727     /* Calculate cycle code */
3728     if (sTriggerConfig->RepeatFactor == FDCAN_TT_REPEAT_EVERY_CYCLE)
3729     {
3730       CycleCode = FDCAN_TT_REPEAT_EVERY_CYCLE;
3731     }
3732     else /* sTriggerConfig->RepeatFactor != FDCAN_TT_REPEAT_EVERY_CYCLE */
3733     {
3734       CycleCode = sTriggerConfig->RepeatFactor + sTriggerConfig->StartCycle;
3735     }
3736 
3737     /* Build first word of trigger element */
3738     TriggerElementW1 = ((sTriggerConfig->TimeMark << 16) | \
3739                         (CycleCode << 8)                 | \
3740                         sTriggerConfig->TmEventInt       | \
3741                         sTriggerConfig->TmEventExt       | \
3742                         sTriggerConfig->TriggerType);
3743 
3744     /* Select message number depending on trigger type (transmission or reception) */
3745     if (sTriggerConfig->TriggerType == FDCAN_TT_RX_TRIGGER)
3746     {
3747       MessageNumber = sTriggerConfig->FilterIndex;
3748     }
3749     else if ((sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_SINGLE) ||
3750              (sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_CONTINUOUS) ||
3751              (sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_ARBITRATION) ||
3752              (sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_MERGED))
3753     {
3754       MessageNumber = POSITION_VAL(sTriggerConfig->TxBufferIndex);
3755     }
3756     else
3757     {
3758       MessageNumber = 0U;
3759     }
3760 
3761     /* Build second word of trigger element */
3762     TriggerElementW2 = ((sTriggerConfig->FilterType >> 7) | (MessageNumber << 16));
3763 
3764     /* Calculate trigger address */
3765     TriggerAddress = (uint32_t *)(hfdcan->msgRam.TTMemorySA + (sTriggerConfig->TriggerIndex * 4U * 2U));
3766 
3767     /* Write trigger element to the message RAM */
3768     *TriggerAddress = TriggerElementW1;
3769     TriggerAddress++;
3770     *TriggerAddress = TriggerElementW2;
3771 
3772     /* Return function status */
3773     return HAL_OK;
3774   }
3775   else
3776   {
3777     /* Update error code */
3778     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
3779 
3780     return HAL_ERROR;
3781   }
3782 }
3783 
3784 /**
3785   * @brief  Schedule global time adjustment for the next reference message.
3786   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3787   *         the configuration information for the specified FDCAN.
3788   * @param  TimePreset time preset value.
3789   *         This parameter must be a number between:
3790   *           - 0x0000 and 0x7FFF, Next_Master_Ref_Mark = Current_Master_Ref_Mark + TimePreset
3791   *           or
3792   *           - 0x8001 and 0xFFFF, Next_Master_Ref_Mark = Current_Master_Ref_Mark - (0x10000 - TimePreset)
3793   * @retval HAL status
3794   */
HAL_FDCAN_TT_SetGlobalTime(FDCAN_HandleTypeDef * hfdcan,uint32_t TimePreset)3795 HAL_StatusTypeDef HAL_FDCAN_TT_SetGlobalTime(FDCAN_HandleTypeDef *hfdcan, uint32_t TimePreset)
3796 {
3797   uint32_t Counter = 0U;
3798   HAL_FDCAN_StateTypeDef state = hfdcan->State;
3799 
3800   /* Check function parameters */
3801   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3802   assert_param(IS_FDCAN_TT_TIME_PRESET(TimePreset));
3803 
3804   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3805   {
3806     /* Check that the external clock synchronization is enabled */
3807     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_EECS) != FDCAN_TTOCF_EECS)
3808     {
3809       /* Update error code */
3810       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
3811 
3812       return HAL_ERROR;
3813     }
3814 
3815     /* Check that no global time preset is pending */
3816     if ((hfdcan->ttcan->TTOST & FDCAN_TTOST_WGTD) == FDCAN_TTOST_WGTD)
3817     {
3818       /* Update error code */
3819       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PENDING;
3820 
3821       return HAL_ERROR;
3822     }
3823 
3824     /* Configure time preset */
3825     MODIFY_REG(hfdcan->ttcan->TTGTP, FDCAN_TTGTP_TP, (TimePreset << FDCAN_TTGTP_TP_Pos));
3826 
3827     /* Wait until the LCKC bit into TTOCN register is reset */
3828     while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
3829     {
3830       /* Check for the Timeout */
3831       if (Counter > FDCAN_TIMEOUT_COUNT)
3832       {
3833         /* Update error code */
3834         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3835 
3836         /* Change FDCAN state */
3837         hfdcan->State = HAL_FDCAN_STATE_ERROR;
3838 
3839         return HAL_ERROR;
3840       }
3841 
3842       /* Increment counter */
3843       Counter++;
3844     }
3845 
3846     /* Schedule time preset to take effect by the next reference message */
3847     SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_SGT);
3848 
3849     /* Return function status */
3850     return HAL_OK;
3851   }
3852   else
3853   {
3854     /* Update error code */
3855     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3856 
3857     return HAL_ERROR;
3858   }
3859 }
3860 
3861 /**
3862   * @brief  Schedule TUR numerator update for the next reference message.
3863   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3864   *         the configuration information for the specified FDCAN.
3865   * @param  NewTURNumerator new value of the TUR numerator.
3866   *         This parameter must be a number between 0x10000 and 0x1FFFF.
3867   * @retval HAL status
3868   */
HAL_FDCAN_TT_SetClockSynchronization(FDCAN_HandleTypeDef * hfdcan,uint32_t NewTURNumerator)3869 HAL_StatusTypeDef HAL_FDCAN_TT_SetClockSynchronization(FDCAN_HandleTypeDef *hfdcan, uint32_t NewTURNumerator)
3870 {
3871   uint32_t Counter = 0U;
3872   HAL_FDCAN_StateTypeDef state = hfdcan->State;
3873 
3874   /* Check function parameters */
3875   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3876   assert_param(IS_FDCAN_TT_TUR_NUMERATOR(NewTURNumerator));
3877 
3878   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3879   {
3880     /* Check that the external clock synchronization is enabled */
3881     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_EECS) != FDCAN_TTOCF_EECS)
3882     {
3883       /* Update error code */
3884       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
3885 
3886       return HAL_ERROR;
3887     }
3888 
3889     /* Check that no external clock synchronization is pending */
3890     if ((hfdcan->ttcan->TTOST & FDCAN_TTOST_WECS) == FDCAN_TTOST_WECS)
3891     {
3892       /* Update error code */
3893       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PENDING;
3894 
3895       return HAL_ERROR;
3896     }
3897 
3898     /* Configure new TUR numerator */
3899     MODIFY_REG(hfdcan->ttcan->TURCF, FDCAN_TURCF_NCL, (NewTURNumerator - 0x10000U));
3900 
3901     /* Wait until the LCKC bit into TTOCN register is reset */
3902     while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
3903     {
3904       /* Check for the Timeout */
3905       if (Counter > FDCAN_TIMEOUT_COUNT)
3906       {
3907         /* Update error code */
3908         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3909 
3910         /* Change FDCAN state */
3911         hfdcan->State = HAL_FDCAN_STATE_ERROR;
3912 
3913         return HAL_ERROR;
3914       }
3915 
3916       /* Increment counter */
3917       Counter++;
3918     }
3919 
3920     /* Schedule TUR numerator update by the next reference message */
3921     SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_ECS);
3922 
3923     /* Return function status */
3924     return HAL_OK;
3925   }
3926   else
3927   {
3928     /* Update error code */
3929     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3930 
3931     return HAL_ERROR;
3932   }
3933 }
3934 
3935 /**
3936   * @brief  Configure stop watch source and polarity.
3937   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3938   *         the configuration information for the specified FDCAN.
3939   * @param  Source stop watch source.
3940   *         This parameter can be a value of @arg FDCAN_TT_stop_watch_source.
3941   * @param  Polarity stop watch polarity.
3942   *         This parameter can be a value of @arg FDCAN_TT_stop_watch_polarity.
3943   * @retval HAL status
3944   */
HAL_FDCAN_TT_ConfigStopWatch(FDCAN_HandleTypeDef * hfdcan,uint32_t Source,uint32_t Polarity)3945 HAL_StatusTypeDef HAL_FDCAN_TT_ConfigStopWatch(FDCAN_HandleTypeDef *hfdcan, uint32_t Source, uint32_t Polarity)
3946 {
3947   uint32_t Counter = 0U;
3948   HAL_FDCAN_StateTypeDef state = hfdcan->State;
3949 
3950   /* Check function parameters */
3951   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3952   assert_param(IS_FDCAN_TT_STOP_WATCH_SOURCE(Source));
3953   assert_param(IS_FDCAN_TT_STOP_WATCH_POLARITY(Polarity));
3954 
3955   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3956   {
3957     /* Wait until the LCKC bit into TTOCN register is reset */
3958     while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
3959     {
3960       /* Check for the Timeout */
3961       if (Counter > FDCAN_TIMEOUT_COUNT)
3962       {
3963         /* Update error code */
3964         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3965 
3966         /* Change FDCAN state */
3967         hfdcan->State = HAL_FDCAN_STATE_ERROR;
3968 
3969         return HAL_ERROR;
3970       }
3971 
3972       /* Increment counter */
3973       Counter++;
3974     }
3975 
3976     /* Select stop watch source and polarity */
3977     MODIFY_REG(hfdcan->ttcan->TTOCN, (FDCAN_TTOCN_SWS | FDCAN_TTOCN_SWP), (Source | Polarity));
3978 
3979     /* Return function status */
3980     return HAL_OK;
3981   }
3982   else
3983   {
3984     /* Update error code */
3985     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3986 
3987     return HAL_ERROR;
3988   }
3989 }
3990 
3991 /**
3992   * @brief  Configure register time mark pulse generation.
3993   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3994   *         the configuration information for the specified FDCAN.
3995   * @param  TimeMarkSource time mark source.
3996   *         This parameter can be a value of @arg FDCAN_TT_time_mark_source.
3997   * @param  TimeMarkValue time mark value (reference).
3998   *         This parameter must be a number between 0 and 0xFFFF.
3999   * @param  RepeatFactor repeat factor of the cycle for which the time mark is valid.
4000   *         This parameter can be a value of @arg FDCAN_TT_Repeat_Factor.
4001   * @param  StartCycle index of the first cycle in which the time mark becomes valid.
4002   *         This parameter is ignored if RepeatFactor is set to FDCAN_TT_REPEAT_EVERY_CYCLE.
4003   *         This parameter must be a number between 0 and RepeatFactor.
4004   * @retval HAL status
4005   */
HAL_FDCAN_TT_ConfigRegisterTimeMark(FDCAN_HandleTypeDef * hfdcan,uint32_t TimeMarkSource,uint32_t TimeMarkValue,uint32_t RepeatFactor,uint32_t StartCycle)4006 HAL_StatusTypeDef HAL_FDCAN_TT_ConfigRegisterTimeMark(FDCAN_HandleTypeDef *hfdcan,
4007                                                       uint32_t TimeMarkSource, uint32_t TimeMarkValue,
4008                                                       uint32_t RepeatFactor, uint32_t StartCycle)
4009 {
4010   uint32_t Counter = 0U;
4011   uint32_t CycleCode;
4012   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4013 
4014   /* Check function parameters */
4015   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4016   assert_param(IS_FDCAN_TT_REGISTER_TIME_MARK_SOURCE(TimeMarkSource));
4017   assert_param(IS_FDCAN_MAX_VALUE(TimeMarkValue, 0xFFFFU));
4018   assert_param(IS_FDCAN_TT_REPEAT_FACTOR(RepeatFactor));
4019   if (RepeatFactor != FDCAN_TT_REPEAT_EVERY_CYCLE)
4020   {
4021     assert_param(IS_FDCAN_MAX_VALUE(StartCycle, (RepeatFactor - 1U)));
4022   }
4023 
4024   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4025   {
4026     /* Wait until the LCKC bit into TTOCN register is reset */
4027     while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4028     {
4029       /* Check for the Timeout */
4030       if (Counter > FDCAN_TIMEOUT_COUNT)
4031       {
4032         /* Update error code */
4033         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4034 
4035         /* Change FDCAN state */
4036         hfdcan->State = HAL_FDCAN_STATE_ERROR;
4037 
4038         return HAL_ERROR;
4039       }
4040 
4041       /* Increment counter */
4042       Counter++;
4043     }
4044 
4045     /* Disable the time mark compare function */
4046     CLEAR_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_TMC);
4047 
4048     if (TimeMarkSource != FDCAN_TT_REG_TIMEMARK_DIABLED)
4049     {
4050       /* Calculate cycle code */
4051       if (RepeatFactor == FDCAN_TT_REPEAT_EVERY_CYCLE)
4052       {
4053         CycleCode = FDCAN_TT_REPEAT_EVERY_CYCLE;
4054       }
4055       else /* RepeatFactor != FDCAN_TT_REPEAT_EVERY_CYCLE */
4056       {
4057         CycleCode = RepeatFactor + StartCycle;
4058       }
4059 
4060       Counter = 0U;
4061 
4062       /* Wait until the LCKM bit into TTTMK register is reset */
4063       while ((hfdcan->ttcan->TTTMK & FDCAN_TTTMK_LCKM) != 0U)
4064       {
4065         /* Check for the Timeout */
4066         if (Counter > FDCAN_TIMEOUT_COUNT)
4067         {
4068           /* Update error code */
4069           hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4070 
4071           /* Change FDCAN state */
4072           hfdcan->State = HAL_FDCAN_STATE_ERROR;
4073 
4074           return HAL_ERROR;
4075         }
4076 
4077         /* Increment counter */
4078         Counter++;
4079       }
4080 
4081       /* Configure time mark value and cycle code */
4082       hfdcan->ttcan->TTTMK = ((TimeMarkValue << FDCAN_TTTMK_TM_Pos) | (CycleCode << FDCAN_TTTMK_TICC_Pos));
4083 
4084       Counter = 0U;
4085 
4086       /* Wait until the LCKC bit into TTOCN register is reset */
4087       while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4088       {
4089         /* Check for the Timeout */
4090         if (Counter > FDCAN_TIMEOUT_COUNT)
4091         {
4092           /* Update error code */
4093           hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4094 
4095           /* Change FDCAN state */
4096           hfdcan->State = HAL_FDCAN_STATE_ERROR;
4097 
4098           return HAL_ERROR;
4099         }
4100 
4101         /* Increment counter */
4102         Counter++;
4103       }
4104 
4105       /* Update the register time mark compare source */
4106       MODIFY_REG(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_TMC, TimeMarkSource);
4107     }
4108 
4109     /* Return function status */
4110     return HAL_OK;
4111   }
4112   else
4113   {
4114     /* Update error code */
4115     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4116 
4117     return HAL_ERROR;
4118   }
4119 }
4120 
4121 /**
4122   * @brief  Enable register time mark pulse generation.
4123   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4124   *         the configuration information for the specified FDCAN.
4125   * @retval HAL status
4126   */
HAL_FDCAN_TT_EnableRegisterTimeMarkPulse(FDCAN_HandleTypeDef * hfdcan)4127 HAL_StatusTypeDef HAL_FDCAN_TT_EnableRegisterTimeMarkPulse(FDCAN_HandleTypeDef *hfdcan)
4128 {
4129   uint32_t Counter = 0U;
4130   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4131 
4132   /* Check function parameters */
4133   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4134 
4135   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
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     /* Enable Register Time Mark Interrupt output on fdcan1_rtp */
4157     SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_RTIE);
4158 
4159     /* Return function status */
4160     return HAL_OK;
4161   }
4162   else
4163   {
4164     /* Update error code */
4165     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4166 
4167     return HAL_ERROR;
4168   }
4169 }
4170 
4171 /**
4172   * @brief  Disable register time mark pulse generation.
4173   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4174   *         the configuration information for the specified FDCAN.
4175   * @retval HAL status
4176   */
HAL_FDCAN_TT_DisableRegisterTimeMarkPulse(FDCAN_HandleTypeDef * hfdcan)4177 HAL_StatusTypeDef HAL_FDCAN_TT_DisableRegisterTimeMarkPulse(FDCAN_HandleTypeDef *hfdcan)
4178 {
4179   uint32_t Counter = 0U;
4180   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4181 
4182   /* Check function parameters */
4183   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4184 
4185   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4186   {
4187     /* Wait until the LCKC bit into TTOCN register is reset */
4188     while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4189     {
4190       /* Check for the Timeout */
4191       if (Counter > FDCAN_TIMEOUT_COUNT)
4192       {
4193         /* Update error code */
4194         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4195 
4196         /* Change FDCAN state */
4197         hfdcan->State = HAL_FDCAN_STATE_ERROR;
4198 
4199         return HAL_ERROR;
4200       }
4201 
4202       /* Increment counter */
4203       Counter++;
4204     }
4205 
4206     /* Disable Register Time Mark Interrupt output on fdcan1_rtp */
4207     CLEAR_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_RTIE);
4208 
4209     /* Return function status */
4210     return HAL_OK;
4211   }
4212   else
4213   {
4214     /* Update error code */
4215     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4216 
4217     return HAL_ERROR;
4218   }
4219 }
4220 
4221 /**
4222   * @brief  Enable trigger time mark pulse generation.
4223   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4224   *         the configuration information for the specified FDCAN.
4225   * @retval HAL status
4226   */
HAL_FDCAN_TT_EnableTriggerTimeMarkPulse(FDCAN_HandleTypeDef * hfdcan)4227 HAL_StatusTypeDef HAL_FDCAN_TT_EnableTriggerTimeMarkPulse(FDCAN_HandleTypeDef *hfdcan)
4228 {
4229   uint32_t Counter = 0U;
4230   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4231 
4232   /* Check function parameters */
4233   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4234 
4235   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4236   {
4237     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
4238     {
4239       /* Wait until the LCKC bit into TTOCN register is reset */
4240       while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4241       {
4242         /* Check for the Timeout */
4243         if (Counter > FDCAN_TIMEOUT_COUNT)
4244         {
4245           /* Update error code */
4246           hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4247 
4248           /* Change FDCAN state */
4249           hfdcan->State = HAL_FDCAN_STATE_ERROR;
4250 
4251           return HAL_ERROR;
4252         }
4253 
4254         /* Increment counter */
4255         Counter++;
4256       }
4257 
4258       /* Enable Trigger Time Mark Interrupt output on fdcan1_tmp */
4259       SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_TTIE);
4260 
4261       /* Return function status */
4262       return HAL_OK;
4263     }
4264     else
4265     {
4266       /* Update error code.
4267          Feature not supported for TT Level 0 */
4268       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
4269 
4270       return HAL_ERROR;
4271     }
4272   }
4273   else
4274   {
4275     /* Update error code */
4276     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4277 
4278     return HAL_ERROR;
4279   }
4280 }
4281 
4282 /**
4283   * @brief  Disable trigger time mark pulse generation.
4284   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4285   *         the configuration information for the specified FDCAN.
4286   * @retval HAL status
4287   */
HAL_FDCAN_TT_DisableTriggerTimeMarkPulse(FDCAN_HandleTypeDef * hfdcan)4288 HAL_StatusTypeDef HAL_FDCAN_TT_DisableTriggerTimeMarkPulse(FDCAN_HandleTypeDef *hfdcan)
4289 {
4290   uint32_t Counter = 0U;
4291   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4292 
4293   /* Check function parameters */
4294   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4295 
4296   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4297   {
4298     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
4299     {
4300       /* Wait until the LCKC bit into TTOCN register is reset */
4301       while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4302       {
4303         /* Check for the Timeout */
4304         if (Counter > FDCAN_TIMEOUT_COUNT)
4305         {
4306           /* Update error code */
4307           hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4308 
4309           /* Change FDCAN state */
4310           hfdcan->State = HAL_FDCAN_STATE_ERROR;
4311 
4312           return HAL_ERROR;
4313         }
4314 
4315         /* Increment counter */
4316         Counter++;
4317       }
4318 
4319       /* Disable Trigger Time Mark Interrupt output on fdcan1_rtp */
4320       CLEAR_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_TTIE);
4321 
4322       /* Return function status */
4323       return HAL_OK;
4324     }
4325     else
4326     {
4327       /* Update error code.
4328          Feature not supported for TT Level 0 */
4329       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
4330 
4331       return HAL_ERROR;
4332     }
4333   }
4334   else
4335   {
4336     /* Update error code */
4337     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4338 
4339     return HAL_ERROR;
4340   }
4341 }
4342 
4343 /**
4344   * @brief  Enable gap control by input pin fdcan1_evt.
4345   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4346   *         the configuration information for the specified FDCAN.
4347   * @retval HAL status
4348   */
HAL_FDCAN_TT_EnableHardwareGapControl(FDCAN_HandleTypeDef * hfdcan)4349 HAL_StatusTypeDef HAL_FDCAN_TT_EnableHardwareGapControl(FDCAN_HandleTypeDef *hfdcan)
4350 {
4351   uint32_t Counter = 0U;
4352   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4353 
4354   /* Check function parameters */
4355   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4356 
4357   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4358   {
4359     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
4360     {
4361       /* Wait until the LCKC bit into TTOCN register is reset */
4362       while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4363       {
4364         /* Check for the Timeout */
4365         if (Counter > FDCAN_TIMEOUT_COUNT)
4366         {
4367           /* Update error code */
4368           hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4369 
4370           /* Change FDCAN state */
4371           hfdcan->State = HAL_FDCAN_STATE_ERROR;
4372 
4373           return HAL_ERROR;
4374         }
4375 
4376         /* Increment counter */
4377         Counter++;
4378       }
4379 
4380       /* Enable gap control by pin fdcan1_evt */
4381       SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_GCS);
4382 
4383       /* Return function status */
4384       return HAL_OK;
4385     }
4386     else
4387     {
4388       /* Update error code.
4389          Feature not supported for TT Level 0 */
4390       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
4391 
4392       return HAL_ERROR;
4393     }
4394   }
4395   else
4396   {
4397     /* Update error code */
4398     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4399 
4400     return HAL_ERROR;
4401   }
4402 }
4403 
4404 /**
4405   * @brief  Disable gap control by input pin fdcan1_evt.
4406   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4407   *         the configuration information for the specified FDCAN.
4408   * @retval HAL status
4409   */
HAL_FDCAN_TT_DisableHardwareGapControl(FDCAN_HandleTypeDef * hfdcan)4410 HAL_StatusTypeDef HAL_FDCAN_TT_DisableHardwareGapControl(FDCAN_HandleTypeDef *hfdcan)
4411 {
4412   uint32_t Counter = 0U;
4413   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4414 
4415   /* Check function parameters */
4416   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4417 
4418   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4419   {
4420     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
4421     {
4422       /* Wait until the LCKC bit into TTOCN register is reset */
4423       while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4424       {
4425         /* Check for the Timeout */
4426         if (Counter > FDCAN_TIMEOUT_COUNT)
4427         {
4428           /* Update error code */
4429           hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4430 
4431           /* Change FDCAN state */
4432           hfdcan->State = HAL_FDCAN_STATE_ERROR;
4433 
4434           return HAL_ERROR;
4435         }
4436 
4437         /* Increment counter */
4438         Counter++;
4439       }
4440 
4441       /* Disable gap control by pin fdcan1_evt */
4442       CLEAR_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_GCS);
4443 
4444       /* Return function status */
4445       return HAL_OK;
4446     }
4447     else
4448     {
4449       /* Update error code.
4450          Feature not supported for TT Level 0 */
4451       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
4452 
4453       return HAL_ERROR;
4454     }
4455   }
4456   else
4457   {
4458     /* Update error code */
4459     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4460 
4461     return HAL_ERROR;
4462   }
4463 }
4464 
4465 /**
4466   * @brief  Enable gap control (finish only) by register time mark interrupt.
4467   *         The next register time mark interrupt (TTIR.RTMI = "1") will finish
4468   *         the Gap and start the reference message.
4469   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4470   *         the configuration information for the specified FDCAN.
4471   * @retval HAL status
4472   */
HAL_FDCAN_TT_EnableTimeMarkGapControl(FDCAN_HandleTypeDef * hfdcan)4473 HAL_StatusTypeDef HAL_FDCAN_TT_EnableTimeMarkGapControl(FDCAN_HandleTypeDef *hfdcan)
4474 {
4475   uint32_t Counter = 0U;
4476   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4477 
4478   /* Check function parameters */
4479   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4480 
4481   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4482   {
4483     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
4484     {
4485       /* Wait until the LCKC bit into TTOCN register is reset */
4486       while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4487       {
4488         /* Check for the Timeout */
4489         if (Counter > FDCAN_TIMEOUT_COUNT)
4490         {
4491           /* Update error code */
4492           hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4493 
4494           /* Change FDCAN state */
4495           hfdcan->State = HAL_FDCAN_STATE_ERROR;
4496 
4497           return HAL_ERROR;
4498         }
4499 
4500         /* Increment counter */
4501         Counter++;
4502       }
4503 
4504       /* Enable gap control by register time mark interrupt */
4505       SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_TMG);
4506 
4507       /* Return function status */
4508       return HAL_OK;
4509     }
4510     else
4511     {
4512       /* Update error code.
4513          Feature not supported for TT Level 0 */
4514       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
4515 
4516       return HAL_ERROR;
4517     }
4518   }
4519   else
4520   {
4521     /* Update error code */
4522     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4523 
4524     return HAL_ERROR;
4525   }
4526 }
4527 
4528 /**
4529   * @brief  Disable gap control by register time mark interrupt.
4530   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4531   *         the configuration information for the specified FDCAN.
4532   * @retval HAL status
4533   */
HAL_FDCAN_TT_DisableTimeMarkGapControl(FDCAN_HandleTypeDef * hfdcan)4534 HAL_StatusTypeDef HAL_FDCAN_TT_DisableTimeMarkGapControl(FDCAN_HandleTypeDef *hfdcan)
4535 {
4536   uint32_t Counter = 0U;
4537   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4538 
4539   /* Check function parameters */
4540   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4541 
4542   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4543   {
4544     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
4545     {
4546       /* Wait until the LCKC bit into TTOCN register is reset */
4547       while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4548       {
4549         /* Check for the Timeout */
4550         if (Counter > FDCAN_TIMEOUT_COUNT)
4551         {
4552           /* Update error code */
4553           hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4554 
4555           /* Change FDCAN state */
4556           hfdcan->State = HAL_FDCAN_STATE_ERROR;
4557 
4558           return HAL_ERROR;
4559         }
4560 
4561         /* Increment counter */
4562         Counter++;
4563       }
4564 
4565       /* Disable gap control by register time mark interrupt */
4566       CLEAR_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_TMG);
4567 
4568       /* Return function status */
4569       return HAL_OK;
4570     }
4571     else
4572     {
4573       /* Update error code.
4574          Feature not supported for TT Level 0 */
4575       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
4576 
4577       return HAL_ERROR;
4578     }
4579   }
4580   else
4581   {
4582     /* Update error code */
4583     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4584 
4585     return HAL_ERROR;
4586   }
4587 }
4588 
4589 /**
4590   * @brief  Transmit next reference message with Next_is_Gap = "1".
4591   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4592   *         the configuration information for the specified FDCAN.
4593   * @retval HAL status
4594   */
HAL_FDCAN_TT_SetNextIsGap(FDCAN_HandleTypeDef * hfdcan)4595 HAL_StatusTypeDef HAL_FDCAN_TT_SetNextIsGap(FDCAN_HandleTypeDef *hfdcan)
4596 {
4597   uint32_t Counter = 0U;
4598   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4599 
4600   /* Check function parameters */
4601   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4602 
4603   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4604   {
4605     /* Check that the node is configured for external event-synchronized TT operation */
4606     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_GEN) != FDCAN_TTOCF_GEN)
4607     {
4608       /* Update error code */
4609       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
4610 
4611       return HAL_ERROR;
4612     }
4613 
4614     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
4615     {
4616       /* Wait until the LCKC bit into TTOCN register is reset */
4617       while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4618       {
4619         /* Check for the Timeout */
4620         if (Counter > FDCAN_TIMEOUT_COUNT)
4621         {
4622           /* Update error code */
4623           hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4624 
4625           /* Change FDCAN state */
4626           hfdcan->State = HAL_FDCAN_STATE_ERROR;
4627 
4628           return HAL_ERROR;
4629         }
4630 
4631         /* Increment counter */
4632         Counter++;
4633       }
4634 
4635       /* Set Next is Gap */
4636       SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_NIG);
4637 
4638       /* Return function status */
4639       return HAL_OK;
4640     }
4641     else
4642     {
4643       /* Update error code.
4644          Feature not supported for TT Level 0 */
4645       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
4646 
4647       return HAL_ERROR;
4648     }
4649   }
4650   else
4651   {
4652     /* Update error code */
4653     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4654 
4655     return HAL_ERROR;
4656   }
4657 }
4658 
4659 /**
4660   * @brief  Finish a Gap by requesting start of reference message.
4661   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4662   *         the configuration information for the specified FDCAN.
4663   * @retval HAL status
4664   */
HAL_FDCAN_TT_SetEndOfGap(FDCAN_HandleTypeDef * hfdcan)4665 HAL_StatusTypeDef HAL_FDCAN_TT_SetEndOfGap(FDCAN_HandleTypeDef *hfdcan)
4666 {
4667   uint32_t Counter = 0U;
4668   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4669 
4670   /* Check function parameters */
4671   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4672 
4673   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4674   {
4675     /* Check that the node is configured for external event-synchronized TT operation */
4676     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_GEN) != FDCAN_TTOCF_GEN)
4677     {
4678       /* Update error code */
4679       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
4680 
4681       return HAL_ERROR;
4682     }
4683 
4684     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
4685     {
4686       /* Wait until the LCKC bit into TTOCN register is reset */
4687       while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4688       {
4689         /* Check for the Timeout */
4690         if (Counter > FDCAN_TIMEOUT_COUNT)
4691         {
4692           /* Update error code */
4693           hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4694 
4695           /* Change FDCAN state */
4696           hfdcan->State = HAL_FDCAN_STATE_ERROR;
4697 
4698           return HAL_ERROR;
4699         }
4700 
4701         /* Increment counter */
4702         Counter++;
4703       }
4704 
4705       /* Set Finish Gap */
4706       SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_FGP);
4707 
4708       /* Return function status */
4709       return HAL_OK;
4710     }
4711     else
4712     {
4713       /* Update error code.
4714          Feature not supported for TT Level 0 */
4715       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
4716 
4717       return HAL_ERROR;
4718     }
4719   }
4720   else
4721   {
4722     /* Update error code */
4723     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4724 
4725     return HAL_ERROR;
4726   }
4727 }
4728 
4729 /**
4730   * @brief  Configure target phase used for external synchronization by event
4731   *         trigger input pin fdcan1_evt.
4732   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4733   *         the configuration information for the specified FDCAN.
4734   * @param  TargetPhase defines target value of cycle time when a rising edge
4735   *         of fdcan1_evt is expected.
4736   *         This parameter must be a number between 0 and 0xFFFF.
4737   * @retval HAL status
4738   */
HAL_FDCAN_TT_ConfigExternalSyncPhase(FDCAN_HandleTypeDef * hfdcan,uint32_t TargetPhase)4739 HAL_StatusTypeDef HAL_FDCAN_TT_ConfigExternalSyncPhase(FDCAN_HandleTypeDef *hfdcan, uint32_t TargetPhase)
4740 {
4741   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4742 
4743   /* Check function parameters */
4744   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4745   assert_param(IS_FDCAN_MAX_VALUE(TargetPhase, 0xFFFFU));
4746 
4747   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4748   {
4749     /* Check that no external schedule synchronization is pending */
4750     if ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_ESCN) == FDCAN_TTOCN_ESCN)
4751     {
4752       /* Update error code */
4753       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PENDING;
4754 
4755       return HAL_ERROR;
4756     }
4757 
4758     /* Configure cycle time target phase */
4759     MODIFY_REG(hfdcan->ttcan->TTGTP, FDCAN_TTGTP_CTP, (TargetPhase << FDCAN_TTGTP_CTP_Pos));
4760 
4761     /* Return function status */
4762     return HAL_OK;
4763   }
4764   else
4765   {
4766     /* Update error code */
4767     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4768 
4769     return HAL_ERROR;
4770   }
4771 }
4772 
4773 /**
4774   * @brief  Synchronize the phase of the FDCAN schedule to an external schedule
4775   *         using event trigger input pin fdcan1_evt.
4776   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4777   *         the configuration information for the specified FDCAN.
4778   * @retval HAL status
4779   */
HAL_FDCAN_TT_EnableExternalSynchronization(FDCAN_HandleTypeDef * hfdcan)4780 HAL_StatusTypeDef HAL_FDCAN_TT_EnableExternalSynchronization(FDCAN_HandleTypeDef *hfdcan)
4781 {
4782   uint32_t Counter = 0U;
4783   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4784 
4785   /* Check function parameters */
4786   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4787 
4788   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4789   {
4790     /* Wait until the LCKC bit into TTOCN register is reset */
4791     while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4792     {
4793       /* Check for the Timeout */
4794       if (Counter > FDCAN_TIMEOUT_COUNT)
4795       {
4796         /* Update error code */
4797         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4798 
4799         /* Change FDCAN state */
4800         hfdcan->State = HAL_FDCAN_STATE_ERROR;
4801 
4802         return HAL_ERROR;
4803       }
4804 
4805       /* Increment counter */
4806       Counter++;
4807     }
4808 
4809     /* Enable external synchronization */
4810     SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_ESCN);
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  Disable external schedule synchronization.
4826   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4827   *         the configuration information for the specified FDCAN.
4828   * @retval HAL status
4829   */
HAL_FDCAN_TT_DisableExternalSynchronization(FDCAN_HandleTypeDef * hfdcan)4830 HAL_StatusTypeDef HAL_FDCAN_TT_DisableExternalSynchronization(FDCAN_HandleTypeDef *hfdcan)
4831 {
4832   uint32_t Counter = 0U;
4833   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4834 
4835   /* Check function parameters */
4836   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4837 
4838   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4839   {
4840     /* Wait until the LCKC bit into TTOCN register is reset */
4841     while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
4842     {
4843       /* Check for the Timeout */
4844       if (Counter > FDCAN_TIMEOUT_COUNT)
4845       {
4846         /* Update error code */
4847         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
4848 
4849         /* Change FDCAN state */
4850         hfdcan->State = HAL_FDCAN_STATE_ERROR;
4851 
4852         return HAL_ERROR;
4853       }
4854 
4855       /* Increment counter */
4856       Counter++;
4857     }
4858 
4859     /* Disable external synchronization */
4860     CLEAR_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_ESCN);
4861 
4862     /* Return function status */
4863     return HAL_OK;
4864   }
4865   else
4866   {
4867     /* Update error code */
4868     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4869 
4870     return HAL_ERROR;
4871   }
4872 }
4873 
4874 /**
4875   * @brief  Get TT operation status.
4876   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4877   *         the configuration information for the specified FDCAN.
4878   * @param  TTOpStatus pointer to an FDCAN_TTOperationStatusTypeDef structure.
4879   * @retval HAL status
4880   */
HAL_FDCAN_TT_GetOperationStatus(FDCAN_HandleTypeDef * hfdcan,FDCAN_TTOperationStatusTypeDef * TTOpStatus)4881 HAL_StatusTypeDef HAL_FDCAN_TT_GetOperationStatus(FDCAN_HandleTypeDef *hfdcan, FDCAN_TTOperationStatusTypeDef *TTOpStatus)
4882 {
4883   uint32_t TTStatusReg;
4884 
4885   /* Check function parameters */
4886   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4887 
4888   /* Read the TT operation status register */
4889   TTStatusReg = READ_REG(hfdcan->ttcan->TTOST);
4890 
4891   /* Fill the TT operation status structure */
4892   TTOpStatus->ErrorLevel = (TTStatusReg & FDCAN_TTOST_EL);
4893   TTOpStatus->MasterState = (TTStatusReg & FDCAN_TTOST_MS);
4894   TTOpStatus->SyncState = (TTStatusReg & FDCAN_TTOST_SYS);
4895   TTOpStatus->GTimeQuality = ((TTStatusReg & FDCAN_TTOST_QGTP) >> FDCAN_TTOST_QGTP_Pos);
4896   TTOpStatus->ClockQuality = ((TTStatusReg & FDCAN_TTOST_QCS) >> FDCAN_TTOST_QCS_Pos);
4897   TTOpStatus->RefTrigOffset = ((TTStatusReg & FDCAN_TTOST_RTO) >> FDCAN_TTOST_RTO_Pos);
4898   TTOpStatus->GTimeDiscPending = ((TTStatusReg & FDCAN_TTOST_WGTD) >> FDCAN_TTOST_WGTD_Pos);
4899   TTOpStatus->GapFinished = ((TTStatusReg & FDCAN_TTOST_GFI) >> FDCAN_TTOST_GFI_Pos);
4900   TTOpStatus->MasterPriority = ((TTStatusReg & FDCAN_TTOST_TMP) >> FDCAN_TTOST_TMP_Pos);
4901   TTOpStatus->GapStarted = ((TTStatusReg & FDCAN_TTOST_GSI) >> FDCAN_TTOST_GSI_Pos);
4902   TTOpStatus->WaitForEvt = ((TTStatusReg & FDCAN_TTOST_WFE) >> FDCAN_TTOST_WFE_Pos);
4903   TTOpStatus->AppWdgEvt = ((TTStatusReg & FDCAN_TTOST_AWE) >> FDCAN_TTOST_AWE_Pos);
4904   TTOpStatus->ECSPending = ((TTStatusReg & FDCAN_TTOST_WECS) >> FDCAN_TTOST_WECS_Pos);
4905   TTOpStatus->PhaseLock = ((TTStatusReg & FDCAN_TTOST_SPL) >> FDCAN_TTOST_SPL_Pos);
4906 
4907   /* Return function status */
4908   return HAL_OK;
4909 }
4910 
4911 /**
4912   * @}
4913   */
4914 
4915 /** @defgroup FDCAN_Exported_Functions_Group5 Interrupts management
4916  *  @brief    Interrupts management
4917  *
4918 @verbatim
4919   ==============================================================================
4920                        ##### Interrupts management #####
4921   ==============================================================================
4922     [..]  This section provides functions allowing to:
4923       (+) HAL_FDCAN_ConfigInterruptLines      : Assign interrupts to either Interrupt line 0 or 1
4924       (+) HAL_FDCAN_TT_ConfigInterruptLines   : Assign TT interrupts to either Interrupt line 0 or 1
4925       (+) HAL_FDCAN_ActivateNotification      : Enable interrupts
4926       (+) HAL_FDCAN_DeactivateNotification    : Disable interrupts
4927       (+) HAL_FDCAN_TT_ActivateNotification   : Enable TT interrupts
4928       (+) HAL_FDCAN_TT_DeactivateNotification : Disable TT interrupts
4929       (+) HAL_FDCAN_IRQHandler                : Handles FDCAN interrupt request
4930 
4931 @endverbatim
4932   * @{
4933   */
4934 
4935 /**
4936   * @brief  Assign interrupts to either Interrupt line 0 or 1.
4937   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4938   *         the configuration information for the specified FDCAN.
4939   * @param  ITList indicates which interrupts will be assigned to the selected interrupt line.
4940   *         This parameter can be any combination of @arg FDCAN_Interrupts.
4941   * @param  InterruptLine Interrupt line.
4942   *         This parameter can be a value of @arg FDCAN_Interrupt_Line.
4943   * @retval HAL status
4944   */
HAL_FDCAN_ConfigInterruptLines(FDCAN_HandleTypeDef * hfdcan,uint32_t ITList,uint32_t InterruptLine)4945 HAL_StatusTypeDef HAL_FDCAN_ConfigInterruptLines(FDCAN_HandleTypeDef *hfdcan, uint32_t ITList, uint32_t InterruptLine)
4946 {
4947   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4948 
4949   /* Check function parameters */
4950   assert_param(IS_FDCAN_IT(ITList));
4951   assert_param(IS_FDCAN_IT_LINE(InterruptLine));
4952 
4953   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4954   {
4955     /* Assign list of interrupts to the selected line */
4956     if (InterruptLine == FDCAN_INTERRUPT_LINE0)
4957     {
4958       CLEAR_BIT(hfdcan->Instance->ILS, ITList);
4959     }
4960     else /* InterruptLine == FDCAN_INTERRUPT_LINE1 */
4961     {
4962       SET_BIT(hfdcan->Instance->ILS, ITList);
4963     }
4964 
4965     /* Return function status */
4966     return HAL_OK;
4967   }
4968   else
4969   {
4970     /* Update error code */
4971     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4972 
4973     return HAL_ERROR;
4974   }
4975 }
4976 
4977 /**
4978   * @brief  Assign TT interrupts to either Interrupt line 0 or 1.
4979   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4980   *         the configuration information for the specified FDCAN.
4981   * @param  TTITList indicates which interrupts will be assigned to the selected interrupt line.
4982   *         This parameter can be any combination of @arg FDCAN_TTInterrupts.
4983   * @param  InterruptLine Interrupt line.
4984   *         This parameter can be a value of @arg FDCAN_Interrupt_Line.
4985   * @retval HAL status
4986   */
HAL_FDCAN_TT_ConfigInterruptLines(FDCAN_HandleTypeDef * hfdcan,uint32_t TTITList,uint32_t InterruptLine)4987 HAL_StatusTypeDef HAL_FDCAN_TT_ConfigInterruptLines(FDCAN_HandleTypeDef *hfdcan, uint32_t TTITList, uint32_t InterruptLine)
4988 {
4989   HAL_FDCAN_StateTypeDef state = hfdcan->State;
4990 
4991   /* Check function parameters */
4992   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4993   assert_param(IS_FDCAN_TT_IT(TTITList));
4994   assert_param(IS_FDCAN_IT_LINE(InterruptLine));
4995 
4996   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4997   {
4998     /* Assign list of interrupts to the selected line */
4999     if (InterruptLine == FDCAN_INTERRUPT_LINE0)
5000     {
5001       CLEAR_BIT(hfdcan->ttcan->TTILS, TTITList);
5002     }
5003     else /* InterruptLine == FDCAN_INTERRUPT_LINE1 */
5004     {
5005       SET_BIT(hfdcan->ttcan->TTILS, TTITList);
5006     }
5007 
5008     /* Return function status */
5009     return HAL_OK;
5010   }
5011   else
5012   {
5013     /* Update error code */
5014     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
5015 
5016     return HAL_ERROR;
5017   }
5018 }
5019 
5020 /**
5021   * @brief  Enable interrupts.
5022   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5023   *         the configuration information for the specified FDCAN.
5024   * @param  ActiveITs indicates which interrupts will be enabled.
5025   *         This parameter can be any combination of @arg FDCAN_Interrupts.
5026   * @param  BufferIndexes Tx Buffer Indexes.
5027   *         This parameter can be any combination of @arg FDCAN_Tx_location.
5028   *         This parameter is ignored if ActiveITs does not include one of the following:
5029   *           - FDCAN_IT_TX_COMPLETE
5030   *           - FDCAN_IT_TX_ABORT_COMPLETE
5031   * @retval HAL status
5032   */
HAL_FDCAN_ActivateNotification(FDCAN_HandleTypeDef * hfdcan,uint32_t ActiveITs,uint32_t BufferIndexes)5033 HAL_StatusTypeDef HAL_FDCAN_ActivateNotification(FDCAN_HandleTypeDef *hfdcan, uint32_t ActiveITs, uint32_t BufferIndexes)
5034 {
5035   HAL_FDCAN_StateTypeDef state = hfdcan->State;
5036 
5037   /* Check function parameters */
5038   assert_param(IS_FDCAN_IT(ActiveITs));
5039 
5040   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
5041   {
5042     /* Enable Interrupt lines */
5043     if ((ActiveITs & hfdcan->Instance->ILS) == 0U)
5044     {
5045       /* Enable Interrupt line 0 */
5046       SET_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE0);
5047     }
5048     else if ((ActiveITs & hfdcan->Instance->ILS) == ActiveITs)
5049     {
5050       /* Enable Interrupt line 1 */
5051       SET_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE1);
5052     }
5053     else
5054     {
5055       /* Enable Interrupt lines 0 and 1 */
5056       hfdcan->Instance->ILE = (FDCAN_INTERRUPT_LINE0 | FDCAN_INTERRUPT_LINE1);
5057     }
5058 
5059     if ((ActiveITs & FDCAN_IT_TX_COMPLETE) != 0U)
5060     {
5061       /* Enable Tx Buffer Transmission Interrupt to set TC flag in IR register,
5062          but interrupt will only occur if TC is enabled in IE register */
5063       SET_BIT(hfdcan->Instance->TXBTIE, BufferIndexes);
5064     }
5065 
5066     if ((ActiveITs & FDCAN_IT_TX_ABORT_COMPLETE) != 0U)
5067     {
5068       /* Enable Tx Buffer Cancellation Finished Interrupt to set TCF flag in IR register,
5069          but interrupt will only occur if TCF is enabled in IE register */
5070       SET_BIT(hfdcan->Instance->TXBCIE, BufferIndexes);
5071     }
5072 
5073     /* Enable the selected interrupts */
5074     __HAL_FDCAN_ENABLE_IT(hfdcan, ActiveITs);
5075 
5076     /* Return function status */
5077     return HAL_OK;
5078   }
5079   else
5080   {
5081     /* Update error code */
5082     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
5083 
5084     return HAL_ERROR;
5085   }
5086 }
5087 
5088 /**
5089   * @brief  Disable interrupts.
5090   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5091   *         the configuration information for the specified FDCAN.
5092   * @param  InactiveITs indicates which interrupts will be disabled.
5093   *         This parameter can be any combination of @arg FDCAN_Interrupts.
5094   * @retval HAL status
5095   */
HAL_FDCAN_DeactivateNotification(FDCAN_HandleTypeDef * hfdcan,uint32_t InactiveITs)5096 HAL_StatusTypeDef HAL_FDCAN_DeactivateNotification(FDCAN_HandleTypeDef *hfdcan, uint32_t InactiveITs)
5097 {
5098   uint32_t ITLineSelection;
5099   HAL_FDCAN_StateTypeDef state = hfdcan->State;
5100 
5101   /* Check function parameters */
5102   assert_param(IS_FDCAN_IT(InactiveITs));
5103 
5104   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
5105   {
5106     /* Disable the selected interrupts */
5107     __HAL_FDCAN_DISABLE_IT(hfdcan, InactiveITs);
5108 
5109     if ((InactiveITs & FDCAN_IT_TX_COMPLETE) != 0U)
5110     {
5111       /* Disable Tx Buffer Transmission Interrupts */
5112       CLEAR_REG(hfdcan->Instance->TXBTIE);
5113     }
5114 
5115     if ((InactiveITs & FDCAN_IT_TX_ABORT_COMPLETE) != 0U)
5116     {
5117       /* Disable Tx Buffer Cancellation Finished Interrupt */
5118       CLEAR_REG(hfdcan->Instance->TXBCIE);
5119     }
5120 
5121     ITLineSelection = hfdcan->Instance->ILS;
5122 
5123     if ((hfdcan->Instance->IE | ITLineSelection) == ITLineSelection)
5124     {
5125       /* Disable Interrupt line 0 */
5126       CLEAR_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE0);
5127     }
5128 
5129     if ((hfdcan->Instance->IE & ITLineSelection) == 0U)
5130     {
5131       /* Disable Interrupt line 1 */
5132       CLEAR_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE1);
5133     }
5134 
5135     /* Return function status */
5136     return HAL_OK;
5137   }
5138   else
5139   {
5140     /* Update error code */
5141     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
5142 
5143     return HAL_ERROR;
5144   }
5145 }
5146 
5147 /**
5148   * @brief  Enable TT interrupts.
5149   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5150   *         the configuration information for the specified FDCAN.
5151   * @param  ActiveTTITs indicates which TT interrupts will be enabled.
5152   *         This parameter can be any combination of @arg FDCAN_TTInterrupts.
5153   * @retval HAL status
5154   */
HAL_FDCAN_TT_ActivateNotification(FDCAN_HandleTypeDef * hfdcan,uint32_t ActiveTTITs)5155 HAL_StatusTypeDef HAL_FDCAN_TT_ActivateNotification(FDCAN_HandleTypeDef *hfdcan, uint32_t ActiveTTITs)
5156 {
5157   HAL_FDCAN_StateTypeDef state = hfdcan->State;
5158 
5159   /* Check function parameters */
5160   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
5161   assert_param(IS_FDCAN_TT_IT(ActiveTTITs));
5162 
5163   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
5164   {
5165     /* Enable Interrupt lines */
5166     if ((ActiveTTITs & hfdcan->ttcan->TTILS) == 0U)
5167     {
5168       /* Enable Interrupt line 0 */
5169       SET_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE0);
5170     }
5171     else if ((ActiveTTITs & hfdcan->ttcan->TTILS) == ActiveTTITs)
5172     {
5173       /* Enable Interrupt line 1 */
5174       SET_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE1);
5175     }
5176     else
5177     {
5178       /* Enable Interrupt lines 0 and 1 */
5179       hfdcan->Instance->ILE = (FDCAN_INTERRUPT_LINE0 | FDCAN_INTERRUPT_LINE1);
5180     }
5181 
5182     /* Enable the selected TT interrupts */
5183     __HAL_FDCAN_TT_ENABLE_IT(hfdcan, ActiveTTITs);
5184 
5185     /* Return function status */
5186     return HAL_OK;
5187   }
5188   else
5189   {
5190     /* Update error code */
5191     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
5192 
5193     return HAL_ERROR;
5194   }
5195 }
5196 
5197 /**
5198   * @brief  Disable TT interrupts.
5199   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5200   *         the configuration information for the specified FDCAN.
5201   * @param  InactiveTTITs indicates which TT interrupts will be disabled.
5202   *         This parameter can be any combination of @arg FDCAN_TTInterrupts.
5203   * @retval HAL status
5204   */
HAL_FDCAN_TT_DeactivateNotification(FDCAN_HandleTypeDef * hfdcan,uint32_t InactiveTTITs)5205 HAL_StatusTypeDef HAL_FDCAN_TT_DeactivateNotification(FDCAN_HandleTypeDef *hfdcan, uint32_t InactiveTTITs)
5206 {
5207   uint32_t ITLineSelection;
5208   HAL_FDCAN_StateTypeDef state = hfdcan->State;
5209 
5210   /* Check function parameters */
5211   assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
5212   assert_param(IS_FDCAN_TT_IT(InactiveTTITs));
5213 
5214   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
5215   {
5216     /* Disable the selected TT interrupts */
5217     __HAL_FDCAN_TT_DISABLE_IT(hfdcan, InactiveTTITs);
5218 
5219     ITLineSelection = hfdcan->ttcan->TTILS;
5220 
5221     if ((hfdcan->ttcan->TTIE | ITLineSelection) == ITLineSelection)
5222     {
5223       /* Disable Interrupt line 0 */
5224       CLEAR_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE0);
5225     }
5226 
5227     if ((hfdcan->ttcan->TTIE & ITLineSelection) == 0U)
5228     {
5229       /* Disable Interrupt line 1 */
5230       CLEAR_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE1);
5231     }
5232 
5233     /* Return function status */
5234     return HAL_OK;
5235   }
5236   else
5237   {
5238     /* Update error code */
5239     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
5240 
5241     return HAL_ERROR;
5242   }
5243 }
5244 
5245 /**
5246   * @brief  Handles FDCAN interrupt request.
5247   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5248   *         the configuration information for the specified FDCAN.
5249   * @retval HAL status
5250   */
HAL_FDCAN_IRQHandler(FDCAN_HandleTypeDef * hfdcan)5251 void HAL_FDCAN_IRQHandler(FDCAN_HandleTypeDef *hfdcan)
5252 {
5253   uint32_t ClkCalibrationITs;
5254   uint32_t TxEventFifoITs;
5255   uint32_t RxFifo0ITs;
5256   uint32_t RxFifo1ITs;
5257   uint32_t Errors;
5258   uint32_t ErrorStatusITs;
5259   uint32_t TransmittedBuffers;
5260   uint32_t AbortedBuffers;
5261   uint32_t TTSchedSyncITs;
5262   uint32_t TTTimeMarkITs;
5263   uint32_t TTGlobTimeITs;
5264   uint32_t TTDistErrors;
5265   uint32_t TTFatalErrors;
5266   uint32_t SWTime;
5267   uint32_t SWCycleCount;
5268 
5269   ClkCalibrationITs = (FDCAN_CCU->IR << 30);
5270   ClkCalibrationITs &= (FDCAN_CCU->IE << 30);
5271   TxEventFifoITs = hfdcan->Instance->IR & FDCAN_TX_EVENT_FIFO_MASK;
5272   TxEventFifoITs &= hfdcan->Instance->IE;
5273   RxFifo0ITs = hfdcan->Instance->IR & FDCAN_RX_FIFO0_MASK;
5274   RxFifo0ITs &= hfdcan->Instance->IE;
5275   RxFifo1ITs = hfdcan->Instance->IR & FDCAN_RX_FIFO1_MASK;
5276   RxFifo1ITs &= hfdcan->Instance->IE;
5277   Errors = hfdcan->Instance->IR & FDCAN_ERROR_MASK;
5278   Errors &= hfdcan->Instance->IE;
5279   ErrorStatusITs = hfdcan->Instance->IR & FDCAN_ERROR_STATUS_MASK;
5280   ErrorStatusITs &= hfdcan->Instance->IE;
5281 
5282   /* High Priority Message interrupt management *******************************/
5283   if (__HAL_FDCAN_GET_IT_SOURCE(hfdcan, FDCAN_IT_RX_HIGH_PRIORITY_MSG) != 0U)
5284   {
5285     if (__HAL_FDCAN_GET_FLAG(hfdcan, FDCAN_FLAG_RX_HIGH_PRIORITY_MSG) != 0U)
5286     {
5287       /* Clear the High Priority Message flag */
5288       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_RX_HIGH_PRIORITY_MSG);
5289 
5290 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5291       /* Call registered callback*/
5292       hfdcan->HighPriorityMessageCallback(hfdcan);
5293 #else
5294       /* High Priority Message Callback */
5295       HAL_FDCAN_HighPriorityMessageCallback(hfdcan);
5296 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5297     }
5298   }
5299 
5300   /* Transmission Abort interrupt management **********************************/
5301   if (__HAL_FDCAN_GET_IT_SOURCE(hfdcan, FDCAN_IT_TX_ABORT_COMPLETE) != 0U)
5302   {
5303     if (__HAL_FDCAN_GET_FLAG(hfdcan, FDCAN_FLAG_TX_ABORT_COMPLETE) != 0U)
5304     {
5305       /* List of aborted monitored buffers */
5306       AbortedBuffers = hfdcan->Instance->TXBCF;
5307       AbortedBuffers &= hfdcan->Instance->TXBCIE;
5308 
5309       /* Clear the Transmission Cancellation flag */
5310       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TX_ABORT_COMPLETE);
5311 
5312 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5313       /* Call registered callback*/
5314       hfdcan->TxBufferAbortCallback(hfdcan, AbortedBuffers);
5315 #else
5316       /* Transmission Cancellation Callback */
5317       HAL_FDCAN_TxBufferAbortCallback(hfdcan, AbortedBuffers);
5318 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5319     }
5320   }
5321 
5322   /* Clock calibration unit interrupts management *****************************/
5323   if (ClkCalibrationITs != 0U)
5324   {
5325     /* Clear the Clock Calibration flags */
5326     __HAL_FDCAN_CLEAR_FLAG(hfdcan, ClkCalibrationITs);
5327 
5328 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5329     /* Call registered callback*/
5330     hfdcan->ClockCalibrationCallback(hfdcan, ClkCalibrationITs);
5331 #else
5332     /* Clock Calibration Callback */
5333     HAL_FDCAN_ClockCalibrationCallback(hfdcan, ClkCalibrationITs);
5334 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5335   }
5336 
5337   /* Tx event FIFO interrupts management **************************************/
5338   if (TxEventFifoITs != 0U)
5339   {
5340     /* Clear the Tx Event FIFO flags */
5341     __HAL_FDCAN_CLEAR_FLAG(hfdcan, TxEventFifoITs);
5342 
5343 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5344     /* Call registered callback*/
5345     hfdcan->TxEventFifoCallback(hfdcan, TxEventFifoITs);
5346 #else
5347     /* Tx Event FIFO Callback */
5348     HAL_FDCAN_TxEventFifoCallback(hfdcan, TxEventFifoITs);
5349 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5350   }
5351 
5352   /* Rx FIFO 0 interrupts management ******************************************/
5353   if (RxFifo0ITs != 0U)
5354   {
5355     /* Clear the Rx FIFO 0 flags */
5356     __HAL_FDCAN_CLEAR_FLAG(hfdcan, RxFifo0ITs);
5357 
5358 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5359     /* Call registered callback*/
5360     hfdcan->RxFifo0Callback(hfdcan, RxFifo0ITs);
5361 #else
5362     /* Rx FIFO 0 Callback */
5363     HAL_FDCAN_RxFifo0Callback(hfdcan, RxFifo0ITs);
5364 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5365   }
5366 
5367   /* Rx FIFO 1 interrupts management ******************************************/
5368   if (RxFifo1ITs != 0U)
5369   {
5370     /* Clear the Rx FIFO 1 flags */
5371     __HAL_FDCAN_CLEAR_FLAG(hfdcan, RxFifo1ITs);
5372 
5373 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5374     /* Call registered callback*/
5375     hfdcan->RxFifo1Callback(hfdcan, RxFifo1ITs);
5376 #else
5377     /* Rx FIFO 1 Callback */
5378     HAL_FDCAN_RxFifo1Callback(hfdcan, RxFifo1ITs);
5379 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5380   }
5381 
5382   /* Tx FIFO empty interrupt management ***************************************/
5383   if (__HAL_FDCAN_GET_IT_SOURCE(hfdcan, FDCAN_IT_TX_FIFO_EMPTY) != 0U)
5384   {
5385     if (__HAL_FDCAN_GET_FLAG(hfdcan, FDCAN_FLAG_TX_FIFO_EMPTY) != 0U)
5386     {
5387       /* Clear the Tx FIFO empty flag */
5388       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TX_FIFO_EMPTY);
5389 
5390 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5391       /* Call registered callback*/
5392       hfdcan->TxFifoEmptyCallback(hfdcan);
5393 #else
5394       /* Tx FIFO empty Callback */
5395       HAL_FDCAN_TxFifoEmptyCallback(hfdcan);
5396 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5397     }
5398   }
5399 
5400   /* Transmission Complete interrupt management *******************************/
5401   if (__HAL_FDCAN_GET_IT_SOURCE(hfdcan, FDCAN_IT_TX_COMPLETE) != 0U)
5402   {
5403     if (__HAL_FDCAN_GET_FLAG(hfdcan, FDCAN_FLAG_TX_COMPLETE) != 0U)
5404     {
5405       /* List of transmitted monitored buffers */
5406       TransmittedBuffers = hfdcan->Instance->TXBTO;
5407       TransmittedBuffers &= hfdcan->Instance->TXBTIE;
5408 
5409       /* Clear the Transmission Complete flag */
5410       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TX_COMPLETE);
5411 
5412 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5413       /* Call registered callback*/
5414       hfdcan->TxBufferCompleteCallback(hfdcan, TransmittedBuffers);
5415 #else
5416       /* Transmission Complete Callback */
5417       HAL_FDCAN_TxBufferCompleteCallback(hfdcan, TransmittedBuffers);
5418 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5419     }
5420   }
5421 
5422   /* Rx Buffer New Message interrupt management *******************************/
5423   if (__HAL_FDCAN_GET_IT_SOURCE(hfdcan, FDCAN_IT_RX_BUFFER_NEW_MESSAGE) != 0U)
5424   {
5425     if (__HAL_FDCAN_GET_FLAG(hfdcan, FDCAN_FLAG_RX_BUFFER_NEW_MESSAGE) != 0U)
5426     {
5427       /* Clear the Rx Buffer New Message flag */
5428       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_RX_BUFFER_NEW_MESSAGE);
5429 
5430 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5431       /* Call registered callback*/
5432       hfdcan->RxBufferNewMessageCallback(hfdcan);
5433 #else
5434       /* Rx Buffer New Message Callback */
5435       HAL_FDCAN_RxBufferNewMessageCallback(hfdcan);
5436 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5437     }
5438   }
5439 
5440   /* Timestamp Wraparound interrupt management ********************************/
5441   if (__HAL_FDCAN_GET_IT_SOURCE(hfdcan, FDCAN_IT_TIMESTAMP_WRAPAROUND) != 0U)
5442   {
5443     if (__HAL_FDCAN_GET_FLAG(hfdcan, FDCAN_FLAG_TIMESTAMP_WRAPAROUND) != 0U)
5444     {
5445       /* Clear the Timestamp Wraparound flag */
5446       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TIMESTAMP_WRAPAROUND);
5447 
5448 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5449       /* Call registered callback*/
5450       hfdcan->TimestampWraparoundCallback(hfdcan);
5451 #else
5452       /* Timestamp Wraparound Callback */
5453       HAL_FDCAN_TimestampWraparoundCallback(hfdcan);
5454 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5455     }
5456   }
5457 
5458   /* Timeout Occurred interrupt management ************************************/
5459   if (__HAL_FDCAN_GET_IT_SOURCE(hfdcan, FDCAN_IT_TIMEOUT_OCCURRED) != 0U)
5460   {
5461     if (__HAL_FDCAN_GET_FLAG(hfdcan, FDCAN_FLAG_TIMEOUT_OCCURRED) != 0U)
5462     {
5463       /* Clear the Timeout Occurred flag */
5464       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TIMEOUT_OCCURRED);
5465 
5466 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5467       /* Call registered callback*/
5468       hfdcan->TimeoutOccurredCallback(hfdcan);
5469 #else
5470       /* Timeout Occurred Callback */
5471       HAL_FDCAN_TimeoutOccurredCallback(hfdcan);
5472 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5473     }
5474   }
5475 
5476   /* Message RAM access failure interrupt management **************************/
5477   if (__HAL_FDCAN_GET_IT_SOURCE(hfdcan, FDCAN_IT_RAM_ACCESS_FAILURE) != 0U)
5478   {
5479     if (__HAL_FDCAN_GET_FLAG(hfdcan, FDCAN_FLAG_RAM_ACCESS_FAILURE) != 0U)
5480     {
5481       /* Clear the Message RAM access failure flag */
5482       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_RAM_ACCESS_FAILURE);
5483 
5484       /* Update error code */
5485       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_RAM_ACCESS;
5486     }
5487   }
5488 
5489   /* Error Status interrupts management ***************************************/
5490   if (ErrorStatusITs != 0U)
5491   {
5492     /* Clear the Error flags */
5493     __HAL_FDCAN_CLEAR_FLAG(hfdcan, ErrorStatusITs);
5494 
5495 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5496     /* Call registered callback*/
5497     hfdcan->ErrorStatusCallback(hfdcan, ErrorStatusITs);
5498 #else
5499     /* Error Status Callback */
5500     HAL_FDCAN_ErrorStatusCallback(hfdcan, ErrorStatusITs);
5501 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5502   }
5503 
5504   /* Error interrupts management **********************************************/
5505   if (Errors != 0U)
5506   {
5507     /* Clear the Error flags */
5508     __HAL_FDCAN_CLEAR_FLAG(hfdcan, Errors);
5509 
5510     /* Update error code */
5511     hfdcan->ErrorCode |= Errors;
5512   }
5513 
5514   if (hfdcan->Instance == FDCAN1)
5515   {
5516     if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != 0U)
5517     {
5518       TTSchedSyncITs = hfdcan->ttcan->TTIR & FDCAN_TT_SCHEDULE_SYNC_MASK;
5519       TTSchedSyncITs &= hfdcan->ttcan->TTIE;
5520       TTTimeMarkITs = hfdcan->ttcan->TTIR & FDCAN_TT_TIME_MARK_MASK;
5521       TTTimeMarkITs &= hfdcan->ttcan->TTIE;
5522       TTGlobTimeITs = hfdcan->ttcan->TTIR & FDCAN_TT_GLOBAL_TIME_MASK;
5523       TTGlobTimeITs &= hfdcan->ttcan->TTIE;
5524       TTDistErrors = hfdcan->ttcan->TTIR & FDCAN_TT_DISTURBING_ERROR_MASK;
5525       TTDistErrors &= hfdcan->ttcan->TTIE;
5526       TTFatalErrors = hfdcan->ttcan->TTIR & FDCAN_TT_FATAL_ERROR_MASK;
5527       TTFatalErrors &= hfdcan->ttcan->TTIE;
5528 
5529       /* TT Schedule Synchronization interrupts management **********************/
5530       if (TTSchedSyncITs != 0U)
5531       {
5532         /* Clear the TT Schedule Synchronization flags */
5533         __HAL_FDCAN_TT_CLEAR_FLAG(hfdcan, TTSchedSyncITs);
5534 
5535 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5536         /* Call registered callback*/
5537         hfdcan->TT_ScheduleSyncCallback(hfdcan, TTSchedSyncITs);
5538 #else
5539         /* TT Schedule Synchronization Callback */
5540         HAL_FDCAN_TT_ScheduleSyncCallback(hfdcan, TTSchedSyncITs);
5541 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5542       }
5543 
5544       /* TT Time Mark interrupts management *************************************/
5545       if (TTTimeMarkITs != 0U)
5546       {
5547         /* Clear the TT Time Mark flags */
5548         __HAL_FDCAN_TT_CLEAR_FLAG(hfdcan, TTTimeMarkITs);
5549 
5550 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5551         /* Call registered callback*/
5552         hfdcan->TT_TimeMarkCallback(hfdcan, TTTimeMarkITs);
5553 #else
5554         /* TT Time Mark Callback */
5555         HAL_FDCAN_TT_TimeMarkCallback(hfdcan, TTTimeMarkITs);
5556 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5557       }
5558 
5559       /* TT Stop Watch interrupt management *************************************/
5560       if (__HAL_FDCAN_TT_GET_IT_SOURCE(hfdcan, FDCAN_TT_IT_STOP_WATCH) != 0U)
5561       {
5562         if (__HAL_FDCAN_TT_GET_FLAG(hfdcan, FDCAN_TT_FLAG_STOP_WATCH) != 0U)
5563         {
5564           /* Retrieve Stop watch Time and Cycle count */
5565           SWTime = ((hfdcan->ttcan->TTCPT & FDCAN_TTCPT_SWV) >> FDCAN_TTCPT_SWV_Pos);
5566           SWCycleCount = ((hfdcan->ttcan->TTCPT & FDCAN_TTCPT_CCV) >> FDCAN_TTCPT_CCV_Pos);
5567 
5568           /* Clear the TT Stop Watch flag */
5569           __HAL_FDCAN_TT_CLEAR_FLAG(hfdcan, FDCAN_TT_FLAG_STOP_WATCH);
5570 
5571 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5572           /* Call registered callback*/
5573           hfdcan->TT_StopWatchCallback(hfdcan, SWTime, SWCycleCount);
5574 #else
5575           /* TT Stop Watch Callback */
5576           HAL_FDCAN_TT_StopWatchCallback(hfdcan, SWTime, SWCycleCount);
5577 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5578         }
5579       }
5580 
5581       /* TT Global Time interrupts management ***********************************/
5582       if (TTGlobTimeITs != 0U)
5583       {
5584         /* Clear the TT Global Time flags */
5585         __HAL_FDCAN_TT_CLEAR_FLAG(hfdcan, TTGlobTimeITs);
5586 
5587 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5588         /* Call registered callback*/
5589         hfdcan->TT_GlobalTimeCallback(hfdcan, TTGlobTimeITs);
5590 #else
5591         /* TT Global Time Callback */
5592         HAL_FDCAN_TT_GlobalTimeCallback(hfdcan, TTGlobTimeITs);
5593 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5594       }
5595 
5596       /* TT Disturbing Error interrupts management ******************************/
5597       if (TTDistErrors != 0U)
5598       {
5599         /* Clear the TT Disturbing Error flags */
5600         __HAL_FDCAN_TT_CLEAR_FLAG(hfdcan, TTDistErrors);
5601 
5602         /* Update error code */
5603         hfdcan->ErrorCode |= TTDistErrors;
5604       }
5605 
5606       /* TT Fatal Error interrupts management ***********************************/
5607       if (TTFatalErrors != 0U)
5608       {
5609         /* Clear the TT Fatal Error flags */
5610         __HAL_FDCAN_TT_CLEAR_FLAG(hfdcan, TTFatalErrors);
5611 
5612         /* Update error code */
5613         hfdcan->ErrorCode |= TTFatalErrors;
5614       }
5615     }
5616   }
5617 
5618   if (hfdcan->ErrorCode != HAL_FDCAN_ERROR_NONE)
5619   {
5620 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
5621     /* Call registered callback*/
5622     hfdcan->ErrorCallback(hfdcan);
5623 #else
5624     /* Error Callback */
5625     HAL_FDCAN_ErrorCallback(hfdcan);
5626 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
5627   }
5628 }
5629 
5630 /**
5631   * @}
5632   */
5633 
5634 /** @defgroup FDCAN_Exported_Functions_Group6 Callback functions
5635  *  @brief   FDCAN Callback functions
5636  *
5637 @verbatim
5638   ==============================================================================
5639                           ##### Callback functions #####
5640   ==============================================================================
5641     [..]
5642     This subsection provides the following callback functions:
5643       (+) HAL_FDCAN_ClockCalibrationCallback
5644       (+) HAL_FDCAN_TxEventFifoCallback
5645       (+) HAL_FDCAN_RxFifo0Callback
5646       (+) HAL_FDCAN_RxFifo1Callback
5647       (+) HAL_FDCAN_TxFifoEmptyCallback
5648       (+) HAL_FDCAN_TxBufferCompleteCallback
5649       (+) HAL_FDCAN_TxBufferAbortCallback
5650       (+) HAL_FDCAN_RxBufferNewMessageCallback
5651       (+) HAL_FDCAN_HighPriorityMessageCallback
5652       (+) HAL_FDCAN_TimestampWraparoundCallback
5653       (+) HAL_FDCAN_TimeoutOccurredCallback
5654       (+) HAL_FDCAN_ErrorCallback
5655       (+) HAL_FDCAN_ErrorStatusCallback
5656       (+) HAL_FDCAN_TT_ScheduleSyncCallback
5657       (+) HAL_FDCAN_TT_TimeMarkCallback
5658       (+) HAL_FDCAN_TT_StopWatchCallback
5659       (+) HAL_FDCAN_TT_GlobalTimeCallback
5660 
5661 @endverbatim
5662   * @{
5663   */
5664 
5665 /**
5666   * @brief  Clock Calibration callback.
5667   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5668   *         the configuration information for the specified FDCAN.
5669   * @param  ClkCalibrationITs indicates which Clock Calibration interrupts are signaled.
5670   *         This parameter can be any combination of @arg FDCAN_Clock_Calibration_Interrupts.
5671   * @retval None
5672   */
HAL_FDCAN_ClockCalibrationCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t ClkCalibrationITs)5673 __weak void HAL_FDCAN_ClockCalibrationCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t ClkCalibrationITs)
5674 {
5675   /* Prevent unused argument(s) compilation warning */
5676   UNUSED(hfdcan);
5677   UNUSED(ClkCalibrationITs);
5678 
5679   /* NOTE : This function Should not be modified, when the callback is needed,
5680             the HAL_FDCAN_ClockCalibrationCallback could be implemented in the user file
5681    */
5682 }
5683 
5684 /**
5685   * @brief  Tx Event callback.
5686   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5687   *         the configuration information for the specified FDCAN.
5688   * @param  TxEventFifoITs indicates which Tx Event FIFO interrupts are signaled.
5689   *         This parameter can be any combination of @arg FDCAN_Tx_Event_Fifo_Interrupts.
5690   * @retval None
5691   */
HAL_FDCAN_TxEventFifoCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t TxEventFifoITs)5692 __weak void HAL_FDCAN_TxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t TxEventFifoITs)
5693 {
5694   /* Prevent unused argument(s) compilation warning */
5695   UNUSED(hfdcan);
5696   UNUSED(TxEventFifoITs);
5697 
5698   /* NOTE : This function Should not be modified, when the callback is needed,
5699             the HAL_FDCAN_TxEventFifoCallback could be implemented in the user file
5700    */
5701 }
5702 
5703 /**
5704   * @brief  Rx FIFO 0 callback.
5705   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5706   *         the configuration information for the specified FDCAN.
5707   * @param  RxFifo0ITs indicates which Rx FIFO 0 interrupts are signaled.
5708   *         This parameter can be any combination of @arg FDCAN_Rx_Fifo0_Interrupts.
5709   * @retval None
5710   */
HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef * hfdcan,uint32_t RxFifo0ITs)5711 __weak void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
5712 {
5713   /* Prevent unused argument(s) compilation warning */
5714   UNUSED(hfdcan);
5715   UNUSED(RxFifo0ITs);
5716 
5717   /* NOTE : This function Should not be modified, when the callback is needed,
5718             the HAL_FDCAN_RxFifo0Callback could be implemented in the user file
5719    */
5720 }
5721 
5722 /**
5723   * @brief  Rx FIFO 1 callback.
5724   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5725   *         the configuration information for the specified FDCAN.
5726   * @param  RxFifo1ITs indicates which Rx FIFO 1 interrupts are signaled.
5727   *         This parameter can be any combination of @arg FDCAN_Rx_Fifo1_Interrupts.
5728   * @retval None
5729   */
HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef * hfdcan,uint32_t RxFifo1ITs)5730 __weak void HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo1ITs)
5731 {
5732   /* Prevent unused argument(s) compilation warning */
5733   UNUSED(hfdcan);
5734   UNUSED(RxFifo1ITs);
5735 
5736   /* NOTE : This function Should not be modified, when the callback is needed,
5737             the HAL_FDCAN_RxFifo1Callback could be implemented in the user file
5738    */
5739 }
5740 
5741 /**
5742   * @brief  Tx FIFO Empty callback.
5743   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5744   *         the configuration information for the specified FDCAN.
5745   * @retval None
5746   */
HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef * hfdcan)5747 __weak void HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef *hfdcan)
5748 {
5749   /* Prevent unused argument(s) compilation warning */
5750   UNUSED(hfdcan);
5751 
5752   /* NOTE : This function Should not be modified, when the callback is needed,
5753             the HAL_FDCAN_TxFifoEmptyCallback could be implemented in the user file
5754    */
5755 }
5756 
5757 /**
5758   * @brief  Transmission Complete callback.
5759   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5760   *         the configuration information for the specified FDCAN.
5761   * @param  BufferIndexes Indexes of the transmitted buffers.
5762   *         This parameter can be any combination of @arg FDCAN_Tx_location.
5763   * @retval None
5764   */
HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t BufferIndexes)5765 __weak void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes)
5766 {
5767   /* Prevent unused argument(s) compilation warning */
5768   UNUSED(hfdcan);
5769   UNUSED(BufferIndexes);
5770 
5771   /* NOTE : This function Should not be modified, when the callback is needed,
5772             the HAL_FDCAN_TxBufferCompleteCallback could be implemented in the user file
5773    */
5774 }
5775 
5776 /**
5777   * @brief  Transmission Cancellation callback.
5778   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5779   *         the configuration information for the specified FDCAN.
5780   * @param  BufferIndexes Indexes of the aborted buffers.
5781   *         This parameter can be any combination of @arg FDCAN_Tx_location.
5782   * @retval None
5783   */
HAL_FDCAN_TxBufferAbortCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t BufferIndexes)5784 __weak void HAL_FDCAN_TxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes)
5785 {
5786   /* Prevent unused argument(s) compilation warning */
5787   UNUSED(hfdcan);
5788   UNUSED(BufferIndexes);
5789 
5790   /* NOTE : This function Should not be modified, when the callback is needed,
5791             the HAL_FDCAN_TxBufferAbortCallback could be implemented in the user file
5792    */
5793 }
5794 
5795 /**
5796   * @brief  Rx Buffer New Message callback.
5797   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5798   *         the configuration information for the specified FDCAN.
5799   * @retval None
5800   */
HAL_FDCAN_RxBufferNewMessageCallback(FDCAN_HandleTypeDef * hfdcan)5801 __weak void HAL_FDCAN_RxBufferNewMessageCallback(FDCAN_HandleTypeDef *hfdcan)
5802 {
5803   /* Prevent unused argument(s) compilation warning */
5804   UNUSED(hfdcan);
5805 
5806   /* NOTE : This function Should not be modified, when the callback is needed,
5807             the HAL_FDCAN_RxBufferNewMessageCallback could be implemented in the user file
5808    */
5809 }
5810 
5811 /**
5812   * @brief  Timestamp Wraparound callback.
5813   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5814   *         the configuration information for the specified FDCAN.
5815   * @retval None
5816   */
HAL_FDCAN_TimestampWraparoundCallback(FDCAN_HandleTypeDef * hfdcan)5817 __weak void HAL_FDCAN_TimestampWraparoundCallback(FDCAN_HandleTypeDef *hfdcan)
5818 {
5819   /* Prevent unused argument(s) compilation warning */
5820   UNUSED(hfdcan);
5821 
5822   /* NOTE : This function Should not be modified, when the callback is needed,
5823             the HAL_FDCAN_TimestampWraparoundCallback could be implemented in the user file
5824    */
5825 }
5826 
5827 /**
5828   * @brief  Timeout Occurred callback.
5829   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5830   *         the configuration information for the specified FDCAN.
5831   * @retval None
5832   */
HAL_FDCAN_TimeoutOccurredCallback(FDCAN_HandleTypeDef * hfdcan)5833 __weak void HAL_FDCAN_TimeoutOccurredCallback(FDCAN_HandleTypeDef *hfdcan)
5834 {
5835   /* Prevent unused argument(s) compilation warning */
5836   UNUSED(hfdcan);
5837 
5838   /* NOTE : This function Should not be modified, when the callback is needed,
5839             the HAL_FDCAN_TimeoutOccurredCallback could be implemented in the user file
5840    */
5841 }
5842 
5843 /**
5844   * @brief  High Priority Message callback.
5845   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5846   *         the configuration information for the specified FDCAN.
5847   * @retval None
5848   */
HAL_FDCAN_HighPriorityMessageCallback(FDCAN_HandleTypeDef * hfdcan)5849 __weak void HAL_FDCAN_HighPriorityMessageCallback(FDCAN_HandleTypeDef *hfdcan)
5850 {
5851   /* Prevent unused argument(s) compilation warning */
5852   UNUSED(hfdcan);
5853 
5854   /* NOTE : This function Should not be modified, when the callback is needed,
5855             the HAL_FDCAN_HighPriorityMessageCallback could be implemented in the user file
5856    */
5857 }
5858 
5859 /**
5860   * @brief  Error callback.
5861   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5862   *         the configuration information for the specified FDCAN.
5863   * @retval None
5864   */
HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef * hfdcan)5865 __weak void HAL_FDCAN_ErrorCallback(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_ErrorCallback could be implemented in the user file
5872    */
5873 }
5874 
5875 /**
5876   * @brief  Error status callback.
5877   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5878   *         the configuration information for the specified FDCAN.
5879   * @param  ErrorStatusITs indicates which Error Status interrupts are signaled.
5880   *         This parameter can be any combination of @arg FDCAN_Error_Status_Interrupts.
5881   * @retval None
5882   */
HAL_FDCAN_ErrorStatusCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t ErrorStatusITs)5883 __weak void HAL_FDCAN_ErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t ErrorStatusITs)
5884 {
5885   /* Prevent unused argument(s) compilation warning */
5886   UNUSED(hfdcan);
5887   UNUSED(ErrorStatusITs);
5888 
5889   /* NOTE : This function Should not be modified, when the callback is needed,
5890             the HAL_FDCAN_ErrorStatusCallback could be implemented in the user file
5891    */
5892 }
5893 
5894 /**
5895   * @brief  TT Schedule Synchronization callback.
5896   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5897   *         the configuration information for the specified FDCAN.
5898   * @param  TTSchedSyncITs indicates which TT Schedule Synchronization interrupts are signaled.
5899   *         This parameter can be any combination of @arg FDCAN_TTScheduleSynchronization_Interrupts.
5900   * @retval None
5901   */
HAL_FDCAN_TT_ScheduleSyncCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t TTSchedSyncITs)5902 __weak void HAL_FDCAN_TT_ScheduleSyncCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t TTSchedSyncITs)
5903 {
5904   /* Prevent unused argument(s) compilation warning */
5905   UNUSED(hfdcan);
5906   UNUSED(TTSchedSyncITs);
5907 
5908   /* NOTE : This function Should not be modified, when the callback is needed,
5909             the HAL_FDCAN_TT_ScheduleSyncCallback could be implemented in the user file
5910    */
5911 }
5912 
5913 /**
5914   * @brief  TT Time Mark callback.
5915   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5916   *         the configuration information for the specified FDCAN.
5917   * @param  TTTimeMarkITs indicates which TT Schedule Synchronization interrupts are signaled.
5918   *         This parameter can be any combination of @arg FDCAN_TTTimeMark_Interrupts.
5919   * @retval None
5920   */
HAL_FDCAN_TT_TimeMarkCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t TTTimeMarkITs)5921 __weak void HAL_FDCAN_TT_TimeMarkCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t TTTimeMarkITs)
5922 {
5923   /* Prevent unused argument(s) compilation warning */
5924   UNUSED(hfdcan);
5925   UNUSED(TTTimeMarkITs);
5926 
5927   /* NOTE : This function Should not be modified, when the callback is needed,
5928             the HAL_FDCAN_TT_TimeMarkCallback could be implemented in the user file
5929    */
5930 }
5931 
5932 /**
5933   * @brief  TT Stop Watch callback.
5934   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5935   *         the configuration information for the specified FDCAN.
5936   * @param  SWTime Time Value captured at the Stop Watch Trigger pin (fdcan1_swt) falling/rising
5937   *         edge (as configured via HAL_FDCAN_TTConfigStopWatch).
5938   *         This parameter is a number between 0 and 0xFFFF.
5939   * @param  SWCycleCount Cycle count value captured together with SWTime.
5940   *         This parameter is a number between 0 and 0x3F.
5941   * @retval None
5942   */
HAL_FDCAN_TT_StopWatchCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t SWTime,uint32_t SWCycleCount)5943 __weak void HAL_FDCAN_TT_StopWatchCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t SWTime, uint32_t SWCycleCount)
5944 {
5945   /* Prevent unused argument(s) compilation warning */
5946   UNUSED(hfdcan);
5947   UNUSED(SWTime);
5948   UNUSED(SWCycleCount);
5949 
5950   /* NOTE : This function Should not be modified, when the callback is needed,
5951             the HAL_FDCAN_TT_StopWatchCallback could be implemented in the user file
5952    */
5953 }
5954 
5955 /**
5956   * @brief  TT Global Time callback.
5957   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5958   *         the configuration information for the specified FDCAN.
5959   * @param  TTGlobTimeITs indicates which TT Global Time interrupts are signaled.
5960   *         This parameter can be any combination of @arg FDCAN_TTGlobalTime_Interrupts.
5961   * @retval None
5962   */
HAL_FDCAN_TT_GlobalTimeCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t TTGlobTimeITs)5963 __weak void HAL_FDCAN_TT_GlobalTimeCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t TTGlobTimeITs)
5964 {
5965   /* Prevent unused argument(s) compilation warning */
5966   UNUSED(hfdcan);
5967   UNUSED(TTGlobTimeITs);
5968 
5969   /* NOTE : This function Should not be modified, when the callback is needed,
5970             the HAL_FDCAN_TT_GlobalTimeCallback could be implemented in the user file
5971    */
5972 }
5973 
5974 /**
5975   * @}
5976   */
5977 
5978 /** @defgroup FDCAN_Exported_Functions_Group7 Peripheral State functions
5979  *  @brief   FDCAN Peripheral State functions
5980  *
5981 @verbatim
5982   ==============================================================================
5983                       ##### Peripheral State functions #####
5984   ==============================================================================
5985     [..]
5986     This subsection provides functions allowing to :
5987       (+) HAL_FDCAN_GetState()  : Return the FDCAN state.
5988       (+) HAL_FDCAN_GetError()  : Return the FDCAN error code if any.
5989 
5990 @endverbatim
5991   * @{
5992   */
5993 /**
5994   * @brief  Return the FDCAN state
5995   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5996   *         the configuration information for the specified FDCAN.
5997   * @retval HAL state
5998   */
HAL_FDCAN_GetState(FDCAN_HandleTypeDef * hfdcan)5999 HAL_FDCAN_StateTypeDef HAL_FDCAN_GetState(FDCAN_HandleTypeDef *hfdcan)
6000 {
6001   /* Return FDCAN state */
6002   return hfdcan->State;
6003 }
6004 
6005 /**
6006   * @brief  Return the FDCAN error code
6007   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
6008   *         the configuration information for the specified FDCAN.
6009   * @retval FDCAN Error Code
6010   */
HAL_FDCAN_GetError(FDCAN_HandleTypeDef * hfdcan)6011 uint32_t HAL_FDCAN_GetError(FDCAN_HandleTypeDef *hfdcan)
6012 {
6013   /* Return FDCAN error code */
6014   return hfdcan->ErrorCode;
6015 }
6016 
6017 /**
6018   * @}
6019   */
6020 
6021 /**
6022   * @}
6023   */
6024 
6025 /** @addtogroup FDCAN_Private_Functions
6026   * @{
6027   */
6028 
6029 /**
6030   * @brief  Calculate each RAM block start address and size
6031   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
6032   *         the configuration information for the specified FDCAN.
6033   * @retval HAL status
6034  */
FDCAN_CalcultateRamBlockAddresses(FDCAN_HandleTypeDef * hfdcan)6035 static HAL_StatusTypeDef FDCAN_CalcultateRamBlockAddresses(FDCAN_HandleTypeDef *hfdcan)
6036 {
6037   uint32_t RAMcounter;
6038   uint32_t StartAddress;
6039 
6040   StartAddress = hfdcan->Init.MessageRAMOffset;
6041 
6042   /* Standard filter list start address */
6043   MODIFY_REG(hfdcan->Instance->SIDFC, FDCAN_SIDFC_FLSSA, (StartAddress << FDCAN_SIDFC_FLSSA_Pos));
6044 
6045   /* Standard filter elements number */
6046   MODIFY_REG(hfdcan->Instance->SIDFC, FDCAN_SIDFC_LSS, (hfdcan->Init.StdFiltersNbr << FDCAN_SIDFC_LSS_Pos));
6047 
6048   /* Extended filter list start address */
6049   StartAddress += hfdcan->Init.StdFiltersNbr;
6050   MODIFY_REG(hfdcan->Instance->XIDFC, FDCAN_XIDFC_FLESA, (StartAddress << FDCAN_XIDFC_FLESA_Pos));
6051 
6052   /* Extended filter elements number */
6053   MODIFY_REG(hfdcan->Instance->XIDFC, FDCAN_XIDFC_LSE, (hfdcan->Init.ExtFiltersNbr << FDCAN_XIDFC_LSE_Pos));
6054 
6055   /* Rx FIFO 0 start address */
6056   StartAddress += (hfdcan->Init.ExtFiltersNbr * 2U);
6057   MODIFY_REG(hfdcan->Instance->RXF0C, FDCAN_RXF0C_F0SA, (StartAddress << FDCAN_RXF0C_F0SA_Pos));
6058 
6059   /* Rx FIFO 0 elements number */
6060   MODIFY_REG(hfdcan->Instance->RXF0C, FDCAN_RXF0C_F0S, (hfdcan->Init.RxFifo0ElmtsNbr << FDCAN_RXF0C_F0S_Pos));
6061 
6062   /* Rx FIFO 1 start address */
6063   StartAddress += (hfdcan->Init.RxFifo0ElmtsNbr * hfdcan->Init.RxFifo0ElmtSize);
6064   MODIFY_REG(hfdcan->Instance->RXF1C, FDCAN_RXF1C_F1SA, (StartAddress << FDCAN_RXF1C_F1SA_Pos));
6065 
6066   /* Rx FIFO 1 elements number */
6067   MODIFY_REG(hfdcan->Instance->RXF1C, FDCAN_RXF1C_F1S, (hfdcan->Init.RxFifo1ElmtsNbr << FDCAN_RXF1C_F1S_Pos));
6068 
6069   /* Rx buffer list start address */
6070   StartAddress += (hfdcan->Init.RxFifo1ElmtsNbr * hfdcan->Init.RxFifo1ElmtSize);
6071   MODIFY_REG(hfdcan->Instance->RXBC, FDCAN_RXBC_RBSA, (StartAddress << FDCAN_RXBC_RBSA_Pos));
6072 
6073   /* Tx event FIFO start address */
6074   StartAddress += (hfdcan->Init.RxBuffersNbr * hfdcan->Init.RxBufferSize);
6075   MODIFY_REG(hfdcan->Instance->TXEFC, FDCAN_TXEFC_EFSA, (StartAddress << FDCAN_TXEFC_EFSA_Pos));
6076 
6077   /* Tx event FIFO elements number */
6078   MODIFY_REG(hfdcan->Instance->TXEFC, FDCAN_TXEFC_EFS, (hfdcan->Init.TxEventsNbr << FDCAN_TXEFC_EFS_Pos));
6079 
6080   /* Tx buffer list start address */
6081   StartAddress += (hfdcan->Init.TxEventsNbr * 2U);
6082   MODIFY_REG(hfdcan->Instance->TXBC, FDCAN_TXBC_TBSA, (StartAddress << FDCAN_TXBC_TBSA_Pos));
6083 
6084   /* Dedicated Tx buffers number */
6085   MODIFY_REG(hfdcan->Instance->TXBC, FDCAN_TXBC_NDTB, (hfdcan->Init.TxBuffersNbr << FDCAN_TXBC_NDTB_Pos));
6086 
6087   /* Tx FIFO/queue elements number */
6088   MODIFY_REG(hfdcan->Instance->TXBC, FDCAN_TXBC_TFQS, (hfdcan->Init.TxFifoQueueElmtsNbr << FDCAN_TXBC_TFQS_Pos));
6089 
6090   hfdcan->msgRam.StandardFilterSA = SRAMCAN_BASE + (hfdcan->Init.MessageRAMOffset * 4U);
6091   hfdcan->msgRam.ExtendedFilterSA = hfdcan->msgRam.StandardFilterSA + (hfdcan->Init.StdFiltersNbr * 4U);
6092   hfdcan->msgRam.RxFIFO0SA = hfdcan->msgRam.ExtendedFilterSA + (hfdcan->Init.ExtFiltersNbr * 2U * 4U);
6093   hfdcan->msgRam.RxFIFO1SA = hfdcan->msgRam.RxFIFO0SA + (hfdcan->Init.RxFifo0ElmtsNbr * hfdcan->Init.RxFifo0ElmtSize * 4U);
6094   hfdcan->msgRam.RxBufferSA = hfdcan->msgRam.RxFIFO1SA + (hfdcan->Init.RxFifo1ElmtsNbr * hfdcan->Init.RxFifo1ElmtSize * 4U);
6095   hfdcan->msgRam.TxEventFIFOSA = hfdcan->msgRam.RxBufferSA + (hfdcan->Init.RxBuffersNbr * hfdcan->Init.RxBufferSize * 4U);
6096   hfdcan->msgRam.TxBufferSA = hfdcan->msgRam.TxEventFIFOSA + (hfdcan->Init.TxEventsNbr * 2U * 4U);
6097   hfdcan->msgRam.TxFIFOQSA = hfdcan->msgRam.TxBufferSA + (hfdcan->Init.TxBuffersNbr * hfdcan->Init.TxElmtSize * 4U);
6098 
6099   hfdcan->msgRam.EndAddress = hfdcan->msgRam.TxFIFOQSA + (hfdcan->Init.TxFifoQueueElmtsNbr * hfdcan->Init.TxElmtSize * 4U);
6100 
6101   if (hfdcan->msgRam.EndAddress > FDCAN_MESSAGE_RAM_END_ADDRESS) /* Last address of the Message RAM */
6102   {
6103     /* Update error code.
6104        Message RAM overflow */
6105     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
6106 
6107     /* Change FDCAN state */
6108     hfdcan->State = HAL_FDCAN_STATE_ERROR;
6109 
6110     return HAL_ERROR;
6111   }
6112   else
6113   {
6114     /* Flush the allocated Message RAM area */
6115     for (RAMcounter = hfdcan->msgRam.StandardFilterSA; RAMcounter < hfdcan->msgRam.EndAddress; RAMcounter += 4U)
6116     {
6117       *(uint32_t *)(RAMcounter) = 0x00000000;
6118     }
6119   }
6120 
6121   /* Return function status */
6122   return HAL_OK;
6123 }
6124 
6125 /**
6126   * @brief  Copy Tx message to the message RAM.
6127   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
6128   *         the configuration information for the specified FDCAN.
6129   * @param  pTxHeader pointer to a FDCAN_TxHeaderTypeDef structure.
6130   * @param  pTxData pointer to a buffer containing the payload of the Tx frame.
6131   * @param  BufferIndex index of the buffer to be configured.
6132   * @retval HAL status
6133  */
FDCAN_CopyMessageToRAM(FDCAN_HandleTypeDef * hfdcan,FDCAN_TxHeaderTypeDef * pTxHeader,uint8_t * pTxData,uint32_t BufferIndex)6134 static void FDCAN_CopyMessageToRAM(FDCAN_HandleTypeDef *hfdcan, FDCAN_TxHeaderTypeDef *pTxHeader, uint8_t *pTxData, uint32_t BufferIndex)
6135 {
6136   uint32_t TxElementW1;
6137   uint32_t TxElementW2;
6138   uint32_t *TxAddress;
6139   uint32_t ByteCounter;
6140 
6141   /* Build first word of Tx header element */
6142   if (pTxHeader->IdType == FDCAN_STANDARD_ID)
6143   {
6144     TxElementW1 = (pTxHeader->ErrorStateIndicator |
6145                    FDCAN_STANDARD_ID |
6146                    pTxHeader->TxFrameType |
6147                    (pTxHeader->Identifier << 18));
6148   }
6149   else /* pTxHeader->IdType == FDCAN_EXTENDED_ID */
6150   {
6151     TxElementW1 = (pTxHeader->ErrorStateIndicator |
6152                    FDCAN_EXTENDED_ID |
6153                    pTxHeader->TxFrameType |
6154                    pTxHeader->Identifier);
6155   }
6156 
6157   /* Build second word of Tx header element */
6158   TxElementW2 = ((pTxHeader->MessageMarker << 24) |
6159                  pTxHeader->TxEventFifoControl |
6160                  pTxHeader->FDFormat |
6161                  pTxHeader->BitRateSwitch |
6162                  pTxHeader->DataLength);
6163 
6164   /* Calculate Tx element address */
6165   TxAddress = (uint32_t *)(hfdcan->msgRam.TxBufferSA + (BufferIndex * hfdcan->Init.TxElmtSize * 4U));
6166 
6167   /* Write Tx element header to the message RAM */
6168   *TxAddress = TxElementW1;
6169   TxAddress++;
6170   *TxAddress = TxElementW2;
6171   TxAddress++;
6172 
6173   /* Write Tx payload to the message RAM */
6174   for (ByteCounter = 0; ByteCounter < DLCtoBytes[pTxHeader->DataLength >> 16]; ByteCounter += 4U)
6175   {
6176     *TxAddress = (((uint32_t)pTxData[ByteCounter + 3U] << 24) |
6177                   ((uint32_t)pTxData[ByteCounter + 2U] << 16) |
6178                   ((uint32_t)pTxData[ByteCounter + 1U] << 8) |
6179                   (uint32_t)pTxData[ByteCounter]);
6180     TxAddress++;
6181   }
6182 }
6183 
6184 /**
6185   * @}
6186   */
6187 #endif /* HAL_FDCAN_MODULE_ENABLED */
6188 /**
6189   * @}
6190   */
6191 
6192 /**
6193   * @}
6194   */
6195 
6196 #endif /* FDCAN1 */
6197 
6198 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
6199