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