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