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