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