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