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