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