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