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