1 /**
2   ******************************************************************************
3   * @file    stm32u5xx_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) 2021 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_ConfigFilter
34             (++) HAL_FDCAN_ConfigGlobalFilter
35             (++) HAL_FDCAN_ConfigExtendedIdMask
36             (++) HAL_FDCAN_ConfigRxFifoOverwrite
37             (++) HAL_FDCAN_ConfigRamWatchdog
38             (++) HAL_FDCAN_ConfigTimestampCounter
39             (++) HAL_FDCAN_EnableTimestampCounter
40             (++) HAL_FDCAN_DisableTimestampCounter
41             (++) HAL_FDCAN_ConfigTimeoutCounter
42             (++) HAL_FDCAN_EnableTimeoutCounter
43             (++) HAL_FDCAN_DisableTimeoutCounter
44             (++) HAL_FDCAN_ConfigTxDelayCompensation
45             (++) HAL_FDCAN_EnableTxDelayCompensation
46             (++) HAL_FDCAN_DisableTxDelayCompensation
47             (++) HAL_FDCAN_EnableISOMode
48             (++) HAL_FDCAN_DisableISOMode
49             (++) HAL_FDCAN_EnableEdgeFiltering
50             (++) HAL_FDCAN_DisableEdgeFiltering
51 
52       (#) Start the FDCAN module using HAL_FDCAN_Start function. At this level
53           the node is active on the bus: it can send and receive messages.
54 
55       (#) The following Tx control functions can only be called when the FDCAN
56           module is started:
57             (++) HAL_FDCAN_AddMessageToTxFifoQ
58             (++) HAL_FDCAN_AbortTxRequest
59 
60       (#) After having submitted a Tx request in Tx Fifo or Queue, it is possible to
61           get Tx buffer location used to place the Tx request thanks to
62           HAL_FDCAN_GetLatestTxFifoQRequestBuffer API.
63           It is then possible to abort later on the corresponding Tx Request using
64           HAL_FDCAN_AbortTxRequest API.
65 
66       (#) When a message is received into the FDCAN message RAM, it can be
67           retrieved using the HAL_FDCAN_GetRxMessage function.
68 
69       (#) Calling the HAL_FDCAN_Stop function stops the FDCAN module by entering
70           it to initialization mode and re-enabling access to configuration
71           registers through the configuration functions listed here above.
72 
73       (#) All other control functions can be called any time after initialization
74           phase, no matter if the FDCAN module is started or stopped.
75 
76       *** Polling mode operation ***
77       ==============================
78     [..]
79         (#) Reception and transmission states can be monitored via the following
80             functions:
81               (++) HAL_FDCAN_IsTxBufferMessagePending
82               (++) HAL_FDCAN_GetRxFifoFillLevel
83               (++) HAL_FDCAN_GetTxFifoFreeLevel
84 
85       *** Interrupt mode operation ***
86       ================================
87       [..]
88         (#) There are two interrupt lines: line 0 and 1.
89             By default, all interrupts are assigned to line 0. Interrupt lines
90             can be configured using HAL_FDCAN_ConfigInterruptLines function.
91 
92         (#) Notifications are activated using HAL_FDCAN_ActivateNotification
93             function. Then, the process can be controlled through one of the
94             available user callbacks: HAL_FDCAN_xxxCallback.
95 
96   *** Callback registration ***
97   =============================================
98 
99   The compilation define USE_HAL_FDCAN_REGISTER_CALLBACKS when set to 1
100   allows the user to configure dynamically the driver callbacks.
101   Use Function HAL_FDCAN_RegisterCallback() or HAL_FDCAN_RegisterXXXCallback()
102   to register an interrupt callback.
103 
104   Function HAL_FDCAN_RegisterCallback() allows to register following callbacks:
105     (+) TxFifoEmptyCallback          : Tx Fifo Empty Callback.
106     (+) HighPriorityMessageCallback  : High Priority Message Callback.
107     (+) TimestampWraparoundCallback  : Timestamp Wraparound Callback.
108     (+) TimeoutOccurredCallback      : Timeout Occurred Callback.
109     (+) ErrorCallback                : Error Callback.
110     (+) MspInitCallback              : FDCAN MspInit.
111     (+) MspDeInitCallback            : FDCAN MspDeInit.
112   This function takes as parameters the HAL peripheral handle, the Callback ID
113   and a pointer to the user callback function.
114 
115   For specific callbacks TxEventFifoCallback, RxFifo0Callback, RxFifo1Callback,
116   TxBufferCompleteCallback, TxBufferAbortCallback and ErrorStatusCallback use dedicated
117   register callbacks: respectively HAL_FDCAN_RegisterTxEventFifoCallback(),
118   HAL_FDCAN_RegisterRxFifo0Callback(), HAL_FDCAN_RegisterRxFifo1Callback(),
119   HAL_FDCAN_RegisterTxBufferCompleteCallback(), HAL_FDCAN_RegisterTxBufferAbortCallback()
120   and HAL_FDCAN_RegisterErrorStatusCallback().
121 
122   Use function HAL_FDCAN_UnRegisterCallback() to reset a callback to the default
123   weak function.
124   HAL_FDCAN_UnRegisterCallback takes as parameters the HAL peripheral handle,
125   and the Callback ID.
126   This function allows to reset following callbacks:
127     (+) TxFifoEmptyCallback          : Tx Fifo Empty Callback.
128     (+) HighPriorityMessageCallback  : High Priority Message Callback.
129     (+) TimestampWraparoundCallback  : Timestamp Wraparound Callback.
130     (+) TimeoutOccurredCallback      : Timeout Occurred Callback.
131     (+) ErrorCallback                : Error Callback.
132     (+) MspInitCallback              : FDCAN MspInit.
133     (+) MspDeInitCallback            : FDCAN MspDeInit.
134 
135   For specific callbacks TxEventFifoCallback, RxFifo0Callback, RxFifo1Callback,
136   TxBufferCompleteCallback and TxBufferAbortCallback, use dedicated
137   unregister callbacks: respectively HAL_FDCAN_UnRegisterTxEventFifoCallback(),
138   HAL_FDCAN_UnRegisterRxFifo0Callback(), HAL_FDCAN_UnRegisterRxFifo1Callback(),
139   HAL_FDCAN_UnRegisterTxBufferCompleteCallback(), HAL_FDCAN_UnRegisterTxBufferAbortCallback()
140   and HAL_FDCAN_UnRegisterErrorStatusCallback().
141 
142   By default, after the HAL_FDCAN_Init() and when the state is HAL_FDCAN_STATE_RESET,
143   all callbacks are set to the corresponding weak functions:
144   examples HAL_FDCAN_ErrorCallback().
145   Exception done for MspInit and MspDeInit functions that are
146   reset to the legacy weak function in the HAL_FDCAN_Init()/ HAL_FDCAN_DeInit() only when
147   these callbacks are null (not registered beforehand).
148   if not, MspInit or MspDeInit are not null, the HAL_FDCAN_Init()/ HAL_FDCAN_DeInit()
149   keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
150 
151   Callbacks can be registered/unregistered in HAL_FDCAN_STATE_READY state only.
152   Exception done MspInit/MspDeInit that can be registered/unregistered
153   in HAL_FDCAN_STATE_READY or HAL_FDCAN_STATE_RESET state,
154   thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
155   In that case first register the MspInit/MspDeInit user callbacks
156   using HAL_FDCAN_RegisterCallback() before calling HAL_FDCAN_DeInit()
157   or HAL_FDCAN_Init() function.
158 
159   When The compilation define USE_HAL_FDCAN_REGISTER_CALLBACKS is set to 0 or
160   not defined, the callback registration feature is not available and all callbacks
161   are set to the corresponding weak functions.
162 
163   @endverbatim
164   ******************************************************************************
165   */
166 
167 /* Includes ------------------------------------------------------------------*/
168 #include "stm32u5xx_hal.h"
169 
170 #if defined(FDCAN1)
171 
172 /** @addtogroup STM32U5xx_HAL_Driver
173   * @{
174   */
175 
176 /** @defgroup FDCAN FDCAN
177   * @brief FDCAN HAL module driver
178   * @{
179   */
180 
181 #ifdef HAL_FDCAN_MODULE_ENABLED
182 
183 /* Private typedef -----------------------------------------------------------*/
184 /* Private define ------------------------------------------------------------*/
185 /** @addtogroup FDCAN_Private_Constants
186   * @{
187   */
188 #define FDCAN_TIMEOUT_VALUE 10U
189 
190 #define FDCAN_TX_EVENT_FIFO_MASK (FDCAN_IR_TEFL | FDCAN_IR_TEFF | FDCAN_IR_TEFN)
191 #define FDCAN_RX_FIFO0_MASK (FDCAN_IR_RF0L | FDCAN_IR_RF0F | FDCAN_IR_RF0N)
192 #define FDCAN_RX_FIFO1_MASK (FDCAN_IR_RF1L | FDCAN_IR_RF1F | FDCAN_IR_RF1N)
193 #define FDCAN_ERROR_MASK (FDCAN_IR_ELO | FDCAN_IR_WDI | FDCAN_IR_PEA | FDCAN_IR_PED | FDCAN_IR_ARA)
194 #define FDCAN_ERROR_STATUS_MASK (FDCAN_IR_EP | FDCAN_IR_EW | FDCAN_IR_BO)
195 
196 #define FDCAN_ELEMENT_MASK_STDID ((uint32_t)0x1FFC0000U) /* Standard Identifier         */
197 #define FDCAN_ELEMENT_MASK_EXTID ((uint32_t)0x1FFFFFFFU) /* Extended Identifier         */
198 #define FDCAN_ELEMENT_MASK_RTR   ((uint32_t)0x20000000U) /* Remote Transmission Request */
199 #define FDCAN_ELEMENT_MASK_XTD   ((uint32_t)0x40000000U) /* Extended Identifier         */
200 #define FDCAN_ELEMENT_MASK_ESI   ((uint32_t)0x80000000U) /* Error State Indicator       */
201 #define FDCAN_ELEMENT_MASK_TS    ((uint32_t)0x0000FFFFU) /* Timestamp                   */
202 #define FDCAN_ELEMENT_MASK_DLC   ((uint32_t)0x000F0000U) /* Data Length Code            */
203 #define FDCAN_ELEMENT_MASK_BRS   ((uint32_t)0x00100000U) /* Bit Rate Switch             */
204 #define FDCAN_ELEMENT_MASK_FDF   ((uint32_t)0x00200000U) /* FD Format                   */
205 #define FDCAN_ELEMENT_MASK_EFC   ((uint32_t)0x00800000U) /* Event FIFO Control          */
206 #define FDCAN_ELEMENT_MASK_MM    ((uint32_t)0xFF000000U) /* Message Marker              */
207 #define FDCAN_ELEMENT_MASK_FIDX  ((uint32_t)0x7F000000U) /* Filter Index                */
208 #define FDCAN_ELEMENT_MASK_ANMF  ((uint32_t)0x80000000U) /* Accepted Non-matching Frame */
209 #define FDCAN_ELEMENT_MASK_ET    ((uint32_t)0x00C00000U) /* Event type                  */
210 
211 #define SRAMCAN_FLS_NBR                  (28U)         /* Max. Filter List Standard Number      */
212 #define SRAMCAN_FLE_NBR                  ( 8U)         /* Max. Filter List Extended Number      */
213 #define SRAMCAN_RF0_NBR                  ( 3U)         /* RX FIFO 0 Elements Number             */
214 #define SRAMCAN_RF1_NBR                  ( 3U)         /* RX FIFO 1 Elements Number             */
215 #define SRAMCAN_TEF_NBR                  ( 3U)         /* TX Event FIFO Elements Number         */
216 #define SRAMCAN_TFQ_NBR                  ( 3U)         /* TX FIFO/Queue Elements Number         */
217 
218 #define SRAMCAN_FLS_SIZE            ( 1U * 4U)         /* Filter Standard Element Size in bytes */
219 #define SRAMCAN_FLE_SIZE            ( 2U * 4U)         /* Filter Extended Element Size in bytes */
220 #define SRAMCAN_RF0_SIZE            (18U * 4U)         /* RX FIFO 0 Elements Size in bytes      */
221 #define SRAMCAN_RF1_SIZE            (18U * 4U)         /* RX FIFO 1 Elements Size in bytes      */
222 #define SRAMCAN_TEF_SIZE            ( 2U * 4U)         /* TX Event FIFO Elements Size in bytes  */
223 #define SRAMCAN_TFQ_SIZE            (18U * 4U)         /* TX FIFO/Queue Elements Size in bytes  */
224 
225 #define SRAMCAN_FLSSA ((uint32_t)0)                                                      /* Filter List Standard Start
226                                                                                             Address                  */
227 #define SRAMCAN_FLESA ((uint32_t)(SRAMCAN_FLSSA + (SRAMCAN_FLS_NBR * SRAMCAN_FLS_SIZE))) /* Filter List Extended Start
228                                                                                             Address                  */
229 #define SRAMCAN_RF0SA ((uint32_t)(SRAMCAN_FLESA + (SRAMCAN_FLE_NBR * SRAMCAN_FLE_SIZE))) /* Rx FIFO 0 Start Address  */
230 #define SRAMCAN_RF1SA ((uint32_t)(SRAMCAN_RF0SA + (SRAMCAN_RF0_NBR * SRAMCAN_RF0_SIZE))) /* Rx FIFO 1 Start Address  */
231 #define SRAMCAN_TEFSA ((uint32_t)(SRAMCAN_RF1SA + (SRAMCAN_RF1_NBR * SRAMCAN_RF1_SIZE))) /* Tx Event FIFO Start
232                                                                                             Address */
233 #define SRAMCAN_TFQSA ((uint32_t)(SRAMCAN_TEFSA + (SRAMCAN_TEF_NBR * SRAMCAN_TEF_SIZE))) /* Tx FIFO/Queue Start
234                                                                                             Address                  */
235 #define SRAMCAN_SIZE  ((uint32_t)(SRAMCAN_TFQSA + (SRAMCAN_TFQ_NBR * SRAMCAN_TFQ_SIZE))) /* Message RAM size         */
236 
237 /**
238   * @}
239   */
240 
241 /* Private macro -------------------------------------------------------------*/
242 /* Private variables ---------------------------------------------------------*/
243 /** @addtogroup FDCAN_Private_Variables
244   * @{
245   */
246 static const uint8_t DLCtoBytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64};
247 /**
248   * @}
249   */
250 
251 /* Private function prototypes -----------------------------------------------*/
252 /** @addtogroup FDCAN_Private_Functions_Prototypes
253   * @{
254   */
255 static void FDCAN_CalcultateRamBlockAddresses(FDCAN_HandleTypeDef *hfdcan);
256 static void FDCAN_CopyMessageToRAM(FDCAN_HandleTypeDef *hfdcan, const FDCAN_TxHeaderTypeDef *pTxHeader,
257                                    const uint8_t *pTxData, uint32_t BufferIndex);
258 /**
259   * @}
260   */
261 
262 /* Exported functions --------------------------------------------------------*/
263 /** @defgroup FDCAN_Exported_Functions FDCAN Exported Functions
264   * @{
265   */
266 
267 /** @defgroup FDCAN_Exported_Functions_Group1 Initialization and de-initialization functions
268   *  @brief    Initialization and Configuration functions
269   *
270 @verbatim
271   ==============================================================================
272               ##### Initialization and de-initialization functions #####
273   ==============================================================================
274     [..]  This section provides functions allowing to:
275       (+) Initialize and configure the FDCAN.
276       (+) De-initialize the FDCAN.
277       (+) Enter FDCAN peripheral in power down mode.
278       (+) Exit power down mode.
279       (+) Register callbacks.
280       (+) Unregister callbacks.
281 
282 @endverbatim
283   * @{
284   */
285 
286 /**
287   * @brief  Initializes the FDCAN peripheral according to the specified
288   *         parameters in the FDCAN_InitTypeDef structure.
289   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
290   *         the configuration information for the specified FDCAN.
291   * @retval HAL status
292   */
HAL_FDCAN_Init(FDCAN_HandleTypeDef * hfdcan)293 HAL_StatusTypeDef HAL_FDCAN_Init(FDCAN_HandleTypeDef *hfdcan)
294 {
295   uint32_t tickstart;
296 
297   /* Check FDCAN handle */
298   if (hfdcan == NULL)
299   {
300     return HAL_ERROR;
301   }
302 
303   /* Check function parameters */
304   assert_param(IS_FDCAN_ALL_INSTANCE(hfdcan->Instance));
305   assert_param(IS_FDCAN_CKDIV(hfdcan->Init.ClockDivider));
306   assert_param(IS_FDCAN_FRAME_FORMAT(hfdcan->Init.FrameFormat));
307   assert_param(IS_FDCAN_MODE(hfdcan->Init.Mode));
308   assert_param(IS_FUNCTIONAL_STATE(hfdcan->Init.AutoRetransmission));
309   assert_param(IS_FUNCTIONAL_STATE(hfdcan->Init.TransmitPause));
310   assert_param(IS_FUNCTIONAL_STATE(hfdcan->Init.ProtocolException));
311   assert_param(IS_FDCAN_NOMINAL_PRESCALER(hfdcan->Init.NominalPrescaler));
312   assert_param(IS_FDCAN_NOMINAL_SJW(hfdcan->Init.NominalSyncJumpWidth));
313   assert_param(IS_FDCAN_NOMINAL_TSEG1(hfdcan->Init.NominalTimeSeg1));
314   assert_param(IS_FDCAN_NOMINAL_TSEG2(hfdcan->Init.NominalTimeSeg2));
315   if (hfdcan->Init.FrameFormat == FDCAN_FRAME_FD_BRS)
316   {
317     assert_param(IS_FDCAN_DATA_PRESCALER(hfdcan->Init.DataPrescaler));
318     assert_param(IS_FDCAN_DATA_SJW(hfdcan->Init.DataSyncJumpWidth));
319     assert_param(IS_FDCAN_DATA_TSEG1(hfdcan->Init.DataTimeSeg1));
320     assert_param(IS_FDCAN_DATA_TSEG2(hfdcan->Init.DataTimeSeg2));
321   }
322   assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.StdFiltersNbr, SRAMCAN_FLS_NBR));
323   assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.ExtFiltersNbr, SRAMCAN_FLE_NBR));
324   assert_param(IS_FDCAN_TX_FIFO_QUEUE_MODE(hfdcan->Init.TxFifoQueueMode));
325 
326 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
327   if (hfdcan->State == HAL_FDCAN_STATE_RESET)
328   {
329     /* Allocate lock resource and initialize it */
330     hfdcan->Lock = HAL_UNLOCKED;
331 
332     /* Reset callbacks to legacy functions */
333     hfdcan->TxEventFifoCallback         = HAL_FDCAN_TxEventFifoCallback;         /* TxEventFifoCallback */
334     hfdcan->RxFifo0Callback             = HAL_FDCAN_RxFifo0Callback;             /* RxFifo0Callback     */
335     hfdcan->RxFifo1Callback             = HAL_FDCAN_RxFifo1Callback;             /* RxFifo1Callback     */
336     hfdcan->TxFifoEmptyCallback         = HAL_FDCAN_TxFifoEmptyCallback;         /* TxFifoEmptyCallback */
337     hfdcan->TxBufferCompleteCallback    = HAL_FDCAN_TxBufferCompleteCallback;    /* TxBufferCompleteCallback        */
338     hfdcan->TxBufferAbortCallback       = HAL_FDCAN_TxBufferAbortCallback;       /* TxBufferAbortCallback           */
339     hfdcan->HighPriorityMessageCallback = HAL_FDCAN_HighPriorityMessageCallback; /* HighPriorityMessageCallback     */
340     hfdcan->TimestampWraparoundCallback = HAL_FDCAN_TimestampWraparoundCallback; /* TimestampWraparoundCallback     */
341     hfdcan->TimeoutOccurredCallback     = HAL_FDCAN_TimeoutOccurredCallback;     /* TimeoutOccurredCallback         */
342     hfdcan->ErrorCallback               = HAL_FDCAN_ErrorCallback;               /* ErrorCallback       */
343     hfdcan->ErrorStatusCallback         = HAL_FDCAN_ErrorStatusCallback;         /* ErrorStatusCallback */
344 
345     if (hfdcan->MspInitCallback == NULL)
346     {
347       hfdcan->MspInitCallback = HAL_FDCAN_MspInit;  /* Legacy weak MspInit */
348     }
349 
350     /* Init the low level hardware: CLOCK, NVIC */
351     hfdcan->MspInitCallback(hfdcan);
352   }
353 #else
354   if (hfdcan->State == HAL_FDCAN_STATE_RESET)
355   {
356     /* Allocate lock resource and initialize it */
357     hfdcan->Lock = HAL_UNLOCKED;
358 
359     /* Init the low level hardware: CLOCK, NVIC */
360     HAL_FDCAN_MspInit(hfdcan);
361   }
362 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
363 
364   /* Exit from Sleep mode */
365   CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CSR);
366 
367   /* Get tick */
368   tickstart = HAL_GetTick();
369 
370   /* Check Sleep mode acknowledge */
371   while ((hfdcan->Instance->CCCR & FDCAN_CCCR_CSA) == FDCAN_CCCR_CSA)
372   {
373     if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE)
374     {
375       /* Update error code */
376       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
377 
378       /* Change FDCAN state */
379       hfdcan->State = HAL_FDCAN_STATE_ERROR;
380 
381       return HAL_ERROR;
382     }
383   }
384 
385   /* Request initialisation */
386   SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT);
387 
388   /* Get tick */
389   tickstart = HAL_GetTick();
390 
391   /* Wait until the INIT bit into CCCR register is set */
392   while ((hfdcan->Instance->CCCR & FDCAN_CCCR_INIT) == 0U)
393   {
394     /* Check for the Timeout */
395     if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE)
396     {
397       /* Update error code */
398       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
399 
400       /* Change FDCAN state */
401       hfdcan->State = HAL_FDCAN_STATE_ERROR;
402 
403       return HAL_ERROR;
404     }
405   }
406 
407   /* Enable configuration change */
408   SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CCE);
409 
410   /* Configure Clock divider */
411   FDCAN_CONFIG->CKDIV = hfdcan->Init.ClockDivider;
412 
413   /* Set the no automatic retransmission */
414   if (hfdcan->Init.AutoRetransmission == ENABLE)
415   {
416     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_DAR);
417   }
418   else
419   {
420     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_DAR);
421   }
422 
423   /* Set the transmit pause feature */
424   if (hfdcan->Init.TransmitPause == ENABLE)
425   {
426     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_TXP);
427   }
428   else
429   {
430     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_TXP);
431   }
432 
433   /* Set the Protocol Exception Handling */
434   if (hfdcan->Init.ProtocolException == ENABLE)
435   {
436     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_PXHD);
437   }
438   else
439   {
440     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_PXHD);
441   }
442 
443   /* Set FDCAN Frame Format */
444   MODIFY_REG(hfdcan->Instance->CCCR, FDCAN_FRAME_FD_BRS, hfdcan->Init.FrameFormat);
445 
446   /* Reset FDCAN Operation Mode */
447   CLEAR_BIT(hfdcan->Instance->CCCR, (FDCAN_CCCR_TEST | FDCAN_CCCR_MON | FDCAN_CCCR_ASM));
448   CLEAR_BIT(hfdcan->Instance->TEST, FDCAN_TEST_LBCK);
449 
450   /* Set FDCAN Operating Mode:
451                | Normal | Restricted |    Bus     | Internal | External
452                |        | Operation  | Monitoring | LoopBack | LoopBack
453      CCCR.TEST |   0    |     0      |     0      |    1     |    1
454      CCCR.MON  |   0    |     0      |     1      |    1     |    0
455      TEST.LBCK |   0    |     0      |     0      |    1     |    1
456      CCCR.ASM  |   0    |     1      |     0      |    0     |    0
457   */
458   if (hfdcan->Init.Mode == FDCAN_MODE_RESTRICTED_OPERATION)
459   {
460     /* Enable Restricted Operation mode */
461     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_ASM);
462   }
463   else if (hfdcan->Init.Mode != FDCAN_MODE_NORMAL)
464   {
465     if (hfdcan->Init.Mode != FDCAN_MODE_BUS_MONITORING)
466     {
467       /* Enable write access to TEST register */
468       SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_TEST);
469 
470       /* Enable LoopBack mode */
471       SET_BIT(hfdcan->Instance->TEST, FDCAN_TEST_LBCK);
472 
473       if (hfdcan->Init.Mode == FDCAN_MODE_INTERNAL_LOOPBACK)
474       {
475         SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_MON);
476       }
477     }
478     else
479     {
480       /* Enable bus monitoring mode */
481       SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_MON);
482     }
483   }
484   else
485   {
486     /* Nothing to do: normal mode */
487   }
488 
489   /* Set the nominal bit timing register */
490   hfdcan->Instance->NBTP = ((((uint32_t)hfdcan->Init.NominalSyncJumpWidth - 1U) << FDCAN_NBTP_NSJW_Pos) | \
491                             (((uint32_t)hfdcan->Init.NominalTimeSeg1 - 1U) << FDCAN_NBTP_NTSEG1_Pos)    | \
492                             (((uint32_t)hfdcan->Init.NominalTimeSeg2 - 1U) << FDCAN_NBTP_NTSEG2_Pos)    | \
493                             (((uint32_t)hfdcan->Init.NominalPrescaler - 1U) << FDCAN_NBTP_NBRP_Pos));
494 
495   /* If FD operation with BRS is selected, set the data bit timing register */
496   if (hfdcan->Init.FrameFormat == FDCAN_FRAME_FD_BRS)
497   {
498     hfdcan->Instance->DBTP = ((((uint32_t)hfdcan->Init.DataSyncJumpWidth - 1U) << FDCAN_DBTP_DSJW_Pos)  | \
499                               (((uint32_t)hfdcan->Init.DataTimeSeg1 - 1U) << FDCAN_DBTP_DTSEG1_Pos)     | \
500                               (((uint32_t)hfdcan->Init.DataTimeSeg2 - 1U) << FDCAN_DBTP_DTSEG2_Pos)     | \
501                               (((uint32_t)hfdcan->Init.DataPrescaler - 1U) << FDCAN_DBTP_DBRP_Pos));
502   }
503 
504   /* Select between Tx FIFO and Tx Queue operation modes */
505   SET_BIT(hfdcan->Instance->TXBC, hfdcan->Init.TxFifoQueueMode);
506 
507   /* Calculate each RAM block address */
508   FDCAN_CalcultateRamBlockAddresses(hfdcan);
509 
510   /* Initialize the Latest Tx request buffer index */
511   hfdcan->LatestTxFifoQRequest = 0U;
512 
513   /* Initialize the error code */
514   hfdcan->ErrorCode = HAL_FDCAN_ERROR_NONE;
515 
516   /* Initialize the FDCAN state */
517   hfdcan->State = HAL_FDCAN_STATE_READY;
518 
519   /* Return function status */
520   return HAL_OK;
521 }
522 
523 /**
524   * @brief  Deinitializes the FDCAN peripheral registers to their default reset values.
525   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
526   *         the configuration information for the specified FDCAN.
527   * @retval HAL status
528   */
HAL_FDCAN_DeInit(FDCAN_HandleTypeDef * hfdcan)529 HAL_StatusTypeDef HAL_FDCAN_DeInit(FDCAN_HandleTypeDef *hfdcan)
530 {
531   /* Check FDCAN handle */
532   if (hfdcan == NULL)
533   {
534     return HAL_ERROR;
535   }
536 
537   /* Check function parameters */
538   assert_param(IS_FDCAN_ALL_INSTANCE(hfdcan->Instance));
539 
540   /* Stop the FDCAN module: return value is voluntary ignored */
541   (void)HAL_FDCAN_Stop(hfdcan);
542 
543   /* Disable Interrupt lines */
544   CLEAR_BIT(hfdcan->Instance->ILE, (FDCAN_INTERRUPT_LINE0 | FDCAN_INTERRUPT_LINE1));
545 
546 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
547   if (hfdcan->MspDeInitCallback == NULL)
548   {
549     hfdcan->MspDeInitCallback = HAL_FDCAN_MspDeInit; /* Legacy weak MspDeInit */
550   }
551 
552   /* DeInit the low level hardware: CLOCK, NVIC */
553   hfdcan->MspDeInitCallback(hfdcan);
554 #else
555   /* DeInit the low level hardware: CLOCK, NVIC */
556   HAL_FDCAN_MspDeInit(hfdcan);
557 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
558 
559   /* Reset the FDCAN ErrorCode */
560   hfdcan->ErrorCode = HAL_FDCAN_ERROR_NONE;
561 
562   /* Change FDCAN state */
563   hfdcan->State = HAL_FDCAN_STATE_RESET;
564 
565   /* Return function status */
566   return HAL_OK;
567 }
568 
569 /**
570   * @brief  Initializes the FDCAN MSP.
571   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
572   *         the configuration information for the specified FDCAN.
573   * @retval None
574   */
HAL_FDCAN_MspInit(FDCAN_HandleTypeDef * hfdcan)575 __weak void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef *hfdcan)
576 {
577   /* Prevent unused argument(s) compilation warning */
578   UNUSED(hfdcan);
579   /* NOTE: This function Should not be modified, when the callback is needed,
580             the HAL_FDCAN_MspInit could be implemented in the user file
581    */
582 }
583 
584 /**
585   * @brief  DeInitializes the FDCAN MSP.
586   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
587   *         the configuration information for the specified FDCAN.
588   * @retval None
589   */
HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef * hfdcan)590 __weak void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef *hfdcan)
591 {
592   /* Prevent unused argument(s) compilation warning */
593   UNUSED(hfdcan);
594   /* NOTE: This function Should not be modified, when the callback is needed,
595             the HAL_FDCAN_MspDeInit could be implemented in the user file
596    */
597 }
598 
599 /**
600   * @brief  Enter FDCAN peripheral in sleep mode.
601   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
602   *         the configuration information for the specified FDCAN.
603   * @retval HAL status
604   */
HAL_FDCAN_EnterPowerDownMode(FDCAN_HandleTypeDef * hfdcan)605 HAL_StatusTypeDef HAL_FDCAN_EnterPowerDownMode(FDCAN_HandleTypeDef *hfdcan)
606 {
607   uint32_t tickstart;
608 
609   /* Request clock stop */
610   SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CSR);
611 
612   /* Get tick */
613   tickstart = HAL_GetTick();
614 
615   /* Wait until FDCAN is ready for power down */
616   while ((hfdcan->Instance->CCCR & FDCAN_CCCR_CSA) == 0U)
617   {
618     if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE)
619     {
620       /* Update error code */
621       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
622 
623       /* Change FDCAN state */
624       hfdcan->State = HAL_FDCAN_STATE_ERROR;
625 
626       return HAL_ERROR;
627     }
628   }
629 
630   /* Return function status */
631   return HAL_OK;
632 }
633 
634 /**
635   * @brief  Exit power down mode.
636   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
637   *         the configuration information for the specified FDCAN.
638   * @retval HAL status
639   */
HAL_FDCAN_ExitPowerDownMode(FDCAN_HandleTypeDef * hfdcan)640 HAL_StatusTypeDef HAL_FDCAN_ExitPowerDownMode(FDCAN_HandleTypeDef *hfdcan)
641 {
642   uint32_t tickstart;
643 
644   /* Reset clock stop request */
645   CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CSR);
646 
647   /* Get tick */
648   tickstart = HAL_GetTick();
649 
650   /* Wait until FDCAN exits sleep mode */
651   while ((hfdcan->Instance->CCCR & FDCAN_CCCR_CSA) == FDCAN_CCCR_CSA)
652   {
653     if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE)
654     {
655       /* Update error code */
656       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
657 
658       /* Change FDCAN state */
659       hfdcan->State = HAL_FDCAN_STATE_ERROR;
660 
661       return HAL_ERROR;
662     }
663   }
664 
665   /* Enter normal operation */
666   CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT);
667 
668   /* Return function status */
669   return HAL_OK;
670 }
671 
672 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
673 /**
674   * @brief  Register a FDCAN CallBack.
675   *         To be used instead of the weak predefined callback
676   * @param  hfdcan pointer to a FDCAN_HandleTypeDef structure that contains
677   *         the configuration information for FDCAN module
678   * @param  CallbackID ID of the callback to be registered
679   *         This parameter can be one of the following values:
680   *           @arg @ref HAL_FDCAN_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty callback ID
681   *           @arg @ref HAL_FDCAN_HIGH_PRIO_MESSAGE_CB_ID High priority message callback ID
682   *           @arg @ref HAL_FDCAN_TIMESTAMP_WRAPAROUND_CB_ID Timestamp wraparound callback ID
683   *           @arg @ref HAL_FDCAN_TIMEOUT_OCCURRED_CB_ID Timeout occurred callback ID
684   *           @arg @ref HAL_FDCAN_ERROR_CALLBACK_CB_ID Error callback ID
685   *           @arg @ref HAL_FDCAN_MSPINIT_CB_ID MspInit callback ID
686   *           @arg @ref HAL_FDCAN_MSPDEINIT_CB_ID MspDeInit callback ID
687   * @param  pCallback pointer to the Callback function
688   * @retval HAL status
689   */
HAL_FDCAN_RegisterCallback(FDCAN_HandleTypeDef * hfdcan,HAL_FDCAN_CallbackIDTypeDef CallbackID,void (* pCallback)(FDCAN_HandleTypeDef * _hFDCAN))690 HAL_StatusTypeDef HAL_FDCAN_RegisterCallback(FDCAN_HandleTypeDef *hfdcan, HAL_FDCAN_CallbackIDTypeDef CallbackID,
691                                              void (* pCallback)(FDCAN_HandleTypeDef *_hFDCAN))
692 {
693   HAL_StatusTypeDef status = HAL_OK;
694 
695   if (pCallback == NULL)
696   {
697     /* Update the error code */
698     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
699 
700     return HAL_ERROR;
701   }
702 
703   if (hfdcan->State == HAL_FDCAN_STATE_READY)
704   {
705     switch (CallbackID)
706     {
707       case HAL_FDCAN_TX_FIFO_EMPTY_CB_ID :
708         hfdcan->TxFifoEmptyCallback = pCallback;
709         break;
710 
711       case HAL_FDCAN_HIGH_PRIO_MESSAGE_CB_ID :
712         hfdcan->HighPriorityMessageCallback = pCallback;
713         break;
714 
715       case HAL_FDCAN_TIMESTAMP_WRAPAROUND_CB_ID :
716         hfdcan->TimestampWraparoundCallback = pCallback;
717         break;
718 
719       case HAL_FDCAN_TIMEOUT_OCCURRED_CB_ID :
720         hfdcan->TimeoutOccurredCallback = pCallback;
721         break;
722 
723       case HAL_FDCAN_ERROR_CALLBACK_CB_ID :
724         hfdcan->ErrorCallback = pCallback;
725         break;
726 
727       case HAL_FDCAN_MSPINIT_CB_ID :
728         hfdcan->MspInitCallback = pCallback;
729         break;
730 
731       case HAL_FDCAN_MSPDEINIT_CB_ID :
732         hfdcan->MspDeInitCallback = pCallback;
733         break;
734 
735       default :
736         /* Update the error code */
737         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
738 
739         /* Return error status */
740         status =  HAL_ERROR;
741         break;
742     }
743   }
744   else if (hfdcan->State == HAL_FDCAN_STATE_RESET)
745   {
746     switch (CallbackID)
747     {
748       case HAL_FDCAN_MSPINIT_CB_ID :
749         hfdcan->MspInitCallback = pCallback;
750         break;
751 
752       case HAL_FDCAN_MSPDEINIT_CB_ID :
753         hfdcan->MspDeInitCallback = pCallback;
754         break;
755 
756       default :
757         /* Update the error code */
758         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
759 
760         /* Return error status */
761         status =  HAL_ERROR;
762         break;
763     }
764   }
765   else
766   {
767     /* Update the error code */
768     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
769 
770     /* Return error status */
771     status =  HAL_ERROR;
772   }
773 
774   return status;
775 }
776 
777 /**
778   * @brief  Unregister a FDCAN CallBack.
779   *         FDCAN callback is redirected to the weak predefined callback
780   * @param  hfdcan pointer to a FDCAN_HandleTypeDef structure that contains
781   *         the configuration information for FDCAN module
782   * @param  CallbackID ID of the callback to be unregistered
783   *         This parameter can be one of the following values:
784   *           @arg @ref HAL_FDCAN_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty callback ID
785   *           @arg @ref HAL_FDCAN_HIGH_PRIO_MESSAGE_CB_ID High priority message callback ID
786   *           @arg @ref HAL_FDCAN_TIMESTAMP_WRAPAROUND_CB_ID Timestamp wraparound callback ID
787   *           @arg @ref HAL_FDCAN_TIMEOUT_OCCURRED_CB_ID Timeout occurred callback ID
788   *           @arg @ref HAL_FDCAN_ERROR_CALLBACK_CB_ID Error callback ID
789   *           @arg @ref HAL_FDCAN_MSPINIT_CB_ID MspInit callback ID
790   *           @arg @ref HAL_FDCAN_MSPDEINIT_CB_ID MspDeInit callback ID
791   * @retval HAL status
792   */
HAL_FDCAN_UnRegisterCallback(FDCAN_HandleTypeDef * hfdcan,HAL_FDCAN_CallbackIDTypeDef CallbackID)793 HAL_StatusTypeDef HAL_FDCAN_UnRegisterCallback(FDCAN_HandleTypeDef *hfdcan, HAL_FDCAN_CallbackIDTypeDef CallbackID)
794 {
795   HAL_StatusTypeDef status = HAL_OK;
796 
797   if (hfdcan->State == HAL_FDCAN_STATE_READY)
798   {
799     switch (CallbackID)
800     {
801       case HAL_FDCAN_TX_FIFO_EMPTY_CB_ID :
802         hfdcan->TxFifoEmptyCallback = HAL_FDCAN_TxFifoEmptyCallback;
803         break;
804 
805       case HAL_FDCAN_HIGH_PRIO_MESSAGE_CB_ID :
806         hfdcan->HighPriorityMessageCallback = HAL_FDCAN_HighPriorityMessageCallback;
807         break;
808 
809       case HAL_FDCAN_TIMESTAMP_WRAPAROUND_CB_ID :
810         hfdcan->TimestampWraparoundCallback = HAL_FDCAN_TimestampWraparoundCallback;
811         break;
812 
813       case HAL_FDCAN_TIMEOUT_OCCURRED_CB_ID :
814         hfdcan->TimeoutOccurredCallback = HAL_FDCAN_TimeoutOccurredCallback;
815         break;
816 
817       case HAL_FDCAN_ERROR_CALLBACK_CB_ID :
818         hfdcan->ErrorCallback = HAL_FDCAN_ErrorCallback;
819         break;
820 
821       case HAL_FDCAN_MSPINIT_CB_ID :
822         hfdcan->MspInitCallback = HAL_FDCAN_MspInit;
823         break;
824 
825       case HAL_FDCAN_MSPDEINIT_CB_ID :
826         hfdcan->MspDeInitCallback = HAL_FDCAN_MspDeInit;
827         break;
828 
829       default :
830         /* Update the error code */
831         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
832 
833         /* Return error status */
834         status =  HAL_ERROR;
835         break;
836     }
837   }
838   else if (hfdcan->State == HAL_FDCAN_STATE_RESET)
839   {
840     switch (CallbackID)
841     {
842       case HAL_FDCAN_MSPINIT_CB_ID :
843         hfdcan->MspInitCallback = HAL_FDCAN_MspInit;
844         break;
845 
846       case HAL_FDCAN_MSPDEINIT_CB_ID :
847         hfdcan->MspDeInitCallback = HAL_FDCAN_MspDeInit;
848         break;
849 
850       default :
851         /* Update the error code */
852         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
853 
854         /* Return error status */
855         status =  HAL_ERROR;
856         break;
857     }
858   }
859   else
860   {
861     /* Update the error code */
862     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
863 
864     /* Return error status */
865     status =  HAL_ERROR;
866   }
867 
868   return status;
869 }
870 
871 /**
872   * @brief  Register Tx Event Fifo FDCAN Callback
873   *         To be used instead of the weak HAL_FDCAN_TxEventFifoCallback() predefined callback
874   * @param  hfdcan FDCAN handle
875   * @param  pCallback pointer to the Tx Event Fifo Callback function
876   * @retval HAL status
877   */
HAL_FDCAN_RegisterTxEventFifoCallback(FDCAN_HandleTypeDef * hfdcan,pFDCAN_TxEventFifoCallbackTypeDef pCallback)878 HAL_StatusTypeDef HAL_FDCAN_RegisterTxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan,
879                                                         pFDCAN_TxEventFifoCallbackTypeDef pCallback)
880 {
881   HAL_StatusTypeDef status = HAL_OK;
882 
883   if (pCallback == NULL)
884   {
885     /* Update the error code */
886     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
887     return HAL_ERROR;
888   }
889 
890   if (hfdcan->State == HAL_FDCAN_STATE_READY)
891   {
892     hfdcan->TxEventFifoCallback = pCallback;
893   }
894   else
895   {
896     /* Update the error code */
897     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
898 
899     /* Return error status */
900     status =  HAL_ERROR;
901   }
902 
903   return status;
904 }
905 
906 /**
907   * @brief  UnRegister the Tx Event Fifo FDCAN Callback
908   *         Tx Event Fifo FDCAN Callback is redirected to the weak HAL_FDCAN_TxEventFifoCallback() predefined callback
909   * @param  hfdcan FDCAN handle
910   * @retval HAL status
911   */
HAL_FDCAN_UnRegisterTxEventFifoCallback(FDCAN_HandleTypeDef * hfdcan)912 HAL_StatusTypeDef HAL_FDCAN_UnRegisterTxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan)
913 {
914   HAL_StatusTypeDef status = HAL_OK;
915 
916   if (hfdcan->State == HAL_FDCAN_STATE_READY)
917   {
918     hfdcan->TxEventFifoCallback = HAL_FDCAN_TxEventFifoCallback; /* Legacy weak TxEventFifoCallback  */
919   }
920   else
921   {
922     /* Update the error code */
923     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
924 
925     /* Return error status */
926     status =  HAL_ERROR;
927   }
928 
929   return status;
930 }
931 
932 /**
933   * @brief  Register Rx Fifo 0 FDCAN Callback
934   *         To be used instead of the weak HAL_FDCAN_RxFifo0Callback() predefined callback
935   * @param  hfdcan FDCAN handle
936   * @param  pCallback pointer to the Rx Fifo 0 Callback function
937   * @retval HAL status
938   */
HAL_FDCAN_RegisterRxFifo0Callback(FDCAN_HandleTypeDef * hfdcan,pFDCAN_RxFifo0CallbackTypeDef pCallback)939 HAL_StatusTypeDef HAL_FDCAN_RegisterRxFifo0Callback(FDCAN_HandleTypeDef *hfdcan,
940                                                     pFDCAN_RxFifo0CallbackTypeDef pCallback)
941 {
942   HAL_StatusTypeDef status = HAL_OK;
943 
944   if (pCallback == NULL)
945   {
946     /* Update the error code */
947     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
948     return HAL_ERROR;
949   }
950 
951   if (hfdcan->State == HAL_FDCAN_STATE_READY)
952   {
953     hfdcan->RxFifo0Callback = pCallback;
954   }
955   else
956   {
957     /* Update the error code */
958     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
959 
960     /* Return error status */
961     status =  HAL_ERROR;
962   }
963 
964   return status;
965 }
966 
967 /**
968   * @brief  UnRegister the Rx Fifo 0 FDCAN Callback
969   *         Rx Fifo 0 FDCAN Callback is redirected to the weak HAL_FDCAN_RxFifo0Callback() predefined callback
970   * @param  hfdcan FDCAN handle
971   * @retval HAL status
972   */
HAL_FDCAN_UnRegisterRxFifo0Callback(FDCAN_HandleTypeDef * hfdcan)973 HAL_StatusTypeDef HAL_FDCAN_UnRegisterRxFifo0Callback(FDCAN_HandleTypeDef *hfdcan)
974 {
975   HAL_StatusTypeDef status = HAL_OK;
976 
977   if (hfdcan->State == HAL_FDCAN_STATE_READY)
978   {
979     hfdcan->RxFifo0Callback = HAL_FDCAN_RxFifo0Callback; /* Legacy weak RxFifo0Callback  */
980   }
981   else
982   {
983     /* Update the error code */
984     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
985 
986     /* Return error status */
987     status =  HAL_ERROR;
988   }
989 
990   return status;
991 }
992 
993 /**
994   * @brief  Register Rx Fifo 1 FDCAN Callback
995   *         To be used instead of the weak HAL_FDCAN_RxFifo1Callback() predefined callback
996   * @param  hfdcan FDCAN handle
997   * @param  pCallback pointer to the Rx Fifo 1 Callback function
998   * @retval HAL status
999   */
HAL_FDCAN_RegisterRxFifo1Callback(FDCAN_HandleTypeDef * hfdcan,pFDCAN_RxFifo1CallbackTypeDef pCallback)1000 HAL_StatusTypeDef HAL_FDCAN_RegisterRxFifo1Callback(FDCAN_HandleTypeDef *hfdcan,
1001                                                     pFDCAN_RxFifo1CallbackTypeDef pCallback)
1002 {
1003   HAL_StatusTypeDef status = HAL_OK;
1004 
1005   if (pCallback == NULL)
1006   {
1007     /* Update the error code */
1008     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1009     return HAL_ERROR;
1010   }
1011 
1012   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1013   {
1014     hfdcan->RxFifo1Callback = pCallback;
1015   }
1016   else
1017   {
1018     /* Update the error code */
1019     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1020 
1021     /* Return error status */
1022     status =  HAL_ERROR;
1023   }
1024 
1025   return status;
1026 }
1027 
1028 /**
1029   * @brief  UnRegister the Rx Fifo 1 FDCAN Callback
1030   *         Rx Fifo 1 FDCAN Callback is redirected to the weak HAL_FDCAN_RxFifo1Callback() predefined callback
1031   * @param  hfdcan FDCAN handle
1032   * @retval HAL status
1033   */
HAL_FDCAN_UnRegisterRxFifo1Callback(FDCAN_HandleTypeDef * hfdcan)1034 HAL_StatusTypeDef HAL_FDCAN_UnRegisterRxFifo1Callback(FDCAN_HandleTypeDef *hfdcan)
1035 {
1036   HAL_StatusTypeDef status = HAL_OK;
1037 
1038   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1039   {
1040     hfdcan->RxFifo1Callback = HAL_FDCAN_RxFifo1Callback; /* Legacy weak RxFifo1Callback  */
1041   }
1042   else
1043   {
1044     /* Update the error code */
1045     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1046 
1047     /* Return error status */
1048     status =  HAL_ERROR;
1049   }
1050 
1051   return status;
1052 }
1053 
1054 /**
1055   * @brief  Register Tx Buffer Complete FDCAN Callback
1056   *         To be used instead of the weak HAL_FDCAN_TxBufferCompleteCallback() predefined callback
1057   * @param  hfdcan FDCAN handle
1058   * @param  pCallback pointer to the Tx Buffer Complete Callback function
1059   * @retval HAL status
1060   */
HAL_FDCAN_RegisterTxBufferCompleteCallback(FDCAN_HandleTypeDef * hfdcan,pFDCAN_TxBufferCompleteCallbackTypeDef pCallback)1061 HAL_StatusTypeDef HAL_FDCAN_RegisterTxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan,
1062                                                              pFDCAN_TxBufferCompleteCallbackTypeDef pCallback)
1063 {
1064   HAL_StatusTypeDef status = HAL_OK;
1065 
1066   if (pCallback == NULL)
1067   {
1068     /* Update the error code */
1069     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1070     return HAL_ERROR;
1071   }
1072 
1073   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1074   {
1075     hfdcan->TxBufferCompleteCallback = pCallback;
1076   }
1077   else
1078   {
1079     /* Update the error code */
1080     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1081 
1082     /* Return error status */
1083     status =  HAL_ERROR;
1084   }
1085 
1086   return status;
1087 }
1088 
1089 /**
1090   * @brief  UnRegister the Tx Buffer Complete FDCAN Callback
1091   *         Tx Buffer Complete FDCAN Callback is redirected to
1092   *         the weak HAL_FDCAN_TxBufferCompleteCallback() predefined callback
1093   * @param  hfdcan FDCAN handle
1094   * @retval HAL status
1095   */
HAL_FDCAN_UnRegisterTxBufferCompleteCallback(FDCAN_HandleTypeDef * hfdcan)1096 HAL_StatusTypeDef HAL_FDCAN_UnRegisterTxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan)
1097 {
1098   HAL_StatusTypeDef status = HAL_OK;
1099 
1100   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1101   {
1102     hfdcan->TxBufferCompleteCallback = HAL_FDCAN_TxBufferCompleteCallback; /* Legacy weak TxBufferCompleteCallback  */
1103   }
1104   else
1105   {
1106     /* Update the error code */
1107     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1108 
1109     /* Return error status */
1110     status =  HAL_ERROR;
1111   }
1112 
1113   return status;
1114 }
1115 
1116 /**
1117   * @brief  Register Tx Buffer Abort FDCAN Callback
1118   *         To be used instead of the weak HAL_FDCAN_TxBufferAbortCallback() predefined callback
1119   * @param  hfdcan FDCAN handle
1120   * @param  pCallback pointer to the Tx Buffer Abort Callback function
1121   * @retval HAL status
1122   */
HAL_FDCAN_RegisterTxBufferAbortCallback(FDCAN_HandleTypeDef * hfdcan,pFDCAN_TxBufferAbortCallbackTypeDef pCallback)1123 HAL_StatusTypeDef HAL_FDCAN_RegisterTxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan,
1124                                                           pFDCAN_TxBufferAbortCallbackTypeDef pCallback)
1125 {
1126   HAL_StatusTypeDef status = HAL_OK;
1127 
1128   if (pCallback == NULL)
1129   {
1130     /* Update the error code */
1131     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1132     return HAL_ERROR;
1133   }
1134 
1135   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1136   {
1137     hfdcan->TxBufferAbortCallback = pCallback;
1138   }
1139   else
1140   {
1141     /* Update the error code */
1142     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1143 
1144     /* Return error status */
1145     status =  HAL_ERROR;
1146   }
1147 
1148   return status;
1149 }
1150 
1151 /**
1152   * @brief  UnRegister the Tx Buffer Abort FDCAN Callback
1153   *         Tx Buffer Abort FDCAN Callback is redirected to
1154   *         the weak HAL_FDCAN_TxBufferAbortCallback() predefined callback
1155   * @param  hfdcan FDCAN handle
1156   * @retval HAL status
1157   */
HAL_FDCAN_UnRegisterTxBufferAbortCallback(FDCAN_HandleTypeDef * hfdcan)1158 HAL_StatusTypeDef HAL_FDCAN_UnRegisterTxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan)
1159 {
1160   HAL_StatusTypeDef status = HAL_OK;
1161 
1162   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1163   {
1164     hfdcan->TxBufferAbortCallback = HAL_FDCAN_TxBufferAbortCallback; /* Legacy weak TxBufferAbortCallback  */
1165   }
1166   else
1167   {
1168     /* Update the error code */
1169     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1170 
1171     /* Return error status */
1172     status =  HAL_ERROR;
1173   }
1174 
1175   return status;
1176 }
1177 
1178 /**
1179   * @brief  Register Error Status FDCAN Callback
1180   *         To be used instead of the weak HAL_FDCAN_ErrorStatusCallback() predefined callback
1181   * @param  hfdcan FDCAN handle
1182   * @param  pCallback pointer to the Error Status Callback function
1183   * @retval HAL status
1184   */
HAL_FDCAN_RegisterErrorStatusCallback(FDCAN_HandleTypeDef * hfdcan,pFDCAN_ErrorStatusCallbackTypeDef pCallback)1185 HAL_StatusTypeDef HAL_FDCAN_RegisterErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan,
1186                                                         pFDCAN_ErrorStatusCallbackTypeDef pCallback)
1187 {
1188   HAL_StatusTypeDef status = HAL_OK;
1189 
1190   if (pCallback == NULL)
1191   {
1192     /* Update the error code */
1193     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1194     return HAL_ERROR;
1195   }
1196 
1197   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1198   {
1199     hfdcan->ErrorStatusCallback = pCallback;
1200   }
1201   else
1202   {
1203     /* Update the error code */
1204     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1205 
1206     /* Return error status */
1207     status =  HAL_ERROR;
1208   }
1209 
1210   return status;
1211 }
1212 
1213 /**
1214   * @brief  UnRegister the Error Status FDCAN Callback
1215   *         Error Status FDCAN Callback is redirected to the weak HAL_FDCAN_ErrorStatusCallback() predefined callback
1216   * @param  hfdcan FDCAN handle
1217   * @retval HAL status
1218   */
HAL_FDCAN_UnRegisterErrorStatusCallback(FDCAN_HandleTypeDef * hfdcan)1219 HAL_StatusTypeDef HAL_FDCAN_UnRegisterErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan)
1220 {
1221   HAL_StatusTypeDef status = HAL_OK;
1222 
1223   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1224   {
1225     hfdcan->ErrorStatusCallback = HAL_FDCAN_ErrorStatusCallback; /* Legacy weak ErrorStatusCallback  */
1226   }
1227   else
1228   {
1229     /* Update the error code */
1230     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK;
1231 
1232     /* Return error status */
1233     status =  HAL_ERROR;
1234   }
1235 
1236   return status;
1237 }
1238 
1239 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
1240 
1241 /**
1242   * @}
1243   */
1244 
1245 /** @defgroup FDCAN_Exported_Functions_Group2 Configuration functions
1246   *  @brief    FDCAN Configuration functions.
1247   *
1248 @verbatim
1249   ==============================================================================
1250               ##### Configuration functions #####
1251   ==============================================================================
1252     [..]  This section provides functions allowing to:
1253       (+) HAL_FDCAN_ConfigFilter                  : Configure the FDCAN reception filters
1254       (+) HAL_FDCAN_ConfigGlobalFilter            : Configure the FDCAN global filter
1255       (+) HAL_FDCAN_ConfigExtendedIdMask          : Configure the extended ID mask
1256       (+) HAL_FDCAN_ConfigRxFifoOverwrite         : Configure the Rx FIFO operation mode
1257       (+) HAL_FDCAN_ConfigRamWatchdog             : Configure the RAM watchdog
1258       (+) HAL_FDCAN_ConfigTimestampCounter        : Configure the timestamp counter
1259         (+) HAL_FDCAN_EnableTimestampCounter        : Enable the timestamp counter
1260         (+) HAL_FDCAN_DisableTimestampCounter       : Disable the timestamp counter
1261         (+) HAL_FDCAN_GetTimestampCounter           : Get the timestamp counter value
1262         (+) HAL_FDCAN_ResetTimestampCounter         : Reset the timestamp counter to zero
1263       (+) HAL_FDCAN_ConfigTimeoutCounter          : Configure the timeout counter
1264         (+) HAL_FDCAN_EnableTimeoutCounter          : Enable the timeout counter
1265         (+) HAL_FDCAN_DisableTimeoutCounter         : Disable the timeout counter
1266         (+) HAL_FDCAN_GetTimeoutCounter             : Get the timeout counter value
1267         (+) HAL_FDCAN_ResetTimeoutCounter           : Reset the timeout counter to its start value
1268       (+) HAL_FDCAN_ConfigTxDelayCompensation     : Configure the transmitter delay compensation
1269         (+) HAL_FDCAN_EnableTxDelayCompensation     : Enable the transmitter delay compensation
1270         (+) HAL_FDCAN_DisableTxDelayCompensation    : Disable the transmitter delay compensation
1271       (+) HAL_FDCAN_EnableISOMode                 : Enable ISO 11898-1 protocol mode
1272       (+) HAL_FDCAN_DisableISOMode                : Disable ISO 11898-1 protocol mode
1273       (+) HAL_FDCAN_EnableEdgeFiltering           : Enable edge filtering during bus integration
1274       (+) HAL_FDCAN_DisableEdgeFiltering          : Disable edge filtering during bus integration
1275 
1276 @endverbatim
1277   * @{
1278   */
1279 
1280 /**
1281   * @brief  Configure the FDCAN reception filter according to the specified
1282   *         parameters in the FDCAN_FilterTypeDef structure.
1283   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1284   *         the configuration information for the specified FDCAN.
1285   * @param  sFilterConfig pointer to an FDCAN_FilterTypeDef structure that
1286   *         contains the filter configuration information
1287   * @retval HAL status
1288   */
HAL_FDCAN_ConfigFilter(FDCAN_HandleTypeDef * hfdcan,const FDCAN_FilterTypeDef * sFilterConfig)1289 HAL_StatusTypeDef HAL_FDCAN_ConfigFilter(FDCAN_HandleTypeDef *hfdcan, const FDCAN_FilterTypeDef *sFilterConfig)
1290 {
1291   uint32_t FilterElementW1;
1292   uint32_t FilterElementW2;
1293   uint32_t *FilterAddress;
1294   HAL_FDCAN_StateTypeDef state = hfdcan->State;
1295 
1296   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
1297   {
1298     /* Check function parameters */
1299     assert_param(IS_FDCAN_ID_TYPE(sFilterConfig->IdType));
1300     assert_param(IS_FDCAN_FILTER_CFG(sFilterConfig->FilterConfig));
1301 
1302     if (sFilterConfig->IdType == FDCAN_STANDARD_ID)
1303     {
1304       /* Check function parameters */
1305       assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterIndex, (hfdcan->Init.StdFiltersNbr - 1U)));
1306       assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterID1, 0x7FFU));
1307       assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterID2, 0x7FFU));
1308       assert_param(IS_FDCAN_STD_FILTER_TYPE(sFilterConfig->FilterType));
1309 
1310       /* Build filter element */
1311       FilterElementW1 = ((sFilterConfig->FilterType << 30U)   |
1312                          (sFilterConfig->FilterConfig << 27U) |
1313                          (sFilterConfig->FilterID1 << 16U)    |
1314                          sFilterConfig->FilterID2);
1315 
1316       /* Calculate filter address */
1317       FilterAddress = (uint32_t *)(hfdcan->msgRam.StandardFilterSA + (sFilterConfig->FilterIndex * SRAMCAN_FLS_SIZE));
1318 
1319       /* Write filter element to the message RAM */
1320       *FilterAddress = FilterElementW1;
1321     }
1322     else /* sFilterConfig->IdType == FDCAN_EXTENDED_ID */
1323     {
1324       /* Check function parameters */
1325       assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterIndex, (hfdcan->Init.ExtFiltersNbr - 1U)));
1326       assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterID1, 0x1FFFFFFFU));
1327       assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterID2, 0x1FFFFFFFU));
1328       assert_param(IS_FDCAN_EXT_FILTER_TYPE(sFilterConfig->FilterType));
1329 
1330       /* Build first word of filter element */
1331       FilterElementW1 = ((sFilterConfig->FilterConfig << 29U) | sFilterConfig->FilterID1);
1332 
1333       /* Build second word of filter element */
1334       FilterElementW2 = ((sFilterConfig->FilterType << 30U) | sFilterConfig->FilterID2);
1335 
1336       /* Calculate filter address */
1337       FilterAddress = (uint32_t *)(hfdcan->msgRam.ExtendedFilterSA + (sFilterConfig->FilterIndex * SRAMCAN_FLE_SIZE));
1338 
1339       /* Write filter element to the message RAM */
1340       *FilterAddress = FilterElementW1;
1341       FilterAddress++;
1342       *FilterAddress = FilterElementW2;
1343     }
1344 
1345     /* Return function status */
1346     return HAL_OK;
1347   }
1348   else
1349   {
1350     /* Update error code */
1351     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
1352 
1353     return HAL_ERROR;
1354   }
1355 }
1356 
1357 /**
1358   * @brief  Configure the FDCAN global filter.
1359   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1360   *         the configuration information for the specified FDCAN.
1361   * @param  NonMatchingStd Defines how received messages with 11-bit IDs that
1362   *         do not match any element of the filter list are treated.
1363   *         This parameter can be a value of @arg FDCAN_Non_Matching_Frames.
1364   * @param  NonMatchingExt Defines how received messages with 29-bit IDs that
1365   *         do not match any element of the filter list are treated.
1366   *         This parameter can be a value of @arg FDCAN_Non_Matching_Frames.
1367   * @param  RejectRemoteStd Filter or reject all the remote 11-bit IDs frames.
1368   *         This parameter can be a value of @arg FDCAN_Reject_Remote_Frames.
1369   * @param  RejectRemoteExt Filter or reject all the remote 29-bit IDs frames.
1370   *         This parameter can be a value of @arg FDCAN_Reject_Remote_Frames.
1371   * @retval HAL status
1372   */
HAL_FDCAN_ConfigGlobalFilter(FDCAN_HandleTypeDef * hfdcan,uint32_t NonMatchingStd,uint32_t NonMatchingExt,uint32_t RejectRemoteStd,uint32_t RejectRemoteExt)1373 HAL_StatusTypeDef HAL_FDCAN_ConfigGlobalFilter(FDCAN_HandleTypeDef *hfdcan,
1374                                                uint32_t NonMatchingStd,
1375                                                uint32_t NonMatchingExt,
1376                                                uint32_t RejectRemoteStd,
1377                                                uint32_t RejectRemoteExt)
1378 {
1379   /* Check function parameters */
1380   assert_param(IS_FDCAN_NON_MATCHING(NonMatchingStd));
1381   assert_param(IS_FDCAN_NON_MATCHING(NonMatchingExt));
1382   assert_param(IS_FDCAN_REJECT_REMOTE(RejectRemoteStd));
1383   assert_param(IS_FDCAN_REJECT_REMOTE(RejectRemoteExt));
1384 
1385   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1386   {
1387     /* Configure global filter */
1388     MODIFY_REG(hfdcan->Instance->RXGFC, (FDCAN_RXGFC_ANFS |
1389                                          FDCAN_RXGFC_ANFE |
1390                                          FDCAN_RXGFC_RRFS |
1391                                          FDCAN_RXGFC_RRFE),
1392                ((NonMatchingStd << FDCAN_RXGFC_ANFS_Pos)  |
1393                 (NonMatchingExt << FDCAN_RXGFC_ANFE_Pos)  |
1394                 (RejectRemoteStd << FDCAN_RXGFC_RRFS_Pos) |
1395                 (RejectRemoteExt << FDCAN_RXGFC_RRFE_Pos)));
1396 
1397     /* Return function status */
1398     return HAL_OK;
1399   }
1400   else
1401   {
1402     /* Update error code */
1403     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1404 
1405     return HAL_ERROR;
1406   }
1407 }
1408 
1409 /**
1410   * @brief  Configure the extended ID mask.
1411   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1412   *         the configuration information for the specified FDCAN.
1413   * @param  Mask Extended ID Mask.
1414   *         This parameter must be a number between 0 and 0x1FFFFFFF.
1415   * @retval HAL status
1416   */
HAL_FDCAN_ConfigExtendedIdMask(FDCAN_HandleTypeDef * hfdcan,uint32_t Mask)1417 HAL_StatusTypeDef HAL_FDCAN_ConfigExtendedIdMask(FDCAN_HandleTypeDef *hfdcan, uint32_t Mask)
1418 {
1419   /* Check function parameters */
1420   assert_param(IS_FDCAN_MAX_VALUE(Mask, 0x1FFFFFFFU));
1421 
1422   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1423   {
1424     /* Configure the extended ID mask */
1425     hfdcan->Instance->XIDAM = Mask;
1426 
1427     /* Return function status */
1428     return HAL_OK;
1429   }
1430   else
1431   {
1432     /* Update error code */
1433     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1434 
1435     return HAL_ERROR;
1436   }
1437 }
1438 
1439 /**
1440   * @brief  Configure the Rx FIFO operation mode.
1441   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1442   *         the configuration information for the specified FDCAN.
1443   * @param  RxFifo Rx FIFO.
1444   *         This parameter can be one of the following values:
1445   *           @arg FDCAN_RX_FIFO0: Rx FIFO 0
1446   *           @arg FDCAN_RX_FIFO1: Rx FIFO 1
1447   * @param  OperationMode operation mode.
1448   *         This parameter can be a value of @arg FDCAN_Rx_FIFO_operation_mode.
1449   * @retval HAL status
1450   */
HAL_FDCAN_ConfigRxFifoOverwrite(FDCAN_HandleTypeDef * hfdcan,uint32_t RxFifo,uint32_t OperationMode)1451 HAL_StatusTypeDef HAL_FDCAN_ConfigRxFifoOverwrite(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo, uint32_t OperationMode)
1452 {
1453   /* Check function parameters */
1454   assert_param(IS_FDCAN_RX_FIFO(RxFifo));
1455   assert_param(IS_FDCAN_RX_FIFO_MODE(OperationMode));
1456 
1457   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1458   {
1459     if (RxFifo == FDCAN_RX_FIFO0)
1460     {
1461       /* Select FIFO 0 Operation Mode */
1462       MODIFY_REG(hfdcan->Instance->RXGFC, FDCAN_RXGFC_F0OM, (OperationMode << FDCAN_RXGFC_F0OM_Pos));
1463     }
1464     else /* RxFifo == FDCAN_RX_FIFO1 */
1465     {
1466       /* Select FIFO 1 Operation Mode */
1467       MODIFY_REG(hfdcan->Instance->RXGFC, FDCAN_RXGFC_F1OM, (OperationMode << FDCAN_RXGFC_F1OM_Pos));
1468     }
1469 
1470     /* Return function status */
1471     return HAL_OK;
1472   }
1473   else
1474   {
1475     /* Update error code */
1476     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1477 
1478     return HAL_ERROR;
1479   }
1480 }
1481 
1482 /**
1483   * @brief  Configure the RAM watchdog.
1484   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1485   *         the configuration information for the specified FDCAN.
1486   * @param  CounterStartValue Start value of the Message RAM Watchdog Counter,
1487   *         This parameter must be a number between 0x00 and 0xFF,
1488   *         with the reset value of 0x00 the counter is disabled.
1489   * @retval HAL status
1490   */
HAL_FDCAN_ConfigRamWatchdog(FDCAN_HandleTypeDef * hfdcan,uint32_t CounterStartValue)1491 HAL_StatusTypeDef HAL_FDCAN_ConfigRamWatchdog(FDCAN_HandleTypeDef *hfdcan, uint32_t CounterStartValue)
1492 {
1493   /* Check function parameters */
1494   assert_param(IS_FDCAN_MAX_VALUE(CounterStartValue, 0xFFU));
1495 
1496   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1497   {
1498     /* Configure the RAM watchdog counter start value */
1499     MODIFY_REG(hfdcan->Instance->RWD, FDCAN_RWD_WDC, CounterStartValue);
1500 
1501     /* Return function status */
1502     return HAL_OK;
1503   }
1504   else
1505   {
1506     /* Update error code */
1507     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1508 
1509     return HAL_ERROR;
1510   }
1511 }
1512 
1513 /**
1514   * @brief  Configure the timestamp counter.
1515   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1516   *         the configuration information for the specified FDCAN.
1517   * @param  TimestampPrescaler Timestamp Counter Prescaler.
1518   *         This parameter can be a value of @arg FDCAN_Timestamp_Prescaler.
1519   * @retval HAL status
1520   */
HAL_FDCAN_ConfigTimestampCounter(FDCAN_HandleTypeDef * hfdcan,uint32_t TimestampPrescaler)1521 HAL_StatusTypeDef HAL_FDCAN_ConfigTimestampCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t TimestampPrescaler)
1522 {
1523   /* Check function parameters */
1524   assert_param(IS_FDCAN_TIMESTAMP_PRESCALER(TimestampPrescaler));
1525 
1526   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1527   {
1528     /* Configure prescaler */
1529     MODIFY_REG(hfdcan->Instance->TSCC, FDCAN_TSCC_TCP, TimestampPrescaler);
1530 
1531     /* Return function status */
1532     return HAL_OK;
1533   }
1534   else
1535   {
1536     /* Update error code */
1537     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1538 
1539     return HAL_ERROR;
1540   }
1541 }
1542 
1543 /**
1544   * @brief  Enable the timestamp counter.
1545   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1546   *         the configuration information for the specified FDCAN.
1547   * @param  TimestampOperation Timestamp counter operation.
1548   *         This parameter can be a value of @arg FDCAN_Timestamp.
1549   * @retval HAL status
1550   */
HAL_FDCAN_EnableTimestampCounter(FDCAN_HandleTypeDef * hfdcan,uint32_t TimestampOperation)1551 HAL_StatusTypeDef HAL_FDCAN_EnableTimestampCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t TimestampOperation)
1552 {
1553   /* Check function parameters */
1554   assert_param(IS_FDCAN_TIMESTAMP(TimestampOperation));
1555 
1556   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1557   {
1558     /* Enable timestamp counter */
1559     MODIFY_REG(hfdcan->Instance->TSCC, FDCAN_TSCC_TSS, TimestampOperation);
1560 
1561     /* Return function status */
1562     return HAL_OK;
1563   }
1564   else
1565   {
1566     /* Update error code */
1567     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1568 
1569     return HAL_ERROR;
1570   }
1571 }
1572 
1573 /**
1574   * @brief  Disable the timestamp counter.
1575   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1576   *         the configuration information for the specified FDCAN.
1577   * @retval HAL status
1578   */
HAL_FDCAN_DisableTimestampCounter(FDCAN_HandleTypeDef * hfdcan)1579 HAL_StatusTypeDef HAL_FDCAN_DisableTimestampCounter(FDCAN_HandleTypeDef *hfdcan)
1580 {
1581   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1582   {
1583     /* Disable timestamp counter */
1584     CLEAR_BIT(hfdcan->Instance->TSCC, FDCAN_TSCC_TSS);
1585 
1586     /* Return function status */
1587     return HAL_OK;
1588   }
1589   else
1590   {
1591     /* Update error code */
1592     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1593 
1594     return HAL_ERROR;
1595   }
1596 }
1597 
1598 /**
1599   * @brief  Get the timestamp counter value.
1600   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1601   *         the configuration information for the specified FDCAN.
1602   * @retval Timestamp counter value
1603   */
HAL_FDCAN_GetTimestampCounter(const FDCAN_HandleTypeDef * hfdcan)1604 uint16_t HAL_FDCAN_GetTimestampCounter(const FDCAN_HandleTypeDef *hfdcan)
1605 {
1606   return (uint16_t)(hfdcan->Instance->TSCV);
1607 }
1608 
1609 /**
1610   * @brief  Reset the timestamp counter to zero.
1611   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1612   *         the configuration information for the specified FDCAN.
1613   * @retval HAL status
1614   */
HAL_FDCAN_ResetTimestampCounter(FDCAN_HandleTypeDef * hfdcan)1615 HAL_StatusTypeDef HAL_FDCAN_ResetTimestampCounter(FDCAN_HandleTypeDef *hfdcan)
1616 {
1617   if ((hfdcan->Instance->TSCC & FDCAN_TSCC_TSS) != FDCAN_TIMESTAMP_EXTERNAL)
1618   {
1619     /* Reset timestamp counter.
1620        Actually any write operation to TSCV clears the counter */
1621     CLEAR_REG(hfdcan->Instance->TSCV);
1622   }
1623   else
1624   {
1625     /* Update error code.
1626        Unable to reset external counter */
1627     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
1628 
1629     return HAL_ERROR;
1630   }
1631 
1632   /* Return function status */
1633   return HAL_OK;
1634 }
1635 
1636 /**
1637   * @brief  Configure the timeout counter.
1638   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1639   *         the configuration information for the specified FDCAN.
1640   * @param  TimeoutOperation Timeout counter operation.
1641   *         This parameter can be a value of @arg FDCAN_Timeout_Operation.
1642   * @param  TimeoutPeriod Start value of the timeout down-counter.
1643   *         This parameter must be a number between 0x0000 and 0xFFFF
1644   * @retval HAL status
1645   */
HAL_FDCAN_ConfigTimeoutCounter(FDCAN_HandleTypeDef * hfdcan,uint32_t TimeoutOperation,uint32_t TimeoutPeriod)1646 HAL_StatusTypeDef HAL_FDCAN_ConfigTimeoutCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t TimeoutOperation,
1647                                                  uint32_t TimeoutPeriod)
1648 {
1649   /* Check function parameters */
1650   assert_param(IS_FDCAN_TIMEOUT(TimeoutOperation));
1651   assert_param(IS_FDCAN_MAX_VALUE(TimeoutPeriod, 0xFFFFU));
1652 
1653   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1654   {
1655     /* Select timeout operation and configure period */
1656     MODIFY_REG(hfdcan->Instance->TOCC,
1657                (FDCAN_TOCC_TOS | FDCAN_TOCC_TOP), (TimeoutOperation | (TimeoutPeriod << FDCAN_TOCC_TOP_Pos)));
1658 
1659     /* Return function status */
1660     return HAL_OK;
1661   }
1662   else
1663   {
1664     /* Update error code */
1665     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1666 
1667     return HAL_ERROR;
1668   }
1669 }
1670 
1671 /**
1672   * @brief  Enable the timeout counter.
1673   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1674   *         the configuration information for the specified FDCAN.
1675   * @retval HAL status
1676   */
HAL_FDCAN_EnableTimeoutCounter(FDCAN_HandleTypeDef * hfdcan)1677 HAL_StatusTypeDef HAL_FDCAN_EnableTimeoutCounter(FDCAN_HandleTypeDef *hfdcan)
1678 {
1679   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1680   {
1681     /* Enable timeout counter */
1682     SET_BIT(hfdcan->Instance->TOCC, FDCAN_TOCC_ETOC);
1683 
1684     /* Return function status */
1685     return HAL_OK;
1686   }
1687   else
1688   {
1689     /* Update error code */
1690     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1691 
1692     return HAL_ERROR;
1693   }
1694 }
1695 
1696 /**
1697   * @brief  Disable the timeout counter.
1698   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1699   *         the configuration information for the specified FDCAN.
1700   * @retval HAL status
1701   */
HAL_FDCAN_DisableTimeoutCounter(FDCAN_HandleTypeDef * hfdcan)1702 HAL_StatusTypeDef HAL_FDCAN_DisableTimeoutCounter(FDCAN_HandleTypeDef *hfdcan)
1703 {
1704   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1705   {
1706     /* Disable timeout counter */
1707     CLEAR_BIT(hfdcan->Instance->TOCC, FDCAN_TOCC_ETOC);
1708 
1709     /* Return function status */
1710     return HAL_OK;
1711   }
1712   else
1713   {
1714     /* Update error code */
1715     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1716 
1717     return HAL_ERROR;
1718   }
1719 }
1720 
1721 /**
1722   * @brief  Get the timeout counter value.
1723   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1724   *         the configuration information for the specified FDCAN.
1725   * @retval Timeout counter value
1726   */
HAL_FDCAN_GetTimeoutCounter(const FDCAN_HandleTypeDef * hfdcan)1727 uint16_t HAL_FDCAN_GetTimeoutCounter(const FDCAN_HandleTypeDef *hfdcan)
1728 {
1729   return (uint16_t)(hfdcan->Instance->TOCV);
1730 }
1731 
1732 /**
1733   * @brief  Reset the timeout counter to its start value.
1734   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1735   *         the configuration information for the specified FDCAN.
1736   * @retval HAL status
1737   */
HAL_FDCAN_ResetTimeoutCounter(FDCAN_HandleTypeDef * hfdcan)1738 HAL_StatusTypeDef HAL_FDCAN_ResetTimeoutCounter(FDCAN_HandleTypeDef *hfdcan)
1739 {
1740   if ((hfdcan->Instance->TOCC & FDCAN_TOCC_TOS) == FDCAN_TIMEOUT_CONTINUOUS)
1741   {
1742     /* Reset timeout counter to start value */
1743     CLEAR_REG(hfdcan->Instance->TOCV);
1744 
1745     /* Return function status */
1746     return HAL_OK;
1747   }
1748   else
1749   {
1750     /* Update error code.
1751        Unable to reset counter: controlled only by FIFO empty state */
1752     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
1753 
1754     return HAL_ERROR;
1755   }
1756 }
1757 
1758 /**
1759   * @brief  Configure the transmitter delay compensation.
1760   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1761   *         the configuration information for the specified FDCAN.
1762   * @param  TdcOffset Transmitter Delay Compensation Offset.
1763   *         This parameter must be a number between 0x00 and 0x7F.
1764   * @param  TdcFilter Transmitter Delay Compensation Filter Window Length.
1765   *         This parameter must be a number between 0x00 and 0x7F.
1766   * @retval HAL status
1767   */
HAL_FDCAN_ConfigTxDelayCompensation(FDCAN_HandleTypeDef * hfdcan,uint32_t TdcOffset,uint32_t TdcFilter)1768 HAL_StatusTypeDef HAL_FDCAN_ConfigTxDelayCompensation(FDCAN_HandleTypeDef *hfdcan, uint32_t TdcOffset,
1769                                                       uint32_t TdcFilter)
1770 {
1771   /* Check function parameters */
1772   assert_param(IS_FDCAN_MAX_VALUE(TdcOffset, 0x7FU));
1773   assert_param(IS_FDCAN_MAX_VALUE(TdcFilter, 0x7FU));
1774 
1775   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1776   {
1777     /* Configure TDC offset and filter window */
1778     hfdcan->Instance->TDCR = ((TdcFilter << FDCAN_TDCR_TDCF_Pos) | (TdcOffset << FDCAN_TDCR_TDCO_Pos));
1779 
1780     /* Return function status */
1781     return HAL_OK;
1782   }
1783   else
1784   {
1785     /* Update error code */
1786     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1787 
1788     return HAL_ERROR;
1789   }
1790 }
1791 
1792 /**
1793   * @brief  Enable the transmitter delay compensation.
1794   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1795   *         the configuration information for the specified FDCAN.
1796   * @retval HAL status
1797   */
HAL_FDCAN_EnableTxDelayCompensation(FDCAN_HandleTypeDef * hfdcan)1798 HAL_StatusTypeDef HAL_FDCAN_EnableTxDelayCompensation(FDCAN_HandleTypeDef *hfdcan)
1799 {
1800   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1801   {
1802     /* Enable transmitter delay compensation */
1803     SET_BIT(hfdcan->Instance->DBTP, FDCAN_DBTP_TDC);
1804 
1805     /* Return function status */
1806     return HAL_OK;
1807   }
1808   else
1809   {
1810     /* Update error code */
1811     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1812 
1813     return HAL_ERROR;
1814   }
1815 }
1816 
1817 /**
1818   * @brief  Disable the transmitter delay compensation.
1819   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1820   *         the configuration information for the specified FDCAN.
1821   * @retval HAL status
1822   */
HAL_FDCAN_DisableTxDelayCompensation(FDCAN_HandleTypeDef * hfdcan)1823 HAL_StatusTypeDef HAL_FDCAN_DisableTxDelayCompensation(FDCAN_HandleTypeDef *hfdcan)
1824 {
1825   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1826   {
1827     /* Disable transmitter delay compensation */
1828     CLEAR_BIT(hfdcan->Instance->DBTP, FDCAN_DBTP_TDC);
1829 
1830     /* Return function status */
1831     return HAL_OK;
1832   }
1833   else
1834   {
1835     /* Update error code */
1836     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1837 
1838     return HAL_ERROR;
1839   }
1840 }
1841 
1842 /**
1843   * @brief  Enable ISO 11898-1 protocol mode.
1844   *         CAN FD frame format is according to ISO 11898-1 standard.
1845   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1846   *         the configuration information for the specified FDCAN.
1847   * @retval HAL status
1848   */
HAL_FDCAN_EnableISOMode(FDCAN_HandleTypeDef * hfdcan)1849 HAL_StatusTypeDef HAL_FDCAN_EnableISOMode(FDCAN_HandleTypeDef *hfdcan)
1850 {
1851   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1852   {
1853     /* Disable Non ISO protocol mode */
1854     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_NISO);
1855 
1856     /* Return function status */
1857     return HAL_OK;
1858   }
1859   else
1860   {
1861     /* Update error code */
1862     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1863 
1864     return HAL_ERROR;
1865   }
1866 }
1867 
1868 /**
1869   * @brief  Disable ISO 11898-1 protocol mode.
1870   *         CAN FD frame format is according to Bosch CAN FD specification V1.0.
1871   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1872   *         the configuration information for the specified FDCAN.
1873   * @retval HAL status
1874   */
HAL_FDCAN_DisableISOMode(FDCAN_HandleTypeDef * hfdcan)1875 HAL_StatusTypeDef HAL_FDCAN_DisableISOMode(FDCAN_HandleTypeDef *hfdcan)
1876 {
1877   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1878   {
1879     /* Enable Non ISO protocol mode */
1880     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_NISO);
1881 
1882     /* Return function status */
1883     return HAL_OK;
1884   }
1885   else
1886   {
1887     /* Update error code */
1888     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1889 
1890     return HAL_ERROR;
1891   }
1892 }
1893 
1894 /**
1895   * @brief  Enable edge filtering during bus integration.
1896   *         Two consecutive dominant tq are required to detect an edge for hard synchronization.
1897   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1898   *         the configuration information for the specified FDCAN.
1899   * @retval HAL status
1900   */
HAL_FDCAN_EnableEdgeFiltering(FDCAN_HandleTypeDef * hfdcan)1901 HAL_StatusTypeDef HAL_FDCAN_EnableEdgeFiltering(FDCAN_HandleTypeDef *hfdcan)
1902 {
1903   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1904   {
1905     /* Enable edge filtering */
1906     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_EFBI);
1907 
1908     /* Return function status */
1909     return HAL_OK;
1910   }
1911   else
1912   {
1913     /* Update error code */
1914     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1915 
1916     return HAL_ERROR;
1917   }
1918 }
1919 
1920 /**
1921   * @brief  Disable edge filtering during bus integration.
1922   *         One dominant tq is required to detect an edge for hard synchronization.
1923   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1924   *         the configuration information for the specified FDCAN.
1925   * @retval HAL status
1926   */
HAL_FDCAN_DisableEdgeFiltering(FDCAN_HandleTypeDef * hfdcan)1927 HAL_StatusTypeDef HAL_FDCAN_DisableEdgeFiltering(FDCAN_HandleTypeDef *hfdcan)
1928 {
1929   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1930   {
1931     /* Disable edge filtering */
1932     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_EFBI);
1933 
1934     /* Return function status */
1935     return HAL_OK;
1936   }
1937   else
1938   {
1939     /* Update error code */
1940     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1941 
1942     return HAL_ERROR;
1943   }
1944 }
1945 
1946 /**
1947   * @}
1948   */
1949 
1950 /** @defgroup FDCAN_Exported_Functions_Group3 Control functions
1951   *  @brief    Control functions
1952   *
1953 @verbatim
1954   ==============================================================================
1955                           ##### Control functions #####
1956   ==============================================================================
1957     [..]  This section provides functions allowing to:
1958       (+) HAL_FDCAN_Start                         : Start the FDCAN module
1959       (+) HAL_FDCAN_Stop                          : Stop the FDCAN module and enable access to configuration registers
1960       (+) HAL_FDCAN_AddMessageToTxFifoQ           : Add a message to the Tx FIFO/Queue and activate the corresponding
1961                                                     transmission request
1962       (+) HAL_FDCAN_GetLatestTxFifoQRequestBuffer : Get Tx buffer index of latest Tx FIFO/Queue request
1963       (+) HAL_FDCAN_AbortTxRequest                : Abort transmission request
1964       (+) HAL_FDCAN_GetRxMessage                  : Get an FDCAN frame from the Rx FIFO zone into the message RAM
1965       (+) HAL_FDCAN_GetTxEvent                    : Get an FDCAN Tx event from the Tx Event FIFO zone
1966                                                     into the message RAM
1967       (+) HAL_FDCAN_GetHighPriorityMessageStatus  : Get high priority message status
1968       (+) HAL_FDCAN_GetProtocolStatus             : Get protocol status
1969       (+) HAL_FDCAN_GetErrorCounters              : Get error counter values
1970       (+) HAL_FDCAN_IsTxBufferMessagePending      : Check if a transmission request is pending
1971                                                     on the selected Tx buffer
1972       (+) HAL_FDCAN_GetRxFifoFillLevel            : Return Rx FIFO fill level
1973       (+) HAL_FDCAN_GetTxFifoFreeLevel            : Return Tx FIFO free level
1974       (+) HAL_FDCAN_IsRestrictedOperationMode     : Check if the FDCAN peripheral entered Restricted Operation Mode
1975       (+) HAL_FDCAN_ExitRestrictedOperationMode   : Exit Restricted Operation Mode
1976 
1977 @endverbatim
1978   * @{
1979   */
1980 
1981 /**
1982   * @brief  Start the FDCAN module.
1983   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1984   *         the configuration information for the specified FDCAN.
1985   * @retval HAL status
1986   */
HAL_FDCAN_Start(FDCAN_HandleTypeDef * hfdcan)1987 HAL_StatusTypeDef HAL_FDCAN_Start(FDCAN_HandleTypeDef *hfdcan)
1988 {
1989   if (hfdcan->State == HAL_FDCAN_STATE_READY)
1990   {
1991     /* Change FDCAN peripheral state */
1992     hfdcan->State = HAL_FDCAN_STATE_BUSY;
1993 
1994     /* Request leave initialisation */
1995     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT);
1996 
1997     /* Reset the FDCAN ErrorCode */
1998     hfdcan->ErrorCode = HAL_FDCAN_ERROR_NONE;
1999 
2000     /* Return function status */
2001     return HAL_OK;
2002   }
2003   else
2004   {
2005     /* Update error code */
2006     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2007 
2008     return HAL_ERROR;
2009   }
2010 }
2011 
2012 /**
2013   * @brief  Stop the FDCAN module and enable access to configuration registers.
2014   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2015   *         the configuration information for the specified FDCAN.
2016   * @retval HAL status
2017   */
HAL_FDCAN_Stop(FDCAN_HandleTypeDef * hfdcan)2018 HAL_StatusTypeDef HAL_FDCAN_Stop(FDCAN_HandleTypeDef *hfdcan)
2019 {
2020   uint32_t Counter = 0U;
2021 
2022   if (hfdcan->State == HAL_FDCAN_STATE_BUSY)
2023   {
2024     /* Request initialisation */
2025     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT);
2026 
2027     /* Wait until the INIT bit into CCCR register is set */
2028     while ((hfdcan->Instance->CCCR & FDCAN_CCCR_INIT) == 0U)
2029     {
2030       /* Check for the Timeout */
2031       if (Counter > FDCAN_TIMEOUT_VALUE)
2032       {
2033         /* Update error code */
2034         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
2035 
2036         /* Change FDCAN state */
2037         hfdcan->State = HAL_FDCAN_STATE_ERROR;
2038 
2039         return HAL_ERROR;
2040       }
2041 
2042       /* Increment counter */
2043       Counter++;
2044     }
2045 
2046     /* Reset counter */
2047     Counter = 0U;
2048 
2049     /* Exit from Sleep mode */
2050     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CSR);
2051 
2052     /* Wait until FDCAN exits sleep mode */
2053     while ((hfdcan->Instance->CCCR & FDCAN_CCCR_CSA) == FDCAN_CCCR_CSA)
2054     {
2055       /* Check for the Timeout */
2056       if (Counter > FDCAN_TIMEOUT_VALUE)
2057       {
2058         /* Update error code */
2059         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
2060 
2061         /* Change FDCAN state */
2062         hfdcan->State = HAL_FDCAN_STATE_ERROR;
2063 
2064         return HAL_ERROR;
2065       }
2066 
2067       /* Increment counter */
2068       Counter++;
2069     }
2070 
2071     /* Enable configuration change */
2072     SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CCE);
2073 
2074     /* Reset Latest Tx FIFO/Queue Request Buffer Index */
2075     hfdcan->LatestTxFifoQRequest = 0U;
2076 
2077     /* Change FDCAN peripheral state */
2078     hfdcan->State = HAL_FDCAN_STATE_READY;
2079 
2080     /* Return function status */
2081     return HAL_OK;
2082   }
2083   else
2084   {
2085     /* Update error code */
2086     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
2087 
2088     return HAL_ERROR;
2089   }
2090 }
2091 
2092 /**
2093   * @brief  Add a message to the Tx FIFO/Queue and activate the corresponding transmission request
2094   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2095   *         the configuration information for the specified FDCAN.
2096   * @param  pTxHeader pointer to a FDCAN_TxHeaderTypeDef structure.
2097   * @param  pTxData pointer to a buffer containing the payload of the Tx frame.
2098   * @retval HAL status
2099   */
HAL_FDCAN_AddMessageToTxFifoQ(FDCAN_HandleTypeDef * hfdcan,const FDCAN_TxHeaderTypeDef * pTxHeader,const uint8_t * pTxData)2100 HAL_StatusTypeDef HAL_FDCAN_AddMessageToTxFifoQ(FDCAN_HandleTypeDef *hfdcan, const FDCAN_TxHeaderTypeDef *pTxHeader,
2101                                                 const uint8_t *pTxData)
2102 {
2103   uint32_t PutIndex;
2104 
2105   /* Check function parameters */
2106   assert_param(IS_FDCAN_ID_TYPE(pTxHeader->IdType));
2107   if (pTxHeader->IdType == FDCAN_STANDARD_ID)
2108   {
2109     assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->Identifier, 0x7FFU));
2110   }
2111   else /* pTxHeader->IdType == FDCAN_EXTENDED_ID */
2112   {
2113     assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->Identifier, 0x1FFFFFFFU));
2114   }
2115   assert_param(IS_FDCAN_FRAME_TYPE(pTxHeader->TxFrameType));
2116   assert_param(IS_FDCAN_DLC(pTxHeader->DataLength));
2117   assert_param(IS_FDCAN_ESI(pTxHeader->ErrorStateIndicator));
2118   assert_param(IS_FDCAN_BRS(pTxHeader->BitRateSwitch));
2119   assert_param(IS_FDCAN_FDF(pTxHeader->FDFormat));
2120   assert_param(IS_FDCAN_EFC(pTxHeader->TxEventFifoControl));
2121   assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->MessageMarker, 0xFFU));
2122 
2123   if (hfdcan->State == HAL_FDCAN_STATE_BUSY)
2124   {
2125     /* Check that the Tx FIFO/Queue is not full */
2126     if ((hfdcan->Instance->TXFQS & FDCAN_TXFQS_TFQF) != 0U)
2127     {
2128       /* Update error code */
2129       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_FULL;
2130 
2131       return HAL_ERROR;
2132     }
2133     else
2134     {
2135       /* Retrieve the Tx FIFO PutIndex */
2136       PutIndex = ((hfdcan->Instance->TXFQS & FDCAN_TXFQS_TFQPI) >> FDCAN_TXFQS_TFQPI_Pos);
2137 
2138       /* Add the message to the Tx FIFO/Queue */
2139       FDCAN_CopyMessageToRAM(hfdcan, pTxHeader, pTxData, PutIndex);
2140 
2141       /* Activate the corresponding transmission request */
2142       hfdcan->Instance->TXBAR = ((uint32_t)1 << PutIndex);
2143 
2144       /* Store the Latest Tx FIFO/Queue Request Buffer Index */
2145       hfdcan->LatestTxFifoQRequest = ((uint32_t)1 << PutIndex);
2146     }
2147 
2148     /* Return function status */
2149     return HAL_OK;
2150   }
2151   else
2152   {
2153     /* Update error code */
2154     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
2155 
2156     return HAL_ERROR;
2157   }
2158 }
2159 
2160 /**
2161   * @brief  Get Tx buffer index of latest Tx FIFO/Queue request
2162   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2163   *         the configuration information for the specified FDCAN.
2164   * @retval Tx buffer index of last Tx FIFO/Queue request
2165   *          - Any value of @arg FDCAN_Tx_location if Tx request has been submitted.
2166   *          - 0 if no Tx FIFO/Queue request have been submitted.
2167   */
HAL_FDCAN_GetLatestTxFifoQRequestBuffer(const FDCAN_HandleTypeDef * hfdcan)2168 uint32_t HAL_FDCAN_GetLatestTxFifoQRequestBuffer(const FDCAN_HandleTypeDef *hfdcan)
2169 {
2170   /* Return Last Tx FIFO/Queue Request Buffer */
2171   return hfdcan->LatestTxFifoQRequest;
2172 }
2173 
2174 /**
2175   * @brief  Abort transmission request
2176   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2177   *         the configuration information for the specified FDCAN.
2178   * @param  BufferIndex buffer index.
2179   *         This parameter can be any combination of @arg FDCAN_Tx_location.
2180   * @retval HAL status
2181   */
HAL_FDCAN_AbortTxRequest(FDCAN_HandleTypeDef * hfdcan,uint32_t BufferIndex)2182 HAL_StatusTypeDef HAL_FDCAN_AbortTxRequest(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndex)
2183 {
2184   /* Check function parameters */
2185   assert_param(IS_FDCAN_TX_LOCATION_LIST(BufferIndex));
2186 
2187   if (hfdcan->State == HAL_FDCAN_STATE_BUSY)
2188   {
2189     /* Add cancellation request */
2190     hfdcan->Instance->TXBCR = BufferIndex;
2191 
2192     /* Return function status */
2193     return HAL_OK;
2194   }
2195   else
2196   {
2197     /* Update error code */
2198     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
2199 
2200     return HAL_ERROR;
2201   }
2202 }
2203 
2204 /**
2205   * @brief  Get an FDCAN frame from the Rx FIFO zone into the message RAM.
2206   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2207   *         the configuration information for the specified FDCAN.
2208   * @param  RxLocation Location of the received message to be read.
2209   *         This parameter can be a value of @arg FDCAN_Rx_location.
2210   * @param  pRxHeader pointer to a FDCAN_RxHeaderTypeDef structure.
2211   * @param  pRxData pointer to a buffer where the payload of the Rx frame will be stored.
2212   * @retval HAL status
2213   */
HAL_FDCAN_GetRxMessage(FDCAN_HandleTypeDef * hfdcan,uint32_t RxLocation,FDCAN_RxHeaderTypeDef * pRxHeader,uint8_t * pRxData)2214 HAL_StatusTypeDef HAL_FDCAN_GetRxMessage(FDCAN_HandleTypeDef *hfdcan, uint32_t RxLocation,
2215                                          FDCAN_RxHeaderTypeDef *pRxHeader, uint8_t *pRxData)
2216 {
2217   uint32_t *RxAddress;
2218   uint8_t  *pData;
2219   uint32_t ByteCounter;
2220   uint32_t GetIndex = 0;
2221   HAL_FDCAN_StateTypeDef state = hfdcan->State;
2222 
2223   /* Check function parameters */
2224   assert_param(IS_FDCAN_RX_FIFO(RxLocation));
2225 
2226   if (state == HAL_FDCAN_STATE_BUSY)
2227   {
2228     if (RxLocation == FDCAN_RX_FIFO0) /* Rx element is assigned to the Rx FIFO 0 */
2229     {
2230       /* Check that the Rx FIFO 0 is not empty */
2231       if ((hfdcan->Instance->RXF0S & FDCAN_RXF0S_F0FL) == 0U)
2232       {
2233         /* Update error code */
2234         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_EMPTY;
2235 
2236         return HAL_ERROR;
2237       }
2238       else
2239       {
2240         /* Check that the Rx FIFO 0 is full & overwrite mode is on */
2241         if (((hfdcan->Instance->RXF0S & FDCAN_RXF0S_F0F) >> FDCAN_RXF0S_F0F_Pos) == 1U)
2242         {
2243           if (((hfdcan->Instance->RXGFC & FDCAN_RXGFC_F0OM) >> FDCAN_RXGFC_F0OM_Pos) == FDCAN_RX_FIFO_OVERWRITE)
2244           {
2245             /* When overwrite status is on discard first message in FIFO */
2246             GetIndex = 1U;
2247           }
2248         }
2249 
2250         /* Calculate Rx FIFO 0 element index */
2251         GetIndex += ((hfdcan->Instance->RXF0S & FDCAN_RXF0S_F0GI) >> FDCAN_RXF0S_F0GI_Pos);
2252 
2253         /* Calculate Rx FIFO 0 element address */
2254         RxAddress = (uint32_t *)(hfdcan->msgRam.RxFIFO0SA + (GetIndex * SRAMCAN_RF0_SIZE));
2255       }
2256     }
2257     else /* Rx element is assigned to the Rx FIFO 1 */
2258     {
2259       /* Check that the Rx FIFO 1 is not empty */
2260       if ((hfdcan->Instance->RXF1S & FDCAN_RXF1S_F1FL) == 0U)
2261       {
2262         /* Update error code */
2263         hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_EMPTY;
2264 
2265         return HAL_ERROR;
2266       }
2267       else
2268       {
2269         /* Check that the Rx FIFO 1 is full & overwrite mode is on */
2270         if (((hfdcan->Instance->RXF1S & FDCAN_RXF1S_F1F) >> FDCAN_RXF1S_F1F_Pos) == 1U)
2271         {
2272           if (((hfdcan->Instance->RXGFC & FDCAN_RXGFC_F1OM) >> FDCAN_RXGFC_F1OM_Pos) == FDCAN_RX_FIFO_OVERWRITE)
2273           {
2274             /* When overwrite status is on discard first message in FIFO */
2275             GetIndex = 1U;
2276           }
2277         }
2278 
2279         /* Calculate Rx FIFO 1 element index */
2280         GetIndex += ((hfdcan->Instance->RXF1S & FDCAN_RXF1S_F1GI) >> FDCAN_RXF1S_F1GI_Pos);
2281         /* Calculate Rx FIFO 1 element address */
2282         RxAddress = (uint32_t *)(hfdcan->msgRam.RxFIFO1SA + (GetIndex * SRAMCAN_RF1_SIZE));
2283       }
2284     }
2285 
2286     /* Retrieve IdType */
2287     pRxHeader->IdType = *RxAddress & FDCAN_ELEMENT_MASK_XTD;
2288 
2289     /* Retrieve Identifier */
2290     if (pRxHeader->IdType == FDCAN_STANDARD_ID) /* Standard ID element */
2291     {
2292       pRxHeader->Identifier = ((*RxAddress & FDCAN_ELEMENT_MASK_STDID) >> 18U);
2293     }
2294     else /* Extended ID element */
2295     {
2296       pRxHeader->Identifier = (*RxAddress & FDCAN_ELEMENT_MASK_EXTID);
2297     }
2298 
2299     /* Retrieve RxFrameType */
2300     pRxHeader->RxFrameType = (*RxAddress & FDCAN_ELEMENT_MASK_RTR);
2301 
2302     /* Retrieve ErrorStateIndicator */
2303     pRxHeader->ErrorStateIndicator = (*RxAddress & FDCAN_ELEMENT_MASK_ESI);
2304 
2305     /* Increment RxAddress pointer to second word of Rx FIFO element */
2306     RxAddress++;
2307 
2308     /* Retrieve RxTimestamp */
2309     pRxHeader->RxTimestamp = (*RxAddress & FDCAN_ELEMENT_MASK_TS);
2310 
2311     /* Retrieve DataLength */
2312     pRxHeader->DataLength = ((*RxAddress & FDCAN_ELEMENT_MASK_DLC) >> 16U);
2313 
2314     /* Retrieve BitRateSwitch */
2315     pRxHeader->BitRateSwitch = (*RxAddress & FDCAN_ELEMENT_MASK_BRS);
2316 
2317     /* Retrieve FDFormat */
2318     pRxHeader->FDFormat = (*RxAddress & FDCAN_ELEMENT_MASK_FDF);
2319 
2320     /* Retrieve FilterIndex */
2321     pRxHeader->FilterIndex = ((*RxAddress & FDCAN_ELEMENT_MASK_FIDX) >> 24U);
2322 
2323     /* Retrieve NonMatchingFrame */
2324     pRxHeader->IsFilterMatchingFrame = ((*RxAddress & FDCAN_ELEMENT_MASK_ANMF) >> 31U);
2325 
2326     /* Increment RxAddress pointer to payload of Rx FIFO element */
2327     RxAddress++;
2328 
2329     /* Retrieve Rx payload */
2330     pData = (uint8_t *)RxAddress;
2331     for (ByteCounter = 0; ByteCounter < DLCtoBytes[pRxHeader->DataLength]; ByteCounter++)
2332     {
2333       pRxData[ByteCounter] = pData[ByteCounter];
2334     }
2335 
2336     if (RxLocation == FDCAN_RX_FIFO0) /* Rx element is assigned to the Rx FIFO 0 */
2337     {
2338       /* Acknowledge the Rx FIFO 0 that the oldest element is read so that it increments the GetIndex */
2339       hfdcan->Instance->RXF0A = GetIndex;
2340     }
2341     else /* Rx element is assigned to the Rx FIFO 1 */
2342     {
2343       /* Acknowledge the Rx FIFO 1 that the oldest element is read so that it increments the GetIndex */
2344       hfdcan->Instance->RXF1A = GetIndex;
2345     }
2346 
2347     /* Return function status */
2348     return HAL_OK;
2349   }
2350   else
2351   {
2352     /* Update error code */
2353     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
2354 
2355     return HAL_ERROR;
2356   }
2357 }
2358 
2359 /**
2360   * @brief  Get an FDCAN Tx event from the Tx Event FIFO zone into the message RAM.
2361   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2362   *         the configuration information for the specified FDCAN.
2363   * @param  pTxEvent pointer to a FDCAN_TxEventFifoTypeDef structure.
2364   * @retval HAL status
2365   */
HAL_FDCAN_GetTxEvent(FDCAN_HandleTypeDef * hfdcan,FDCAN_TxEventFifoTypeDef * pTxEvent)2366 HAL_StatusTypeDef HAL_FDCAN_GetTxEvent(FDCAN_HandleTypeDef *hfdcan, FDCAN_TxEventFifoTypeDef *pTxEvent)
2367 {
2368   uint32_t *TxEventAddress;
2369   uint32_t GetIndex;
2370   HAL_FDCAN_StateTypeDef state = hfdcan->State;
2371 
2372   if (state == HAL_FDCAN_STATE_BUSY)
2373   {
2374     /* Check that the Tx event FIFO is not empty */
2375     if ((hfdcan->Instance->TXEFS & FDCAN_TXEFS_EFFL) == 0U)
2376     {
2377       /* Update error code */
2378       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_EMPTY;
2379 
2380       return HAL_ERROR;
2381     }
2382 
2383     /* Calculate Tx event FIFO element address */
2384     GetIndex = ((hfdcan->Instance->TXEFS & FDCAN_TXEFS_EFGI) >> FDCAN_TXEFS_EFGI_Pos);
2385     TxEventAddress = (uint32_t *)(hfdcan->msgRam.TxEventFIFOSA + (GetIndex * SRAMCAN_TEF_SIZE));
2386 
2387     /* Retrieve IdType */
2388     pTxEvent->IdType = *TxEventAddress & FDCAN_ELEMENT_MASK_XTD;
2389 
2390     /* Retrieve Identifier */
2391     if (pTxEvent->IdType == FDCAN_STANDARD_ID) /* Standard ID element */
2392     {
2393       pTxEvent->Identifier = ((*TxEventAddress & FDCAN_ELEMENT_MASK_STDID) >> 18U);
2394     }
2395     else /* Extended ID element */
2396     {
2397       pTxEvent->Identifier = (*TxEventAddress & FDCAN_ELEMENT_MASK_EXTID);
2398     }
2399 
2400     /* Retrieve TxFrameType */
2401     pTxEvent->TxFrameType = (*TxEventAddress & FDCAN_ELEMENT_MASK_RTR);
2402 
2403     /* Retrieve ErrorStateIndicator */
2404     pTxEvent->ErrorStateIndicator = (*TxEventAddress & FDCAN_ELEMENT_MASK_ESI);
2405 
2406     /* Increment TxEventAddress pointer to second word of Tx Event FIFO element */
2407     TxEventAddress++;
2408 
2409     /* Retrieve TxTimestamp */
2410     pTxEvent->TxTimestamp = (*TxEventAddress & FDCAN_ELEMENT_MASK_TS);
2411 
2412     /* Retrieve DataLength */
2413     pTxEvent->DataLength = ((*TxEventAddress & FDCAN_ELEMENT_MASK_DLC) >> 16U);
2414 
2415     /* Retrieve BitRateSwitch */
2416     pTxEvent->BitRateSwitch = (*TxEventAddress & FDCAN_ELEMENT_MASK_BRS);
2417 
2418     /* Retrieve FDFormat */
2419     pTxEvent->FDFormat = (*TxEventAddress & FDCAN_ELEMENT_MASK_FDF);
2420 
2421     /* Retrieve EventType */
2422     pTxEvent->EventType = (*TxEventAddress & FDCAN_ELEMENT_MASK_ET);
2423 
2424     /* Retrieve MessageMarker */
2425     pTxEvent->MessageMarker = ((*TxEventAddress & FDCAN_ELEMENT_MASK_MM) >> 24U);
2426 
2427     /* Acknowledge the Tx Event FIFO that the oldest element is read so that it increments the GetIndex */
2428     hfdcan->Instance->TXEFA = GetIndex;
2429 
2430     /* Return function status */
2431     return HAL_OK;
2432   }
2433   else
2434   {
2435     /* Update error code */
2436     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
2437 
2438     return HAL_ERROR;
2439   }
2440 }
2441 
2442 /**
2443   * @brief  Get high priority message status.
2444   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2445   *         the configuration information for the specified FDCAN.
2446   * @param  HpMsgStatus pointer to an FDCAN_HpMsgStatusTypeDef structure.
2447   * @retval HAL status
2448   */
HAL_FDCAN_GetHighPriorityMessageStatus(const FDCAN_HandleTypeDef * hfdcan,FDCAN_HpMsgStatusTypeDef * HpMsgStatus)2449 HAL_StatusTypeDef HAL_FDCAN_GetHighPriorityMessageStatus(const FDCAN_HandleTypeDef *hfdcan,
2450                                                          FDCAN_HpMsgStatusTypeDef *HpMsgStatus)
2451 {
2452   HpMsgStatus->FilterList = ((hfdcan->Instance->HPMS & FDCAN_HPMS_FLST) >> FDCAN_HPMS_FLST_Pos);
2453   HpMsgStatus->FilterIndex = ((hfdcan->Instance->HPMS & FDCAN_HPMS_FIDX) >> FDCAN_HPMS_FIDX_Pos);
2454   HpMsgStatus->MessageStorage = (hfdcan->Instance->HPMS & FDCAN_HPMS_MSI);
2455   HpMsgStatus->MessageIndex = (hfdcan->Instance->HPMS & FDCAN_HPMS_BIDX);
2456 
2457   /* Return function status */
2458   return HAL_OK;
2459 }
2460 
2461 /**
2462   * @brief  Get protocol status.
2463   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2464   *         the configuration information for the specified FDCAN.
2465   * @param  ProtocolStatus pointer to an FDCAN_ProtocolStatusTypeDef structure.
2466   * @retval HAL status
2467   */
HAL_FDCAN_GetProtocolStatus(const FDCAN_HandleTypeDef * hfdcan,FDCAN_ProtocolStatusTypeDef * ProtocolStatus)2468 HAL_StatusTypeDef HAL_FDCAN_GetProtocolStatus(const FDCAN_HandleTypeDef *hfdcan,
2469                                               FDCAN_ProtocolStatusTypeDef *ProtocolStatus)
2470 {
2471   uint32_t StatusReg;
2472 
2473   /* Read the protocol status register */
2474   StatusReg = READ_REG(hfdcan->Instance->PSR);
2475 
2476   /* Fill the protocol status structure */
2477   ProtocolStatus->LastErrorCode = (StatusReg & FDCAN_PSR_LEC);
2478   ProtocolStatus->DataLastErrorCode = ((StatusReg & FDCAN_PSR_DLEC) >> FDCAN_PSR_DLEC_Pos);
2479   ProtocolStatus->Activity = (StatusReg & FDCAN_PSR_ACT);
2480   ProtocolStatus->ErrorPassive = ((StatusReg & FDCAN_PSR_EP) >> FDCAN_PSR_EP_Pos);
2481   ProtocolStatus->Warning = ((StatusReg & FDCAN_PSR_EW) >> FDCAN_PSR_EW_Pos);
2482   ProtocolStatus->BusOff = ((StatusReg & FDCAN_PSR_BO) >> FDCAN_PSR_BO_Pos);
2483   ProtocolStatus->RxESIflag = ((StatusReg & FDCAN_PSR_RESI) >> FDCAN_PSR_RESI_Pos);
2484   ProtocolStatus->RxBRSflag = ((StatusReg & FDCAN_PSR_RBRS) >> FDCAN_PSR_RBRS_Pos);
2485   ProtocolStatus->RxFDFflag = ((StatusReg & FDCAN_PSR_REDL) >> FDCAN_PSR_REDL_Pos);
2486   ProtocolStatus->ProtocolException = ((StatusReg & FDCAN_PSR_PXE) >> FDCAN_PSR_PXE_Pos);
2487   ProtocolStatus->TDCvalue = ((StatusReg & FDCAN_PSR_TDCV) >> FDCAN_PSR_TDCV_Pos);
2488 
2489   /* Return function status */
2490   return HAL_OK;
2491 }
2492 
2493 /**
2494   * @brief  Get error counter values.
2495   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2496   *         the configuration information for the specified FDCAN.
2497   * @param  ErrorCounters pointer to an FDCAN_ErrorCountersTypeDef structure.
2498   * @retval HAL status
2499   */
HAL_FDCAN_GetErrorCounters(const FDCAN_HandleTypeDef * hfdcan,FDCAN_ErrorCountersTypeDef * ErrorCounters)2500 HAL_StatusTypeDef HAL_FDCAN_GetErrorCounters(const FDCAN_HandleTypeDef *hfdcan,
2501                                              FDCAN_ErrorCountersTypeDef *ErrorCounters)
2502 {
2503   uint32_t CountersReg;
2504 
2505   /* Read the error counters register */
2506   CountersReg = READ_REG(hfdcan->Instance->ECR);
2507 
2508   /* Fill the error counters structure */
2509   ErrorCounters->TxErrorCnt = ((CountersReg & FDCAN_ECR_TEC) >> FDCAN_ECR_TEC_Pos);
2510   ErrorCounters->RxErrorCnt = ((CountersReg & FDCAN_ECR_REC) >> FDCAN_ECR_REC_Pos);
2511   ErrorCounters->RxErrorPassive = ((CountersReg & FDCAN_ECR_RP) >> FDCAN_ECR_RP_Pos);
2512   ErrorCounters->ErrorLogging = ((CountersReg & FDCAN_ECR_CEL) >> FDCAN_ECR_CEL_Pos);
2513 
2514   /* Return function status */
2515   return HAL_OK;
2516 }
2517 
2518 /**
2519   * @brief  Check if a transmission request is pending on the selected Tx buffer.
2520   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2521   *         the configuration information for the specified FDCAN.
2522   * @param  TxBufferIndex Tx buffer index.
2523   *         This parameter can be any combination of @arg FDCAN_Tx_location.
2524   * @retval Status
2525   *          - 0 : No pending transmission request on TxBufferIndex list.
2526   *          - 1 : Pending transmission request on TxBufferIndex.
2527   */
HAL_FDCAN_IsTxBufferMessagePending(const FDCAN_HandleTypeDef * hfdcan,uint32_t TxBufferIndex)2528 uint32_t HAL_FDCAN_IsTxBufferMessagePending(const FDCAN_HandleTypeDef *hfdcan, uint32_t TxBufferIndex)
2529 {
2530   /* Check function parameters */
2531   assert_param(IS_FDCAN_TX_LOCATION_LIST(TxBufferIndex));
2532 
2533   /* Check pending transmission request on the selected buffer */
2534   if ((hfdcan->Instance->TXBRP & TxBufferIndex) == 0U)
2535   {
2536     return 0;
2537   }
2538   return 1;
2539 }
2540 
2541 /**
2542   * @brief  Return Rx FIFO fill level.
2543   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2544   *         the configuration information for the specified FDCAN.
2545   * @param  RxFifo Rx FIFO.
2546   *         This parameter can be one of the following values:
2547   *           @arg FDCAN_RX_FIFO0: Rx FIFO 0
2548   *           @arg FDCAN_RX_FIFO1: Rx FIFO 1
2549   * @retval Rx FIFO fill level.
2550   */
HAL_FDCAN_GetRxFifoFillLevel(const FDCAN_HandleTypeDef * hfdcan,uint32_t RxFifo)2551 uint32_t HAL_FDCAN_GetRxFifoFillLevel(const FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo)
2552 {
2553   uint32_t FillLevel;
2554 
2555   /* Check function parameters */
2556   assert_param(IS_FDCAN_RX_FIFO(RxFifo));
2557 
2558   if (RxFifo == FDCAN_RX_FIFO0)
2559   {
2560     FillLevel = hfdcan->Instance->RXF0S & FDCAN_RXF0S_F0FL;
2561   }
2562   else /* RxFifo == FDCAN_RX_FIFO1 */
2563   {
2564     FillLevel = hfdcan->Instance->RXF1S & FDCAN_RXF1S_F1FL;
2565   }
2566 
2567   /* Return Rx FIFO fill level */
2568   return FillLevel;
2569 }
2570 
2571 /**
2572   * @brief  Return Tx FIFO free level: number of consecutive free Tx FIFO
2573   *         elements starting from Tx FIFO GetIndex.
2574   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2575   *         the configuration information for the specified FDCAN.
2576   * @retval Tx FIFO free level.
2577   */
HAL_FDCAN_GetTxFifoFreeLevel(const FDCAN_HandleTypeDef * hfdcan)2578 uint32_t HAL_FDCAN_GetTxFifoFreeLevel(const FDCAN_HandleTypeDef *hfdcan)
2579 {
2580   uint32_t FreeLevel;
2581 
2582   FreeLevel = hfdcan->Instance->TXFQS & FDCAN_TXFQS_TFFL;
2583 
2584   /* Return Tx FIFO free level */
2585   return FreeLevel;
2586 }
2587 
2588 /**
2589   * @brief  Check if the FDCAN peripheral entered Restricted Operation Mode.
2590   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2591   *         the configuration information for the specified FDCAN.
2592   * @retval Status
2593   *          - 0 : Normal FDCAN operation.
2594   *          - 1 : Restricted Operation Mode active.
2595   */
HAL_FDCAN_IsRestrictedOperationMode(const FDCAN_HandleTypeDef * hfdcan)2596 uint32_t HAL_FDCAN_IsRestrictedOperationMode(const FDCAN_HandleTypeDef *hfdcan)
2597 {
2598   uint32_t OperationMode;
2599 
2600   /* Get Operation Mode */
2601   OperationMode = ((hfdcan->Instance->CCCR & FDCAN_CCCR_ASM) >> FDCAN_CCCR_ASM_Pos);
2602 
2603   return OperationMode;
2604 }
2605 
2606 /**
2607   * @brief  Exit Restricted Operation Mode.
2608   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2609   *         the configuration information for the specified FDCAN.
2610   * @retval HAL status
2611   */
HAL_FDCAN_ExitRestrictedOperationMode(FDCAN_HandleTypeDef * hfdcan)2612 HAL_StatusTypeDef HAL_FDCAN_ExitRestrictedOperationMode(FDCAN_HandleTypeDef *hfdcan)
2613 {
2614   HAL_FDCAN_StateTypeDef state = hfdcan->State;
2615 
2616   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
2617   {
2618     /* Exit Restricted Operation mode */
2619     CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_ASM);
2620 
2621     /* Return function status */
2622     return HAL_OK;
2623   }
2624   else
2625   {
2626     /* Update error code */
2627     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
2628 
2629     return HAL_ERROR;
2630   }
2631 }
2632 
2633 /**
2634   * @}
2635   */
2636 
2637 /** @defgroup FDCAN_Exported_Functions_Group4 Interrupts management
2638   *  @brief    Interrupts management
2639   *
2640 @verbatim
2641   ==============================================================================
2642                        ##### Interrupts management #####
2643   ==============================================================================
2644     [..]  This section provides functions allowing to:
2645       (+) HAL_FDCAN_ConfigInterruptLines      : Assign interrupts to either Interrupt line 0 or 1
2646       (+) HAL_FDCAN_ActivateNotification      : Enable interrupts
2647       (+) HAL_FDCAN_DeactivateNotification    : Disable interrupts
2648       (+) HAL_FDCAN_IRQHandler                : Handles FDCAN interrupt request
2649 
2650 @endverbatim
2651   * @{
2652   */
2653 
2654 /**
2655   * @brief  Assign interrupts to either Interrupt line 0 or 1.
2656   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2657   *         the configuration information for the specified FDCAN.
2658   * @param  ITList indicates which interrupts group will be assigned to the selected interrupt line.
2659   *         This parameter can be any combination of @arg FDCAN_Interrupts_Group.
2660   * @param  InterruptLine Interrupt line.
2661   *         This parameter can be a value of @arg FDCAN_Interrupt_Line.
2662   * @retval HAL status
2663   */
HAL_FDCAN_ConfigInterruptLines(FDCAN_HandleTypeDef * hfdcan,uint32_t ITList,uint32_t InterruptLine)2664 HAL_StatusTypeDef HAL_FDCAN_ConfigInterruptLines(FDCAN_HandleTypeDef *hfdcan, uint32_t ITList, uint32_t InterruptLine)
2665 {
2666   HAL_FDCAN_StateTypeDef state = hfdcan->State;
2667 
2668   /* Check function parameters */
2669   assert_param(IS_FDCAN_IT_GROUP(ITList));
2670   assert_param(IS_FDCAN_IT_LINE(InterruptLine));
2671 
2672   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
2673   {
2674     /* Assign list of interrupts to the selected line */
2675     if (InterruptLine == FDCAN_INTERRUPT_LINE0)
2676     {
2677       CLEAR_BIT(hfdcan->Instance->ILS, ITList);
2678     }
2679     else /* InterruptLine == FDCAN_INTERRUPT_LINE1 */
2680     {
2681       SET_BIT(hfdcan->Instance->ILS, ITList);
2682     }
2683 
2684     /* Return function status */
2685     return HAL_OK;
2686   }
2687   else
2688   {
2689     /* Update error code */
2690     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
2691 
2692     return HAL_ERROR;
2693   }
2694 }
2695 
2696 /**
2697   * @brief  Enable interrupts.
2698   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2699   *         the configuration information for the specified FDCAN.
2700   * @param  ActiveITs indicates which interrupts will be enabled.
2701   *         This parameter can be any combination of @arg FDCAN_Interrupts.
2702   * @param  BufferIndexes Tx Buffer Indexes.
2703   *         This parameter can be any combination of @arg FDCAN_Tx_location.
2704   *         This parameter is ignored if ActiveITs does not include one of the following:
2705   *           - FDCAN_IT_TX_COMPLETE
2706   *           - FDCAN_IT_TX_ABORT_COMPLETE
2707   * @retval HAL status
2708   */
HAL_FDCAN_ActivateNotification(FDCAN_HandleTypeDef * hfdcan,uint32_t ActiveITs,uint32_t BufferIndexes)2709 HAL_StatusTypeDef HAL_FDCAN_ActivateNotification(FDCAN_HandleTypeDef *hfdcan, uint32_t ActiveITs,
2710                                                  uint32_t BufferIndexes)
2711 {
2712   HAL_FDCAN_StateTypeDef state = hfdcan->State;
2713   uint32_t ITs_lines_selection;
2714 
2715   /* Check function parameters */
2716   assert_param(IS_FDCAN_IT(ActiveITs));
2717   if ((ActiveITs & (FDCAN_IT_TX_COMPLETE | FDCAN_IT_TX_ABORT_COMPLETE)) != 0U)
2718   {
2719     assert_param(IS_FDCAN_TX_LOCATION_LIST(BufferIndexes));
2720   }
2721 
2722   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
2723   {
2724     /* Get interrupts line selection */
2725     ITs_lines_selection = hfdcan->Instance->ILS;
2726 
2727     /* Enable Interrupt lines */
2728     if ((((ActiveITs & FDCAN_IT_LIST_RX_FIFO0) != 0U)
2729          && (((ITs_lines_selection) & FDCAN_IT_GROUP_RX_FIFO0) == 0U)) || \
2730         (((ActiveITs & FDCAN_IT_LIST_RX_FIFO1)       != 0U)
2731          && (((ITs_lines_selection) & FDCAN_IT_GROUP_RX_FIFO1) == 0U)) || \
2732         (((ActiveITs & FDCAN_IT_LIST_SMSG)           != 0U)
2733          && (((ITs_lines_selection) & FDCAN_IT_GROUP_SMSG)     == 0U)) || \
2734         (((ActiveITs & FDCAN_IT_LIST_TX_FIFO_ERROR)  != 0U)
2735          && (((ITs_lines_selection) & FDCAN_IT_GROUP_TX_FIFO_ERROR)  == 0U)) || \
2736         (((ActiveITs & FDCAN_IT_LIST_MISC)           != 0U)
2737          && (((ITs_lines_selection) & FDCAN_IT_GROUP_MISC)           == 0U)) || \
2738         (((ActiveITs & FDCAN_IT_LIST_BIT_LINE_ERROR) != 0U)
2739          && (((ITs_lines_selection) & FDCAN_IT_GROUP_BIT_LINE_ERROR) == 0U)) || \
2740         (((ActiveITs & FDCAN_IT_LIST_PROTOCOL_ERROR) != 0U)
2741          && (((ITs_lines_selection) & FDCAN_IT_GROUP_PROTOCOL_ERROR) == 0U)))
2742     {
2743       /* Enable Interrupt line 0 */
2744       SET_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE0);
2745     }
2746     if ((((ActiveITs & FDCAN_IT_LIST_RX_FIFO0)       != 0U)
2747          && (((ITs_lines_selection) & FDCAN_IT_GROUP_RX_FIFO0)      != 0U)) || \
2748         (((ActiveITs & FDCAN_IT_LIST_RX_FIFO1)       != 0U)
2749          && (((ITs_lines_selection) & FDCAN_IT_GROUP_RX_FIFO1)       != 0U)) || \
2750         (((ActiveITs & FDCAN_IT_LIST_SMSG)           != 0U)
2751          && (((ITs_lines_selection) & FDCAN_IT_GROUP_SMSG)           != 0U)) || \
2752         (((ActiveITs & FDCAN_IT_LIST_TX_FIFO_ERROR)  != 0U)
2753          && (((ITs_lines_selection) & FDCAN_IT_GROUP_TX_FIFO_ERROR)  != 0U)) || \
2754         (((ActiveITs & FDCAN_IT_LIST_MISC)           != 0U)
2755          && (((ITs_lines_selection) & FDCAN_IT_GROUP_MISC)           != 0U)) || \
2756         (((ActiveITs & FDCAN_IT_LIST_BIT_LINE_ERROR) != 0U)
2757          && (((ITs_lines_selection) & FDCAN_IT_GROUP_BIT_LINE_ERROR) != 0U)) || \
2758         (((ActiveITs & FDCAN_IT_LIST_PROTOCOL_ERROR) != 0U)
2759          && (((ITs_lines_selection) & FDCAN_IT_GROUP_PROTOCOL_ERROR) != 0U)))
2760     {
2761       /* Enable Interrupt line 1 */
2762       SET_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE1);
2763     }
2764 
2765     if ((ActiveITs & FDCAN_IT_TX_COMPLETE) != 0U)
2766     {
2767       /* Enable Tx Buffer Transmission Interrupt to set TC flag in IR register,
2768          but interrupt will only occur if TC is enabled in IE register */
2769       SET_BIT(hfdcan->Instance->TXBTIE, BufferIndexes);
2770     }
2771 
2772     if ((ActiveITs & FDCAN_IT_TX_ABORT_COMPLETE) != 0U)
2773     {
2774       /* Enable Tx Buffer Cancellation Finished Interrupt to set TCF flag in IR register,
2775          but interrupt will only occur if TCF is enabled in IE register */
2776       SET_BIT(hfdcan->Instance->TXBCIE, BufferIndexes);
2777     }
2778 
2779     /* Enable the selected interrupts */
2780     __HAL_FDCAN_ENABLE_IT(hfdcan, ActiveITs);
2781 
2782     /* Return function status */
2783     return HAL_OK;
2784   }
2785   else
2786   {
2787     /* Update error code */
2788     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
2789 
2790     return HAL_ERROR;
2791   }
2792 }
2793 
2794 /**
2795   * @brief  Disable interrupts.
2796   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2797   *         the configuration information for the specified FDCAN.
2798   * @param  InactiveITs indicates which interrupts will be disabled.
2799   *         This parameter can be any combination of @arg FDCAN_Interrupts.
2800   * @retval HAL status
2801   */
HAL_FDCAN_DeactivateNotification(FDCAN_HandleTypeDef * hfdcan,uint32_t InactiveITs)2802 HAL_StatusTypeDef HAL_FDCAN_DeactivateNotification(FDCAN_HandleTypeDef *hfdcan, uint32_t InactiveITs)
2803 {
2804   HAL_FDCAN_StateTypeDef state = hfdcan->State;
2805   uint32_t ITs_enabled;
2806   uint32_t ITs_lines_selection;
2807 
2808   /* Check function parameters */
2809   assert_param(IS_FDCAN_IT(InactiveITs));
2810 
2811   if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
2812   {
2813     /* Disable the selected interrupts */
2814     __HAL_FDCAN_DISABLE_IT(hfdcan, InactiveITs);
2815 
2816     if ((InactiveITs & FDCAN_IT_TX_COMPLETE) != 0U)
2817     {
2818       /* Disable Tx Buffer Transmission Interrupts */
2819       CLEAR_REG(hfdcan->Instance->TXBTIE);
2820     }
2821 
2822     if ((InactiveITs & FDCAN_IT_TX_ABORT_COMPLETE) != 0U)
2823     {
2824       /* Disable Tx Buffer Cancellation Finished Interrupt */
2825       CLEAR_REG(hfdcan->Instance->TXBCIE);
2826     }
2827 
2828     /* Get interrupts enabled and interrupts line selection */
2829     ITs_enabled = hfdcan->Instance->IE;
2830     ITs_lines_selection = hfdcan->Instance->ILS;
2831 
2832     /* Check if some interrupts are still enabled on interrupt line 0 */
2833     if ((((ITs_enabled & FDCAN_IT_LIST_RX_FIFO0)       != 0U)
2834          && (((ITs_lines_selection) & FDCAN_IT_GROUP_RX_FIFO0)       == 0U)) || \
2835         (((ITs_enabled & FDCAN_IT_LIST_RX_FIFO1)       != 0U)
2836          && (((ITs_lines_selection) & FDCAN_IT_GROUP_RX_FIFO1)       == 0U)) || \
2837         (((ITs_enabled & FDCAN_IT_LIST_SMSG)           != 0U)
2838          && (((ITs_lines_selection) & FDCAN_IT_GROUP_SMSG)           == 0U)) || \
2839         (((ITs_enabled & FDCAN_IT_LIST_TX_FIFO_ERROR)  != 0U)
2840          && (((ITs_lines_selection) & FDCAN_IT_GROUP_TX_FIFO_ERROR)  == 0U)) || \
2841         (((ITs_enabled & FDCAN_IT_LIST_MISC)           != 0U)
2842          && (((ITs_lines_selection) & FDCAN_IT_GROUP_MISC)           == 0U)) || \
2843         (((ITs_enabled & FDCAN_IT_LIST_BIT_LINE_ERROR) != 0U)
2844          && (((ITs_lines_selection) & FDCAN_IT_GROUP_BIT_LINE_ERROR) == 0U)) || \
2845         (((ITs_enabled & FDCAN_IT_LIST_PROTOCOL_ERROR) != 0U)
2846          && (((ITs_lines_selection) & FDCAN_IT_GROUP_PROTOCOL_ERROR) == 0U)))
2847     {
2848       /* Do nothing */
2849     }
2850     else /* no more interrupts enabled on interrupt line 0 */
2851     {
2852       /* Disable interrupt line 0 */
2853       CLEAR_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE0);
2854     }
2855 
2856     /* Check if some interrupts are still enabled on interrupt line 1 */
2857     if ((((ITs_enabled & FDCAN_IT_LIST_RX_FIFO0)       != 0U)
2858          && (((ITs_lines_selection) & FDCAN_IT_GROUP_RX_FIFO0)       != 0U)) || \
2859         (((ITs_enabled & FDCAN_IT_LIST_RX_FIFO1)       != 0U)
2860          && (((ITs_lines_selection) & FDCAN_IT_GROUP_RX_FIFO1)       != 0U)) || \
2861         (((ITs_enabled & FDCAN_IT_LIST_SMSG)           != 0U)
2862          && (((ITs_lines_selection) & FDCAN_IT_GROUP_SMSG)           != 0U)) || \
2863         (((ITs_enabled & FDCAN_IT_LIST_TX_FIFO_ERROR)  != 0U)
2864          && (((ITs_lines_selection) & FDCAN_IT_GROUP_TX_FIFO_ERROR)  != 0U)) || \
2865         (((ITs_enabled & FDCAN_IT_LIST_MISC)           != 0U)
2866          && (((ITs_lines_selection) & FDCAN_IT_GROUP_MISC)           != 0U)) || \
2867         (((ITs_enabled & FDCAN_IT_LIST_BIT_LINE_ERROR) != 0U)
2868          && (((ITs_lines_selection) & FDCAN_IT_GROUP_BIT_LINE_ERROR) != 0U)) || \
2869         (((ITs_enabled & FDCAN_IT_LIST_PROTOCOL_ERROR) != 0U)
2870          && (((ITs_lines_selection) & FDCAN_IT_GROUP_PROTOCOL_ERROR) != 0U)))
2871     {
2872       /* Do nothing */
2873     }
2874     else /* no more interrupts enabled on interrupt line 1 */
2875     {
2876       /* Disable interrupt line 1 */
2877       CLEAR_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE1);
2878     }
2879 
2880     /* Return function status */
2881     return HAL_OK;
2882   }
2883   else
2884   {
2885     /* Update error code */
2886     hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
2887 
2888     return HAL_ERROR;
2889   }
2890 }
2891 
2892 /**
2893   * @brief  Handles FDCAN interrupt request.
2894   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2895   *         the configuration information for the specified FDCAN.
2896   * @retval HAL status
2897   */
HAL_FDCAN_IRQHandler(FDCAN_HandleTypeDef * hfdcan)2898 void HAL_FDCAN_IRQHandler(FDCAN_HandleTypeDef *hfdcan)
2899 {
2900   uint32_t TxEventFifoITs;
2901   uint32_t RxFifo0ITs;
2902   uint32_t RxFifo1ITs;
2903   uint32_t Errors;
2904   uint32_t ErrorStatusITs;
2905   uint32_t TransmittedBuffers;
2906   uint32_t AbortedBuffers;
2907   uint32_t itsource;
2908   uint32_t itflag;
2909 
2910   TxEventFifoITs = hfdcan->Instance->IR & FDCAN_TX_EVENT_FIFO_MASK;
2911   TxEventFifoITs &= hfdcan->Instance->IE;
2912   RxFifo0ITs = hfdcan->Instance->IR & FDCAN_RX_FIFO0_MASK;
2913   RxFifo0ITs &= hfdcan->Instance->IE;
2914   RxFifo1ITs = hfdcan->Instance->IR & FDCAN_RX_FIFO1_MASK;
2915   RxFifo1ITs &= hfdcan->Instance->IE;
2916   Errors = hfdcan->Instance->IR & FDCAN_ERROR_MASK;
2917   Errors &= hfdcan->Instance->IE;
2918   ErrorStatusITs = hfdcan->Instance->IR & FDCAN_ERROR_STATUS_MASK;
2919   ErrorStatusITs &= hfdcan->Instance->IE;
2920   itsource = hfdcan->Instance->IE;
2921   itflag = hfdcan->Instance->IR;
2922 
2923   /* High Priority Message interrupt management *******************************/
2924   if (FDCAN_CHECK_FLAG(itflag, FDCAN_FLAG_RX_HIGH_PRIORITY_MSG) != RESET)
2925   {
2926     if (FDCAN_CHECK_IT_SOURCE(itsource, FDCAN_IT_RX_HIGH_PRIORITY_MSG) != RESET)
2927     {
2928       /* Clear the High Priority Message flag */
2929       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_RX_HIGH_PRIORITY_MSG);
2930 
2931 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
2932       /* Call registered callback*/
2933       hfdcan->HighPriorityMessageCallback(hfdcan);
2934 #else
2935       /* High Priority Message Callback */
2936       HAL_FDCAN_HighPriorityMessageCallback(hfdcan);
2937 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
2938     }
2939   }
2940 
2941   /* Transmission Abort interrupt management **********************************/
2942   if (FDCAN_CHECK_FLAG(itflag, FDCAN_FLAG_TX_ABORT_COMPLETE) != RESET)
2943   {
2944     if (FDCAN_CHECK_IT_SOURCE(itsource, FDCAN_IT_TX_ABORT_COMPLETE) != RESET)
2945     {
2946       /* List of aborted monitored buffers */
2947       AbortedBuffers = hfdcan->Instance->TXBCF;
2948       AbortedBuffers &= hfdcan->Instance->TXBCIE;
2949 
2950       /* Clear the Transmission Cancellation flag */
2951       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TX_ABORT_COMPLETE);
2952 
2953 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
2954       /* Call registered callback*/
2955       hfdcan->TxBufferAbortCallback(hfdcan, AbortedBuffers);
2956 #else
2957       /* Transmission Cancellation Callback */
2958       HAL_FDCAN_TxBufferAbortCallback(hfdcan, AbortedBuffers);
2959 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
2960     }
2961   }
2962 
2963   /* Tx event FIFO interrupts management **************************************/
2964   if (TxEventFifoITs != 0U)
2965   {
2966     /* Clear the Tx Event FIFO flags */
2967     __HAL_FDCAN_CLEAR_FLAG(hfdcan, TxEventFifoITs);
2968 
2969 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
2970     /* Call registered callback*/
2971     hfdcan->TxEventFifoCallback(hfdcan, TxEventFifoITs);
2972 #else
2973     /* Tx Event FIFO Callback */
2974     HAL_FDCAN_TxEventFifoCallback(hfdcan, TxEventFifoITs);
2975 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
2976   }
2977 
2978   /* Rx FIFO 0 interrupts management ******************************************/
2979   if (RxFifo0ITs != 0U)
2980   {
2981     /* Clear the Rx FIFO 0 flags */
2982     __HAL_FDCAN_CLEAR_FLAG(hfdcan, RxFifo0ITs);
2983 
2984 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
2985     /* Call registered callback*/
2986     hfdcan->RxFifo0Callback(hfdcan, RxFifo0ITs);
2987 #else
2988     /* Rx FIFO 0 Callback */
2989     HAL_FDCAN_RxFifo0Callback(hfdcan, RxFifo0ITs);
2990 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
2991   }
2992 
2993   /* Rx FIFO 1 interrupts management ******************************************/
2994   if (RxFifo1ITs != 0U)
2995   {
2996     /* Clear the Rx FIFO 1 flags */
2997     __HAL_FDCAN_CLEAR_FLAG(hfdcan, RxFifo1ITs);
2998 
2999 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
3000     /* Call registered callback*/
3001     hfdcan->RxFifo1Callback(hfdcan, RxFifo1ITs);
3002 #else
3003     /* Rx FIFO 1 Callback */
3004     HAL_FDCAN_RxFifo1Callback(hfdcan, RxFifo1ITs);
3005 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
3006   }
3007 
3008   /* Tx FIFO empty interrupt management ***************************************/
3009   if (FDCAN_CHECK_FLAG(itflag, FDCAN_FLAG_TX_FIFO_EMPTY) != RESET)
3010   {
3011     if (FDCAN_CHECK_IT_SOURCE(itsource, FDCAN_IT_TX_FIFO_EMPTY) != RESET)
3012     {
3013       /* Clear the Tx FIFO empty flag */
3014       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TX_FIFO_EMPTY);
3015 
3016 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
3017       /* Call registered callback*/
3018       hfdcan->TxFifoEmptyCallback(hfdcan);
3019 #else
3020       /* Tx FIFO empty Callback */
3021       HAL_FDCAN_TxFifoEmptyCallback(hfdcan);
3022 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
3023     }
3024   }
3025 
3026   /* Transmission Complete interrupt management *******************************/
3027   if (FDCAN_CHECK_FLAG(itflag, FDCAN_FLAG_TX_COMPLETE) != RESET)
3028   {
3029     if (FDCAN_CHECK_IT_SOURCE(itsource, FDCAN_IT_TX_COMPLETE) != RESET)
3030     {
3031       /* List of transmitted monitored buffers */
3032       TransmittedBuffers = hfdcan->Instance->TXBTO;
3033       TransmittedBuffers &= hfdcan->Instance->TXBTIE;
3034 
3035       /* Clear the Transmission Complete flag */
3036       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TX_COMPLETE);
3037 
3038 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
3039       /* Call registered callback*/
3040       hfdcan->TxBufferCompleteCallback(hfdcan, TransmittedBuffers);
3041 #else
3042       /* Transmission Complete Callback */
3043       HAL_FDCAN_TxBufferCompleteCallback(hfdcan, TransmittedBuffers);
3044 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
3045     }
3046   }
3047 
3048   /* Timestamp Wraparound interrupt management ********************************/
3049   if (FDCAN_CHECK_FLAG(itflag, FDCAN_FLAG_TIMESTAMP_WRAPAROUND) != RESET)
3050   {
3051     if (FDCAN_CHECK_IT_SOURCE(itsource, FDCAN_IT_TIMESTAMP_WRAPAROUND) != RESET)
3052     {
3053       /* Clear the Timestamp Wraparound flag */
3054       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TIMESTAMP_WRAPAROUND);
3055 
3056 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
3057       /* Call registered callback*/
3058       hfdcan->TimestampWraparoundCallback(hfdcan);
3059 #else
3060       /* Timestamp Wraparound Callback */
3061       HAL_FDCAN_TimestampWraparoundCallback(hfdcan);
3062 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
3063     }
3064   }
3065 
3066   /* Timeout Occurred interrupt management ************************************/
3067   if (FDCAN_CHECK_FLAG(itflag, FDCAN_FLAG_TIMEOUT_OCCURRED) != RESET)
3068   {
3069     if (FDCAN_CHECK_IT_SOURCE(itsource, FDCAN_IT_TIMEOUT_OCCURRED) != RESET)
3070     {
3071       /* Clear the Timeout Occurred flag */
3072       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TIMEOUT_OCCURRED);
3073 
3074 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
3075       /* Call registered callback*/
3076       hfdcan->TimeoutOccurredCallback(hfdcan);
3077 #else
3078       /* Timeout Occurred Callback */
3079       HAL_FDCAN_TimeoutOccurredCallback(hfdcan);
3080 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
3081     }
3082   }
3083 
3084   /* Message RAM access failure interrupt management **************************/
3085   if (FDCAN_CHECK_FLAG(itflag, FDCAN_FLAG_RAM_ACCESS_FAILURE) != RESET)
3086   {
3087     if (FDCAN_CHECK_IT_SOURCE(itsource, FDCAN_IT_RAM_ACCESS_FAILURE) != RESET)
3088     {
3089       /* Clear the Message RAM access failure flag */
3090       __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_RAM_ACCESS_FAILURE);
3091 
3092       /* Update error code */
3093       hfdcan->ErrorCode |= HAL_FDCAN_ERROR_RAM_ACCESS;
3094     }
3095   }
3096 
3097   /* Error Status interrupts management ***************************************/
3098   if (ErrorStatusITs != 0U)
3099   {
3100     /* Clear the Error flags */
3101     __HAL_FDCAN_CLEAR_FLAG(hfdcan, ErrorStatusITs);
3102 
3103 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
3104     /* Call registered callback*/
3105     hfdcan->ErrorStatusCallback(hfdcan, ErrorStatusITs);
3106 #else
3107     /* Error Status Callback */
3108     HAL_FDCAN_ErrorStatusCallback(hfdcan, ErrorStatusITs);
3109 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
3110   }
3111 
3112   /* Error interrupts management **********************************************/
3113   if (Errors != 0U)
3114   {
3115     /* Clear the Error flags */
3116     __HAL_FDCAN_CLEAR_FLAG(hfdcan, Errors);
3117 
3118     /* Update error code */
3119     hfdcan->ErrorCode |= Errors;
3120   }
3121 
3122   if (hfdcan->ErrorCode != HAL_FDCAN_ERROR_NONE)
3123   {
3124 #if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
3125     /* Call registered callback*/
3126     hfdcan->ErrorCallback(hfdcan);
3127 #else
3128     /* Error Callback */
3129     HAL_FDCAN_ErrorCallback(hfdcan);
3130 #endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
3131   }
3132 }
3133 
3134 /**
3135   * @}
3136   */
3137 
3138 /** @defgroup FDCAN_Exported_Functions_Group5 Callback functions
3139   *  @brief   FDCAN Callback functions
3140   *
3141 @verbatim
3142   ==============================================================================
3143                           ##### Callback functions #####
3144   ==============================================================================
3145     [..]
3146     This subsection provides the following callback functions:
3147       (+) HAL_FDCAN_TxEventFifoCallback
3148       (+) HAL_FDCAN_RxFifo0Callback
3149       (+) HAL_FDCAN_RxFifo1Callback
3150       (+) HAL_FDCAN_TxFifoEmptyCallback
3151       (+) HAL_FDCAN_TxBufferCompleteCallback
3152       (+) HAL_FDCAN_TxBufferAbortCallback
3153       (+) HAL_FDCAN_HighPriorityMessageCallback
3154       (+) HAL_FDCAN_TimestampWraparoundCallback
3155       (+) HAL_FDCAN_TimeoutOccurredCallback
3156       (+) HAL_FDCAN_ErrorCallback
3157       (+) HAL_FDCAN_ErrorStatusCallback
3158 
3159 @endverbatim
3160   * @{
3161   */
3162 
3163 /**
3164   * @brief  Tx Event callback.
3165   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3166   *         the configuration information for the specified FDCAN.
3167   * @param  TxEventFifoITs indicates which Tx Event FIFO interrupts are signaled.
3168   *         This parameter can be any combination of @arg FDCAN_Tx_Event_Fifo_Interrupts.
3169   * @retval None
3170   */
HAL_FDCAN_TxEventFifoCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t TxEventFifoITs)3171 __weak void HAL_FDCAN_TxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t TxEventFifoITs)
3172 {
3173   /* Prevent unused argument(s) compilation warning */
3174   UNUSED(hfdcan);
3175   UNUSED(TxEventFifoITs);
3176 
3177   /* NOTE: This function Should not be modified, when the callback is needed,
3178             the HAL_FDCAN_TxEventFifoCallback could be implemented in the user file
3179    */
3180 }
3181 
3182 /**
3183   * @brief  Rx FIFO 0 callback.
3184   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3185   *         the configuration information for the specified FDCAN.
3186   * @param  RxFifo0ITs indicates which Rx FIFO 0 interrupts are signaled.
3187   *         This parameter can be any combination of @arg FDCAN_Rx_Fifo0_Interrupts.
3188   * @retval None
3189   */
HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef * hfdcan,uint32_t RxFifo0ITs)3190 __weak void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
3191 {
3192   /* Prevent unused argument(s) compilation warning */
3193   UNUSED(hfdcan);
3194   UNUSED(RxFifo0ITs);
3195 
3196   /* NOTE: This function Should not be modified, when the callback is needed,
3197             the HAL_FDCAN_RxFifo0Callback could be implemented in the user file
3198    */
3199 }
3200 
3201 /**
3202   * @brief  Rx FIFO 1 callback.
3203   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3204   *         the configuration information for the specified FDCAN.
3205   * @param  RxFifo1ITs indicates which Rx FIFO 1 interrupts are signaled.
3206   *         This parameter can be any combination of @arg FDCAN_Rx_Fifo1_Interrupts.
3207   * @retval None
3208   */
HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef * hfdcan,uint32_t RxFifo1ITs)3209 __weak void HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo1ITs)
3210 {
3211   /* Prevent unused argument(s) compilation warning */
3212   UNUSED(hfdcan);
3213   UNUSED(RxFifo1ITs);
3214 
3215   /* NOTE: This function Should not be modified, when the callback is needed,
3216             the HAL_FDCAN_RxFifo1Callback could be implemented in the user file
3217    */
3218 }
3219 
3220 /**
3221   * @brief  Tx FIFO Empty callback.
3222   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3223   *         the configuration information for the specified FDCAN.
3224   * @retval None
3225   */
HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef * hfdcan)3226 __weak void HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef *hfdcan)
3227 {
3228   /* Prevent unused argument(s) compilation warning */
3229   UNUSED(hfdcan);
3230 
3231   /* NOTE: This function Should not be modified, when the callback is needed,
3232             the HAL_FDCAN_TxFifoEmptyCallback could be implemented in the user file
3233    */
3234 }
3235 
3236 /**
3237   * @brief  Transmission Complete callback.
3238   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3239   *         the configuration information for the specified FDCAN.
3240   * @param  BufferIndexes Indexes of the transmitted buffers.
3241   *         This parameter can be any combination of @arg FDCAN_Tx_location.
3242   * @retval None
3243   */
HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t BufferIndexes)3244 __weak void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes)
3245 {
3246   /* Prevent unused argument(s) compilation warning */
3247   UNUSED(hfdcan);
3248   UNUSED(BufferIndexes);
3249 
3250   /* NOTE: This function Should not be modified, when the callback is needed,
3251             the HAL_FDCAN_TxBufferCompleteCallback could be implemented in the user file
3252    */
3253 }
3254 
3255 /**
3256   * @brief  Transmission Cancellation callback.
3257   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3258   *         the configuration information for the specified FDCAN.
3259   * @param  BufferIndexes Indexes of the aborted buffers.
3260   *         This parameter can be any combination of @arg FDCAN_Tx_location.
3261   * @retval None
3262   */
HAL_FDCAN_TxBufferAbortCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t BufferIndexes)3263 __weak void HAL_FDCAN_TxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes)
3264 {
3265   /* Prevent unused argument(s) compilation warning */
3266   UNUSED(hfdcan);
3267   UNUSED(BufferIndexes);
3268 
3269   /* NOTE: This function Should not be modified, when the callback is needed,
3270             the HAL_FDCAN_TxBufferAbortCallback could be implemented in the user file
3271    */
3272 }
3273 
3274 /**
3275   * @brief  Timestamp Wraparound callback.
3276   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3277   *         the configuration information for the specified FDCAN.
3278   * @retval None
3279   */
HAL_FDCAN_TimestampWraparoundCallback(FDCAN_HandleTypeDef * hfdcan)3280 __weak void HAL_FDCAN_TimestampWraparoundCallback(FDCAN_HandleTypeDef *hfdcan)
3281 {
3282   /* Prevent unused argument(s) compilation warning */
3283   UNUSED(hfdcan);
3284 
3285   /* NOTE: This function Should not be modified, when the callback is needed,
3286             the HAL_FDCAN_TimestampWraparoundCallback could be implemented in the user file
3287    */
3288 }
3289 
3290 /**
3291   * @brief  Timeout Occurred callback.
3292   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3293   *         the configuration information for the specified FDCAN.
3294   * @retval None
3295   */
HAL_FDCAN_TimeoutOccurredCallback(FDCAN_HandleTypeDef * hfdcan)3296 __weak void HAL_FDCAN_TimeoutOccurredCallback(FDCAN_HandleTypeDef *hfdcan)
3297 {
3298   /* Prevent unused argument(s) compilation warning */
3299   UNUSED(hfdcan);
3300 
3301   /* NOTE: This function Should not be modified, when the callback is needed,
3302             the HAL_FDCAN_TimeoutOccurredCallback could be implemented in the user file
3303    */
3304 }
3305 
3306 /**
3307   * @brief  High Priority Message callback.
3308   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3309   *         the configuration information for the specified FDCAN.
3310   * @retval None
3311   */
HAL_FDCAN_HighPriorityMessageCallback(FDCAN_HandleTypeDef * hfdcan)3312 __weak void HAL_FDCAN_HighPriorityMessageCallback(FDCAN_HandleTypeDef *hfdcan)
3313 {
3314   /* Prevent unused argument(s) compilation warning */
3315   UNUSED(hfdcan);
3316 
3317   /* NOTE: This function Should not be modified, when the callback is needed,
3318             the HAL_FDCAN_HighPriorityMessageCallback could be implemented in the user file
3319    */
3320 }
3321 
3322 /**
3323   * @brief  Error callback.
3324   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3325   *         the configuration information for the specified FDCAN.
3326   * @retval None
3327   */
HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef * hfdcan)3328 __weak void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan)
3329 {
3330   /* Prevent unused argument(s) compilation warning */
3331   UNUSED(hfdcan);
3332 
3333   /* NOTE: This function Should not be modified, when the callback is needed,
3334             the HAL_FDCAN_ErrorCallback could be implemented in the user file
3335    */
3336 }
3337 
3338 /**
3339   * @brief  Error status callback.
3340   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3341   *         the configuration information for the specified FDCAN.
3342   * @param  ErrorStatusITs indicates which Error Status interrupts are signaled.
3343   *         This parameter can be any combination of @arg FDCAN_Error_Status_Interrupts.
3344   * @retval None
3345   */
HAL_FDCAN_ErrorStatusCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t ErrorStatusITs)3346 __weak void HAL_FDCAN_ErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t ErrorStatusITs)
3347 {
3348   /* Prevent unused argument(s) compilation warning */
3349   UNUSED(hfdcan);
3350   UNUSED(ErrorStatusITs);
3351 
3352   /* NOTE: This function Should not be modified, when the callback is needed,
3353             the HAL_FDCAN_ErrorStatusCallback could be implemented in the user file
3354    */
3355 }
3356 
3357 /**
3358   * @}
3359   */
3360 
3361 /** @defgroup FDCAN_Exported_Functions_Group6 Peripheral State functions
3362   *  @brief   FDCAN Peripheral State functions
3363   *
3364 @verbatim
3365   ==============================================================================
3366                       ##### Peripheral State functions #####
3367   ==============================================================================
3368     [..]
3369     This subsection provides functions allowing to :
3370       (+) HAL_FDCAN_GetState()  : Return the FDCAN state.
3371       (+) HAL_FDCAN_GetError()  : Return the FDCAN error code if any.
3372 
3373 @endverbatim
3374   * @{
3375   */
3376 /**
3377   * @brief  Return the FDCAN state
3378   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3379   *         the configuration information for the specified FDCAN.
3380   * @retval HAL state
3381   */
HAL_FDCAN_GetState(const FDCAN_HandleTypeDef * hfdcan)3382 HAL_FDCAN_StateTypeDef HAL_FDCAN_GetState(const FDCAN_HandleTypeDef *hfdcan)
3383 {
3384   /* Return FDCAN state */
3385   return hfdcan->State;
3386 }
3387 
3388 /**
3389   * @brief  Return the FDCAN error code
3390   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3391   *         the configuration information for the specified FDCAN.
3392   * @retval FDCAN Error Code
3393   */
HAL_FDCAN_GetError(const FDCAN_HandleTypeDef * hfdcan)3394 uint32_t HAL_FDCAN_GetError(const FDCAN_HandleTypeDef *hfdcan)
3395 {
3396   /* Return FDCAN error code */
3397   return hfdcan->ErrorCode;
3398 }
3399 
3400 /**
3401   * @}
3402   */
3403 
3404 /**
3405   * @}
3406   */
3407 
3408 /** @defgroup FDCAN_Private_Functions FDCAN Private Functions
3409   * @{
3410   */
3411 
3412 /**
3413   * @brief  Calculate each RAM block start address and size
3414   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3415   *         the configuration information for the specified FDCAN.
3416   * @retval none
3417  */
FDCAN_CalcultateRamBlockAddresses(FDCAN_HandleTypeDef * hfdcan)3418 static void FDCAN_CalcultateRamBlockAddresses(FDCAN_HandleTypeDef *hfdcan)
3419 {
3420   uint32_t RAMcounter;
3421   uint32_t SramCanInstanceBase = SRAMCAN_BASE;
3422 
3423   /* Standard filter list start address */
3424   hfdcan->msgRam.StandardFilterSA = SramCanInstanceBase + SRAMCAN_FLSSA;
3425 
3426   /* Standard filter elements number */
3427   MODIFY_REG(hfdcan->Instance->RXGFC, FDCAN_RXGFC_LSS, (hfdcan->Init.StdFiltersNbr << FDCAN_RXGFC_LSS_Pos));
3428 
3429   /* Extended filter list start address */
3430   hfdcan->msgRam.ExtendedFilterSA = SramCanInstanceBase + SRAMCAN_FLESA;
3431 
3432   /* Extended filter elements number */
3433   MODIFY_REG(hfdcan->Instance->RXGFC, FDCAN_RXGFC_LSE, (hfdcan->Init.ExtFiltersNbr << FDCAN_RXGFC_LSE_Pos));
3434 
3435   /* Rx FIFO 0 start address */
3436   hfdcan->msgRam.RxFIFO0SA = SramCanInstanceBase + SRAMCAN_RF0SA;
3437 
3438   /* Rx FIFO 1 start address */
3439   hfdcan->msgRam.RxFIFO1SA = SramCanInstanceBase + SRAMCAN_RF1SA;
3440 
3441   /* Tx event FIFO start address */
3442   hfdcan->msgRam.TxEventFIFOSA = SramCanInstanceBase + SRAMCAN_TEFSA;
3443 
3444   /* Tx FIFO/queue start address */
3445   hfdcan->msgRam.TxFIFOQSA = SramCanInstanceBase + SRAMCAN_TFQSA;
3446 
3447   /* Flush the allocated Message RAM area */
3448   for (RAMcounter = SramCanInstanceBase; RAMcounter < (SramCanInstanceBase + SRAMCAN_SIZE); RAMcounter += 4U)
3449   {
3450     *(uint32_t *)(RAMcounter) = 0x00000000U;
3451   }
3452 }
3453 
3454 /**
3455   * @brief  Copy Tx message to the message RAM.
3456   * @param  hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3457   *         the configuration information for the specified FDCAN.
3458   * @param  pTxHeader pointer to a FDCAN_TxHeaderTypeDef structure.
3459   * @param  pTxData pointer to a buffer containing the payload of the Tx frame.
3460   * @param  BufferIndex index of the buffer to be configured.
3461   * @retval none
3462  */
FDCAN_CopyMessageToRAM(FDCAN_HandleTypeDef * hfdcan,const FDCAN_TxHeaderTypeDef * pTxHeader,const uint8_t * pTxData,uint32_t BufferIndex)3463 static void FDCAN_CopyMessageToRAM(FDCAN_HandleTypeDef *hfdcan, const FDCAN_TxHeaderTypeDef *pTxHeader,
3464                                    const uint8_t *pTxData, uint32_t BufferIndex)
3465 {
3466   uint32_t TxElementW1;
3467   uint32_t TxElementW2;
3468   uint32_t *TxAddress;
3469   uint32_t ByteCounter;
3470 
3471   /* Build first word of Tx header element */
3472   if (pTxHeader->IdType == FDCAN_STANDARD_ID)
3473   {
3474     TxElementW1 = (pTxHeader->ErrorStateIndicator |
3475                    FDCAN_STANDARD_ID |
3476                    pTxHeader->TxFrameType |
3477                    (pTxHeader->Identifier << 18U));
3478   }
3479   else /* pTxHeader->IdType == FDCAN_EXTENDED_ID */
3480   {
3481     TxElementW1 = (pTxHeader->ErrorStateIndicator |
3482                    FDCAN_EXTENDED_ID |
3483                    pTxHeader->TxFrameType |
3484                    pTxHeader->Identifier);
3485   }
3486 
3487   /* Build second word of Tx header element */
3488   TxElementW2 = ((pTxHeader->MessageMarker << 24U) |
3489                  pTxHeader->TxEventFifoControl |
3490                  pTxHeader->FDFormat |
3491                  pTxHeader->BitRateSwitch |
3492                  (pTxHeader->DataLength << 16U));
3493 
3494   /* Calculate Tx element address */
3495   TxAddress = (uint32_t *)(hfdcan->msgRam.TxFIFOQSA + (BufferIndex * SRAMCAN_TFQ_SIZE));
3496 
3497   /* Write Tx element header to the message RAM */
3498   *TxAddress = TxElementW1;
3499   TxAddress++;
3500   *TxAddress = TxElementW2;
3501   TxAddress++;
3502 
3503   /* Write Tx payload to the message RAM */
3504   for (ByteCounter = 0; ByteCounter < DLCtoBytes[pTxHeader->DataLength]; ByteCounter += 4U)
3505   {
3506     *TxAddress = (((uint32_t)pTxData[ByteCounter + 3U] << 24U) |
3507                   ((uint32_t)pTxData[ByteCounter + 2U] << 16U) |
3508                   ((uint32_t)pTxData[ByteCounter + 1U] << 8U)  |
3509                   (uint32_t)pTxData[ByteCounter]);
3510     TxAddress++;
3511   }
3512 }
3513 
3514 /**
3515   * @}
3516   */
3517 #endif /* HAL_FDCAN_MODULE_ENABLED */
3518 /**
3519   * @}
3520   */
3521 
3522 /**
3523   * @}
3524   */
3525 
3526 #endif /* FDCAN1 */
3527