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