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