1 /**
2 ******************************************************************************
3 * @file stm32mp1xx_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 ******************************************************************************
15 * @attention
16 *
17 * Copyright (c) 2019 STMicroelectronics.
18 * All rights reserved.
19 *
20 * This software is licensed under terms that can be found in the LICENSE file
21 * in the root directory of this software component.
22 * If no LICENSE file comes with this software, it is provided AS-IS.
23 *
24 ******************************************************************************
25 @verbatim
26 ==============================================================================
27 ##### How to use this driver #####
28 ==============================================================================
29 [..]
30 (#) Initialize the FDCAN peripheral using HAL_FDCAN_Init function.
31
32 (#) If needed , configure the reception filters and optional features using
33 the following configuration functions:
34 (++) HAL_FDCAN_ConfigClockCalibration
35 (++) HAL_FDCAN_ConfigFilter
36 (++) HAL_FDCAN_ConfigGlobalFilter
37 (++) HAL_FDCAN_ConfigExtendedIdMask
38 (++) HAL_FDCAN_ConfigRxFifoOverwrite
39 (++) HAL_FDCAN_ConfigFifoWatermark
40 (++) HAL_FDCAN_ConfigRamWatchdog
41 (++) HAL_FDCAN_ConfigTimestampCounter
42 (++) HAL_FDCAN_EnableTimestampCounter
43 (++) HAL_FDCAN_DisableTimestampCounter
44 (++) HAL_FDCAN_ConfigTimeoutCounter
45 (++) HAL_FDCAN_EnableTimeoutCounter
46 (++) HAL_FDCAN_DisableTimeoutCounter
47 (++) HAL_FDCAN_ConfigTxDelayCompensation
48 (++) HAL_FDCAN_EnableTxDelayCompensation
49 (++) HAL_FDCAN_DisableTxDelayCompensation
50 (++) HAL_FDCAN_EnableISOMode
51 (++) HAL_FDCAN_DisableISOMode
52 (++) HAL_FDCAN_EnableEdgeFiltering
53 (++) HAL_FDCAN_DisableEdgeFiltering
54 (++) HAL_FDCAN_TT_ConfigOperation
55 (++) HAL_FDCAN_TT_ConfigReferenceMessage
56 (++) HAL_FDCAN_TT_ConfigTrigger
57
58 (#) Start the FDCAN module using HAL_FDCAN_Start function. At this level
59 the node is active on the bus: it can send and receive messages.
60
61 (#) The following Tx control functions can only be called when the FDCAN
62 module is started:
63 (++) HAL_FDCAN_AddMessageToTxFifoQ
64 (++) HAL_FDCAN_EnableTxBufferRequest
65 (++) HAL_FDCAN_AbortTxRequest
66
67 (#) After having submitted a Tx request in Tx Fifo or Queue, it is possible to
68 get Tx buffer location used to place the Tx request thanks to
69 HAL_FDCAN_GetLatestTxFifoQRequestBuffer API.
70 It is then possible to abort later on the corresponding Tx Request using
71 HAL_FDCAN_AbortTxRequest API.
72
73 (#) When a message is received into the FDCAN message RAM, it can be
74 retrieved using the HAL_FDCAN_GetRxMessage function.
75
76 (#) Calling the HAL_FDCAN_Stop function stops the FDCAN module by entering
77 it to initialization mode and re-enabling access to configuration
78 registers through the configuration functions listed here above.
79
80 (#) All other control functions can be called any time after initialization
81 phase, no matter if the FDCAN module is started or stoped.
82
83 *** Polling mode operation ***
84 ==============================
85
86 [..]
87 (#) Reception and transmission states can be monitored via the following
88 functions:
89 (++) HAL_FDCAN_IsRxBufferMessageAvailable
90 (++) HAL_FDCAN_IsTxBufferMessagePending
91 (++) HAL_FDCAN_GetRxFifoFillLevel
92 (++) HAL_FDCAN_GetTxFifoFreeLevel
93
94 *** Interrupt mode operation ***
95 ================================
96 [..]
97 (#) There are two interrupt lines: line 0 and 1.
98 By default, all interrupts are assigned to line 0. Interrupt lines
99 can be configured using HAL_FDCAN_ConfigInterruptLines function.
100
101 (#) Notifications are activated using HAL_FDCAN_ActivateNotification
102 function. Then, the process can be controlled through one of the
103 available user callbacks: HAL_FDCAN_xxxCallback.
104
105 @endverbatim
106 ******************************************************************************
107 */
108
109 /* Includes ------------------------------------------------------------------*/
110 #include "stm32mp1xx_hal.h"
111
112 #if defined(FDCAN1)
113
114 /** @addtogroup STM32MP1xx_HAL_Driver
115 * @{
116 */
117
118 /** @defgroup FDCAN FDCAN
119 * @brief FDCAN HAL module driver
120 * @{
121 */
122
123 #ifdef HAL_FDCAN_MODULE_ENABLED
124
125 /* Private typedef -----------------------------------------------------------*/
126 /* Private define ------------------------------------------------------------*/
127 /** @addtogroup FDCAN_Private_Constants
128 * @{
129 */
130 #define FDCAN_TIMEOUT_VALUE 10U
131
132 #define FDCAN_TX_EVENT_FIFO_MASK (FDCAN_IR_TEFL | FDCAN_IR_TEFF | FDCAN_IR_TEFW | FDCAN_IR_TEFN)
133 #define FDCAN_RX_FIFO0_MASK (FDCAN_IR_RF0L | FDCAN_IR_RF0F | FDCAN_IR_RF0W | FDCAN_IR_RF0N)
134 #define FDCAN_RX_FIFO1_MASK (FDCAN_IR_RF1L | FDCAN_IR_RF1F | FDCAN_IR_RF1W | FDCAN_IR_RF1N)
135 #define FDCAN_ERROR_MASK (FDCAN_IR_ELO | FDCAN_IR_WDI | FDCAN_IR_PEA | FDCAN_IR_PED | FDCAN_IR_ARA)
136 #define FDCAN_ERROR_STATUS_MASK (FDCAN_IR_EP | FDCAN_IR_EW | FDCAN_IR_BO)
137 #define FDCAN_TT_SCHEDULE_SYNC_MASK (FDCAN_TTIR_SBC | FDCAN_TTIR_SMC | FDCAN_TTIR_CSM | FDCAN_TTIR_SOG)
138 #define FDCAN_TT_TIME_MARK_MASK (FDCAN_TTIR_RTMI | FDCAN_TTIR_TTMI)
139 #define FDCAN_TT_GLOBAL_TIME_MASK (FDCAN_TTIR_GTW | FDCAN_TTIR_GTD)
140 #define FDCAN_TT_DISTURBING_ERROR_MASK (FDCAN_TTIR_GTE | FDCAN_TTIR_TXU | FDCAN_TTIR_TXO | \
141 FDCAN_TTIR_SE1 | FDCAN_TTIR_SE2 | FDCAN_TTIR_ELC)
142 #define FDCAN_TT_FATAL_ERROR_MASK (FDCAN_TTIR_IWT | FDCAN_TTIR_WT | FDCAN_TTIR_AW | FDCAN_TTIR_CER)
143
144 #define FDCAN_ELEMENT_MASK_STDID ((uint32_t)0x1FFC0000U) /* Standard Identifier */
145 #define FDCAN_ELEMENT_MASK_EXTID ((uint32_t)0x1FFFFFFFU) /* Extended Identifier */
146 #define FDCAN_ELEMENT_MASK_RTR ((uint32_t)0x20000000U) /* Remote Transmission Request */
147 #define FDCAN_ELEMENT_MASK_XTD ((uint32_t)0x40000000U) /* Extended Identifier */
148 #define FDCAN_ELEMENT_MASK_ESI ((uint32_t)0x80000000U) /* Error State Indicator */
149 #define FDCAN_ELEMENT_MASK_TS ((uint32_t)0x0000FFFFU) /* Timestamp */
150 #define FDCAN_ELEMENT_MASK_DLC ((uint32_t)0x000F0000U) /* Data Length Code */
151 #define FDCAN_ELEMENT_MASK_BRS ((uint32_t)0x00100000U) /* Bit Rate Switch */
152 #define FDCAN_ELEMENT_MASK_FDF ((uint32_t)0x00200000U) /* FD Format */
153 #define FDCAN_ELEMENT_MASK_EFC ((uint32_t)0x00800000U) /* Event FIFO Control */
154 #define FDCAN_ELEMENT_MASK_MM ((uint32_t)0xFF000000U) /* Message Marker */
155 #define FDCAN_ELEMENT_MASK_FIDX ((uint32_t)0x7F000000U) /* Filter Index */
156 #define FDCAN_ELEMENT_MASK_ANMF ((uint32_t)0x80000000U) /* Accepted Non-matching Frame */
157 #define FDCAN_ELEMENT_MASK_ET ((uint32_t)0x00C00000U) /* Event type */
158
159 #define FDCAN_MESSAGE_RAM_SIZE 0x2800U
160 #define FDCAN_MESSAGE_RAM_END_ADDRESS (SRAMCAN_BASE + FDCAN_MESSAGE_RAM_SIZE - 0x4U) /* The Message RAM has a width of 4 Bytes */
161
162 /**
163 * @}
164 */
165
166 /* Private macro -------------------------------------------------------------*/
167 /* Private variables ---------------------------------------------------------*/
168 static const uint8_t DLCtoBytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64};
169
170 /* Private function prototypes -----------------------------------------------*/
171 /** @addtogroup FDCAN_Private_Functions_Prototypes
172 * @{
173 */
174 static HAL_StatusTypeDef FDCAN_CalcultateRamBlockAddresses(FDCAN_HandleTypeDef *hfdcan);
175 static void FDCAN_CopyMessageToRAM(FDCAN_HandleTypeDef *hfdcan, FDCAN_TxHeaderTypeDef *pTxHeader, uint8_t *pTxData, uint32_t BufferIndex);
176 /**
177 * @}
178 */
179
180 /* Exported functions --------------------------------------------------------*/
181 /** @defgroup FDCAN_Exported_Functions FDCAN Exported Functions
182 * @{
183 */
184
185 /** @defgroup FDCAN_Exported_Functions_Group1 Initialization and de-initialization functions
186 * @brief Initialization and Configuration functions
187 *
188 @verbatim
189 ==============================================================================
190 ##### Initialization and de-initialization functions #####
191 ==============================================================================
192 [..] This section provides functions allowing to:
193 (+) Initialize and configure the FDCAN.
194 (+) De-initialize the FDCAN.
195 (+) Enter FDCAN peripheral in power down mode.
196 (+) Exit power down mode.
197
198 @endverbatim
199 * @{
200 */
201
202 /**
203 * @brief Initializes the FDCAN peripheral according to the specified
204 * parameters in the FDCAN_InitTypeDef structure.
205 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
206 * the configuration information for the specified FDCAN.
207 * @retval HAL status
208 */
HAL_FDCAN_Init(FDCAN_HandleTypeDef * hfdcan)209 HAL_StatusTypeDef HAL_FDCAN_Init(FDCAN_HandleTypeDef *hfdcan)
210 {
211 uint32_t tickstart;
212 HAL_StatusTypeDef status;
213 const uint32_t CvtEltSize[] = {0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7};
214
215 /* Check FDCAN handle */
216 if (hfdcan == NULL)
217 {
218 return HAL_ERROR;
219 }
220
221 /* Check FDCAN instance */
222 if (hfdcan->Instance == FDCAN1)
223 {
224 hfdcan->ttcan = (TTCAN_TypeDef *)((uint32_t)hfdcan->Instance + 0x100U);
225 }
226
227 /* Check function parameters */
228 assert_param(IS_FDCAN_ALL_INSTANCE(hfdcan->Instance));
229 assert_param(IS_FDCAN_FRAME_FORMAT(hfdcan->Init.FrameFormat));
230 assert_param(IS_FDCAN_MODE(hfdcan->Init.Mode));
231 assert_param(IS_FUNCTIONAL_STATE(hfdcan->Init.AutoRetransmission));
232 assert_param(IS_FUNCTIONAL_STATE(hfdcan->Init.TransmitPause));
233 assert_param(IS_FUNCTIONAL_STATE(hfdcan->Init.ProtocolException));
234 assert_param(IS_FDCAN_NOMINAL_PRESCALER(hfdcan->Init.NominalPrescaler));
235 assert_param(IS_FDCAN_NOMINAL_SJW(hfdcan->Init.NominalSyncJumpWidth));
236 assert_param(IS_FDCAN_NOMINAL_TSEG1(hfdcan->Init.NominalTimeSeg1));
237 assert_param(IS_FDCAN_NOMINAL_TSEG2(hfdcan->Init.NominalTimeSeg2));
238 if (hfdcan->Init.FrameFormat == FDCAN_FRAME_FD_BRS)
239 {
240 assert_param(IS_FDCAN_DATA_PRESCALER(hfdcan->Init.DataPrescaler));
241 assert_param(IS_FDCAN_DATA_SJW(hfdcan->Init.DataSyncJumpWidth));
242 assert_param(IS_FDCAN_DATA_TSEG1(hfdcan->Init.DataTimeSeg1));
243 assert_param(IS_FDCAN_DATA_TSEG2(hfdcan->Init.DataTimeSeg2));
244 }
245 assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.StdFiltersNbr, 128U));
246 assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.ExtFiltersNbr, 64U));
247 assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.RxFifo0ElmtsNbr, 64U));
248 if (hfdcan->Init.RxFifo0ElmtsNbr > 0U)
249 {
250 assert_param(IS_FDCAN_DATA_SIZE(hfdcan->Init.RxFifo0ElmtSize));
251 }
252 assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.RxFifo1ElmtsNbr, 64U));
253 if (hfdcan->Init.RxFifo1ElmtsNbr > 0U)
254 {
255 assert_param(IS_FDCAN_DATA_SIZE(hfdcan->Init.RxFifo1ElmtSize));
256 }
257 assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.RxBuffersNbr, 64U));
258 if (hfdcan->Init.RxBuffersNbr > 0U)
259 {
260 assert_param(IS_FDCAN_DATA_SIZE(hfdcan->Init.RxBufferSize));
261 }
262 assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.TxEventsNbr, 32U));
263 assert_param(IS_FDCAN_MAX_VALUE((hfdcan->Init.TxBuffersNbr + hfdcan->Init.TxFifoQueueElmtsNbr), 32U));
264 if (hfdcan->Init.TxFifoQueueElmtsNbr > 0U)
265 {
266 assert_param(IS_FDCAN_TX_FIFO_QUEUE_MODE(hfdcan->Init.TxFifoQueueMode));
267 }
268 if ((hfdcan->Init.TxBuffersNbr + hfdcan->Init.TxFifoQueueElmtsNbr) > 0U)
269 {
270 assert_param(IS_FDCAN_DATA_SIZE(hfdcan->Init.TxElmtSize));
271 }
272
273 if (hfdcan->State == HAL_FDCAN_STATE_RESET)
274 {
275 /* Allocate lock resource and initialize it */
276 hfdcan->Lock = HAL_UNLOCKED;
277
278 /* Init the low level hardware: CLOCK, NVIC */
279 HAL_FDCAN_MspInit(hfdcan);
280 }
281
282 /* Exit from Sleep mode */
283 CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CSR);
284
285 /* Get tick */
286 tickstart = HAL_GetTick();
287
288 /* Check Sleep mode acknowledge */
289 while ((hfdcan->Instance->CCCR & FDCAN_CCCR_CSA) == FDCAN_CCCR_CSA)
290 {
291 if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE)
292 {
293 /* Update error code */
294 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
295
296 /* Change FDCAN state */
297 hfdcan->State = HAL_FDCAN_STATE_ERROR;
298
299 return HAL_ERROR;
300 }
301 }
302
303 /* Request initialisation */
304 SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT);
305
306 /* Get tick */
307 tickstart = HAL_GetTick();
308
309 /* Wait until the INIT bit into CCCR register is set */
310 while ((hfdcan->Instance->CCCR & FDCAN_CCCR_INIT) == 0U)
311 {
312 /* Check for the Timeout */
313 if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE)
314 {
315 /* Update error code */
316 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
317
318 /* Change FDCAN state */
319 hfdcan->State = HAL_FDCAN_STATE_ERROR;
320
321 return HAL_ERROR;
322 }
323 }
324
325 /* Enable configuration change */
326 SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CCE);
327
328 /* Set the no automatic retransmission */
329 if (hfdcan->Init.AutoRetransmission == ENABLE)
330 {
331 CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_DAR);
332 }
333 else
334 {
335 SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_DAR);
336 }
337
338 /* Set the transmit pause feature */
339 if (hfdcan->Init.TransmitPause == ENABLE)
340 {
341 SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_TXP);
342 }
343 else
344 {
345 CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_TXP);
346 }
347
348 /* Set the Protocol Exception Handling */
349 if (hfdcan->Init.ProtocolException == ENABLE)
350 {
351 CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_PXHD);
352 }
353 else
354 {
355 SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_PXHD);
356 }
357
358 /* Set FDCAN Frame Format */
359 MODIFY_REG(hfdcan->Instance->CCCR, FDCAN_FRAME_FD_BRS, hfdcan->Init.FrameFormat);
360
361 /* Reset FDCAN Operation Mode */
362 CLEAR_BIT(hfdcan->Instance->CCCR, (FDCAN_CCCR_TEST | FDCAN_CCCR_MON | FDCAN_CCCR_ASM));
363 CLEAR_BIT(hfdcan->Instance->TEST, FDCAN_TEST_LBCK);
364
365 /* Set FDCAN Operating Mode:
366 | Normal | Restricted | Bus | Internal | External
367 | | Operation | Monitoring | LoopBack | LoopBack
368 CCCR.TEST | 0 | 0 | 0 | 1 | 1
369 CCCR.MON | 0 | 0 | 1 | 1 | 0
370 TEST.LBCK | 0 | 0 | 0 | 1 | 1
371 CCCR.ASM | 0 | 1 | 0 | 0 | 0
372 */
373 if (hfdcan->Init.Mode == FDCAN_MODE_RESTRICTED_OPERATION)
374 {
375 /* Enable Restricted Operation mode */
376 SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_ASM);
377 }
378 else if (hfdcan->Init.Mode != FDCAN_MODE_NORMAL)
379 {
380 if (hfdcan->Init.Mode != FDCAN_MODE_BUS_MONITORING)
381 {
382 /* Enable write access to TEST register */
383 SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_TEST);
384
385 /* Enable LoopBack mode */
386 SET_BIT(hfdcan->Instance->TEST, FDCAN_TEST_LBCK);
387
388 if (hfdcan->Init.Mode == FDCAN_MODE_INTERNAL_LOOPBACK)
389 {
390 SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_MON);
391 }
392 }
393 else
394 {
395 /* Enable bus monitoring mode */
396 SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_MON);
397 }
398 }
399 else
400 {
401 /* Nothing to do: normal mode */
402 }
403
404 /* Set the nominal bit timing register */
405 hfdcan->Instance->NBTP = ((((uint32_t)hfdcan->Init.NominalSyncJumpWidth - 1U) << FDCAN_NBTP_NSJW_Pos) | \
406 (((uint32_t)hfdcan->Init.NominalTimeSeg1 - 1U) << FDCAN_NBTP_NTSEG1_Pos) | \
407 (((uint32_t)hfdcan->Init.NominalTimeSeg2 - 1U) << FDCAN_NBTP_NTSEG2_Pos) | \
408 (((uint32_t)hfdcan->Init.NominalPrescaler - 1U) << FDCAN_NBTP_NBRP_Pos));
409
410 /* If FD operation with BRS is selected, set the data bit timing register */
411 if (hfdcan->Init.FrameFormat == FDCAN_FRAME_FD_BRS)
412 {
413 hfdcan->Instance->DBTP = ((((uint32_t)hfdcan->Init.DataSyncJumpWidth - 1U) << FDCAN_DBTP_DSJW_Pos) | \
414 (((uint32_t)hfdcan->Init.DataTimeSeg1 - 1U) << FDCAN_DBTP_DTSEG1_Pos) | \
415 (((uint32_t)hfdcan->Init.DataTimeSeg2 - 1U) << FDCAN_DBTP_DTSEG2_Pos) | \
416 (((uint32_t)hfdcan->Init.DataPrescaler - 1U) << FDCAN_DBTP_DBRP_Pos));
417 }
418
419 if (hfdcan->Init.TxFifoQueueElmtsNbr > 0U)
420 {
421 /* Select between Tx FIFO and Tx Queue operation modes */
422 SET_BIT(hfdcan->Instance->TXBC, hfdcan->Init.TxFifoQueueMode);
423 }
424
425 /* Configure Tx element size */
426 if ((hfdcan->Init.TxBuffersNbr + hfdcan->Init.TxFifoQueueElmtsNbr) > 0U)
427 {
428 MODIFY_REG(hfdcan->Instance->TXESC, FDCAN_TXESC_TBDS, CvtEltSize[hfdcan->Init.TxElmtSize]);
429 }
430
431 /* Configure Rx FIFO 0 element size */
432 if (hfdcan->Init.RxFifo0ElmtsNbr > 0U)
433 {
434 MODIFY_REG(hfdcan->Instance->RXESC, FDCAN_RXESC_F0DS, (CvtEltSize[hfdcan->Init.RxFifo0ElmtSize] << FDCAN_RXESC_F0DS_Pos));
435 }
436
437 /* Configure Rx FIFO 1 element size */
438 if (hfdcan->Init.RxFifo1ElmtsNbr > 0U)
439 {
440 MODIFY_REG(hfdcan->Instance->RXESC, FDCAN_RXESC_F1DS, (CvtEltSize[hfdcan->Init.RxFifo1ElmtSize] << FDCAN_RXESC_F1DS_Pos));
441 }
442
443 /* Configure Rx buffer element size */
444 if (hfdcan->Init.RxBuffersNbr > 0U)
445 {
446 MODIFY_REG(hfdcan->Instance->RXESC, FDCAN_RXESC_RBDS, (CvtEltSize[hfdcan->Init.RxBufferSize] << FDCAN_RXESC_RBDS_Pos));
447 }
448
449 /* By default operation mode is set to Event-driven communication.
450 If Time-triggered communication is needed, user should call the
451 HAL_FDCAN_TT_ConfigOperation function just after the HAL_FDCAN_Init */
452 if (hfdcan->Instance == FDCAN1)
453 {
454 CLEAR_BIT(hfdcan->ttcan->TTOCF, FDCAN_TTOCF_OM);
455 }
456
457 /* Initialize the Latest Tx FIFO/Queue request buffer index */
458 hfdcan->LatestTxFifoQRequest = 0U;
459
460 /* Initialize the error code */
461 hfdcan->ErrorCode = HAL_FDCAN_ERROR_NONE;
462
463 /* Initialize the FDCAN state */
464 hfdcan->State = HAL_FDCAN_STATE_READY;
465
466 /* Calculate each RAM block address */
467 status = FDCAN_CalcultateRamBlockAddresses(hfdcan);
468
469 /* Return function status */
470 return status;
471 }
472
473 /**
474 * @brief Deinitializes the FDCAN peripheral registers to their default reset values.
475 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
476 * the configuration information for the specified FDCAN.
477 * @retval HAL status
478 */
HAL_FDCAN_DeInit(FDCAN_HandleTypeDef * hfdcan)479 HAL_StatusTypeDef HAL_FDCAN_DeInit(FDCAN_HandleTypeDef *hfdcan)
480 {
481 /* Check FDCAN handle */
482 if (hfdcan == NULL)
483 {
484 return HAL_ERROR;
485 }
486
487 /* Check function parameters */
488 assert_param(IS_FDCAN_ALL_INSTANCE(hfdcan->Instance));
489
490 /* Stop the FDCAN module: return value is voluntary ignored */
491 (void)HAL_FDCAN_Stop(hfdcan);
492
493 /* Disable Interrupt lines */
494 CLEAR_BIT(hfdcan->Instance->ILE, (FDCAN_INTERRUPT_LINE0 | FDCAN_INTERRUPT_LINE1));
495
496 /* DeInit the low level hardware: CLOCK, NVIC */
497 HAL_FDCAN_MspDeInit(hfdcan);
498
499 /* Reset the FDCAN ErrorCode */
500 hfdcan->ErrorCode = HAL_FDCAN_ERROR_NONE;
501
502 /* Change FDCAN state */
503 hfdcan->State = HAL_FDCAN_STATE_RESET;
504
505 /* Return function status */
506 return HAL_OK;
507 }
508
509 /**
510 * @brief Initializes the FDCAN MSP.
511 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
512 * the configuration information for the specified FDCAN.
513 * @retval None
514 */
HAL_FDCAN_MspInit(FDCAN_HandleTypeDef * hfdcan)515 __weak void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef *hfdcan)
516 {
517 /* Prevent unused argument(s) compilation warning */
518 UNUSED(hfdcan);
519 /* NOTE : This function Should not be modified, when the callback is needed,
520 the HAL_FDCAN_MspInit could be implemented in the user file
521 */
522 }
523
524 /**
525 * @brief DeInitializes the FDCAN MSP.
526 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
527 * the configuration information for the specified FDCAN.
528 * @retval None
529 */
HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef * hfdcan)530 __weak void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef *hfdcan)
531 {
532 /* Prevent unused argument(s) compilation warning */
533 UNUSED(hfdcan);
534 /* NOTE : This function Should not be modified, when the callback is needed,
535 the HAL_FDCAN_MspDeInit could be implemented in the user file
536 */
537 }
538
539 /**
540 * @brief Enter FDCAN peripheral in sleep mode.
541 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
542 * the configuration information for the specified FDCAN.
543 * @retval HAL status
544 */
HAL_FDCAN_EnterPowerDownMode(FDCAN_HandleTypeDef * hfdcan)545 HAL_StatusTypeDef HAL_FDCAN_EnterPowerDownMode(FDCAN_HandleTypeDef *hfdcan)
546 {
547 uint32_t tickstart;
548
549 /* Request clock stop */
550 SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CSR);
551
552 /* Get tick */
553 tickstart = HAL_GetTick();
554
555 /* Wait until FDCAN is ready for power down */
556 while ((hfdcan->Instance->CCCR & FDCAN_CCCR_CSA) == 0U)
557 {
558 if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE)
559 {
560 /* Update error code */
561 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
562
563 /* Change FDCAN state */
564 hfdcan->State = HAL_FDCAN_STATE_ERROR;
565
566 return HAL_ERROR;
567 }
568 }
569
570 /* Return function status */
571 return HAL_OK;
572 }
573
574 /**
575 * @brief Exit power down mode.
576 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
577 * the configuration information for the specified FDCAN.
578 * @retval HAL status
579 */
HAL_FDCAN_ExitPowerDownMode(FDCAN_HandleTypeDef * hfdcan)580 HAL_StatusTypeDef HAL_FDCAN_ExitPowerDownMode(FDCAN_HandleTypeDef *hfdcan)
581 {
582 uint32_t tickstart;
583
584 /* Reset clock stop request */
585 CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CSR);
586
587 /* Get tick */
588 tickstart = HAL_GetTick();
589
590 /* Wait until FDCAN exits sleep mode */
591 while ((hfdcan->Instance->CCCR & FDCAN_CCCR_CSA) == FDCAN_CCCR_CSA)
592 {
593 if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE)
594 {
595 /* Update error code */
596 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
597
598 /* Change FDCAN state */
599 hfdcan->State = HAL_FDCAN_STATE_ERROR;
600
601 return HAL_ERROR;
602 }
603 }
604
605 /* Enter normal operation */
606 CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT);
607
608 /* Return function status */
609 return HAL_OK;
610 }
611
612
613 /**
614 * @}
615 */
616
617 /** @defgroup FDCAN_Exported_Functions_Group2 Configuration functions
618 * @brief FDCAN Configuration functions.
619 *
620 @verbatim
621 ==============================================================================
622 ##### Configuration functions #####
623 ==============================================================================
624 [..] This section provides functions allowing to:
625 (+) HAL_FDCAN_ConfigClockCalibration : Configure the FDCAN clock calibration unit
626 (+) HAL_FDCAN_GetClockCalibrationState : Get the clock calibration state
627 (+) HAL_FDCAN_ResetClockCalibrationState : Reset the clock calibration state
628 (+) HAL_FDCAN_GetClockCalibrationCounter : Get the clock calibration counters values
629 (+) HAL_FDCAN_ConfigFilter : Configure the FDCAN reception filters
630 (+) HAL_FDCAN_ConfigGlobalFilter : Configure the FDCAN global filter
631 (+) HAL_FDCAN_ConfigExtendedIdMask : Configure the extended ID mask
632 (+) HAL_FDCAN_ConfigRxFifoOverwrite : Configure the Rx FIFO operation mode
633 (+) HAL_FDCAN_ConfigFifoWatermark : Configure the FIFO watermark
634 (+) HAL_FDCAN_ConfigRamWatchdog : Configure the RAM watchdog
635 (+) HAL_FDCAN_ConfigTimestampCounter : Configure the timestamp counter
636 (+) HAL_FDCAN_EnableTimestampCounter : Enable the timestamp counter
637 (+) HAL_FDCAN_DisableTimestampCounter : Disable the timestamp counter
638 (+) HAL_FDCAN_GetTimestampCounter : Get the timestamp counter value
639 (+) HAL_FDCAN_ResetTimestampCounter : Reset the timestamp counter to zero
640 (+) HAL_FDCAN_ConfigTimeoutCounter : Configure the timeout counter
641 (+) HAL_FDCAN_EnableTimeoutCounter : Enable the timeout counter
642 (+) HAL_FDCAN_DisableTimeoutCounter : Disable the timeout counter
643 (+) HAL_FDCAN_GetTimeoutCounter : Get the timeout counter value
644 (+) HAL_FDCAN_ResetTimeoutCounter : Reset the timeout counter to its start value
645 (+) HAL_FDCAN_ConfigTxDelayCompensation : Configure the transmitter delay compensation
646 (+) HAL_FDCAN_EnableTxDelayCompensation : Enable the transmitter delay compensation
647 (+) HAL_FDCAN_DisableTxDelayCompensation : Disable the transmitter delay compensation
648 (+) HAL_FDCAN_EnableISOMode : Enable ISO 11898-1 protocol mode
649 (+) HAL_FDCAN_DisableISOMode : Disable ISO 11898-1 protocol mode
650 (+) HAL_FDCAN_EnableEdgeFiltering : Enable edge filtering during bus integration
651 (+) HAL_FDCAN_DisableEdgeFiltering : Disable edge filtering during bus integration
652
653 @endverbatim
654 * @{
655 */
656
657 /**
658 * @brief Configure the FDCAN clock calibration unit according to the specified
659 * parameters in the FDCAN_ClkCalUnitTypeDef structure.
660 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
661 * the configuration information for the specified FDCAN.
662 * @param sCcuConfig pointer to an FDCAN_ClkCalUnitTypeDef structure that
663 * contains the clock calibration information
664 * @retval HAL status
665 */
HAL_FDCAN_ConfigClockCalibration(FDCAN_HandleTypeDef * hfdcan,FDCAN_ClkCalUnitTypeDef * sCcuConfig)666 HAL_StatusTypeDef HAL_FDCAN_ConfigClockCalibration(FDCAN_HandleTypeDef *hfdcan, FDCAN_ClkCalUnitTypeDef *sCcuConfig)
667 {
668 /* Check function parameters */
669 assert_param(IS_FDCAN_CLOCK_CALIBRATION(sCcuConfig->ClockCalibration));
670 if (sCcuConfig->ClockCalibration == FDCAN_CLOCK_CALIBRATION_DISABLE)
671 {
672 assert_param(IS_FDCAN_CKDIV(sCcuConfig->ClockDivider));
673 }
674 else
675 {
676 assert_param(IS_FDCAN_MAX_VALUE(sCcuConfig->MinOscClkPeriods, 0xFFU));
677 assert_param(IS_FDCAN_CALIBRATION_FIELD_LENGTH(sCcuConfig->CalFieldLength));
678 assert_param(IS_FDCAN_MIN_VALUE(sCcuConfig->TimeQuantaPerBitTime, 4U));
679 assert_param(IS_FDCAN_MAX_VALUE(sCcuConfig->TimeQuantaPerBitTime, 0x25U));
680 assert_param(IS_FDCAN_MAX_VALUE(sCcuConfig->WatchdogStartValue, 0xFFFFU));
681 }
682
683 /* FDCAN1 should be initialized in order to use clock calibration */
684 if (hfdcan->Instance != FDCAN1)
685 {
686 /* Update error code */
687 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
688
689 return HAL_ERROR;
690 }
691
692 if (hfdcan->State == HAL_FDCAN_STATE_READY)
693 {
694 if (sCcuConfig->ClockCalibration == FDCAN_CLOCK_CALIBRATION_DISABLE)
695 {
696 /* Bypass clock calibration */
697 SET_BIT(FDCAN_CCU->CCFG, FDCANCCU_CCFG_BCC);
698
699 /* Configure clock divider */
700 MODIFY_REG(FDCAN_CCU->CCFG, FDCANCCU_CCFG_CDIV, sCcuConfig->ClockDivider);
701 }
702 else /* sCcuConfig->ClockCalibration == ENABLE */
703 {
704 /* Clock calibration unit generates time quanta clock */
705 CLEAR_BIT(FDCAN_CCU->CCFG, FDCANCCU_CCFG_BCC);
706
707 /* Configure clock calibration unit */
708 MODIFY_REG(FDCAN_CCU->CCFG,
709 (FDCANCCU_CCFG_TQBT | FDCANCCU_CCFG_CFL | FDCANCCU_CCFG_OCPM),
710 ((sCcuConfig->TimeQuantaPerBitTime << FDCANCCU_CCFG_TQBT_Pos) | sCcuConfig->CalFieldLength | (sCcuConfig->MinOscClkPeriods << FDCANCCU_CCFG_OCPM_Pos)));
711
712 /* Configure the start value of the calibration watchdog counter */
713 MODIFY_REG(FDCAN_CCU->CWD, FDCANCCU_CWD_WDC, sCcuConfig->WatchdogStartValue);
714 }
715
716 /* Return function status */
717 return HAL_OK;
718 }
719 else
720 {
721 /* Update error code */
722 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
723
724 return HAL_ERROR;
725 }
726 }
727
728 /**
729 * @brief Get the clock calibration state.
730 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
731 * the configuration information for the specified FDCAN.
732 * @retval State clock calibration state (can be a value of @arg FDCAN_calibration_state)
733 */
HAL_FDCAN_GetClockCalibrationState(FDCAN_HandleTypeDef * hfdcan)734 uint32_t HAL_FDCAN_GetClockCalibrationState(FDCAN_HandleTypeDef *hfdcan)
735 {
736 /* Prevent unused argument(s) compilation warning */
737 UNUSED(hfdcan);
738
739 return (FDCAN_CCU->CSTAT & FDCANCCU_CSTAT_CALS);
740 }
741
742 /**
743 * @brief Reset the clock calibration state.
744 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
745 * the configuration information for the specified FDCAN.
746 * @retval HAL status
747 */
HAL_FDCAN_ResetClockCalibrationState(FDCAN_HandleTypeDef * hfdcan)748 HAL_StatusTypeDef HAL_FDCAN_ResetClockCalibrationState(FDCAN_HandleTypeDef *hfdcan)
749 {
750 /* FDCAN1 should be initialized in order to use clock calibration */
751 if (hfdcan->Instance != FDCAN1)
752 {
753 /* Update error code */
754 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
755
756 return HAL_ERROR;
757 }
758
759 if (hfdcan->State == HAL_FDCAN_STATE_READY)
760 {
761 /* Calibration software reset */
762 SET_BIT(FDCAN_CCU->CCFG, FDCANCCU_CCFG_SWR);
763
764 /* Return function status */
765 return HAL_OK;
766 }
767 else
768 {
769 /* Update error code */
770 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
771
772 return HAL_ERROR;
773 }
774 }
775
776 /**
777 * @brief Get the clock calibration counter value.
778 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
779 * the configuration information for the specified FDCAN.
780 * @param Counter clock calibration counter.
781 * This parameter can be a value of @arg FDCAN_calibration_counter.
782 * @retval Value clock calibration counter value
783 */
HAL_FDCAN_GetClockCalibrationCounter(FDCAN_HandleTypeDef * hfdcan,uint32_t Counter)784 uint32_t HAL_FDCAN_GetClockCalibrationCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t Counter)
785 {
786 /* Prevent unused argument(s) compilation warning */
787 UNUSED(hfdcan);
788
789 /* Check function parameters */
790 assert_param(IS_FDCAN_CALIBRATION_COUNTER(Counter));
791
792 if (Counter == FDCAN_CALIB_TIME_QUANTA_COUNTER)
793 {
794 return ((FDCAN_CCU->CSTAT & FDCANCCU_CSTAT_TQC) >> FDCANCCU_CSTAT_TQC_Pos);
795 }
796 else if (Counter == FDCAN_CALIB_CLOCK_PERIOD_COUNTER)
797 {
798 return (FDCAN_CCU->CSTAT & FDCANCCU_CSTAT_OCPC);
799 }
800 else /* Counter == FDCAN_CALIB_WATCHDOG_COUNTER */
801 {
802 return ((FDCAN_CCU->CWD & FDCANCCU_CWD_WDV) >> FDCANCCU_CWD_WDV_Pos);
803 }
804 }
805
806 /**
807 * @brief Configure the FDCAN reception filter according to the specified
808 * parameters in the FDCAN_FilterTypeDef structure.
809 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
810 * the configuration information for the specified FDCAN.
811 * @param sFilterConfig pointer to an FDCAN_FilterTypeDef structure that
812 * contains the filter configuration information
813 * @retval HAL status
814 */
HAL_FDCAN_ConfigFilter(FDCAN_HandleTypeDef * hfdcan,FDCAN_FilterTypeDef * sFilterConfig)815 HAL_StatusTypeDef HAL_FDCAN_ConfigFilter(FDCAN_HandleTypeDef *hfdcan, FDCAN_FilterTypeDef *sFilterConfig)
816 {
817 uint32_t FilterElementW1;
818 uint32_t FilterElementW2;
819 uint32_t *FilterAddress;
820 HAL_FDCAN_StateTypeDef state = hfdcan->State;
821
822 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
823 {
824 /* Check function parameters */
825 assert_param(IS_FDCAN_ID_TYPE(sFilterConfig->IdType));
826 assert_param(IS_FDCAN_FILTER_CFG(sFilterConfig->FilterConfig));
827 if (sFilterConfig->FilterConfig == FDCAN_FILTER_TO_RXBUFFER)
828 {
829 assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->RxBufferIndex, 63U));
830 assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->IsCalibrationMsg, 1U));
831 }
832
833 if (sFilterConfig->IdType == FDCAN_STANDARD_ID)
834 {
835 /* Check function parameters */
836 assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterIndex, (hfdcan->Init.StdFiltersNbr - 1U)));
837 assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterID1, 0x7FFU));
838 if (sFilterConfig->FilterConfig != FDCAN_FILTER_TO_RXBUFFER)
839 {
840 assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterID2, 0x7FFU));
841 assert_param(IS_FDCAN_STD_FILTER_TYPE(sFilterConfig->FilterType));
842 }
843
844 /* Build filter element */
845 if (sFilterConfig->FilterConfig == FDCAN_FILTER_TO_RXBUFFER)
846 {
847 FilterElementW1 = ((FDCAN_FILTER_TO_RXBUFFER << 27U) |
848 (sFilterConfig->FilterID1 << 16U) |
849 (sFilterConfig->IsCalibrationMsg << 8U) |
850 sFilterConfig->RxBufferIndex);
851 }
852 else
853 {
854 FilterElementW1 = ((sFilterConfig->FilterType << 30U) |
855 (sFilterConfig->FilterConfig << 27U) |
856 (sFilterConfig->FilterID1 << 16U) |
857 sFilterConfig->FilterID2);
858 }
859
860 /* Calculate filter address */
861 FilterAddress = (uint32_t *)(hfdcan->msgRam.StandardFilterSA + (sFilterConfig->FilterIndex * 4U));
862
863 /* Write filter element to the message RAM */
864 *FilterAddress = FilterElementW1;
865 }
866 else /* sFilterConfig->IdType == FDCAN_EXTENDED_ID */
867 {
868 /* Check function parameters */
869 assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterIndex, (hfdcan->Init.ExtFiltersNbr - 1U)));
870 assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterID1, 0x1FFFFFFFU));
871 if (sFilterConfig->FilterConfig != FDCAN_FILTER_TO_RXBUFFER)
872 {
873 assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterID2, 0x1FFFFFFFU));
874 assert_param(IS_FDCAN_EXT_FILTER_TYPE(sFilterConfig->FilterType));
875 }
876
877 /* Build first word of filter element */
878 FilterElementW1 = ((sFilterConfig->FilterConfig << 29U) | sFilterConfig->FilterID1);
879
880 /* Build second word of filter element */
881 if (sFilterConfig->FilterConfig == FDCAN_FILTER_TO_RXBUFFER)
882 {
883 FilterElementW2 = sFilterConfig->RxBufferIndex;
884 }
885 else
886 {
887 FilterElementW2 = ((sFilterConfig->FilterType << 30U) | sFilterConfig->FilterID2);
888 }
889
890 /* Calculate filter address */
891 FilterAddress = (uint32_t *)(hfdcan->msgRam.ExtendedFilterSA + (sFilterConfig->FilterIndex * 4U * 2U));
892
893 /* Write filter element to the message RAM */
894 *FilterAddress = FilterElementW1;
895 FilterAddress++;
896 *FilterAddress = FilterElementW2;
897 }
898
899 /* Return function status */
900 return HAL_OK;
901 }
902 else
903 {
904 /* Update error code */
905 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
906
907 return HAL_ERROR;
908 }
909 }
910
911 /**
912 * @brief Configure the FDCAN global filter.
913 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
914 * the configuration information for the specified FDCAN.
915 * @param NonMatchingStd Defines how received messages with 11-bit IDs that
916 * do not match any element of the filter list are treated.
917 * This parameter can be a value of @arg FDCAN_Non_Matching_Frames.
918 * @param NonMatchingExt Defines how received messages with 29-bit IDs that
919 * do not match any element of the filter list are treated.
920 * This parameter can be a value of @arg FDCAN_Non_Matching_Frames.
921 * @param RejectRemoteStd Filter or reject all the remote 11-bit IDs frames.
922 * This parameter can be a value of @arg FDCAN_Reject_Remote_Frames.
923 * @param RejectRemoteExt Filter or reject all the remote 29-bit IDs frames.
924 * This parameter can be a value of @arg FDCAN_Reject_Remote_Frames.
925 * @retval HAL status
926 */
HAL_FDCAN_ConfigGlobalFilter(FDCAN_HandleTypeDef * hfdcan,uint32_t NonMatchingStd,uint32_t NonMatchingExt,uint32_t RejectRemoteStd,uint32_t RejectRemoteExt)927 HAL_StatusTypeDef HAL_FDCAN_ConfigGlobalFilter(FDCAN_HandleTypeDef *hfdcan,
928 uint32_t NonMatchingStd,
929 uint32_t NonMatchingExt,
930 uint32_t RejectRemoteStd,
931 uint32_t RejectRemoteExt)
932 {
933 /* Check function parameters */
934 assert_param(IS_FDCAN_NON_MATCHING(NonMatchingStd));
935 assert_param(IS_FDCAN_NON_MATCHING(NonMatchingExt));
936 assert_param(IS_FDCAN_REJECT_REMOTE(RejectRemoteStd));
937 assert_param(IS_FDCAN_REJECT_REMOTE(RejectRemoteExt));
938
939 if (hfdcan->State == HAL_FDCAN_STATE_READY)
940 {
941 /* Configure global filter */
942 hfdcan->Instance->GFC = ((NonMatchingStd << FDCAN_GFC_ANFS_Pos) |
943 (NonMatchingExt << FDCAN_GFC_ANFE_Pos) |
944 (RejectRemoteStd << FDCAN_GFC_RRFS_Pos) |
945 (RejectRemoteExt << FDCAN_GFC_RRFE_Pos));
946
947 /* Return function status */
948 return HAL_OK;
949 }
950 else
951 {
952 /* Update error code */
953 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
954
955 return HAL_ERROR;
956 }
957 }
958
959 /**
960 * @brief Configure the extended ID mask.
961 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
962 * the configuration information for the specified FDCAN.
963 * @param Mask Extended ID Mask.
964 * This parameter must be a number between 0 and 0x1FFFFFFF
965 * @retval HAL status
966 */
HAL_FDCAN_ConfigExtendedIdMask(FDCAN_HandleTypeDef * hfdcan,uint32_t Mask)967 HAL_StatusTypeDef HAL_FDCAN_ConfigExtendedIdMask(FDCAN_HandleTypeDef *hfdcan, uint32_t Mask)
968 {
969 /* Check function parameters */
970 assert_param(IS_FDCAN_MAX_VALUE(Mask, 0x1FFFFFFFU));
971
972 if (hfdcan->State == HAL_FDCAN_STATE_READY)
973 {
974 /* Configure the extended ID mask */
975 hfdcan->Instance->XIDAM = Mask;
976
977 /* Return function status */
978 return HAL_OK;
979 }
980 else
981 {
982 /* Update error code */
983 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
984
985 return HAL_ERROR;
986 }
987 }
988
989 /**
990 * @brief Configure the Rx FIFO operation mode.
991 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
992 * the configuration information for the specified FDCAN.
993 * @param RxFifo Rx FIFO.
994 * This parameter can be one of the following values:
995 * @arg FDCAN_RX_FIFO0: Rx FIFO 0
996 * @arg FDCAN_RX_FIFO1: Rx FIFO 1
997 * @param OperationMode operation mode.
998 * This parameter can be a value of @arg FDCAN_Rx_FIFO_operation_mode.
999 * @retval HAL status
1000 */
HAL_FDCAN_ConfigRxFifoOverwrite(FDCAN_HandleTypeDef * hfdcan,uint32_t RxFifo,uint32_t OperationMode)1001 HAL_StatusTypeDef HAL_FDCAN_ConfigRxFifoOverwrite(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo, uint32_t OperationMode)
1002 {
1003 /* Check function parameters */
1004 assert_param(IS_FDCAN_RX_FIFO(RxFifo));
1005 assert_param(IS_FDCAN_RX_FIFO_MODE(OperationMode));
1006
1007 if (hfdcan->State == HAL_FDCAN_STATE_READY)
1008 {
1009 if (RxFifo == FDCAN_RX_FIFO0)
1010 {
1011 /* Select FIFO 0 Operation Mode */
1012 MODIFY_REG(hfdcan->Instance->RXF0C, FDCAN_RXF0C_F0OM, OperationMode);
1013 }
1014 else /* RxFifo == FDCAN_RX_FIFO1 */
1015 {
1016 /* Select FIFO 1 Operation Mode */
1017 MODIFY_REG(hfdcan->Instance->RXF1C, FDCAN_RXF1C_F1OM, OperationMode);
1018 }
1019
1020 /* Return function status */
1021 return HAL_OK;
1022 }
1023 else
1024 {
1025 /* Update error code */
1026 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1027
1028 return HAL_ERROR;
1029 }
1030 }
1031
1032 /**
1033 * @brief Configure the FIFO watermark.
1034 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1035 * the configuration information for the specified FDCAN.
1036 * @param FIFO select the FIFO to be configured.
1037 * This parameter can be a value of @arg FDCAN_FIFO_watermark.
1038 * @param Watermark level for FIFO watermark interrupt.
1039 * This parameter must be a number between:
1040 * - 0 and 32, if FIFO is FDCAN_CFG_TX_EVENT_FIFO
1041 * - 0 and 64, if FIFO is FDCAN_CFG_RX_FIFO0 or FDCAN_CFG_RX_FIFO1
1042 * @retval HAL status
1043 */
HAL_FDCAN_ConfigFifoWatermark(FDCAN_HandleTypeDef * hfdcan,uint32_t FIFO,uint32_t Watermark)1044 HAL_StatusTypeDef HAL_FDCAN_ConfigFifoWatermark(FDCAN_HandleTypeDef *hfdcan, uint32_t FIFO, uint32_t Watermark)
1045 {
1046 /* Check function parameters */
1047 assert_param(IS_FDCAN_FIFO_WATERMARK(FIFO));
1048 if (FIFO == FDCAN_CFG_TX_EVENT_FIFO)
1049 {
1050 assert_param(IS_FDCAN_MAX_VALUE(Watermark, 32U));
1051 }
1052 else /* (FIFO == FDCAN_CFG_RX_FIFO0) || (FIFO == FDCAN_CFG_RX_FIFO1) */
1053 {
1054 assert_param(IS_FDCAN_MAX_VALUE(Watermark, 64U));
1055 }
1056
1057 if (hfdcan->State == HAL_FDCAN_STATE_READY)
1058 {
1059 /* Set the level for FIFO watermark interrupt */
1060 if (FIFO == FDCAN_CFG_TX_EVENT_FIFO)
1061 {
1062 MODIFY_REG(hfdcan->Instance->TXEFC, FDCAN_TXEFC_EFWM, (Watermark << FDCAN_TXEFC_EFWM_Pos));
1063 }
1064 else if (FIFO == FDCAN_CFG_RX_FIFO0)
1065 {
1066 MODIFY_REG(hfdcan->Instance->RXF0C, FDCAN_RXF0C_F0WM, (Watermark << FDCAN_RXF0C_F0WM_Pos));
1067 }
1068 else /* FIFO == FDCAN_CFG_RX_FIFO1 */
1069 {
1070 MODIFY_REG(hfdcan->Instance->RXF1C, FDCAN_RXF1C_F1WM, (Watermark << FDCAN_RXF1C_F1WM_Pos));
1071 }
1072
1073 /* Return function status */
1074 return HAL_OK;
1075 }
1076 else
1077 {
1078 /* Update error code */
1079 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1080
1081 return HAL_ERROR;
1082 }
1083 }
1084
1085 /**
1086 * @brief Configure the RAM watchdog.
1087 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1088 * the configuration information for the specified FDCAN.
1089 * @param CounterStartValue Start value of the Message RAM Watchdog Counter,
1090 * This parameter must be a number between 0x00 and 0xFF,
1091 * with the reset value of 0x00 the counter is disabled.
1092 * @retval HAL status
1093 */
HAL_FDCAN_ConfigRamWatchdog(FDCAN_HandleTypeDef * hfdcan,uint32_t CounterStartValue)1094 HAL_StatusTypeDef HAL_FDCAN_ConfigRamWatchdog(FDCAN_HandleTypeDef *hfdcan, uint32_t CounterStartValue)
1095 {
1096 /* Check function parameters */
1097 assert_param(IS_FDCAN_MAX_VALUE(CounterStartValue, 0xFFU));
1098
1099 if (hfdcan->State == HAL_FDCAN_STATE_READY)
1100 {
1101 /* Configure the RAM watchdog counter start value */
1102 MODIFY_REG(hfdcan->Instance->RWD, FDCAN_RWD_WDC, CounterStartValue);
1103
1104 /* Return function status */
1105 return HAL_OK;
1106 }
1107 else
1108 {
1109 /* Update error code */
1110 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1111
1112 return HAL_ERROR;
1113 }
1114 }
1115
1116 /**
1117 * @brief Configure the timestamp counter.
1118 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1119 * the configuration information for the specified FDCAN.
1120 * @param TimestampPrescaler Timestamp Counter Prescaler.
1121 * This parameter can be a value of @arg FDCAN_Timestamp_Prescaler.
1122 * @retval HAL status
1123 */
HAL_FDCAN_ConfigTimestampCounter(FDCAN_HandleTypeDef * hfdcan,uint32_t TimestampPrescaler)1124 HAL_StatusTypeDef HAL_FDCAN_ConfigTimestampCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t TimestampPrescaler)
1125 {
1126 /* Check function parameters */
1127 assert_param(IS_FDCAN_TIMESTAMP_PRESCALER(TimestampPrescaler));
1128
1129 if (hfdcan->State == HAL_FDCAN_STATE_READY)
1130 {
1131 /* Configure prescaler */
1132 MODIFY_REG(hfdcan->Instance->TSCC, FDCAN_TSCC_TCP, TimestampPrescaler);
1133
1134 /* Return function status */
1135 return HAL_OK;
1136 }
1137 else
1138 {
1139 /* Update error code */
1140 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1141
1142 return HAL_ERROR;
1143 }
1144 }
1145
1146 /**
1147 * @brief Enable the timestamp counter.
1148 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1149 * the configuration information for the specified FDCAN.
1150 * @param TimestampOperation Timestamp counter operation.
1151 * This parameter can be a value of @arg FDCAN_Timestamp.
1152 * @retval HAL status
1153 */
HAL_FDCAN_EnableTimestampCounter(FDCAN_HandleTypeDef * hfdcan,uint32_t TimestampOperation)1154 HAL_StatusTypeDef HAL_FDCAN_EnableTimestampCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t TimestampOperation)
1155 {
1156 /* Check function parameters */
1157 assert_param(IS_FDCAN_TIMESTAMP(TimestampOperation));
1158
1159 if (hfdcan->State == HAL_FDCAN_STATE_READY)
1160 {
1161 /* Enable timestamp counter */
1162 MODIFY_REG(hfdcan->Instance->TSCC, FDCAN_TSCC_TSS, TimestampOperation);
1163
1164 /* Return function status */
1165 return HAL_OK;
1166 }
1167 else
1168 {
1169 /* Update error code */
1170 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1171
1172 return HAL_ERROR;
1173 }
1174 }
1175
1176 /**
1177 * @brief Disable the timestamp counter.
1178 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1179 * the configuration information for the specified FDCAN.
1180 * @retval HAL status
1181 */
HAL_FDCAN_DisableTimestampCounter(FDCAN_HandleTypeDef * hfdcan)1182 HAL_StatusTypeDef HAL_FDCAN_DisableTimestampCounter(FDCAN_HandleTypeDef *hfdcan)
1183 {
1184 if (hfdcan->State == HAL_FDCAN_STATE_READY)
1185 {
1186 /* Disable timestamp counter */
1187 CLEAR_BIT(hfdcan->Instance->TSCC, FDCAN_TSCC_TSS);
1188
1189 /* Return function status */
1190 return HAL_OK;
1191 }
1192 else
1193 {
1194 /* Update error code */
1195 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1196
1197 return HAL_ERROR;
1198 }
1199 }
1200
1201 /**
1202 * @brief Get the timestamp counter value.
1203 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1204 * the configuration information for the specified FDCAN.
1205 * @retval Value Timestamp counter value
1206 */
HAL_FDCAN_GetTimestampCounter(FDCAN_HandleTypeDef * hfdcan)1207 uint16_t HAL_FDCAN_GetTimestampCounter(FDCAN_HandleTypeDef *hfdcan)
1208 {
1209 return (uint16_t)(hfdcan->Instance->TSCV);
1210 }
1211
1212 /**
1213 * @brief Reset the timestamp counter to zero.
1214 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1215 * the configuration information for the specified FDCAN.
1216 * @retval HAL status
1217 */
HAL_FDCAN_ResetTimestampCounter(FDCAN_HandleTypeDef * hfdcan)1218 HAL_StatusTypeDef HAL_FDCAN_ResetTimestampCounter(FDCAN_HandleTypeDef *hfdcan)
1219 {
1220 if ((hfdcan->Instance->TSCC & FDCAN_TSCC_TSS) != FDCAN_TIMESTAMP_EXTERNAL)
1221 {
1222 /* Reset timestamp counter.
1223 Actually any write operation to TSCV clears the counter */
1224 CLEAR_REG(hfdcan->Instance->TSCV);
1225 }
1226 else
1227 {
1228 /* Update error code.
1229 Unable to reset external counter */
1230 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
1231
1232 return HAL_ERROR;
1233 }
1234
1235 /* Return function status */
1236 return HAL_OK;
1237 }
1238
1239 /**
1240 * @brief Configure the timeout counter.
1241 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1242 * the configuration information for the specified FDCAN.
1243 * @param TimeoutOperation Timeout counter operation.
1244 * This parameter can be a value of @arg FDCAN_Timeout_Operation.
1245 * @param TimeoutPeriod Start value of the timeout down-counter.
1246 * This parameter must be a number between 0x0000 and 0xFFFF
1247 * @retval HAL status
1248 */
HAL_FDCAN_ConfigTimeoutCounter(FDCAN_HandleTypeDef * hfdcan,uint32_t TimeoutOperation,uint32_t TimeoutPeriod)1249 HAL_StatusTypeDef HAL_FDCAN_ConfigTimeoutCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t TimeoutOperation, uint32_t TimeoutPeriod)
1250 {
1251 /* Check function parameters */
1252 assert_param(IS_FDCAN_TIMEOUT(TimeoutOperation));
1253 assert_param(IS_FDCAN_MAX_VALUE(TimeoutPeriod, 0xFFFFU));
1254
1255 if (hfdcan->State == HAL_FDCAN_STATE_READY)
1256 {
1257 /* Select timeout operation and configure period */
1258 MODIFY_REG(hfdcan->Instance->TOCC, (FDCAN_TOCC_TOS | FDCAN_TOCC_TOP), (TimeoutOperation | (TimeoutPeriod << FDCAN_TOCC_TOP_Pos)));
1259
1260 /* Return function status */
1261 return HAL_OK;
1262 }
1263 else
1264 {
1265 /* Update error code */
1266 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1267
1268 return HAL_ERROR;
1269 }
1270 }
1271
1272 /**
1273 * @brief Enable the timeout counter.
1274 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1275 * the configuration information for the specified FDCAN.
1276 * @retval HAL status
1277 */
HAL_FDCAN_EnableTimeoutCounter(FDCAN_HandleTypeDef * hfdcan)1278 HAL_StatusTypeDef HAL_FDCAN_EnableTimeoutCounter(FDCAN_HandleTypeDef *hfdcan)
1279 {
1280 if (hfdcan->State == HAL_FDCAN_STATE_READY)
1281 {
1282 /* Enable timeout counter */
1283 SET_BIT(hfdcan->Instance->TOCC, FDCAN_TOCC_ETOC);
1284
1285 /* Return function status */
1286 return HAL_OK;
1287 }
1288 else
1289 {
1290 /* Update error code */
1291 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1292
1293 return HAL_ERROR;
1294 }
1295 }
1296
1297 /**
1298 * @brief Disable the timeout counter.
1299 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1300 * the configuration information for the specified FDCAN.
1301 * @retval HAL status
1302 */
HAL_FDCAN_DisableTimeoutCounter(FDCAN_HandleTypeDef * hfdcan)1303 HAL_StatusTypeDef HAL_FDCAN_DisableTimeoutCounter(FDCAN_HandleTypeDef *hfdcan)
1304 {
1305 if (hfdcan->State == HAL_FDCAN_STATE_READY)
1306 {
1307 /* Disable timeout counter */
1308 CLEAR_BIT(hfdcan->Instance->TOCC, FDCAN_TOCC_ETOC);
1309
1310 /* Return function status */
1311 return HAL_OK;
1312 }
1313 else
1314 {
1315 /* Update error code */
1316 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1317
1318 return HAL_ERROR;
1319 }
1320 }
1321
1322 /**
1323 * @brief Get the timeout counter value.
1324 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1325 * the configuration information for the specified FDCAN.
1326 * @retval Value Timeout counter value
1327 */
HAL_FDCAN_GetTimeoutCounter(FDCAN_HandleTypeDef * hfdcan)1328 uint16_t HAL_FDCAN_GetTimeoutCounter(FDCAN_HandleTypeDef *hfdcan)
1329 {
1330 return (uint16_t)(hfdcan->Instance->TOCV);
1331 }
1332
1333 /**
1334 * @brief Reset the timeout counter to its start value.
1335 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1336 * the configuration information for the specified FDCAN.
1337 * @retval HAL status
1338 */
HAL_FDCAN_ResetTimeoutCounter(FDCAN_HandleTypeDef * hfdcan)1339 HAL_StatusTypeDef HAL_FDCAN_ResetTimeoutCounter(FDCAN_HandleTypeDef *hfdcan)
1340 {
1341 if ((hfdcan->Instance->TOCC & FDCAN_TOCC_TOS) == FDCAN_TIMEOUT_CONTINUOUS)
1342 {
1343 /* Reset timeout counter to start value */
1344 CLEAR_REG(hfdcan->Instance->TOCV);
1345
1346 /* Return function status */
1347 return HAL_OK;
1348 }
1349 else
1350 {
1351 /* Update error code.
1352 Unable to reset counter: controlled only by FIFO empty state */
1353 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
1354
1355 return HAL_ERROR;
1356 }
1357 }
1358
1359 /**
1360 * @brief Configure the transmitter delay compensation.
1361 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1362 * the configuration information for the specified FDCAN.
1363 * @param TdcOffset Transmitter Delay Compensation Offset.
1364 * This parameter must be a number between 0x00 and 0x7F.
1365 * @param TdcFilter Transmitter Delay Compensation Filter Window Length.
1366 * This parameter must be a number between 0x00 and 0x7F.
1367 * @retval HAL status
1368 */
HAL_FDCAN_ConfigTxDelayCompensation(FDCAN_HandleTypeDef * hfdcan,uint32_t TdcOffset,uint32_t TdcFilter)1369 HAL_StatusTypeDef HAL_FDCAN_ConfigTxDelayCompensation(FDCAN_HandleTypeDef *hfdcan, uint32_t TdcOffset, uint32_t TdcFilter)
1370 {
1371 /* Check function parameters */
1372 assert_param(IS_FDCAN_MAX_VALUE(TdcOffset, 0x7FU));
1373 assert_param(IS_FDCAN_MAX_VALUE(TdcFilter, 0x7FU));
1374
1375 if (hfdcan->State == HAL_FDCAN_STATE_READY)
1376 {
1377 /* Configure TDC offset and filter window */
1378 hfdcan->Instance->TDCR = ((TdcFilter << FDCAN_TDCR_TDCF_Pos) | (TdcOffset << FDCAN_TDCR_TDCO_Pos));
1379
1380 /* Return function status */
1381 return HAL_OK;
1382 }
1383 else
1384 {
1385 /* Update error code */
1386 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1387
1388 return HAL_ERROR;
1389 }
1390 }
1391
1392 /**
1393 * @brief Enable the transmitter delay compensation.
1394 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1395 * the configuration information for the specified FDCAN.
1396 * @retval HAL status
1397 */
HAL_FDCAN_EnableTxDelayCompensation(FDCAN_HandleTypeDef * hfdcan)1398 HAL_StatusTypeDef HAL_FDCAN_EnableTxDelayCompensation(FDCAN_HandleTypeDef *hfdcan)
1399 {
1400 if (hfdcan->State == HAL_FDCAN_STATE_READY)
1401 {
1402 /* Enable transmitter delay compensation */
1403 SET_BIT(hfdcan->Instance->DBTP, FDCAN_DBTP_TDC);
1404
1405 /* Return function status */
1406 return HAL_OK;
1407 }
1408 else
1409 {
1410 /* Update error code */
1411 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1412
1413 return HAL_ERROR;
1414 }
1415 }
1416
1417 /**
1418 * @brief Disable the transmitter delay compensation.
1419 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1420 * the configuration information for the specified FDCAN.
1421 * @retval HAL status
1422 */
HAL_FDCAN_DisableTxDelayCompensation(FDCAN_HandleTypeDef * hfdcan)1423 HAL_StatusTypeDef HAL_FDCAN_DisableTxDelayCompensation(FDCAN_HandleTypeDef *hfdcan)
1424 {
1425 if (hfdcan->State == HAL_FDCAN_STATE_READY)
1426 {
1427 /* Disable transmitter delay compensation */
1428 CLEAR_BIT(hfdcan->Instance->DBTP, FDCAN_DBTP_TDC);
1429
1430 /* Return function status */
1431 return HAL_OK;
1432 }
1433 else
1434 {
1435 /* Update error code */
1436 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1437
1438 return HAL_ERROR;
1439 }
1440 }
1441
1442 /**
1443 * @brief Enable ISO 11898-1 protocol mode.
1444 * CAN FD frame format is according to ISO 11898-1 standard.
1445 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1446 * the configuration information for the specified FDCAN.
1447 * @retval HAL status
1448 */
HAL_FDCAN_EnableISOMode(FDCAN_HandleTypeDef * hfdcan)1449 HAL_StatusTypeDef HAL_FDCAN_EnableISOMode(FDCAN_HandleTypeDef *hfdcan)
1450 {
1451 if (hfdcan->State == HAL_FDCAN_STATE_READY)
1452 {
1453 /* Disable Non ISO protocol mode */
1454 CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_NISO);
1455
1456 /* Return function status */
1457 return HAL_OK;
1458 }
1459 else
1460 {
1461 /* Update error code */
1462 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1463
1464 return HAL_ERROR;
1465 }
1466 }
1467
1468 /**
1469 * @brief Disable ISO 11898-1 protocol mode.
1470 * CAN FD frame format is according to Bosch CAN FD specification V1.0.
1471 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1472 * the configuration information for the specified FDCAN.
1473 * @retval HAL status
1474 */
HAL_FDCAN_DisableISOMode(FDCAN_HandleTypeDef * hfdcan)1475 HAL_StatusTypeDef HAL_FDCAN_DisableISOMode(FDCAN_HandleTypeDef *hfdcan)
1476 {
1477 if (hfdcan->State == HAL_FDCAN_STATE_READY)
1478 {
1479 /* Enable Non ISO protocol mode */
1480 SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_NISO);
1481
1482 /* Return function status */
1483 return HAL_OK;
1484 }
1485 else
1486 {
1487 /* Update error code */
1488 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1489
1490 return HAL_ERROR;
1491 }
1492 }
1493
1494 /**
1495 * @brief Enable edge filtering during bus integration.
1496 * Two consecutive dominant tq are required to detect an edge for hard synchronization.
1497 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1498 * the configuration information for the specified FDCAN.
1499 * @retval HAL status
1500 */
HAL_FDCAN_EnableEdgeFiltering(FDCAN_HandleTypeDef * hfdcan)1501 HAL_StatusTypeDef HAL_FDCAN_EnableEdgeFiltering(FDCAN_HandleTypeDef *hfdcan)
1502 {
1503 if (hfdcan->State == HAL_FDCAN_STATE_READY)
1504 {
1505 /* Enable edge filtering */
1506 SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_EFBI);
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 Disable edge filtering during bus integration.
1522 * One dominant tq is required to detect an edge for hard synchronization.
1523 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1524 * the configuration information for the specified FDCAN.
1525 * @retval HAL status
1526 */
HAL_FDCAN_DisableEdgeFiltering(FDCAN_HandleTypeDef * hfdcan)1527 HAL_StatusTypeDef HAL_FDCAN_DisableEdgeFiltering(FDCAN_HandleTypeDef *hfdcan)
1528 {
1529 if (hfdcan->State == HAL_FDCAN_STATE_READY)
1530 {
1531 /* Disable edge filtering */
1532 CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_EFBI);
1533
1534 /* Return function status */
1535 return HAL_OK;
1536 }
1537 else
1538 {
1539 /* Update error code */
1540 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1541
1542 return HAL_ERROR;
1543 }
1544 }
1545
1546 /**
1547 * @}
1548 */
1549
1550 /** @defgroup FDCAN_Exported_Functions_Group3 Control functions
1551 * @brief Control functions
1552 *
1553 @verbatim
1554 ==============================================================================
1555 ##### Control functions #####
1556 ==============================================================================
1557 [..] This section provides functions allowing to:
1558 (+) HAL_FDCAN_Start : Start the FDCAN module
1559 (+) HAL_FDCAN_Stop : Stop the FDCAN module and enable access to configuration registers
1560 (+) HAL_FDCAN_AddMessageToTxFifoQ : Add a message to the Tx FIFO/Queue and activate the corresponding transmission request
1561 (+) HAL_FDCAN_AddMessageToTxBuffer : Add a message to a dedicated Tx buffer
1562 (+) HAL_FDCAN_EnableTxBufferRequest : Enable transmission request
1563 (+) HAL_FDCAN_GetLatestTxFifoQRequestBuffer : Get Tx buffer index of latest Tx FIFO/Queue request
1564 (+) HAL_FDCAN_AbortTxRequest : Abort transmission request
1565 (+) HAL_FDCAN_GetRxMessage : Get an FDCAN frame from the Rx Buffer/FIFO zone into the message RAM
1566 (+) HAL_FDCAN_GetTxEvent : Get an FDCAN Tx event from the Tx Event FIFO zone into the message RAM
1567 (+) HAL_FDCAN_GetHighPriorityMessageStatus : Get high priority message status
1568 (+) HAL_FDCAN_GetProtocolStatus : Get protocol status
1569 (+) HAL_FDCAN_GetErrorCounters : Get error counter values
1570 (+) HAL_FDCAN_IsRxBufferMessageAvailable : Check if a new message is received in the selected Rx buffer
1571 (+) HAL_FDCAN_IsTxBufferMessagePending : Check if a transmission request is pending on the selected Tx buffer
1572 (+) HAL_FDCAN_GetRxFifoFillLevel : Return Rx FIFO fill level
1573 (+) HAL_FDCAN_GetTxFifoFreeLevel : Return Tx FIFO free level
1574 (+) HAL_FDCAN_IsRestrictedOperationMode : Check if the FDCAN peripheral entered Restricted Operation Mode
1575 (+) HAL_FDCAN_ExitRestrictedOperationMode : Exit Restricted Operation Mode
1576
1577 @endverbatim
1578 * @{
1579 */
1580
1581 /**
1582 * @brief Start the FDCAN module.
1583 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1584 * the configuration information for the specified FDCAN.
1585 * @retval HAL status
1586 */
HAL_FDCAN_Start(FDCAN_HandleTypeDef * hfdcan)1587 HAL_StatusTypeDef HAL_FDCAN_Start(FDCAN_HandleTypeDef *hfdcan)
1588 {
1589 if (hfdcan->State == HAL_FDCAN_STATE_READY)
1590 {
1591 /* Change FDCAN peripheral state */
1592 hfdcan->State = HAL_FDCAN_STATE_BUSY;
1593
1594 /* Request leave initialisation */
1595 CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT);
1596
1597 /* Reset the FDCAN ErrorCode */
1598 hfdcan->ErrorCode = HAL_FDCAN_ERROR_NONE;
1599
1600 /* Return function status */
1601 return HAL_OK;
1602 }
1603 else
1604 {
1605 /* Update error code */
1606 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
1607
1608 return HAL_ERROR;
1609 }
1610 }
1611
1612 /**
1613 * @brief Stop the FDCAN module and enable access to configuration registers.
1614 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1615 * the configuration information for the specified FDCAN.
1616 * @retval HAL status
1617 */
HAL_FDCAN_Stop(FDCAN_HandleTypeDef * hfdcan)1618 HAL_StatusTypeDef HAL_FDCAN_Stop(FDCAN_HandleTypeDef *hfdcan)
1619 {
1620 uint32_t Counter = 0U;
1621
1622 if (hfdcan->State == HAL_FDCAN_STATE_BUSY)
1623 {
1624 /* Request initialisation */
1625 SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT);
1626
1627 /* Wait until the INIT bit into CCCR register is set */
1628 while ((hfdcan->Instance->CCCR & FDCAN_CCCR_INIT) == 0U)
1629 {
1630 /* Check for the Timeout */
1631 if (Counter > FDCAN_TIMEOUT_VALUE)
1632 {
1633 /* Update error code */
1634 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
1635
1636 /* Change FDCAN state */
1637 hfdcan->State = HAL_FDCAN_STATE_ERROR;
1638
1639 return HAL_ERROR;
1640 }
1641
1642 /* Increment counter */
1643 Counter++;
1644 }
1645
1646 /* Reset counter */
1647 Counter = 0U;
1648
1649 /* Exit from Sleep mode */
1650 CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CSR);
1651
1652 /* Wait until FDCAN exits sleep mode */
1653 while ((hfdcan->Instance->CCCR & FDCAN_CCCR_CSA) == FDCAN_CCCR_CSA)
1654 {
1655 /* Check for the Timeout */
1656 if (Counter > FDCAN_TIMEOUT_VALUE)
1657 {
1658 /* Update error code */
1659 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
1660
1661 /* Change FDCAN state */
1662 hfdcan->State = HAL_FDCAN_STATE_ERROR;
1663
1664 return HAL_ERROR;
1665 }
1666
1667 /* Increment counter */
1668 Counter++;
1669 }
1670
1671 /* Enable configuration change */
1672 SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CCE);
1673
1674 /* Reset Latest Tx FIFO/Queue Request Buffer Index */
1675 hfdcan->LatestTxFifoQRequest = 0U;
1676
1677 /* Change FDCAN peripheral state */
1678 hfdcan->State = HAL_FDCAN_STATE_READY;
1679
1680 /* Return function status */
1681 return HAL_OK;
1682 }
1683 else
1684 {
1685 /* Update error code */
1686 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
1687
1688 return HAL_ERROR;
1689 }
1690 }
1691
1692 /**
1693 * @brief Add a message to the Tx FIFO/Queue and activate the corresponding transmission request
1694 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1695 * the configuration information for the specified FDCAN.
1696 * @param pTxHeader pointer to a FDCAN_TxHeaderTypeDef structure.
1697 * @param pTxData pointer to a buffer containing the payload of the Tx frame.
1698 * @retval HAL status
1699 */
HAL_FDCAN_AddMessageToTxFifoQ(FDCAN_HandleTypeDef * hfdcan,FDCAN_TxHeaderTypeDef * pTxHeader,uint8_t * pTxData)1700 HAL_StatusTypeDef HAL_FDCAN_AddMessageToTxFifoQ(FDCAN_HandleTypeDef *hfdcan, FDCAN_TxHeaderTypeDef *pTxHeader, uint8_t *pTxData)
1701 {
1702 uint32_t PutIndex;
1703
1704 /* Check function parameters */
1705 assert_param(IS_FDCAN_ID_TYPE(pTxHeader->IdType));
1706 if (pTxHeader->IdType == FDCAN_STANDARD_ID)
1707 {
1708 assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->Identifier, 0x7FFU));
1709 }
1710 else /* pTxHeader->IdType == FDCAN_EXTENDED_ID */
1711 {
1712 assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->Identifier, 0x1FFFFFFFU));
1713 }
1714 assert_param(IS_FDCAN_FRAME_TYPE(pTxHeader->TxFrameType));
1715 assert_param(IS_FDCAN_DLC(pTxHeader->DataLength));
1716 assert_param(IS_FDCAN_ESI(pTxHeader->ErrorStateIndicator));
1717 assert_param(IS_FDCAN_BRS(pTxHeader->BitRateSwitch));
1718 assert_param(IS_FDCAN_FDF(pTxHeader->FDFormat));
1719 assert_param(IS_FDCAN_EFC(pTxHeader->TxEventFifoControl));
1720 assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->MessageMarker, 0xFFU));
1721
1722 if (hfdcan->State == HAL_FDCAN_STATE_BUSY)
1723 {
1724 /* Check that the Tx FIFO/Queue has an allocated area into the RAM */
1725 if ((hfdcan->Instance->TXBC & FDCAN_TXBC_TFQS) == 0U)
1726 {
1727 /* Update error code */
1728 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
1729
1730 return HAL_ERROR;
1731 }
1732
1733 /* Check that the Tx FIFO/Queue is not full */
1734 if ((hfdcan->Instance->TXFQS & FDCAN_TXFQS_TFQF) != 0U)
1735 {
1736 /* Update error code */
1737 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_FULL;
1738
1739 return HAL_ERROR;
1740 }
1741 else
1742 {
1743 /* Retrieve the Tx FIFO PutIndex */
1744 PutIndex = ((hfdcan->Instance->TXFQS & FDCAN_TXFQS_TFQPI) >> FDCAN_TXFQS_TFQPI_Pos);
1745
1746 /* Add the message to the Tx FIFO/Queue */
1747 FDCAN_CopyMessageToRAM(hfdcan, pTxHeader, pTxData, PutIndex);
1748
1749 /* Activate the corresponding transmission request */
1750 hfdcan->Instance->TXBAR = ((uint32_t)1 << PutIndex);
1751
1752 /* Store the Latest Tx FIFO/Queue Request Buffer Index */
1753 hfdcan->LatestTxFifoQRequest = ((uint32_t)1 << PutIndex);
1754 }
1755
1756 /* Return function status */
1757 return HAL_OK;
1758 }
1759 else
1760 {
1761 /* Update error code */
1762 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
1763
1764 return HAL_ERROR;
1765 }
1766 }
1767
1768 /**
1769 * @brief Add a message to a dedicated Tx buffer
1770 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1771 * the configuration information for the specified FDCAN.
1772 * @param pTxHeader pointer to a FDCAN_TxHeaderTypeDef structure.
1773 * @param pTxData pointer to a buffer containing the payload of the Tx frame.
1774 * @param BufferIndex index of the buffer to be configured.
1775 * This parameter can be a value of @arg FDCAN_Tx_location.
1776 * @retval HAL status
1777 */
HAL_FDCAN_AddMessageToTxBuffer(FDCAN_HandleTypeDef * hfdcan,FDCAN_TxHeaderTypeDef * pTxHeader,uint8_t * pTxData,uint32_t BufferIndex)1778 HAL_StatusTypeDef HAL_FDCAN_AddMessageToTxBuffer(FDCAN_HandleTypeDef *hfdcan, FDCAN_TxHeaderTypeDef *pTxHeader, uint8_t *pTxData, uint32_t BufferIndex)
1779 {
1780 HAL_FDCAN_StateTypeDef state = hfdcan->State;
1781
1782 /* Check function parameters */
1783 assert_param(IS_FDCAN_ID_TYPE(pTxHeader->IdType));
1784 if (pTxHeader->IdType == FDCAN_STANDARD_ID)
1785 {
1786 assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->Identifier, 0x7FFU));
1787 }
1788 else /* pTxHeader->IdType == FDCAN_EXTENDED_ID */
1789 {
1790 assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->Identifier, 0x1FFFFFFFU));
1791 }
1792 assert_param(IS_FDCAN_FRAME_TYPE(pTxHeader->TxFrameType));
1793 assert_param(IS_FDCAN_DLC(pTxHeader->DataLength));
1794 assert_param(IS_FDCAN_ESI(pTxHeader->ErrorStateIndicator));
1795 assert_param(IS_FDCAN_BRS(pTxHeader->BitRateSwitch));
1796 assert_param(IS_FDCAN_FDF(pTxHeader->FDFormat));
1797 assert_param(IS_FDCAN_EFC(pTxHeader->TxEventFifoControl));
1798 assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->MessageMarker, 0xFFU));
1799 assert_param(IS_FDCAN_TX_LOCATION(BufferIndex));
1800
1801 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
1802 {
1803 /* Check that the selected buffer has an allocated area into the RAM */
1804 if (POSITION_VAL(BufferIndex) >= ((hfdcan->Instance->TXBC & FDCAN_TXBC_NDTB) >> FDCAN_TXBC_NDTB_Pos))
1805 {
1806 /* Update error code */
1807 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
1808
1809 return HAL_ERROR;
1810 }
1811
1812 /* Check that there is no transmittion request pending for the selected buffer */
1813 if ((hfdcan->Instance->TXBRP & BufferIndex) != 0U)
1814 {
1815 /* Update error code */
1816 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PENDING;
1817
1818 return HAL_ERROR;
1819 }
1820 else
1821 {
1822 /* Add the message to the Tx buffer */
1823 FDCAN_CopyMessageToRAM(hfdcan, pTxHeader, pTxData, POSITION_VAL(BufferIndex));
1824 }
1825
1826 /* Return function status */
1827 return HAL_OK;
1828 }
1829 else
1830 {
1831 /* Update error code */
1832 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
1833
1834 return HAL_ERROR;
1835 }
1836 }
1837
1838 /**
1839 * @brief Enable transmission request.
1840 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1841 * the configuration information for the specified FDCAN.
1842 * @param BufferIndex buffer index.
1843 * This parameter can be any combination of @arg FDCAN_Tx_location.
1844 * @retval HAL status
1845 */
HAL_FDCAN_EnableTxBufferRequest(FDCAN_HandleTypeDef * hfdcan,uint32_t BufferIndex)1846 HAL_StatusTypeDef HAL_FDCAN_EnableTxBufferRequest(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndex)
1847 {
1848 if (hfdcan->State == HAL_FDCAN_STATE_BUSY)
1849 {
1850 /* Add transmission request */
1851 hfdcan->Instance->TXBAR = BufferIndex;
1852
1853 /* Return function status */
1854 return HAL_OK;
1855 }
1856 else
1857 {
1858 /* Update error code */
1859 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
1860
1861 return HAL_ERROR;
1862 }
1863 }
1864
1865 /**
1866 * @brief Get Tx buffer index of latest Tx FIFO/Queue request
1867 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1868 * the configuration information for the specified FDCAN.
1869 * @retval Tx buffer index of last Tx FIFO/Queue request
1870 * - Any value of @arg FDCAN_Tx_location if Tx request has been submitted.
1871 * - 0 if no Tx FIFO/Queue request have been submitted.
1872 */
HAL_FDCAN_GetLatestTxFifoQRequestBuffer(FDCAN_HandleTypeDef * hfdcan)1873 uint32_t HAL_FDCAN_GetLatestTxFifoQRequestBuffer(FDCAN_HandleTypeDef *hfdcan)
1874 {
1875 /* Return Last Tx FIFO/Queue Request Buffer */
1876 return hfdcan->LatestTxFifoQRequest;
1877 }
1878
1879 /**
1880 * @brief Abort transmission request
1881 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1882 * the configuration information for the specified FDCAN.
1883 * @param BufferIndex buffer index.
1884 * This parameter can be any combination of @arg FDCAN_Tx_location.
1885 * @retval HAL status
1886 */
HAL_FDCAN_AbortTxRequest(FDCAN_HandleTypeDef * hfdcan,uint32_t BufferIndex)1887 HAL_StatusTypeDef HAL_FDCAN_AbortTxRequest(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndex)
1888 {
1889 if (hfdcan->State == HAL_FDCAN_STATE_BUSY)
1890 {
1891 /* Add cancellation request */
1892 hfdcan->Instance->TXBCR = BufferIndex;
1893
1894 /* Return function status */
1895 return HAL_OK;
1896 }
1897 else
1898 {
1899 /* Update error code */
1900 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
1901
1902 return HAL_ERROR;
1903 }
1904 }
1905
1906 /**
1907 * @brief Get an FDCAN frame from the Rx Buffer/FIFO zone into the message RAM.
1908 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
1909 * the configuration information for the specified FDCAN.
1910 * @param RxLocation Location of the received message to be read.
1911 * This parameter can be a value of @arg FDCAN_Rx_location.
1912 * @param pRxHeader pointer to a FDCAN_RxHeaderTypeDef structure.
1913 * @param pRxData pointer to a buffer where the payload of the Rx frame will be stored.
1914 * @retval HAL status
1915 */
HAL_FDCAN_GetRxMessage(FDCAN_HandleTypeDef * hfdcan,uint32_t RxLocation,FDCAN_RxHeaderTypeDef * pRxHeader,uint8_t * pRxData)1916 HAL_StatusTypeDef HAL_FDCAN_GetRxMessage(FDCAN_HandleTypeDef *hfdcan, uint32_t RxLocation, FDCAN_RxHeaderTypeDef *pRxHeader, uint8_t *pRxData)
1917 {
1918 uint32_t *RxAddress;
1919 uint8_t *pData;
1920 uint32_t ByteCounter;
1921 uint32_t GetIndex = 0;
1922 HAL_FDCAN_StateTypeDef state = hfdcan->State;
1923
1924 if (state == HAL_FDCAN_STATE_BUSY)
1925 {
1926 if (RxLocation == FDCAN_RX_FIFO0) /* Rx element is assigned to the Rx FIFO 0 */
1927 {
1928 /* Check that the Rx FIFO 0 has an allocated area into the RAM */
1929 if ((hfdcan->Instance->RXF0C & FDCAN_RXF0C_F0S) == 0U)
1930 {
1931 /* Update error code */
1932 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
1933
1934 return HAL_ERROR;
1935 }
1936
1937 /* Check that the Rx FIFO 0 is not empty */
1938 if ((hfdcan->Instance->RXF0S & FDCAN_RXF0S_F0FL) == 0U)
1939 {
1940 /* Update error code */
1941 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_EMPTY;
1942
1943 return HAL_ERROR;
1944 }
1945 else
1946 {
1947 /* Calculate Rx FIFO 0 element address */
1948 GetIndex = ((hfdcan->Instance->RXF0S & FDCAN_RXF0S_F0GI) >> FDCAN_RXF0S_F0GI_Pos);
1949 RxAddress = (uint32_t *)(hfdcan->msgRam.RxFIFO0SA + (GetIndex * hfdcan->Init.RxFifo0ElmtSize * 4U));
1950 }
1951 }
1952 else if (RxLocation == FDCAN_RX_FIFO1) /* Rx element is assigned to the Rx FIFO 1 */
1953 {
1954 /* Check that the Rx FIFO 1 has an allocated area into the RAM */
1955 if ((hfdcan->Instance->RXF1C & FDCAN_RXF1C_F1S) == 0U)
1956 {
1957 /* Update error code */
1958 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
1959
1960 return HAL_ERROR;
1961 }
1962
1963 /* Check that the Rx FIFO 0 is not empty */
1964 if ((hfdcan->Instance->RXF1S & FDCAN_RXF1S_F1FL) == 0U)
1965 {
1966 /* Update error code */
1967 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_EMPTY;
1968
1969 return HAL_ERROR;
1970 }
1971 else
1972 {
1973 /* Calculate Rx FIFO 1 element address */
1974 GetIndex = ((hfdcan->Instance->RXF1S & FDCAN_RXF1S_F1GI) >> FDCAN_RXF1S_F1GI_Pos);
1975 RxAddress = (uint32_t *)(hfdcan->msgRam.RxFIFO1SA + (GetIndex * hfdcan->Init.RxFifo1ElmtSize * 4U));
1976 }
1977 }
1978 else /* Rx element is assigned to a dedicated Rx buffer */
1979 {
1980 /* Check that the selected buffer has an allocated area into the RAM */
1981 if (RxLocation >= hfdcan->Init.RxBuffersNbr)
1982 {
1983 /* Update error code */
1984 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
1985
1986 return HAL_ERROR;
1987 }
1988 else
1989 {
1990 /* Calculate Rx buffer address */
1991 RxAddress = (uint32_t *)(hfdcan->msgRam.RxBufferSA + (RxLocation * hfdcan->Init.RxBufferSize * 4U));
1992 }
1993 }
1994
1995 /* Retrieve IdType */
1996 pRxHeader->IdType = *RxAddress & FDCAN_ELEMENT_MASK_XTD;
1997
1998 /* Retrieve Identifier */
1999 if (pRxHeader->IdType == FDCAN_STANDARD_ID) /* Standard ID element */
2000 {
2001 pRxHeader->Identifier = ((*RxAddress & FDCAN_ELEMENT_MASK_STDID) >> 18);
2002 }
2003 else /* Extended ID element */
2004 {
2005 pRxHeader->Identifier = (*RxAddress & FDCAN_ELEMENT_MASK_EXTID);
2006 }
2007
2008 /* Retrieve RxFrameType */
2009 pRxHeader->RxFrameType = (*RxAddress & FDCAN_ELEMENT_MASK_RTR);
2010
2011 /* Retrieve ErrorStateIndicator */
2012 pRxHeader->ErrorStateIndicator = (*RxAddress & FDCAN_ELEMENT_MASK_ESI);
2013
2014 /* Increment RxAddress pointer to second word of Rx FIFO element */
2015 RxAddress++;
2016
2017 /* Retrieve RxTimestamp */
2018 pRxHeader->RxTimestamp = (*RxAddress & FDCAN_ELEMENT_MASK_TS);
2019
2020 /* Retrieve DataLength */
2021 pRxHeader->DataLength = (*RxAddress & FDCAN_ELEMENT_MASK_DLC);
2022
2023 /* Retrieve BitRateSwitch */
2024 pRxHeader->BitRateSwitch = (*RxAddress & FDCAN_ELEMENT_MASK_BRS);
2025
2026 /* Retrieve FDFormat */
2027 pRxHeader->FDFormat = (*RxAddress & FDCAN_ELEMENT_MASK_FDF);
2028
2029 /* Retrieve FilterIndex */
2030 pRxHeader->FilterIndex = ((*RxAddress & FDCAN_ELEMENT_MASK_FIDX) >> 24);
2031
2032 /* Retrieve NonMatchingFrame */
2033 pRxHeader->IsFilterMatchingFrame = ((*RxAddress & FDCAN_ELEMENT_MASK_ANMF) >> 31);
2034
2035 /* Increment RxAddress pointer to payload of Rx FIFO element */
2036 RxAddress++;
2037
2038 /* Retrieve Rx payload */
2039 pData = (uint8_t *)RxAddress;
2040 for (ByteCounter = 0; ByteCounter < DLCtoBytes[pRxHeader->DataLength >> 16]; ByteCounter++)
2041 {
2042 pRxData[ByteCounter] = pData[ByteCounter];
2043 }
2044
2045 if (RxLocation == FDCAN_RX_FIFO0) /* Rx element is assigned to the Rx FIFO 0 */
2046 {
2047 /* Acknowledge the Rx FIFO 0 that the oldest element is read so that it increments the GetIndex */
2048 hfdcan->Instance->RXF0A = GetIndex;
2049 }
2050 else if (RxLocation == FDCAN_RX_FIFO1) /* Rx element is assigned to the Rx FIFO 1 */
2051 {
2052 /* Acknowledge the Rx FIFO 1 that the oldest element is read so that it increments the GetIndex */
2053 hfdcan->Instance->RXF1A = GetIndex;
2054 }
2055 else /* Rx element is assigned to a dedicated Rx buffer */
2056 {
2057 /* Clear the New Data flag of the current Rx buffer */
2058 if (RxLocation < FDCAN_RX_BUFFER32)
2059 {
2060 hfdcan->Instance->NDAT1 = ((uint32_t)1 << RxLocation);
2061 }
2062 else /* FDCAN_RX_BUFFER32 <= RxLocation <= FDCAN_RX_BUFFER63 */
2063 {
2064 hfdcan->Instance->NDAT2 = ((uint32_t)1 << (RxLocation & 0x1FU));
2065 }
2066 }
2067
2068 /* Return function status */
2069 return HAL_OK;
2070 }
2071 else
2072 {
2073 /* Update error code */
2074 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
2075
2076 return HAL_ERROR;
2077 }
2078 }
2079
2080 /**
2081 * @brief Get an FDCAN Tx event from the Tx Event FIFO zone into the message RAM.
2082 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2083 * the configuration information for the specified FDCAN.
2084 * @param pTxEvent pointer to a FDCAN_TxEventFifoTypeDef structure.
2085 * @retval HAL status
2086 */
HAL_FDCAN_GetTxEvent(FDCAN_HandleTypeDef * hfdcan,FDCAN_TxEventFifoTypeDef * pTxEvent)2087 HAL_StatusTypeDef HAL_FDCAN_GetTxEvent(FDCAN_HandleTypeDef *hfdcan, FDCAN_TxEventFifoTypeDef *pTxEvent)
2088 {
2089 uint32_t *TxEventAddress;
2090 uint32_t GetIndex;
2091 HAL_FDCAN_StateTypeDef state = hfdcan->State;
2092
2093 /* Check function parameters */
2094 assert_param(IS_FDCAN_MIN_VALUE(hfdcan->Init.TxEventsNbr, 1U));
2095
2096 if (state == HAL_FDCAN_STATE_BUSY)
2097 {
2098 /* Check that the Tx Event FIFO has an allocated area into the RAM */
2099 if ((hfdcan->Instance->TXEFC & FDCAN_TXEFC_EFS) == 0U)
2100 {
2101 /* Update error code */
2102 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
2103
2104 return HAL_ERROR;
2105 }
2106
2107 /* Check that the Tx event FIFO is not empty */
2108 if ((hfdcan->Instance->TXEFS & FDCAN_TXEFS_EFFL) == 0U)
2109 {
2110 /* Update error code */
2111 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_EMPTY;
2112
2113 return HAL_ERROR;
2114 }
2115
2116 /* Calculate Tx event FIFO element address */
2117 GetIndex = ((hfdcan->Instance->TXEFS & FDCAN_TXEFS_EFGI) >> FDCAN_TXEFS_EFGI_Pos);
2118 TxEventAddress = (uint32_t *)(hfdcan->msgRam.TxEventFIFOSA + (GetIndex * 2U * 4U));
2119
2120 /* Retrieve IdType */
2121 pTxEvent->IdType = *TxEventAddress & FDCAN_ELEMENT_MASK_XTD;
2122
2123 /* Retrieve Identifier */
2124 if (pTxEvent->IdType == FDCAN_STANDARD_ID) /* Standard ID element */
2125 {
2126 pTxEvent->Identifier = ((*TxEventAddress & FDCAN_ELEMENT_MASK_STDID) >> 18U);
2127 }
2128 else /* Extended ID element */
2129 {
2130 pTxEvent->Identifier = (*TxEventAddress & FDCAN_ELEMENT_MASK_EXTID);
2131 }
2132
2133 /* Retrieve TxFrameType */
2134 pTxEvent->TxFrameType = (*TxEventAddress & FDCAN_ELEMENT_MASK_RTR);
2135
2136 /* Retrieve ErrorStateIndicator */
2137 pTxEvent->ErrorStateIndicator = (*TxEventAddress & FDCAN_ELEMENT_MASK_ESI);
2138
2139 /* Increment TxEventAddress pointer to second word of Tx Event FIFO element */
2140 TxEventAddress++;
2141
2142 /* Retrieve TxTimestamp */
2143 pTxEvent->TxTimestamp = (*TxEventAddress & FDCAN_ELEMENT_MASK_TS);
2144
2145 /* Retrieve DataLength */
2146 pTxEvent->DataLength = (*TxEventAddress & FDCAN_ELEMENT_MASK_DLC);
2147
2148 /* Retrieve BitRateSwitch */
2149 pTxEvent->BitRateSwitch = (*TxEventAddress & FDCAN_ELEMENT_MASK_BRS);
2150
2151 /* Retrieve FDFormat */
2152 pTxEvent->FDFormat = (*TxEventAddress & FDCAN_ELEMENT_MASK_FDF);
2153
2154 /* Retrieve EventType */
2155 pTxEvent->EventType = (*TxEventAddress & FDCAN_ELEMENT_MASK_ET);
2156
2157 /* Retrieve MessageMarker */
2158 pTxEvent->MessageMarker = ((*TxEventAddress & FDCAN_ELEMENT_MASK_MM) >> 24);
2159
2160 /* Acknowledge the Tx Event FIFO that the oldest element is read so that it increments the GetIndex */
2161 hfdcan->Instance->TXEFA = GetIndex;
2162
2163 /* Return function status */
2164 return HAL_OK;
2165 }
2166 else
2167 {
2168 /* Update error code */
2169 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
2170
2171 return HAL_ERROR;
2172 }
2173 }
2174
2175 /**
2176 * @brief Get high priority message status.
2177 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2178 * the configuration information for the specified FDCAN.
2179 * @param HpMsgStatus pointer to an FDCAN_HpMsgStatusTypeDef structure.
2180 * @retval HAL status
2181 */
HAL_FDCAN_GetHighPriorityMessageStatus(FDCAN_HandleTypeDef * hfdcan,FDCAN_HpMsgStatusTypeDef * HpMsgStatus)2182 HAL_StatusTypeDef HAL_FDCAN_GetHighPriorityMessageStatus(FDCAN_HandleTypeDef *hfdcan, FDCAN_HpMsgStatusTypeDef *HpMsgStatus)
2183 {
2184 HpMsgStatus->FilterList = ((hfdcan->Instance->HPMS & FDCAN_HPMS_FLST) >> FDCAN_HPMS_FLST_Pos);
2185 HpMsgStatus->FilterIndex = ((hfdcan->Instance->HPMS & FDCAN_HPMS_FIDX) >> FDCAN_HPMS_FIDX_Pos);
2186 HpMsgStatus->MessageStorage = (hfdcan->Instance->HPMS & FDCAN_HPMS_MSI);
2187 HpMsgStatus->MessageIndex = (hfdcan->Instance->HPMS & FDCAN_HPMS_BIDX);
2188
2189 /* Return function status */
2190 return HAL_OK;
2191 }
2192
2193 /**
2194 * @brief Get protocol status.
2195 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2196 * the configuration information for the specified FDCAN.
2197 * @param ProtocolStatus pointer to an FDCAN_ProtocolStatusTypeDef structure.
2198 * @retval HAL status
2199 */
HAL_FDCAN_GetProtocolStatus(FDCAN_HandleTypeDef * hfdcan,FDCAN_ProtocolStatusTypeDef * ProtocolStatus)2200 HAL_StatusTypeDef HAL_FDCAN_GetProtocolStatus(FDCAN_HandleTypeDef *hfdcan, FDCAN_ProtocolStatusTypeDef *ProtocolStatus)
2201 {
2202 uint32_t StatusReg;
2203
2204 /* Read the protocol status register */
2205 StatusReg = READ_REG(hfdcan->Instance->PSR);
2206
2207 /* Fill the protocol status structure */
2208 ProtocolStatus->LastErrorCode = (StatusReg & FDCAN_PSR_LEC);
2209 ProtocolStatus->DataLastErrorCode = ((StatusReg & FDCAN_PSR_DLEC) >> FDCAN_PSR_DLEC_Pos);
2210 ProtocolStatus->Activity = (StatusReg & FDCAN_PSR_ACT);
2211 ProtocolStatus->ErrorPassive = ((StatusReg & FDCAN_PSR_EP) >> FDCAN_PSR_EP_Pos);
2212 ProtocolStatus->Warning = ((StatusReg & FDCAN_PSR_EW) >> FDCAN_PSR_EW_Pos);
2213 ProtocolStatus->BusOff = ((StatusReg & FDCAN_PSR_BO) >> FDCAN_PSR_BO_Pos);
2214 ProtocolStatus->RxESIflag = ((StatusReg & FDCAN_PSR_RESI) >> FDCAN_PSR_RESI_Pos);
2215 ProtocolStatus->RxBRSflag = ((StatusReg & FDCAN_PSR_RBRS) >> FDCAN_PSR_RBRS_Pos);
2216 ProtocolStatus->RxFDFflag = ((StatusReg & FDCAN_PSR_REDL) >> FDCAN_PSR_REDL_Pos);
2217 ProtocolStatus->ProtocolException = ((StatusReg & FDCAN_PSR_PXE) >> FDCAN_PSR_PXE_Pos);
2218 ProtocolStatus->TDCvalue = ((StatusReg & FDCAN_PSR_TDCV) >> FDCAN_PSR_TDCV_Pos);
2219
2220 /* Return function status */
2221 return HAL_OK;
2222 }
2223
2224 /**
2225 * @brief Get error counter values.
2226 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2227 * the configuration information for the specified FDCAN.
2228 * @param ErrorCounters pointer to an FDCAN_ErrorCountersTypeDef structure.
2229 * @retval HAL status
2230 */
HAL_FDCAN_GetErrorCounters(FDCAN_HandleTypeDef * hfdcan,FDCAN_ErrorCountersTypeDef * ErrorCounters)2231 HAL_StatusTypeDef HAL_FDCAN_GetErrorCounters(FDCAN_HandleTypeDef *hfdcan, FDCAN_ErrorCountersTypeDef *ErrorCounters)
2232 {
2233 uint32_t CountersReg;
2234
2235 /* Read the error counters register */
2236 CountersReg = READ_REG(hfdcan->Instance->ECR);
2237
2238 /* Fill the error counters structure */
2239 ErrorCounters->TxErrorCnt = ((CountersReg & FDCAN_ECR_TEC) >> FDCAN_ECR_TEC_Pos);
2240 ErrorCounters->RxErrorCnt = ((CountersReg & FDCAN_ECR_REC) >> FDCAN_ECR_REC_Pos);
2241 ErrorCounters->RxErrorPassive = ((CountersReg & FDCAN_ECR_RP) >> FDCAN_ECR_RP_Pos);
2242 ErrorCounters->ErrorLogging = ((CountersReg & FDCAN_ECR_CEL) >> FDCAN_ECR_CEL_Pos);
2243
2244 /* Return function status */
2245 return HAL_OK;
2246 }
2247
2248 /**
2249 * @brief Check if a new message is received in the selected Rx buffer.
2250 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2251 * the configuration information for the specified FDCAN.
2252 * @param RxBufferIndex Rx buffer index.
2253 * This parameter must be a number between 0 and 63.
2254 * @retval Status
2255 * - 0 : No new message on RxBufferIndex.
2256 * - 1 : New message received on RxBufferIndex.
2257 */
HAL_FDCAN_IsRxBufferMessageAvailable(FDCAN_HandleTypeDef * hfdcan,uint32_t RxBufferIndex)2258 uint32_t HAL_FDCAN_IsRxBufferMessageAvailable(FDCAN_HandleTypeDef *hfdcan, uint32_t RxBufferIndex)
2259 {
2260 /* Check function parameters */
2261 assert_param(IS_FDCAN_MAX_VALUE(RxBufferIndex, 63U));
2262 uint32_t NewData1 = hfdcan->Instance->NDAT1;
2263 uint32_t NewData2 = hfdcan->Instance->NDAT2;
2264
2265 /* Check new message reception on the selected buffer */
2266 if (((RxBufferIndex < 32U) && ((NewData1 & (uint32_t)((uint32_t)1 << RxBufferIndex)) == 0U)) ||
2267 ((RxBufferIndex >= 32U) && ((NewData2 & (uint32_t)((uint32_t)1 << (RxBufferIndex & 0x1FU))) == 0U)))
2268 {
2269 return 0;
2270 }
2271
2272 /* Clear the New Data flag of the current Rx buffer */
2273 if (RxBufferIndex < 32U)
2274 {
2275 hfdcan->Instance->NDAT1 = ((uint32_t)1 << RxBufferIndex);
2276 }
2277 else /* 32 <= RxBufferIndex <= 63 */
2278 {
2279 hfdcan->Instance->NDAT2 = ((uint32_t)1 << (RxBufferIndex & 0x1FU));
2280 }
2281
2282 return 1;
2283 }
2284
2285 /**
2286 * @brief Check if a transmission request is pending on the selected Tx buffer.
2287 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2288 * the configuration information for the specified FDCAN.
2289 * @param TxBufferIndex Tx buffer index.
2290 * This parameter can be any combination of @arg FDCAN_Tx_location.
2291 * @retval Status
2292 * - 0 : No pending transmission request on TxBufferIndex.
2293 * - 1 : Pending transmission request on TxBufferIndex.
2294 */
HAL_FDCAN_IsTxBufferMessagePending(FDCAN_HandleTypeDef * hfdcan,uint32_t TxBufferIndex)2295 uint32_t HAL_FDCAN_IsTxBufferMessagePending(FDCAN_HandleTypeDef *hfdcan, uint32_t TxBufferIndex)
2296 {
2297 /* Check pending transmittion request on the selected buffer */
2298 if ((hfdcan->Instance->TXBRP & TxBufferIndex) == 0U)
2299 {
2300 return 0;
2301 }
2302 return 1;
2303 }
2304
2305 /**
2306 * @brief Return Rx FIFO fill level.
2307 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2308 * the configuration information for the specified FDCAN.
2309 * @param RxFifo Rx FIFO.
2310 * This parameter can be one of the following values:
2311 * @arg FDCAN_RX_FIFO0: Rx FIFO 0
2312 * @arg FDCAN_RX_FIFO1: Rx FIFO 1
2313 * @retval Level Rx FIFO fill level.
2314 */
HAL_FDCAN_GetRxFifoFillLevel(FDCAN_HandleTypeDef * hfdcan,uint32_t RxFifo)2315 uint32_t HAL_FDCAN_GetRxFifoFillLevel(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo)
2316 {
2317 uint32_t FillLevel;
2318
2319 /* Check function parameters */
2320 assert_param(IS_FDCAN_RX_FIFO(RxFifo));
2321
2322 if (RxFifo == FDCAN_RX_FIFO0)
2323 {
2324 FillLevel = hfdcan->Instance->RXF0S & FDCAN_RXF0S_F0FL;
2325 }
2326 else /* RxFifo == FDCAN_RX_FIFO1 */
2327 {
2328 FillLevel = hfdcan->Instance->RXF1S & FDCAN_RXF1S_F1FL;
2329 }
2330
2331 /* Return Rx FIFO fill level */
2332 return FillLevel;
2333 }
2334
2335 /**
2336 * @brief Return Tx FIFO free level: number of consecutive free Tx FIFO
2337 * elements starting from Tx FIFO GetIndex.
2338 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2339 * the configuration information for the specified FDCAN.
2340 * @retval Level Tx FIFO free level.
2341 */
HAL_FDCAN_GetTxFifoFreeLevel(FDCAN_HandleTypeDef * hfdcan)2342 uint32_t HAL_FDCAN_GetTxFifoFreeLevel(FDCAN_HandleTypeDef *hfdcan)
2343 {
2344 uint32_t FreeLevel;
2345
2346 FreeLevel = hfdcan->Instance->TXFQS & FDCAN_TXFQS_TFFL;
2347
2348 /* Return Tx FIFO free level */
2349 return FreeLevel;
2350 }
2351
2352 /**
2353 * @brief Check if the FDCAN peripheral entered Restricted Operation Mode.
2354 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2355 * the configuration information for the specified FDCAN.
2356 * @retval Status
2357 * - 0 : Normal FDCAN operation.
2358 * - 1 : Restricted Operation Mode active.
2359 */
HAL_FDCAN_IsRestrictedOperationMode(FDCAN_HandleTypeDef * hfdcan)2360 uint32_t HAL_FDCAN_IsRestrictedOperationMode(FDCAN_HandleTypeDef *hfdcan)
2361 {
2362 uint32_t OperationMode;
2363
2364 /* Get Operation Mode */
2365 OperationMode = ((hfdcan->Instance->CCCR & FDCAN_CCCR_ASM) >> FDCAN_CCCR_ASM_Pos);
2366
2367 return OperationMode;
2368 }
2369
2370 /**
2371 * @brief Exit Restricted Operation Mode.
2372 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2373 * the configuration information for the specified FDCAN.
2374 * @retval HAL status
2375 */
HAL_FDCAN_ExitRestrictedOperationMode(FDCAN_HandleTypeDef * hfdcan)2376 HAL_StatusTypeDef HAL_FDCAN_ExitRestrictedOperationMode(FDCAN_HandleTypeDef *hfdcan)
2377 {
2378 HAL_FDCAN_StateTypeDef state = hfdcan->State;
2379
2380 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
2381 {
2382 /* Exit Restricted Operation mode */
2383 CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_ASM);
2384
2385 /* Return function status */
2386 return HAL_OK;
2387 }
2388 else
2389 {
2390 /* Update error code */
2391 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
2392
2393 return HAL_ERROR;
2394 }
2395 }
2396
2397 /**
2398 * @}
2399 */
2400
2401 /** @defgroup FDCAN_Exported_Functions_Group4 TT Configuration and control functions
2402 * @brief TT Configuration and control functions
2403 *
2404 @verbatim
2405 ==============================================================================
2406 ##### TT Configuration and control functions #####
2407 ==============================================================================
2408 [..] This section provides functions allowing to:
2409 (+) HAL_FDCAN_TT_ConfigOperation : Initialize TT operation parameters
2410 (+) HAL_FDCAN_TT_ConfigReferenceMessage : Configure the reference message
2411 (+) HAL_FDCAN_TT_ConfigTrigger : Configure the FDCAN trigger
2412 (+) HAL_FDCAN_TT_SetGlobalTime : Schedule global time adjustment
2413 (+) HAL_FDCAN_TT_SetClockSynchronization : Schedule TUR numerator update
2414 (+) HAL_FDCAN_TT_ConfigStopWatch : Configure stop watch source and polarity
2415 (+) HAL_FDCAN_TT_ConfigRegisterTimeMark : Configure register time mark pulse generation
2416 (+) HAL_FDCAN_TT_EnableRegisterTimeMarkPulse : Enable register time mark pulse generation
2417 (+) HAL_FDCAN_TT_DisableRegisterTimeMarkPulse : Disable register time mark pulse generation
2418 (+) HAL_FDCAN_TT_EnableTriggerTimeMarkPulse : Enable trigger time mark pulse generation
2419 (+) HAL_FDCAN_TT_DisableTriggerTimeMarkPulse : Disable trigger time mark pulse generation
2420 (+) HAL_FDCAN_TT_EnableHardwareGapControl : Enable gap control by input pin fdcan1_evt
2421 (+) HAL_FDCAN_TT_DisableHardwareGapControl : Disable gap control by input pin fdcan1_evt
2422 (+) HAL_FDCAN_TT_EnableTimeMarkGapControl : Enable gap control (finish only) by register time mark interrupt
2423 (+) HAL_FDCAN_TT_DisableTimeMarkGapControl : Disable gap control by register time mark interrupt
2424 (+) HAL_FDCAN_TT_SetNextIsGap : Transmit next reference message with Next_is_Gap = "1"
2425 (+) HAL_FDCAN_TT_SetEndOfGap : Finish a Gap by requesting start of reference message
2426 (+) HAL_FDCAN_TT_ConfigExternalSyncPhase : Configure target phase used for external synchronization
2427 (+) HAL_FDCAN_TT_EnableExternalSynchronization : Synchronize the phase of the FDCAN schedule to an external schedule
2428 (+) HAL_FDCAN_TT_DisableExternalSynchronization : Disable external schedule synchronization
2429 (+) HAL_FDCAN_TT_GetOperationStatus : Get TT operation status
2430
2431 @endverbatim
2432 * @{
2433 */
2434
2435 /**
2436 * @brief Initialize TT operation parameters.
2437 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2438 * the configuration information for the specified FDCAN.
2439 * @param pTTParams pointer to a FDCAN_TT_ConfigTypeDef structure.
2440 * @retval HAL status
2441 */
HAL_FDCAN_TT_ConfigOperation(FDCAN_HandleTypeDef * hfdcan,FDCAN_TT_ConfigTypeDef * pTTParams)2442 HAL_StatusTypeDef HAL_FDCAN_TT_ConfigOperation(FDCAN_HandleTypeDef *hfdcan, FDCAN_TT_ConfigTypeDef *pTTParams)
2443 {
2444 uint32_t tickstart;
2445 uint32_t RAMcounter;
2446 uint32_t StartAddress;
2447
2448 /* Check function parameters */
2449 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
2450 assert_param(IS_FDCAN_TT_TUR_NUMERATOR(pTTParams->TURNumerator));
2451 assert_param(IS_FDCAN_TT_TUR_DENOMINATOR(pTTParams->TURDenominator));
2452 assert_param(IS_FDCAN_TT_TIME_MASTER(pTTParams->TimeMaster));
2453 assert_param(IS_FDCAN_MAX_VALUE(pTTParams->SyncDevLimit, 7U));
2454 assert_param(IS_FDCAN_MAX_VALUE(pTTParams->InitRefTrigOffset, 127U));
2455 assert_param(IS_FDCAN_MAX_VALUE(pTTParams->TriggerMemoryNbr, 64U));
2456 assert_param(IS_FDCAN_TT_CYCLE_START_SYNC(pTTParams->CycleStartSync));
2457 assert_param(IS_FDCAN_TT_STOP_WATCH_TRIGGER(pTTParams->StopWatchTrigSel));
2458 assert_param(IS_FDCAN_TT_EVENT_TRIGGER(pTTParams->EventTrigSel));
2459 if (pTTParams->TimeMaster == FDCAN_TT_POTENTIAL_MASTER)
2460 {
2461 assert_param(IS_FDCAN_TT_BASIC_CYCLES_NUMBER(pTTParams->BasicCyclesNbr));
2462 }
2463 if (pTTParams->OperationMode != FDCAN_TT_COMMUNICATION_LEVEL0)
2464 {
2465 assert_param(IS_FDCAN_TT_OPERATION(pTTParams->GapEnable));
2466 assert_param(IS_FDCAN_MAX_VALUE(pTTParams->AppWdgLimit, 255U));
2467 assert_param(IS_FDCAN_TT_EVENT_TRIGGER_POLARITY(pTTParams->EvtTrigPolarity));
2468 assert_param(IS_FDCAN_TT_TX_ENABLE_WINDOW(pTTParams->TxEnableWindow));
2469 assert_param(IS_FDCAN_MAX_VALUE(pTTParams->ExpTxTrigNbr, 4095U));
2470 }
2471 if (pTTParams->OperationMode != FDCAN_TT_COMMUNICATION_LEVEL1)
2472 {
2473 assert_param(IS_FDCAN_TT_TUR_LEVEL_0_2(pTTParams->TURNumerator, pTTParams->TURDenominator));
2474 assert_param(IS_FDCAN_TT_EXTERNAL_CLK_SYNC(pTTParams->ExternalClkSync));
2475 assert_param(IS_FDCAN_TT_GLOBAL_TIME_FILTERING(pTTParams->GlobalTimeFilter));
2476 assert_param(IS_FDCAN_TT_AUTO_CLK_CALIBRATION(pTTParams->ClockCalibration));
2477 }
2478 else
2479 {
2480 assert_param(IS_FDCAN_TT_TUR_LEVEL_1(pTTParams->TURNumerator, pTTParams->TURDenominator));
2481 }
2482
2483 if (hfdcan->State == HAL_FDCAN_STATE_READY)
2484 {
2485 /* Stop local time in order to enable write access to the other bits of TURCF register */
2486 CLEAR_BIT(hfdcan->ttcan->TURCF, FDCAN_TURCF_ELT);
2487
2488 /* Get tick */
2489 tickstart = HAL_GetTick();
2490
2491 /* Wait until the ELT bit into TURCF register is reset */
2492 while ((hfdcan->ttcan->TURCF & FDCAN_TURCF_ELT) != 0U)
2493 {
2494 /* Check for the Timeout */
2495 if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE)
2496 {
2497 /* Update error code */
2498 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
2499
2500 /* Change FDCAN state */
2501 hfdcan->State = HAL_FDCAN_STATE_ERROR;
2502
2503 return HAL_ERROR;
2504 }
2505 }
2506
2507 /* Configure TUR (Time Unit Ratio) */
2508 MODIFY_REG(hfdcan->ttcan->TURCF,
2509 (FDCAN_TURCF_NCL | FDCAN_TURCF_DC),
2510 (((pTTParams->TURNumerator - 0x10000U) << FDCAN_TURCF_NCL_Pos) | (pTTParams->TURDenominator << FDCAN_TURCF_DC_Pos)));
2511
2512 /* Enable local time */
2513 SET_BIT(hfdcan->ttcan->TURCF, FDCAN_TURCF_ELT);
2514
2515 /* Configure TT operation */
2516 MODIFY_REG(hfdcan->ttcan->TTOCF,
2517 (FDCAN_TTOCF_OM | FDCAN_TTOCF_TM | FDCAN_TTOCF_LDSDL | FDCAN_TTOCF_IRTO),
2518 (pTTParams->OperationMode | \
2519 pTTParams->TimeMaster | \
2520 (pTTParams->SyncDevLimit << FDCAN_TTOCF_LDSDL_Pos) | \
2521 (pTTParams->InitRefTrigOffset << FDCAN_TTOCF_IRTO_Pos)));
2522 if (pTTParams->OperationMode != FDCAN_TT_COMMUNICATION_LEVEL0)
2523 {
2524 MODIFY_REG(hfdcan->ttcan->TTOCF,
2525 (FDCAN_TTOCF_GEN | FDCAN_TTOCF_AWL | FDCAN_TTOCF_EVTP),
2526 (pTTParams->GapEnable | \
2527 (pTTParams->AppWdgLimit << FDCAN_TTOCF_AWL_Pos) | \
2528 pTTParams->EvtTrigPolarity));
2529 }
2530 if (pTTParams->OperationMode != FDCAN_TT_COMMUNICATION_LEVEL1)
2531 {
2532 MODIFY_REG(hfdcan->ttcan->TTOCF,
2533 (FDCAN_TTOCF_EECS | FDCAN_TTOCF_EGTF | FDCAN_TTOCF_ECC),
2534 (pTTParams->ExternalClkSync | \
2535 pTTParams->GlobalTimeFilter | \
2536 pTTParams->ClockCalibration));
2537 }
2538
2539 /* Configure system matrix limits */
2540 MODIFY_REG(hfdcan->ttcan->TTMLM, FDCAN_TTMLM_CSS, pTTParams->CycleStartSync);
2541 if (pTTParams->OperationMode != FDCAN_TT_COMMUNICATION_LEVEL0)
2542 {
2543 MODIFY_REG(hfdcan->ttcan->TTMLM,
2544 (FDCAN_TTMLM_TXEW | FDCAN_TTMLM_ENTT),
2545 (((pTTParams->TxEnableWindow - 1U) << FDCAN_TTMLM_TXEW_Pos) | (pTTParams->ExpTxTrigNbr << FDCAN_TTMLM_ENTT_Pos)));
2546 }
2547 if (pTTParams->TimeMaster == FDCAN_TT_POTENTIAL_MASTER)
2548 {
2549 MODIFY_REG(hfdcan->ttcan->TTMLM, FDCAN_TTMLM_CCM, pTTParams->BasicCyclesNbr);
2550 }
2551
2552 /* Configure input triggers: Stop watch and Event */
2553 MODIFY_REG(hfdcan->ttcan->TTTS,
2554 (FDCAN_TTTS_SWTSEL | FDCAN_TTTS_EVTSEL),
2555 (pTTParams->StopWatchTrigSel | pTTParams->EventTrigSel));
2556
2557 /* Configure trigger memory start address */
2558 StartAddress = (hfdcan->msgRam.EndAddress - SRAMCAN_BASE) / 4U;
2559 MODIFY_REG(hfdcan->ttcan->TTTMC, FDCAN_TTTMC_TMSA, (StartAddress << FDCAN_TTTMC_TMSA_Pos));
2560
2561 /* Trigger memory elements number */
2562 MODIFY_REG(hfdcan->ttcan->TTTMC, FDCAN_TTTMC_TME, (pTTParams->TriggerMemoryNbr << FDCAN_TTTMC_TME_Pos));
2563
2564 /* Recalculate End Address */
2565 hfdcan->msgRam.TTMemorySA = hfdcan->msgRam.EndAddress;
2566 hfdcan->msgRam.EndAddress = hfdcan->msgRam.TTMemorySA + (pTTParams->TriggerMemoryNbr * 2U * 4U);
2567
2568 if (hfdcan->msgRam.EndAddress > FDCAN_MESSAGE_RAM_END_ADDRESS) /* Last address of the Message RAM */
2569 {
2570 /* Update error code.
2571 Message RAM overflow */
2572 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
2573
2574 return HAL_ERROR;
2575 }
2576 else
2577 {
2578 /* Flush the allocated Message RAM area */
2579 for (RAMcounter = hfdcan->msgRam.TTMemorySA; RAMcounter < hfdcan->msgRam.EndAddress; RAMcounter += 4U)
2580 {
2581 *(uint32_t *)(RAMcounter) = 0x00000000;
2582 }
2583 }
2584
2585 /* Return function status */
2586 return HAL_OK;
2587 }
2588 else
2589 {
2590 /* Update error code */
2591 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2592
2593 return HAL_ERROR;
2594 }
2595 }
2596
2597 /**
2598 * @brief Configure the reference message.
2599 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2600 * the configuration information for the specified FDCAN.
2601 * @param IdType Identifier Type.
2602 * This parameter can be a value of @arg FDCAN_id_type.
2603 * @param Identifier Reference Identifier.
2604 * This parameter must be a number between:
2605 * - 0 and 0x7FF, if IdType is FDCAN_STANDARD_ID
2606 * - 0 and 0x1FFFFFFF, if IdType is FDCAN_EXTENDED_ID
2607 * @param Payload Enable or disable the additional payload.
2608 * This parameter can be a value of @arg FDCAN_TT_Reference_Message_Payload.
2609 * This parameter is ignored in case of time slaves.
2610 * If this parameter is set to FDCAN_TT_REF_MESSAGE_ADD_PAYLOAD, the
2611 * following elements are taken from Tx Buffer 0:
2612 * - MessageMarker
2613 * - TxEventFifoControl
2614 * - DataLength
2615 * - Data Bytes (payload):
2616 * - bytes 2-8, for Level 1
2617 * - bytes 5-8, for Level 0 and Level 2
2618 * @retval HAL status
2619 */
HAL_FDCAN_TT_ConfigReferenceMessage(FDCAN_HandleTypeDef * hfdcan,uint32_t IdType,uint32_t Identifier,uint32_t Payload)2620 HAL_StatusTypeDef HAL_FDCAN_TT_ConfigReferenceMessage(FDCAN_HandleTypeDef *hfdcan, uint32_t IdType, uint32_t Identifier, uint32_t Payload)
2621 {
2622 /* Check function parameters */
2623 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
2624 assert_param(IS_FDCAN_ID_TYPE(IdType));
2625 if (IdType == FDCAN_STANDARD_ID)
2626 {
2627 assert_param(IS_FDCAN_MAX_VALUE(Identifier, 0x7FFU));
2628 }
2629 else /* IdType == FDCAN_EXTENDED_ID */
2630 {
2631 assert_param(IS_FDCAN_MAX_VALUE(Identifier, 0x1FFFFFFFU));
2632 }
2633 assert_param(IS_FDCAN_TT_REFERENCE_MESSAGE_PAYLOAD(Payload));
2634
2635 if (hfdcan->State == HAL_FDCAN_STATE_READY)
2636 {
2637 /* Configure reference message identifier type, identifier and payload */
2638 if (IdType == FDCAN_EXTENDED_ID)
2639 {
2640 MODIFY_REG(hfdcan->ttcan->TTRMC, (FDCAN_TTRMC_RID | FDCAN_TTRMC_XTD | FDCAN_TTRMC_RMPS), (Payload | IdType | Identifier));
2641 }
2642 else /* IdType == FDCAN_STANDARD_ID */
2643 {
2644 MODIFY_REG(hfdcan->ttcan->TTRMC, (FDCAN_TTRMC_RID | FDCAN_TTRMC_XTD | FDCAN_TTRMC_RMPS), (Payload | IdType | (Identifier << 18)));
2645 }
2646
2647 /* Return function status */
2648 return HAL_OK;
2649 }
2650 else
2651 {
2652 /* Update error code */
2653 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2654
2655 return HAL_ERROR;
2656 }
2657 }
2658
2659 /**
2660 * @brief Configure the FDCAN trigger according to the specified
2661 * parameters in the FDCAN_TriggerTypeDef structure.
2662 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2663 * the configuration information for the specified FDCAN.
2664 * @param sTriggerConfig pointer to an FDCAN_TriggerTypeDef structure that
2665 * contains the trigger configuration information
2666 * @retval HAL status
2667 */
HAL_FDCAN_TT_ConfigTrigger(FDCAN_HandleTypeDef * hfdcan,FDCAN_TriggerTypeDef * sTriggerConfig)2668 HAL_StatusTypeDef HAL_FDCAN_TT_ConfigTrigger(FDCAN_HandleTypeDef *hfdcan, FDCAN_TriggerTypeDef *sTriggerConfig)
2669 {
2670 uint32_t CycleCode;
2671 uint32_t MessageNumber;
2672 uint32_t TriggerElementW1;
2673 uint32_t TriggerElementW2;
2674 uint32_t *TriggerAddress;
2675
2676 /* Check function parameters */
2677 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
2678 assert_param(IS_FDCAN_MAX_VALUE(sTriggerConfig->TriggerIndex, 63U));
2679 assert_param(IS_FDCAN_MAX_VALUE(sTriggerConfig->TimeMark, 0xFFFFU));
2680 assert_param(IS_FDCAN_TT_REPEAT_FACTOR(sTriggerConfig->RepeatFactor));
2681 if (sTriggerConfig->RepeatFactor != FDCAN_TT_REPEAT_EVERY_CYCLE)
2682 {
2683 assert_param(IS_FDCAN_MAX_VALUE(sTriggerConfig->StartCycle, (sTriggerConfig->RepeatFactor - 1U)));
2684 }
2685 assert_param(IS_FDCAN_TT_TM_EVENT_INTERNAL(sTriggerConfig->TmEventInt));
2686 assert_param(IS_FDCAN_TT_TM_EVENT_EXTERNAL(sTriggerConfig->TmEventExt));
2687 assert_param(IS_FDCAN_TT_TRIGGER_TYPE(sTriggerConfig->TriggerType));
2688 assert_param(IS_FDCAN_ID_TYPE(sTriggerConfig->FilterType));
2689 if ((sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_SINGLE) ||
2690 (sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_CONTINUOUS) ||
2691 (sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_ARBITRATION) ||
2692 (sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_MERGED))
2693 {
2694 assert_param(IS_FDCAN_TX_LOCATION(sTriggerConfig->TxBufferIndex));
2695 }
2696 if (sTriggerConfig->TriggerType == FDCAN_TT_RX_TRIGGER)
2697 {
2698 if (sTriggerConfig->FilterType == FDCAN_STANDARD_ID)
2699 {
2700 assert_param(IS_FDCAN_MAX_VALUE(sTriggerConfig->FilterIndex, 63U));
2701 }
2702 else /* sTriggerConfig->FilterType == FDCAN_EXTENDED_ID */
2703 {
2704 assert_param(IS_FDCAN_MAX_VALUE(sTriggerConfig->FilterIndex, 127U));
2705 }
2706 }
2707
2708 if (hfdcan->State == HAL_FDCAN_STATE_READY)
2709 {
2710 /* Calculate cycle code */
2711 if (sTriggerConfig->RepeatFactor == FDCAN_TT_REPEAT_EVERY_CYCLE)
2712 {
2713 CycleCode = FDCAN_TT_REPEAT_EVERY_CYCLE;
2714 }
2715 else /* sTriggerConfig->RepeatFactor != FDCAN_TT_REPEAT_EVERY_CYCLE */
2716 {
2717 CycleCode = sTriggerConfig->RepeatFactor + sTriggerConfig->StartCycle;
2718 }
2719
2720 /* Build first word of trigger element */
2721 TriggerElementW1 = ((sTriggerConfig->TimeMark << 16) | \
2722 (CycleCode << 8) | \
2723 sTriggerConfig->TmEventInt | \
2724 sTriggerConfig->TmEventExt | \
2725 sTriggerConfig->TriggerType);
2726
2727 /* Select message number depending on trigger type (transmission or reception) */
2728 if (sTriggerConfig->TriggerType == FDCAN_TT_RX_TRIGGER)
2729 {
2730 MessageNumber = sTriggerConfig->FilterIndex;
2731 }
2732 else if ((sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_SINGLE) ||
2733 (sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_CONTINUOUS) ||
2734 (sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_ARBITRATION) ||
2735 (sTriggerConfig->TriggerType == FDCAN_TT_TX_TRIGGER_MERGED))
2736 {
2737 MessageNumber = POSITION_VAL(sTriggerConfig->TxBufferIndex);
2738 }
2739 else
2740 {
2741 MessageNumber = 0U;
2742 }
2743
2744 /* Build second word of trigger element */
2745 TriggerElementW2 = ((sTriggerConfig->FilterType >> 7) | (MessageNumber << 16));
2746
2747 /* Calculate trigger address */
2748 TriggerAddress = (uint32_t *)(hfdcan->msgRam.TTMemorySA + (sTriggerConfig->TriggerIndex * 4U * 2U));
2749
2750 /* Write trigger element to the message RAM */
2751 *TriggerAddress = TriggerElementW1;
2752 TriggerAddress++;
2753 *TriggerAddress = TriggerElementW2;
2754
2755 /* Return function status */
2756 return HAL_OK;
2757 }
2758 else
2759 {
2760 /* Update error code */
2761 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY;
2762
2763 return HAL_ERROR;
2764 }
2765 }
2766
2767 /**
2768 * @brief Schedule global time adjustment for the next reference message.
2769 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2770 * the configuration information for the specified FDCAN.
2771 * @param TimePreset time preset value.
2772 * This parameter must be a number between:
2773 * - 0x0000 and 0x7FFF, Next_Master_Ref_Mark = Current_Master_Ref_Mark + TimePreset
2774 * or
2775 * - 0x8001 and 0xFFFF, Next_Master_Ref_Mark = Current_Master_Ref_Mark - (0x10000 - TimePreset)
2776 * @retval HAL status
2777 */
HAL_FDCAN_TT_SetGlobalTime(FDCAN_HandleTypeDef * hfdcan,uint32_t TimePreset)2778 HAL_StatusTypeDef HAL_FDCAN_TT_SetGlobalTime(FDCAN_HandleTypeDef *hfdcan, uint32_t TimePreset)
2779 {
2780 uint32_t Counter = 0U;
2781 HAL_FDCAN_StateTypeDef state = hfdcan->State;
2782
2783 /* Check function parameters */
2784 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
2785 assert_param(IS_FDCAN_TT_TIME_PRESET(TimePreset));
2786
2787 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
2788 {
2789 /* Check that the external clock synchronization is enabled */
2790 if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_EECS) != FDCAN_TTOCF_EECS)
2791 {
2792 /* Update error code */
2793 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
2794
2795 return HAL_ERROR;
2796 }
2797
2798 /* Check that no global time preset is pending */
2799 if ((hfdcan->ttcan->TTOST & FDCAN_TTOST_WGTD) == FDCAN_TTOST_WGTD)
2800 {
2801 /* Update error code */
2802 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PENDING;
2803
2804 return HAL_ERROR;
2805 }
2806
2807 /* Configure time preset */
2808 MODIFY_REG(hfdcan->ttcan->TTGTP, FDCAN_TTGTP_TP, (TimePreset << FDCAN_TTGTP_TP_Pos));
2809
2810 /* Wait until the LCKC bit into TTOCN register is reset */
2811 while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
2812 {
2813 /* Check for the Timeout */
2814 if (Counter > FDCAN_TIMEOUT_VALUE)
2815 {
2816 /* Update error code */
2817 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
2818
2819 /* Change FDCAN state */
2820 hfdcan->State = HAL_FDCAN_STATE_ERROR;
2821
2822 return HAL_ERROR;
2823 }
2824
2825 /* Increment counter */
2826 Counter++;
2827 }
2828
2829 /* Schedule time preset to take effect by the next reference message */
2830 SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_SGT);
2831
2832 /* Return function status */
2833 return HAL_OK;
2834 }
2835 else
2836 {
2837 /* Update error code */
2838 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
2839
2840 return HAL_ERROR;
2841 }
2842 }
2843
2844 /**
2845 * @brief Schedule TUR numerator update for the next reference message.
2846 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2847 * the configuration information for the specified FDCAN.
2848 * @param NewTURNumerator new value of the TUR numerator.
2849 * This parameter must be a number between 0x10000 and 0x1FFFF.
2850 * @retval HAL status
2851 */
HAL_FDCAN_TT_SetClockSynchronization(FDCAN_HandleTypeDef * hfdcan,uint32_t NewTURNumerator)2852 HAL_StatusTypeDef HAL_FDCAN_TT_SetClockSynchronization(FDCAN_HandleTypeDef *hfdcan, uint32_t NewTURNumerator)
2853 {
2854 uint32_t Counter = 0U;
2855 HAL_FDCAN_StateTypeDef state = hfdcan->State;
2856
2857 /* Check function parameters */
2858 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
2859 assert_param(IS_FDCAN_TT_TUR_NUMERATOR(NewTURNumerator));
2860
2861 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
2862 {
2863 /* Check that the external clock synchronization is enabled */
2864 if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_EECS) != FDCAN_TTOCF_EECS)
2865 {
2866 /* Update error code */
2867 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
2868
2869 return HAL_ERROR;
2870 }
2871
2872 /* Check that no external clock synchronization is pending */
2873 if ((hfdcan->ttcan->TTOST & FDCAN_TTOST_WECS) == FDCAN_TTOST_WECS)
2874 {
2875 /* Update error code */
2876 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PENDING;
2877
2878 return HAL_ERROR;
2879 }
2880
2881 /* Configure new TUR numerator */
2882 MODIFY_REG(hfdcan->ttcan->TURCF, FDCAN_TURCF_NCL, (NewTURNumerator - 0x10000U));
2883
2884 /* Wait until the LCKC bit into TTOCN register is reset */
2885 while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
2886 {
2887 /* Check for the Timeout */
2888 if (Counter > FDCAN_TIMEOUT_VALUE)
2889 {
2890 /* Update error code */
2891 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
2892
2893 /* Change FDCAN state */
2894 hfdcan->State = HAL_FDCAN_STATE_ERROR;
2895
2896 return HAL_ERROR;
2897 }
2898
2899 /* Increment counter */
2900 Counter++;
2901 }
2902
2903 /* Schedule TUR numerator update by the next reference message */
2904 SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_ECS);
2905
2906 /* Return function status */
2907 return HAL_OK;
2908 }
2909 else
2910 {
2911 /* Update error code */
2912 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
2913
2914 return HAL_ERROR;
2915 }
2916 }
2917
2918 /**
2919 * @brief Configure stop watch source and polarity.
2920 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2921 * the configuration information for the specified FDCAN.
2922 * @param Source stop watch source.
2923 * This parameter can be a value of @arg FDCAN_TT_stop_watch_source.
2924 * @param Polarity stop watch polarity.
2925 * This parameter can be a value of @arg FDCAN_TT_stop_watch_polarity.
2926 * @retval HAL status
2927 */
HAL_FDCAN_TT_ConfigStopWatch(FDCAN_HandleTypeDef * hfdcan,uint32_t Source,uint32_t Polarity)2928 HAL_StatusTypeDef HAL_FDCAN_TT_ConfigStopWatch(FDCAN_HandleTypeDef *hfdcan, uint32_t Source, uint32_t Polarity)
2929 {
2930 uint32_t Counter = 0U;
2931 HAL_FDCAN_StateTypeDef state = hfdcan->State;
2932
2933 /* Check function parameters */
2934 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
2935 assert_param(IS_FDCAN_TT_STOP_WATCH_SOURCE(Source));
2936 assert_param(IS_FDCAN_TT_STOP_WATCH_POLARITY(Polarity));
2937
2938 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
2939 {
2940 /* Wait until the LCKC bit into TTOCN register is reset */
2941 while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
2942 {
2943 /* Check for the Timeout */
2944 if (Counter > FDCAN_TIMEOUT_VALUE)
2945 {
2946 /* Update error code */
2947 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
2948
2949 /* Change FDCAN state */
2950 hfdcan->State = HAL_FDCAN_STATE_ERROR;
2951
2952 return HAL_ERROR;
2953 }
2954
2955 /* Increment counter */
2956 Counter++;
2957 }
2958
2959 /* Select stop watch source and polarity */
2960 MODIFY_REG(hfdcan->ttcan->TTOCN, (FDCAN_TTOCN_SWS | FDCAN_TTOCN_SWP), (Source | Polarity));
2961
2962 /* Return function status */
2963 return HAL_OK;
2964 }
2965 else
2966 {
2967 /* Update error code */
2968 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
2969
2970 return HAL_ERROR;
2971 }
2972 }
2973
2974 /**
2975 * @brief Configure register time mark pulse generation.
2976 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
2977 * the configuration information for the specified FDCAN.
2978 * @param TimeMarkSource time mark source.
2979 * This parameter can be a value of @arg FDCAN_TT_time_mark_source.
2980 * @param TimeMarkValue time mark value (reference).
2981 * This parameter must be a number between 0 and 0xFFFF.
2982 * @param RepeatFactor repeat factor of the cycle for which the time mark is valid.
2983 * This parameter can be a value of @arg FDCAN_TT_Repeat_Factor.
2984 * @param StartCycle index of the first cycle in which the time mark becomes valid.
2985 * This parameter is ignored if RepeatFactor is set to FDCAN_TT_REPEAT_EVERY_CYCLE.
2986 * This parameter must be a number between 0 and RepeatFactor.
2987 * @retval HAL status
2988 */
HAL_FDCAN_TT_ConfigRegisterTimeMark(FDCAN_HandleTypeDef * hfdcan,uint32_t TimeMarkSource,uint32_t TimeMarkValue,uint32_t RepeatFactor,uint32_t StartCycle)2989 HAL_StatusTypeDef HAL_FDCAN_TT_ConfigRegisterTimeMark(FDCAN_HandleTypeDef *hfdcan,
2990 uint32_t TimeMarkSource, uint32_t TimeMarkValue,
2991 uint32_t RepeatFactor, uint32_t StartCycle)
2992 {
2993 uint32_t Counter = 0U;
2994 uint32_t CycleCode;
2995 HAL_FDCAN_StateTypeDef state = hfdcan->State;
2996
2997 /* Check function parameters */
2998 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
2999 assert_param(IS_FDCAN_TT_REGISTER_TIME_MARK_SOURCE(TimeMarkSource));
3000 assert_param(IS_FDCAN_MAX_VALUE(TimeMarkValue, 0xFFFFU));
3001 assert_param(IS_FDCAN_TT_REPEAT_FACTOR(RepeatFactor));
3002 if (RepeatFactor != FDCAN_TT_REPEAT_EVERY_CYCLE)
3003 {
3004 assert_param(IS_FDCAN_MAX_VALUE(StartCycle, (RepeatFactor - 1U)));
3005 }
3006
3007 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3008 {
3009 /* Wait until the LCKC bit into TTOCN register is reset */
3010 while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
3011 {
3012 /* Check for the Timeout */
3013 if (Counter > FDCAN_TIMEOUT_VALUE)
3014 {
3015 /* Update error code */
3016 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3017
3018 /* Change FDCAN state */
3019 hfdcan->State = HAL_FDCAN_STATE_ERROR;
3020
3021 return HAL_ERROR;
3022 }
3023
3024 /* Increment counter */
3025 Counter++;
3026 }
3027
3028 /* Disable the time mark compare function */
3029 CLEAR_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_TMC);
3030
3031 if (TimeMarkSource != FDCAN_TT_REG_TIMEMARK_DIABLED)
3032 {
3033 /* Calculate cycle code */
3034 if (RepeatFactor == FDCAN_TT_REPEAT_EVERY_CYCLE)
3035 {
3036 CycleCode = FDCAN_TT_REPEAT_EVERY_CYCLE;
3037 }
3038 else /* RepeatFactor != FDCAN_TT_REPEAT_EVERY_CYCLE */
3039 {
3040 CycleCode = RepeatFactor + StartCycle;
3041 }
3042
3043 Counter = 0U;
3044
3045 /* Wait until the LCKM bit into TTTMK register is reset */
3046 while ((hfdcan->ttcan->TTTMK & FDCAN_TTTMK_LCKM) != 0U)
3047 {
3048 /* Check for the Timeout */
3049 if (Counter > FDCAN_TIMEOUT_VALUE)
3050 {
3051 /* Update error code */
3052 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3053
3054 /* Change FDCAN state */
3055 hfdcan->State = HAL_FDCAN_STATE_ERROR;
3056
3057 return HAL_ERROR;
3058 }
3059
3060 /* Increment counter */
3061 Counter++;
3062 }
3063
3064 /* Configure time mark value and cycle code */
3065 hfdcan->ttcan->TTTMK = ((TimeMarkValue << FDCAN_TTTMK_TM_Pos) | (CycleCode << FDCAN_TTTMK_TICC_Pos));
3066
3067 Counter = 0U;
3068
3069 /* Wait until the LCKC bit into TTOCN register is reset */
3070 while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
3071 {
3072 /* Check for the Timeout */
3073 if (Counter > FDCAN_TIMEOUT_VALUE)
3074 {
3075 /* Update error code */
3076 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3077
3078 /* Change FDCAN state */
3079 hfdcan->State = HAL_FDCAN_STATE_ERROR;
3080
3081 return HAL_ERROR;
3082 }
3083
3084 /* Increment counter */
3085 Counter++;
3086 }
3087
3088 /* Update the register time mark compare source */
3089 MODIFY_REG(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_TMC, TimeMarkSource);
3090 }
3091
3092 /* Return function status */
3093 return HAL_OK;
3094 }
3095 else
3096 {
3097 /* Update error code */
3098 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3099
3100 return HAL_ERROR;
3101 }
3102 }
3103
3104 /**
3105 * @brief Enable register time mark pulse generation.
3106 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3107 * the configuration information for the specified FDCAN.
3108 * @retval HAL status
3109 */
HAL_FDCAN_TT_EnableRegisterTimeMarkPulse(FDCAN_HandleTypeDef * hfdcan)3110 HAL_StatusTypeDef HAL_FDCAN_TT_EnableRegisterTimeMarkPulse(FDCAN_HandleTypeDef *hfdcan)
3111 {
3112 uint32_t Counter = 0U;
3113 HAL_FDCAN_StateTypeDef state = hfdcan->State;
3114
3115 /* Check function parameters */
3116 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3117
3118 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3119 {
3120 /* Wait until the LCKC bit into TTOCN register is reset */
3121 while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
3122 {
3123 /* Check for the Timeout */
3124 if (Counter > FDCAN_TIMEOUT_VALUE)
3125 {
3126 /* Update error code */
3127 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3128
3129 /* Change FDCAN state */
3130 hfdcan->State = HAL_FDCAN_STATE_ERROR;
3131
3132 return HAL_ERROR;
3133 }
3134
3135 /* Increment counter */
3136 Counter++;
3137 }
3138
3139 /* Enable Register Time Mark Interrupt output on fdcan1_rtp */
3140 SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_RTIE);
3141
3142 /* Return function status */
3143 return HAL_OK;
3144 }
3145 else
3146 {
3147 /* Update error code */
3148 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3149
3150 return HAL_ERROR;
3151 }
3152 }
3153
3154 /**
3155 * @brief Disable register time mark pulse generation.
3156 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3157 * the configuration information for the specified FDCAN.
3158 * @retval HAL status
3159 */
HAL_FDCAN_TT_DisableRegisterTimeMarkPulse(FDCAN_HandleTypeDef * hfdcan)3160 HAL_StatusTypeDef HAL_FDCAN_TT_DisableRegisterTimeMarkPulse(FDCAN_HandleTypeDef *hfdcan)
3161 {
3162 uint32_t Counter = 0U;
3163 HAL_FDCAN_StateTypeDef state = hfdcan->State;
3164
3165 /* Check function parameters */
3166 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3167
3168 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3169 {
3170 /* Wait until the LCKC bit into TTOCN register is reset */
3171 while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
3172 {
3173 /* Check for the Timeout */
3174 if (Counter > FDCAN_TIMEOUT_VALUE)
3175 {
3176 /* Update error code */
3177 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3178
3179 /* Change FDCAN state */
3180 hfdcan->State = HAL_FDCAN_STATE_ERROR;
3181
3182 return HAL_ERROR;
3183 }
3184
3185 /* Increment counter */
3186 Counter++;
3187 }
3188
3189 /* Disable Register Time Mark Interrupt output on fdcan1_rtp */
3190 CLEAR_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_RTIE);
3191
3192 /* Return function status */
3193 return HAL_OK;
3194 }
3195 else
3196 {
3197 /* Update error code */
3198 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3199
3200 return HAL_ERROR;
3201 }
3202 }
3203
3204 /**
3205 * @brief Enable trigger time mark pulse generation.
3206 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3207 * the configuration information for the specified FDCAN.
3208 * @retval HAL status
3209 */
HAL_FDCAN_TT_EnableTriggerTimeMarkPulse(FDCAN_HandleTypeDef * hfdcan)3210 HAL_StatusTypeDef HAL_FDCAN_TT_EnableTriggerTimeMarkPulse(FDCAN_HandleTypeDef *hfdcan)
3211 {
3212 uint32_t Counter = 0U;
3213 HAL_FDCAN_StateTypeDef state = hfdcan->State;
3214
3215 /* Check function parameters */
3216 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3217
3218 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3219 {
3220 if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
3221 {
3222 /* Wait until the LCKC bit into TTOCN register is reset */
3223 while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
3224 {
3225 /* Check for the Timeout */
3226 if (Counter > FDCAN_TIMEOUT_VALUE)
3227 {
3228 /* Update error code */
3229 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3230
3231 /* Change FDCAN state */
3232 hfdcan->State = HAL_FDCAN_STATE_ERROR;
3233
3234 return HAL_ERROR;
3235 }
3236
3237 /* Increment counter */
3238 Counter++;
3239 }
3240
3241 /* Enable Trigger Time Mark Interrupt output on fdcan1_tmp */
3242 SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_TTIE);
3243
3244 /* Return function status */
3245 return HAL_OK;
3246 }
3247 else
3248 {
3249 /* Update error code.
3250 Feature not supported for TT Level 0 */
3251 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
3252
3253 return HAL_ERROR;
3254 }
3255 }
3256 else
3257 {
3258 /* Update error code */
3259 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3260
3261 return HAL_ERROR;
3262 }
3263 }
3264
3265 /**
3266 * @brief Disable trigger time mark pulse generation.
3267 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3268 * the configuration information for the specified FDCAN.
3269 * @retval HAL status
3270 */
HAL_FDCAN_TT_DisableTriggerTimeMarkPulse(FDCAN_HandleTypeDef * hfdcan)3271 HAL_StatusTypeDef HAL_FDCAN_TT_DisableTriggerTimeMarkPulse(FDCAN_HandleTypeDef *hfdcan)
3272 {
3273 uint32_t Counter = 0U;
3274 HAL_FDCAN_StateTypeDef state = hfdcan->State;
3275
3276 /* Check function parameters */
3277 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3278
3279 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3280 {
3281 if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
3282 {
3283 /* Wait until the LCKC bit into TTOCN register is reset */
3284 while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
3285 {
3286 /* Check for the Timeout */
3287 if (Counter > FDCAN_TIMEOUT_VALUE)
3288 {
3289 /* Update error code */
3290 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3291
3292 /* Change FDCAN state */
3293 hfdcan->State = HAL_FDCAN_STATE_ERROR;
3294
3295 return HAL_ERROR;
3296 }
3297
3298 /* Increment counter */
3299 Counter++;
3300 }
3301
3302 /* Disable Trigger Time Mark Interrupt output on fdcan1_rtp */
3303 CLEAR_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_TTIE);
3304
3305 /* Return function status */
3306 return HAL_OK;
3307 }
3308 else
3309 {
3310 /* Update error code.
3311 Feature not supported for TT Level 0 */
3312 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
3313
3314 return HAL_ERROR;
3315 }
3316 }
3317 else
3318 {
3319 /* Update error code */
3320 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3321
3322 return HAL_ERROR;
3323 }
3324 }
3325
3326 /**
3327 * @brief Enable gap control by input pin fdcan1_evt.
3328 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3329 * the configuration information for the specified FDCAN.
3330 * @retval HAL status
3331 */
HAL_FDCAN_TT_EnableHardwareGapControl(FDCAN_HandleTypeDef * hfdcan)3332 HAL_StatusTypeDef HAL_FDCAN_TT_EnableHardwareGapControl(FDCAN_HandleTypeDef *hfdcan)
3333 {
3334 uint32_t Counter = 0U;
3335 HAL_FDCAN_StateTypeDef state = hfdcan->State;
3336
3337 /* Check function parameters */
3338 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3339
3340 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3341 {
3342 if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
3343 {
3344 /* Wait until the LCKC bit into TTOCN register is reset */
3345 while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
3346 {
3347 /* Check for the Timeout */
3348 if (Counter > FDCAN_TIMEOUT_VALUE)
3349 {
3350 /* Update error code */
3351 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3352
3353 /* Change FDCAN state */
3354 hfdcan->State = HAL_FDCAN_STATE_ERROR;
3355
3356 return HAL_ERROR;
3357 }
3358
3359 /* Increment counter */
3360 Counter++;
3361 }
3362
3363 /* Enable gap control by pin fdcan1_evt */
3364 SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_GCS);
3365
3366 /* Return function status */
3367 return HAL_OK;
3368 }
3369 else
3370 {
3371 /* Update error code.
3372 Feature not supported for TT Level 0 */
3373 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
3374
3375 return HAL_ERROR;
3376 }
3377 }
3378 else
3379 {
3380 /* Update error code */
3381 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3382
3383 return HAL_ERROR;
3384 }
3385 }
3386
3387 /**
3388 * @brief Disable gap control by input pin fdcan1_evt.
3389 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3390 * the configuration information for the specified FDCAN.
3391 * @retval HAL status
3392 */
HAL_FDCAN_TT_DisableHardwareGapControl(FDCAN_HandleTypeDef * hfdcan)3393 HAL_StatusTypeDef HAL_FDCAN_TT_DisableHardwareGapControl(FDCAN_HandleTypeDef *hfdcan)
3394 {
3395 uint32_t Counter = 0U;
3396 HAL_FDCAN_StateTypeDef state = hfdcan->State;
3397
3398 /* Check function parameters */
3399 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3400
3401 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3402 {
3403 if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
3404 {
3405 /* Wait until the LCKC bit into TTOCN register is reset */
3406 while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
3407 {
3408 /* Check for the Timeout */
3409 if (Counter > FDCAN_TIMEOUT_VALUE)
3410 {
3411 /* Update error code */
3412 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3413
3414 /* Change FDCAN state */
3415 hfdcan->State = HAL_FDCAN_STATE_ERROR;
3416
3417 return HAL_ERROR;
3418 }
3419
3420 /* Increment counter */
3421 Counter++;
3422 }
3423
3424 /* Disable gap control by pin fdcan1_evt */
3425 CLEAR_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_GCS);
3426
3427 /* Return function status */
3428 return HAL_OK;
3429 }
3430 else
3431 {
3432 /* Update error code.
3433 Feature not supported for TT Level 0 */
3434 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
3435
3436 return HAL_ERROR;
3437 }
3438 }
3439 else
3440 {
3441 /* Update error code */
3442 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3443
3444 return HAL_ERROR;
3445 }
3446 }
3447
3448 /**
3449 * @brief Enable gap control (finish only) by register time mark interrupt.
3450 * The next register time mark interrupt (TTIR.RTMI = "1") will finish
3451 * the Gap and start the reference message.
3452 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3453 * the configuration information for the specified FDCAN.
3454 * @retval HAL status
3455 */
HAL_FDCAN_TT_EnableTimeMarkGapControl(FDCAN_HandleTypeDef * hfdcan)3456 HAL_StatusTypeDef HAL_FDCAN_TT_EnableTimeMarkGapControl(FDCAN_HandleTypeDef *hfdcan)
3457 {
3458 uint32_t Counter = 0U;
3459 HAL_FDCAN_StateTypeDef state = hfdcan->State;
3460
3461 /* Check function parameters */
3462 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3463
3464 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3465 {
3466 if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
3467 {
3468 /* Wait until the LCKC bit into TTOCN register is reset */
3469 while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
3470 {
3471 /* Check for the Timeout */
3472 if (Counter > FDCAN_TIMEOUT_VALUE)
3473 {
3474 /* Update error code */
3475 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3476
3477 /* Change FDCAN state */
3478 hfdcan->State = HAL_FDCAN_STATE_ERROR;
3479
3480 return HAL_ERROR;
3481 }
3482
3483 /* Increment counter */
3484 Counter++;
3485 }
3486
3487 /* Enable gap control by register time mark interrupt */
3488 SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_TMG);
3489
3490 /* Return function status */
3491 return HAL_OK;
3492 }
3493 else
3494 {
3495 /* Update error code.
3496 Feature not supported for TT Level 0 */
3497 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
3498
3499 return HAL_ERROR;
3500 }
3501 }
3502 else
3503 {
3504 /* Update error code */
3505 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3506
3507 return HAL_ERROR;
3508 }
3509 }
3510
3511 /**
3512 * @brief Disable gap control by register time mark interrupt.
3513 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3514 * the configuration information for the specified FDCAN.
3515 * @retval HAL status
3516 */
HAL_FDCAN_TT_DisableTimeMarkGapControl(FDCAN_HandleTypeDef * hfdcan)3517 HAL_StatusTypeDef HAL_FDCAN_TT_DisableTimeMarkGapControl(FDCAN_HandleTypeDef *hfdcan)
3518 {
3519 uint32_t Counter = 0U;
3520 HAL_FDCAN_StateTypeDef state = hfdcan->State;
3521
3522 /* Check function parameters */
3523 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3524
3525 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3526 {
3527 if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
3528 {
3529 /* Wait until the LCKC bit into TTOCN register is reset */
3530 while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
3531 {
3532 /* Check for the Timeout */
3533 if (Counter > FDCAN_TIMEOUT_VALUE)
3534 {
3535 /* Update error code */
3536 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3537
3538 /* Change FDCAN state */
3539 hfdcan->State = HAL_FDCAN_STATE_ERROR;
3540
3541 return HAL_ERROR;
3542 }
3543
3544 /* Increment counter */
3545 Counter++;
3546 }
3547
3548 /* Disable gap control by register time mark interrupt */
3549 CLEAR_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_TMG);
3550
3551 /* Return function status */
3552 return HAL_OK;
3553 }
3554 else
3555 {
3556 /* Update error code.
3557 Feature not supported for TT Level 0 */
3558 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
3559
3560 return HAL_ERROR;
3561 }
3562 }
3563 else
3564 {
3565 /* Update error code */
3566 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3567
3568 return HAL_ERROR;
3569 }
3570 }
3571
3572 /**
3573 * @brief Transmit next reference message with Next_is_Gap = "1".
3574 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3575 * the configuration information for the specified FDCAN.
3576 * @retval HAL status
3577 */
HAL_FDCAN_TT_SetNextIsGap(FDCAN_HandleTypeDef * hfdcan)3578 HAL_StatusTypeDef HAL_FDCAN_TT_SetNextIsGap(FDCAN_HandleTypeDef *hfdcan)
3579 {
3580 uint32_t Counter = 0U;
3581 HAL_FDCAN_StateTypeDef state = hfdcan->State;
3582
3583 /* Check function parameters */
3584 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3585
3586 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3587 {
3588 /* Check that the node is configured for external event-synchronized TT operation */
3589 if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_GEN) != FDCAN_TTOCF_GEN)
3590 {
3591 /* Update error code */
3592 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
3593
3594 return HAL_ERROR;
3595 }
3596
3597 if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
3598 {
3599 /* Wait until the LCKC bit into TTOCN register is reset */
3600 while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
3601 {
3602 /* Check for the Timeout */
3603 if (Counter > FDCAN_TIMEOUT_VALUE)
3604 {
3605 /* Update error code */
3606 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3607
3608 /* Change FDCAN state */
3609 hfdcan->State = HAL_FDCAN_STATE_ERROR;
3610
3611 return HAL_ERROR;
3612 }
3613
3614 /* Increment counter */
3615 Counter++;
3616 }
3617
3618 /* Set Next is Gap */
3619 SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_NIG);
3620
3621 /* Return function status */
3622 return HAL_OK;
3623 }
3624 else
3625 {
3626 /* Update error code.
3627 Feature not supported for TT Level 0 */
3628 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
3629
3630 return HAL_ERROR;
3631 }
3632 }
3633 else
3634 {
3635 /* Update error code */
3636 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3637
3638 return HAL_ERROR;
3639 }
3640 }
3641
3642 /**
3643 * @brief Finish a Gap by requesting start of reference message.
3644 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3645 * the configuration information for the specified FDCAN.
3646 * @retval HAL status
3647 */
HAL_FDCAN_TT_SetEndOfGap(FDCAN_HandleTypeDef * hfdcan)3648 HAL_StatusTypeDef HAL_FDCAN_TT_SetEndOfGap(FDCAN_HandleTypeDef *hfdcan)
3649 {
3650 uint32_t Counter = 0U;
3651 HAL_FDCAN_StateTypeDef state = hfdcan->State;
3652
3653 /* Check function parameters */
3654 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3655
3656 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3657 {
3658 /* Check that the node is configured for external event-synchronized TT operation */
3659 if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_GEN) != FDCAN_TTOCF_GEN)
3660 {
3661 /* Update error code */
3662 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
3663
3664 return HAL_ERROR;
3665 }
3666
3667 if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != FDCAN_TT_COMMUNICATION_LEVEL0)
3668 {
3669 /* Wait until the LCKC bit into TTOCN register is reset */
3670 while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
3671 {
3672 /* Check for the Timeout */
3673 if (Counter > FDCAN_TIMEOUT_VALUE)
3674 {
3675 /* Update error code */
3676 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3677
3678 /* Change FDCAN state */
3679 hfdcan->State = HAL_FDCAN_STATE_ERROR;
3680
3681 return HAL_ERROR;
3682 }
3683
3684 /* Increment counter */
3685 Counter++;
3686 }
3687
3688 /* Set Finish Gap */
3689 SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_FGP);
3690
3691 /* Return function status */
3692 return HAL_OK;
3693 }
3694 else
3695 {
3696 /* Update error code.
3697 Feature not supported for TT Level 0 */
3698 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED;
3699
3700 return HAL_ERROR;
3701 }
3702 }
3703 else
3704 {
3705 /* Update error code */
3706 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3707
3708 return HAL_ERROR;
3709 }
3710 }
3711
3712 /**
3713 * @brief Configure target phase used for external synchronization by event
3714 * trigger input pin fdcan1_evt.
3715 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3716 * the configuration information for the specified FDCAN.
3717 * @param TargetPhase defines target value of cycle time when a rising edge
3718 * of fdcan1_evt is expected.
3719 * This parameter must be a number between 0 and 0xFFFF.
3720 * @retval HAL status
3721 */
HAL_FDCAN_TT_ConfigExternalSyncPhase(FDCAN_HandleTypeDef * hfdcan,uint32_t TargetPhase)3722 HAL_StatusTypeDef HAL_FDCAN_TT_ConfigExternalSyncPhase(FDCAN_HandleTypeDef *hfdcan, uint32_t TargetPhase)
3723 {
3724 HAL_FDCAN_StateTypeDef state = hfdcan->State;
3725
3726 /* Check function parameters */
3727 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3728 assert_param(IS_FDCAN_MAX_VALUE(TargetPhase, 0xFFFFU));
3729
3730 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3731 {
3732 /* Check that no external schedule synchronization is pending */
3733 if ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_ESCN) == FDCAN_TTOCN_ESCN)
3734 {
3735 /* Update error code */
3736 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PENDING;
3737
3738 return HAL_ERROR;
3739 }
3740
3741 /* Configure cycle time target phase */
3742 MODIFY_REG(hfdcan->ttcan->TTGTP, FDCAN_TTGTP_CTP, (TargetPhase << FDCAN_TTGTP_CTP_Pos));
3743
3744 /* Return function status */
3745 return HAL_OK;
3746 }
3747 else
3748 {
3749 /* Update error code */
3750 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3751
3752 return HAL_ERROR;
3753 }
3754 }
3755
3756 /**
3757 * @brief Synchronize the phase of the FDCAN schedule to an external schedule
3758 * using event trigger input pin fdcan1_evt.
3759 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3760 * the configuration information for the specified FDCAN.
3761 * @retval HAL status
3762 */
HAL_FDCAN_TT_EnableExternalSynchronization(FDCAN_HandleTypeDef * hfdcan)3763 HAL_StatusTypeDef HAL_FDCAN_TT_EnableExternalSynchronization(FDCAN_HandleTypeDef *hfdcan)
3764 {
3765 uint32_t Counter = 0U;
3766 HAL_FDCAN_StateTypeDef state = hfdcan->State;
3767
3768 /* Check function parameters */
3769 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3770
3771 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3772 {
3773 /* Wait until the LCKC bit into TTOCN register is reset */
3774 while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
3775 {
3776 /* Check for the Timeout */
3777 if (Counter > FDCAN_TIMEOUT_VALUE)
3778 {
3779 /* Update error code */
3780 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3781
3782 /* Change FDCAN state */
3783 hfdcan->State = HAL_FDCAN_STATE_ERROR;
3784
3785 return HAL_ERROR;
3786 }
3787
3788 /* Increment counter */
3789 Counter++;
3790 }
3791
3792 /* Enable external synchronization */
3793 SET_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_ESCN);
3794
3795 /* Return function status */
3796 return HAL_OK;
3797 }
3798 else
3799 {
3800 /* Update error code */
3801 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3802
3803 return HAL_ERROR;
3804 }
3805 }
3806
3807 /**
3808 * @brief Disable external schedule synchronization.
3809 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3810 * the configuration information for the specified FDCAN.
3811 * @retval HAL status
3812 */
HAL_FDCAN_TT_DisableExternalSynchronization(FDCAN_HandleTypeDef * hfdcan)3813 HAL_StatusTypeDef HAL_FDCAN_TT_DisableExternalSynchronization(FDCAN_HandleTypeDef *hfdcan)
3814 {
3815 uint32_t Counter = 0U;
3816 HAL_FDCAN_StateTypeDef state = hfdcan->State;
3817
3818 /* Check function parameters */
3819 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3820
3821 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3822 {
3823 /* Wait until the LCKC bit into TTOCN register is reset */
3824 while ((hfdcan->ttcan->TTOCN & FDCAN_TTOCN_LCKC) != 0U)
3825 {
3826 /* Check for the Timeout */
3827 if (Counter > FDCAN_TIMEOUT_VALUE)
3828 {
3829 /* Update error code */
3830 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT;
3831
3832 /* Change FDCAN state */
3833 hfdcan->State = HAL_FDCAN_STATE_ERROR;
3834
3835 return HAL_ERROR;
3836 }
3837
3838 /* Increment counter */
3839 Counter++;
3840 }
3841
3842 /* Disable external synchronization */
3843 CLEAR_BIT(hfdcan->ttcan->TTOCN, FDCAN_TTOCN_ESCN);
3844
3845 /* Return function status */
3846 return HAL_OK;
3847 }
3848 else
3849 {
3850 /* Update error code */
3851 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3852
3853 return HAL_ERROR;
3854 }
3855 }
3856
3857 /**
3858 * @brief Get TT operation status.
3859 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3860 * the configuration information for the specified FDCAN.
3861 * @param TTOpStatus pointer to an FDCAN_TTOperationStatusTypeDef structure.
3862 * @retval HAL status
3863 */
HAL_FDCAN_TT_GetOperationStatus(FDCAN_HandleTypeDef * hfdcan,FDCAN_TTOperationStatusTypeDef * TTOpStatus)3864 HAL_StatusTypeDef HAL_FDCAN_TT_GetOperationStatus(FDCAN_HandleTypeDef *hfdcan, FDCAN_TTOperationStatusTypeDef *TTOpStatus)
3865 {
3866 uint32_t TTStatusReg;
3867
3868 /* Check function parameters */
3869 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3870
3871 /* Read the TT operation status register */
3872 TTStatusReg = READ_REG(hfdcan->ttcan->TTOST);
3873
3874 /* Fill the TT operation status structure */
3875 TTOpStatus->ErrorLevel = (TTStatusReg & FDCAN_TTOST_EL);
3876 TTOpStatus->MasterState = (TTStatusReg & FDCAN_TTOST_MS);
3877 TTOpStatus->SyncState = (TTStatusReg & FDCAN_TTOST_SYS);
3878 TTOpStatus->GTimeQuality = ((TTStatusReg & FDCAN_TTOST_QGTP) >> FDCAN_TTOST_QGTP_Pos);
3879 TTOpStatus->ClockQuality = ((TTStatusReg & FDCAN_TTOST_QCS) >> FDCAN_TTOST_QCS_Pos);
3880 TTOpStatus->RefTrigOffset = ((TTStatusReg & FDCAN_TTOST_RTO) >> FDCAN_TTOST_RTO_Pos);
3881 TTOpStatus->GTimeDiscPending = ((TTStatusReg & FDCAN_TTOST_WGTD) >> FDCAN_TTOST_WGTD_Pos);
3882 TTOpStatus->GapFinished = ((TTStatusReg & FDCAN_TTOST_GFI) >> FDCAN_TTOST_GFI_Pos);
3883 TTOpStatus->MasterPriority = ((TTStatusReg & FDCAN_TTOST_TMP) >> FDCAN_TTOST_TMP_Pos);
3884 TTOpStatus->GapStarted = ((TTStatusReg & FDCAN_TTOST_GSI) >> FDCAN_TTOST_GSI_Pos);
3885 TTOpStatus->WaitForEvt = ((TTStatusReg & FDCAN_TTOST_WFE) >> FDCAN_TTOST_WFE_Pos);
3886 TTOpStatus->AppWdgEvt = ((TTStatusReg & FDCAN_TTOST_AWE) >> FDCAN_TTOST_AWE_Pos);
3887 TTOpStatus->ECSPending = ((TTStatusReg & FDCAN_TTOST_WECS) >> FDCAN_TTOST_WECS_Pos);
3888 TTOpStatus->PhaseLock = ((TTStatusReg & FDCAN_TTOST_SPL) >> FDCAN_TTOST_SPL_Pos);
3889
3890 /* Return function status */
3891 return HAL_OK;
3892 }
3893
3894 /**
3895 * @}
3896 */
3897
3898 /** @defgroup FDCAN_Exported_Functions_Group5 Interrupts management
3899 * @brief Interrupts management
3900 *
3901 @verbatim
3902 ==============================================================================
3903 ##### Interrupts management #####
3904 ==============================================================================
3905 [..] This section provides functions allowing to:
3906 (+) HAL_FDCAN_ConfigInterruptLines : Assign interrupts to either Interrupt line 0 or 1
3907 (+) HAL_FDCAN_TT_ConfigInterruptLines : Assign TT interrupts to either Interrupt line 0 or 1
3908 (+) HAL_FDCAN_ActivateNotification : Enable interrupts
3909 (+) HAL_FDCAN_DeactivateNotification : Disable interrupts
3910 (+) HAL_FDCAN_TT_ActivateNotification : Enable TT interrupts
3911 (+) HAL_FDCAN_TT_DeactivateNotification : Disable TT interrupts
3912 (+) HAL_FDCAN_IRQHandler : Handles FDCAN interrupt request
3913
3914 @endverbatim
3915 * @{
3916 */
3917
3918 /**
3919 * @brief Assign interrupts to either Interrupt line 0 or 1.
3920 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3921 * the configuration information for the specified FDCAN.
3922 * @param ITList indicates which interrupts will be assigned to the selected interrupt line.
3923 * This parameter can be any combination of @arg FDCAN_Interrupts.
3924 * @param InterruptLine Interrupt line.
3925 * This parameter can be a value of @arg FDCAN_Interrupt_Line.
3926 * @retval HAL status
3927 */
HAL_FDCAN_ConfigInterruptLines(FDCAN_HandleTypeDef * hfdcan,uint32_t ITList,uint32_t InterruptLine)3928 HAL_StatusTypeDef HAL_FDCAN_ConfigInterruptLines(FDCAN_HandleTypeDef *hfdcan, uint32_t ITList, uint32_t InterruptLine)
3929 {
3930 HAL_FDCAN_StateTypeDef state = hfdcan->State;
3931
3932 /* Check function parameters */
3933 assert_param(IS_FDCAN_IT(ITList));
3934 assert_param(IS_FDCAN_IT_LINE(InterruptLine));
3935
3936 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3937 {
3938 /* Assign list of interrupts to the selected line */
3939 if (InterruptLine == FDCAN_INTERRUPT_LINE0)
3940 {
3941 CLEAR_BIT(hfdcan->Instance->ILS, ITList);
3942 }
3943 else /* InterruptLine == FDCAN_INTERRUPT_LINE1 */
3944 {
3945 SET_BIT(hfdcan->Instance->ILS, ITList);
3946 }
3947
3948 /* Return function status */
3949 return HAL_OK;
3950 }
3951 else
3952 {
3953 /* Update error code */
3954 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3955
3956 return HAL_ERROR;
3957 }
3958 }
3959
3960 /**
3961 * @brief Assign TT interrupts to either Interrupt line 0 or 1.
3962 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
3963 * the configuration information for the specified FDCAN.
3964 * @param TTITList indicates which interrupts will be assigned to the selected interrupt line.
3965 * This parameter can be any combination of @arg FDCAN_TTInterrupts.
3966 * @param InterruptLine Interrupt line.
3967 * This parameter can be a value of @arg FDCAN_Interrupt_Line.
3968 * @retval HAL status
3969 */
HAL_FDCAN_TT_ConfigInterruptLines(FDCAN_HandleTypeDef * hfdcan,uint32_t TTITList,uint32_t InterruptLine)3970 HAL_StatusTypeDef HAL_FDCAN_TT_ConfigInterruptLines(FDCAN_HandleTypeDef *hfdcan, uint32_t TTITList, uint32_t InterruptLine)
3971 {
3972 HAL_FDCAN_StateTypeDef state = hfdcan->State;
3973
3974 /* Check function parameters */
3975 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
3976 assert_param(IS_FDCAN_TT_IT(TTITList));
3977 assert_param(IS_FDCAN_IT_LINE(InterruptLine));
3978
3979 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
3980 {
3981 /* Assign list of interrupts to the selected line */
3982 if (InterruptLine == FDCAN_INTERRUPT_LINE0)
3983 {
3984 CLEAR_BIT(hfdcan->ttcan->TTILS, TTITList);
3985 }
3986 else /* InterruptLine == FDCAN_INTERRUPT_LINE1 */
3987 {
3988 SET_BIT(hfdcan->ttcan->TTILS, TTITList);
3989 }
3990
3991 /* Return function status */
3992 return HAL_OK;
3993 }
3994 else
3995 {
3996 /* Update error code */
3997 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
3998
3999 return HAL_ERROR;
4000 }
4001 }
4002
4003 /**
4004 * @brief Enable interrupts.
4005 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4006 * the configuration information for the specified FDCAN.
4007 * @param ActiveITs indicates which interrupts will be enabled.
4008 * This parameter can be any combination of @arg FDCAN_Interrupts.
4009 * @param BufferIndexes Tx Buffer Indexes.
4010 * This parameter can be any combination of @arg FDCAN_Tx_location.
4011 * This parameter is ignored if ActiveITs does not include one of the following:
4012 * - FDCAN_IT_TX_COMPLETE
4013 * - FDCAN_IT_TX_ABORT_COMPLETE
4014 * @retval HAL status
4015 */
HAL_FDCAN_ActivateNotification(FDCAN_HandleTypeDef * hfdcan,uint32_t ActiveITs,uint32_t BufferIndexes)4016 HAL_StatusTypeDef HAL_FDCAN_ActivateNotification(FDCAN_HandleTypeDef *hfdcan, uint32_t ActiveITs, uint32_t BufferIndexes)
4017 {
4018 HAL_FDCAN_StateTypeDef state = hfdcan->State;
4019
4020 /* Check function parameters */
4021 assert_param(IS_FDCAN_IT(ActiveITs));
4022
4023 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4024 {
4025 /* Enable Interrupt lines */
4026 if ((ActiveITs & hfdcan->Instance->ILS) == 0U)
4027 {
4028 /* Enable Interrupt line 0 */
4029 SET_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE0);
4030 }
4031 else if ((ActiveITs & hfdcan->Instance->ILS) == ActiveITs)
4032 {
4033 /* Enable Interrupt line 1 */
4034 SET_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE1);
4035 }
4036 else
4037 {
4038 /* Enable Interrupt lines 0 and 1 */
4039 hfdcan->Instance->ILE = (FDCAN_INTERRUPT_LINE0 | FDCAN_INTERRUPT_LINE1);
4040 }
4041
4042 if ((ActiveITs & FDCAN_IT_TX_COMPLETE) != 0U)
4043 {
4044 /* Enable Tx Buffer Transmission Interrupt to set TC flag in IR register,
4045 but interrupt will only occure if TC is enabled in IE register */
4046 SET_BIT(hfdcan->Instance->TXBTIE, BufferIndexes);
4047 }
4048
4049 if ((ActiveITs & FDCAN_IT_TX_ABORT_COMPLETE) != 0U)
4050 {
4051 /* Enable Tx Buffer Cancellation Finished Interrupt to set TCF flag in IR register,
4052 but interrupt will only occure if TCF is enabled in IE register */
4053 SET_BIT(hfdcan->Instance->TXBCIE, BufferIndexes);
4054 }
4055
4056 /* Enable the selected interrupts */
4057 __HAL_FDCAN_ENABLE_IT(hfdcan, ActiveITs);
4058
4059 /* Return function status */
4060 return HAL_OK;
4061 }
4062 else
4063 {
4064 /* Update error code */
4065 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4066
4067 return HAL_ERROR;
4068 }
4069 }
4070
4071 /**
4072 * @brief Disable interrupts.
4073 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4074 * the configuration information for the specified FDCAN.
4075 * @param InactiveITs indicates which interrupts will be disabled.
4076 * This parameter can be any combination of @arg FDCAN_Interrupts.
4077 * @retval HAL status
4078 */
HAL_FDCAN_DeactivateNotification(FDCAN_HandleTypeDef * hfdcan,uint32_t InactiveITs)4079 HAL_StatusTypeDef HAL_FDCAN_DeactivateNotification(FDCAN_HandleTypeDef *hfdcan, uint32_t InactiveITs)
4080 {
4081 uint32_t ITLineSelection;
4082 HAL_FDCAN_StateTypeDef state = hfdcan->State;
4083
4084 /* Check function parameters */
4085 assert_param(IS_FDCAN_IT(InactiveITs));
4086
4087 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4088 {
4089 /* Disable the selected interrupts */
4090 __HAL_FDCAN_DISABLE_IT(hfdcan, InactiveITs);
4091
4092 if ((InactiveITs & FDCAN_IT_TX_COMPLETE) != 0U)
4093 {
4094 /* Disable Tx Buffer Transmission Interrupts */
4095 CLEAR_REG(hfdcan->Instance->TXBTIE);
4096 }
4097
4098 if ((InactiveITs & FDCAN_IT_TX_ABORT_COMPLETE) != 0U)
4099 {
4100 /* Disable Tx Buffer Cancellation Finished Interrupt */
4101 CLEAR_REG(hfdcan->Instance->TXBCIE);
4102 }
4103
4104 ITLineSelection = hfdcan->Instance->ILS;
4105
4106 if ((hfdcan->Instance->IE | ITLineSelection) == ITLineSelection)
4107 {
4108 /* Disable Interrupt line 0 */
4109 CLEAR_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE0);
4110 }
4111
4112 if ((hfdcan->Instance->IE & ITLineSelection) == 0U)
4113 {
4114 /* Disable Interrupt line 1 */
4115 CLEAR_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE1);
4116 }
4117
4118 /* Return function status */
4119 return HAL_OK;
4120 }
4121 else
4122 {
4123 /* Update error code */
4124 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4125
4126 return HAL_ERROR;
4127 }
4128 }
4129
4130 /**
4131 * @brief Enable TT interrupts.
4132 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4133 * the configuration information for the specified FDCAN.
4134 * @param ActiveTTITs indicates which TT interrupts will be enabled.
4135 * This parameter can be any combination of @arg FDCAN_TTInterrupts.
4136 * @retval HAL status
4137 */
HAL_FDCAN_TT_ActivateNotification(FDCAN_HandleTypeDef * hfdcan,uint32_t ActiveTTITs)4138 HAL_StatusTypeDef HAL_FDCAN_TT_ActivateNotification(FDCAN_HandleTypeDef *hfdcan, uint32_t ActiveTTITs)
4139 {
4140 HAL_FDCAN_StateTypeDef state = hfdcan->State;
4141
4142 /* Check function parameters */
4143 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4144 assert_param(IS_FDCAN_TT_IT(ActiveTTITs));
4145
4146 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4147 {
4148 /* Enable Interrupt lines */
4149 if ((ActiveTTITs & hfdcan->ttcan->TTILS) == 0U)
4150 {
4151 /* Enable Interrupt line 0 */
4152 SET_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE0);
4153 }
4154 else if ((ActiveTTITs & hfdcan->ttcan->TTILS) == ActiveTTITs)
4155 {
4156 /* Enable Interrupt line 1 */
4157 SET_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE1);
4158 }
4159 else
4160 {
4161 /* Enable Interrupt lines 0 and 1 */
4162 hfdcan->Instance->ILE = (FDCAN_INTERRUPT_LINE0 | FDCAN_INTERRUPT_LINE1);
4163 }
4164
4165 /* Enable the selected TT interrupts */
4166 __HAL_FDCAN_TT_ENABLE_IT(hfdcan, ActiveTTITs);
4167
4168 /* Return function status */
4169 return HAL_OK;
4170 }
4171 else
4172 {
4173 /* Update error code */
4174 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4175
4176 return HAL_ERROR;
4177 }
4178 }
4179
4180 /**
4181 * @brief Disable TT interrupts.
4182 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4183 * the configuration information for the specified FDCAN.
4184 * @param InactiveTTITs indicates which TT interrupts will be disabled.
4185 * This parameter can be any combination of @arg FDCAN_TTInterrupts.
4186 * @retval HAL status
4187 */
HAL_FDCAN_TT_DeactivateNotification(FDCAN_HandleTypeDef * hfdcan,uint32_t InactiveTTITs)4188 HAL_StatusTypeDef HAL_FDCAN_TT_DeactivateNotification(FDCAN_HandleTypeDef *hfdcan, uint32_t InactiveTTITs)
4189 {
4190 uint32_t ITLineSelection;
4191 HAL_FDCAN_StateTypeDef state = hfdcan->State;
4192
4193 /* Check function parameters */
4194 assert_param(IS_FDCAN_TT_INSTANCE(hfdcan->Instance));
4195 assert_param(IS_FDCAN_TT_IT(InactiveTTITs));
4196
4197 if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY))
4198 {
4199 /* Disable the selected TT interrupts */
4200 __HAL_FDCAN_TT_DISABLE_IT(hfdcan, InactiveTTITs);
4201
4202 ITLineSelection = hfdcan->ttcan->TTILS;
4203
4204 if ((hfdcan->ttcan->TTIE | ITLineSelection) == ITLineSelection)
4205 {
4206 /* Disable Interrupt line 0 */
4207 CLEAR_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE0);
4208 }
4209
4210 if ((hfdcan->ttcan->TTIE & ITLineSelection) == 0U)
4211 {
4212 /* Disable Interrupt line 1 */
4213 CLEAR_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE1);
4214 }
4215
4216 /* Return function status */
4217 return HAL_OK;
4218 }
4219 else
4220 {
4221 /* Update error code */
4222 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED;
4223
4224 return HAL_ERROR;
4225 }
4226 }
4227
4228 /**
4229 * @brief Handles FDCAN interrupt request.
4230 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4231 * the configuration information for the specified FDCAN.
4232 * @retval HAL status
4233 */
HAL_FDCAN_IRQHandler(FDCAN_HandleTypeDef * hfdcan)4234 void HAL_FDCAN_IRQHandler(FDCAN_HandleTypeDef *hfdcan)
4235 {
4236 uint32_t ClkCalibrationITs;
4237 uint32_t TxEventFifoITs;
4238 uint32_t RxFifo0ITs;
4239 uint32_t RxFifo1ITs;
4240 uint32_t Errors;
4241 uint32_t ErrorStatusITs;
4242 uint32_t TransmittedBuffers;
4243 uint32_t AbortedBuffers;
4244 uint32_t TTSchedSyncITs;
4245 uint32_t TTTimeMarkITs;
4246 uint32_t TTGlobTimeITs;
4247 uint32_t TTDistErrors;
4248 uint32_t TTFatalErrors;
4249 uint32_t SWTime;
4250 uint32_t SWCycleCount;
4251
4252 ClkCalibrationITs = (FDCAN_CCU->IR << 30);
4253 ClkCalibrationITs &= (FDCAN_CCU->IE << 30);
4254 TxEventFifoITs = hfdcan->Instance->IR & FDCAN_TX_EVENT_FIFO_MASK;
4255 TxEventFifoITs &= hfdcan->Instance->IE;
4256 RxFifo0ITs = hfdcan->Instance->IR & FDCAN_RX_FIFO0_MASK;
4257 RxFifo0ITs &= hfdcan->Instance->IE;
4258 RxFifo1ITs = hfdcan->Instance->IR & FDCAN_RX_FIFO1_MASK;
4259 RxFifo1ITs &= hfdcan->Instance->IE;
4260 Errors = hfdcan->Instance->IR & FDCAN_ERROR_MASK;
4261 Errors &= hfdcan->Instance->IE;
4262 ErrorStatusITs = hfdcan->Instance->IR & FDCAN_ERROR_STATUS_MASK;
4263 ErrorStatusITs &= hfdcan->Instance->IE;
4264
4265 /* High Priority Message interrupt management *******************************/
4266 if (__HAL_FDCAN_GET_IT_SOURCE(hfdcan, FDCAN_IT_RX_HIGH_PRIORITY_MSG) != 0U)
4267 {
4268 if (__HAL_FDCAN_GET_FLAG(hfdcan, FDCAN_FLAG_RX_HIGH_PRIORITY_MSG) != 0U)
4269 {
4270 /* Clear the High Priority Message flag */
4271 __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_RX_HIGH_PRIORITY_MSG);
4272
4273 /* High Priority Message Callback */
4274 HAL_FDCAN_HighPriorityMessageCallback(hfdcan);
4275 }
4276 }
4277
4278 /* Transmission Abort interrupt management **********************************/
4279 if (__HAL_FDCAN_GET_IT_SOURCE(hfdcan, FDCAN_IT_TX_ABORT_COMPLETE) != 0U)
4280 {
4281 if (__HAL_FDCAN_GET_FLAG(hfdcan, FDCAN_FLAG_TX_ABORT_COMPLETE) != 0U)
4282 {
4283 /* List of aborted monitored buffers */
4284 AbortedBuffers = hfdcan->Instance->TXBCF;
4285 AbortedBuffers &= hfdcan->Instance->TXBCIE;
4286
4287 /* Clear the Transmission Cancellation flag */
4288 __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TX_ABORT_COMPLETE);
4289
4290 /* Transmission Cancellation Callback */
4291 HAL_FDCAN_TxBufferAbortCallback(hfdcan, AbortedBuffers);
4292 }
4293 }
4294
4295 /* Clock calibration unit interrupts management *****************************/
4296 if (ClkCalibrationITs != 0U)
4297 {
4298 /* Clear the Clock Calibration flags */
4299 __HAL_FDCAN_CLEAR_FLAG(hfdcan, ClkCalibrationITs);
4300
4301 /* Clock Calibration Callback */
4302 HAL_FDCAN_ClockCalibrationCallback(hfdcan, ClkCalibrationITs);
4303 }
4304
4305 /* Tx event FIFO interrupts management **************************************/
4306 if (TxEventFifoITs != 0U)
4307 {
4308 /* Clear the Tx Event FIFO flags */
4309 __HAL_FDCAN_CLEAR_FLAG(hfdcan, TxEventFifoITs);
4310
4311 /* Tx Event FIFO Callback */
4312 HAL_FDCAN_TxEventFifoCallback(hfdcan, TxEventFifoITs);
4313 }
4314
4315 /* Rx FIFO 0 interrupts management ******************************************/
4316 if (RxFifo0ITs != 0U)
4317 {
4318 /* Clear the Rx FIFO 0 flags */
4319 __HAL_FDCAN_CLEAR_FLAG(hfdcan, RxFifo0ITs);
4320
4321 /* Rx FIFO 0 Callback */
4322 HAL_FDCAN_RxFifo0Callback(hfdcan, RxFifo0ITs);
4323 }
4324
4325 /* Rx FIFO 1 interrupts management ******************************************/
4326 if (RxFifo1ITs != 0U)
4327 {
4328 /* Clear the Rx FIFO 1 flags */
4329 __HAL_FDCAN_CLEAR_FLAG(hfdcan, RxFifo1ITs);
4330
4331 /* Rx FIFO 1 Callback */
4332 HAL_FDCAN_RxFifo1Callback(hfdcan, RxFifo1ITs);
4333 }
4334
4335 /* Tx FIFO empty interrupt management ***************************************/
4336 if (__HAL_FDCAN_GET_IT_SOURCE(hfdcan, FDCAN_IT_TX_FIFO_EMPTY) != 0U)
4337 {
4338 if (__HAL_FDCAN_GET_FLAG(hfdcan, FDCAN_FLAG_TX_FIFO_EMPTY) != 0U)
4339 {
4340 /* Clear the Tx FIFO empty flag */
4341 __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TX_FIFO_EMPTY);
4342
4343 /* Tx FIFO empty Callback */
4344 HAL_FDCAN_TxFifoEmptyCallback(hfdcan);
4345 }
4346 }
4347
4348 /* Transmission Complete interrupt management *******************************/
4349 if (__HAL_FDCAN_GET_IT_SOURCE(hfdcan, FDCAN_IT_TX_COMPLETE) != 0U)
4350 {
4351 if (__HAL_FDCAN_GET_FLAG(hfdcan, FDCAN_FLAG_TX_COMPLETE) != 0U)
4352 {
4353 /* List of transmitted monitored buffers */
4354 TransmittedBuffers = hfdcan->Instance->TXBTO;
4355 TransmittedBuffers &= hfdcan->Instance->TXBTIE;
4356
4357 /* Clear the Transmission Complete flag */
4358 __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TX_COMPLETE);
4359
4360 /* Transmission Complete Callback */
4361 HAL_FDCAN_TxBufferCompleteCallback(hfdcan, TransmittedBuffers);
4362 }
4363 }
4364
4365 /* Rx Buffer New Message interrupt management *******************************/
4366 if (__HAL_FDCAN_GET_IT_SOURCE(hfdcan, FDCAN_IT_RX_BUFFER_NEW_MESSAGE) != 0U)
4367 {
4368 if (__HAL_FDCAN_GET_FLAG(hfdcan, FDCAN_FLAG_RX_BUFFER_NEW_MESSAGE) != 0U)
4369 {
4370 /* Clear the Rx Buffer New Message flag */
4371 __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_RX_BUFFER_NEW_MESSAGE);
4372
4373 /* Rx Buffer New Message Callback */
4374 HAL_FDCAN_RxBufferNewMessageCallback(hfdcan);
4375 }
4376 }
4377
4378 /* Timestamp Wraparound interrupt management ********************************/
4379 if (__HAL_FDCAN_GET_IT_SOURCE(hfdcan, FDCAN_IT_TIMESTAMP_WRAPAROUND) != 0U)
4380 {
4381 if (__HAL_FDCAN_GET_FLAG(hfdcan, FDCAN_FLAG_TIMESTAMP_WRAPAROUND) != 0U)
4382 {
4383 /* Clear the Timestamp Wraparound flag */
4384 __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TIMESTAMP_WRAPAROUND);
4385
4386 /* Timestamp Wraparound Callback */
4387 HAL_FDCAN_TimestampWraparoundCallback(hfdcan);
4388 }
4389 }
4390
4391 /* Timeout Occurred interrupt management ************************************/
4392 if (__HAL_FDCAN_GET_IT_SOURCE(hfdcan, FDCAN_IT_TIMEOUT_OCCURRED) != 0U)
4393 {
4394 if (__HAL_FDCAN_GET_FLAG(hfdcan, FDCAN_FLAG_TIMEOUT_OCCURRED) != 0U)
4395 {
4396 /* Clear the Timeout Occurred flag */
4397 __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TIMEOUT_OCCURRED);
4398
4399 /* Timeout Occurred Callback */
4400 HAL_FDCAN_TimeoutOccurredCallback(hfdcan);
4401 }
4402 }
4403
4404 /* Message RAM access failure interrupt management **************************/
4405 if (__HAL_FDCAN_GET_IT_SOURCE(hfdcan, FDCAN_IT_RAM_ACCESS_FAILURE) != 0U)
4406 {
4407 if (__HAL_FDCAN_GET_FLAG(hfdcan, FDCAN_FLAG_RAM_ACCESS_FAILURE) != 0U)
4408 {
4409 /* Clear the Message RAM access failure flag */
4410 __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_RAM_ACCESS_FAILURE);
4411
4412 /* Update error code */
4413 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_RAM_ACCESS;
4414 }
4415 }
4416
4417 /* Error Status interrupts management ***************************************/
4418 if (ErrorStatusITs != 0U)
4419 {
4420 /* Clear the Error flags */
4421 __HAL_FDCAN_CLEAR_FLAG(hfdcan, ErrorStatusITs);
4422
4423 /* Error Status Callback */
4424 HAL_FDCAN_ErrorStatusCallback(hfdcan, ErrorStatusITs);
4425 }
4426
4427 /* Error interrupts management **********************************************/
4428 if (Errors != 0U)
4429 {
4430 /* Clear the Error flags */
4431 __HAL_FDCAN_CLEAR_FLAG(hfdcan, Errors);
4432
4433 /* Update error code */
4434 hfdcan->ErrorCode |= Errors;
4435 }
4436
4437 if (hfdcan->Instance == FDCAN1)
4438 {
4439 if ((hfdcan->ttcan->TTOCF & FDCAN_TTOCF_OM) != 0U)
4440 {
4441 TTSchedSyncITs = hfdcan->ttcan->TTIR & FDCAN_TT_SCHEDULE_SYNC_MASK;
4442 TTSchedSyncITs &= hfdcan->ttcan->TTIE;
4443 TTTimeMarkITs = hfdcan->ttcan->TTIR & FDCAN_TT_TIME_MARK_MASK;
4444 TTTimeMarkITs &= hfdcan->ttcan->TTIE;
4445 TTGlobTimeITs = hfdcan->ttcan->TTIR & FDCAN_TT_GLOBAL_TIME_MASK;
4446 TTGlobTimeITs &= hfdcan->ttcan->TTIE;
4447 TTDistErrors = hfdcan->ttcan->TTIR & FDCAN_TT_DISTURBING_ERROR_MASK;
4448 TTDistErrors &= hfdcan->ttcan->TTIE;
4449 TTFatalErrors = hfdcan->ttcan->TTIR & FDCAN_TT_FATAL_ERROR_MASK;
4450 TTFatalErrors &= hfdcan->ttcan->TTIE;
4451
4452 /* TT Schedule Synchronization interrupts management **********************/
4453 if (TTSchedSyncITs != 0U)
4454 {
4455 /* Clear the TT Schedule Synchronization flags */
4456 __HAL_FDCAN_TT_CLEAR_FLAG(hfdcan, TTSchedSyncITs);
4457
4458 /* TT Schedule Synchronization Callback */
4459 HAL_FDCAN_TT_ScheduleSyncCallback(hfdcan, TTSchedSyncITs);
4460 }
4461
4462 /* TT Time Mark interrupts management *************************************/
4463 if (TTTimeMarkITs != 0U)
4464 {
4465 /* Clear the TT Time Mark flags */
4466 __HAL_FDCAN_TT_CLEAR_FLAG(hfdcan, TTTimeMarkITs);
4467
4468 /* TT Time Mark Callback */
4469 HAL_FDCAN_TT_TimeMarkCallback(hfdcan, TTTimeMarkITs);
4470 }
4471
4472 /* TT Stop Watch interrupt management *************************************/
4473 if (__HAL_FDCAN_TT_GET_IT_SOURCE(hfdcan, FDCAN_TT_IT_STOP_WATCH) != 0U)
4474 {
4475 if (__HAL_FDCAN_TT_GET_FLAG(hfdcan, FDCAN_TT_FLAG_STOP_WATCH) != 0U)
4476 {
4477 /* Retrieve Stop watch Time and Cycle count */
4478 SWTime = ((hfdcan->ttcan->TTCPT & FDCAN_TTCPT_SWV) >> FDCAN_TTCPT_SWV_Pos);
4479 SWCycleCount = ((hfdcan->ttcan->TTCPT & FDCAN_TTCPT_CCV) >> FDCAN_TTCPT_CCV_Pos);
4480
4481 /* Clear the TT Stop Watch flag */
4482 __HAL_FDCAN_TT_CLEAR_FLAG(hfdcan, FDCAN_TT_FLAG_STOP_WATCH);
4483
4484 /* TT Stop Watch Callback */
4485 HAL_FDCAN_TT_StopWatchCallback(hfdcan, SWTime, SWCycleCount);
4486 }
4487 }
4488
4489 /* TT Global Time interrupts management ***********************************/
4490 if (TTGlobTimeITs != 0U)
4491 {
4492 /* Clear the TT Global Time flags */
4493 __HAL_FDCAN_TT_CLEAR_FLAG(hfdcan, TTGlobTimeITs);
4494
4495 /* TT Global Time Callback */
4496 HAL_FDCAN_TT_GlobalTimeCallback(hfdcan, TTGlobTimeITs);
4497 }
4498
4499 /* TT Disturbing Error interrupts management ******************************/
4500 if (TTDistErrors != 0U)
4501 {
4502 /* Clear the TT Disturbing Error flags */
4503 __HAL_FDCAN_TT_CLEAR_FLAG(hfdcan, TTDistErrors);
4504
4505 /* Update error code */
4506 hfdcan->ErrorCode |= TTDistErrors;
4507 }
4508
4509 /* TT Fatal Error interrupts management ***********************************/
4510 if (TTFatalErrors != 0U)
4511 {
4512 /* Clear the TT Fatal Error flags */
4513 __HAL_FDCAN_TT_CLEAR_FLAG(hfdcan, TTFatalErrors);
4514
4515 /* Update error code */
4516 hfdcan->ErrorCode |= TTFatalErrors;
4517 }
4518 }
4519 }
4520
4521 if (hfdcan->ErrorCode != HAL_FDCAN_ERROR_NONE)
4522 {
4523 /* Error Callback */
4524 HAL_FDCAN_ErrorCallback(hfdcan);
4525 }
4526 }
4527
4528 /**
4529 * @}
4530 */
4531
4532 /** @defgroup FDCAN_Exported_Functions_Group6 Callback functions
4533 * @brief FDCAN Callback functions
4534 *
4535 @verbatim
4536 ==============================================================================
4537 ##### Callback functions #####
4538 ==============================================================================
4539 [..]
4540 This subsection provides the following callback functions:
4541 (+) HAL_FDCAN_ClockCalibrationCallback
4542 (+) HAL_FDCAN_TxEventFifoCallback
4543 (+) HAL_FDCAN_RxFifo0Callback
4544 (+) HAL_FDCAN_RxFifo1Callback
4545 (+) HAL_FDCAN_TxFifoEmptyCallback
4546 (+) HAL_FDCAN_TxBufferCompleteCallback
4547 (+) HAL_FDCAN_TxBufferAbortCallback
4548 (+) HAL_FDCAN_RxBufferNewMessageCallback
4549 (+) HAL_FDCAN_HighPriorityMessageCallback
4550 (+) HAL_FDCAN_TimestampWraparoundCallback
4551 (+) HAL_FDCAN_TimeoutOccurredCallback
4552 (+) HAL_FDCAN_ErrorCallback
4553 (+) HAL_FDCAN_ErrorStatusCallback
4554 (+) HAL_FDCAN_TT_ScheduleSyncCallback
4555 (+) HAL_FDCAN_TT_TimeMarkCallback
4556 (+) HAL_FDCAN_TT_StopWatchCallback
4557 (+) HAL_FDCAN_TT_GlobalTimeCallback
4558
4559 @endverbatim
4560 * @{
4561 */
4562
4563 /**
4564 * @brief Clock Calibration callback.
4565 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4566 * the configuration information for the specified FDCAN.
4567 * @param ClkCalibrationITs indicates which Clock Calibration interrupts are signaled.
4568 * This parameter can be any combination of @arg FDCAN_Clock_Calibration_Interrupts.
4569 * @retval None
4570 */
HAL_FDCAN_ClockCalibrationCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t ClkCalibrationITs)4571 __weak void HAL_FDCAN_ClockCalibrationCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t ClkCalibrationITs)
4572 {
4573 /* Prevent unused argument(s) compilation warning */
4574 UNUSED(hfdcan);
4575 UNUSED(ClkCalibrationITs);
4576
4577 /* NOTE : This function Should not be modified, when the callback is needed,
4578 the HAL_FDCAN_ClockCalibrationCallback could be implemented in the user file
4579 */
4580 }
4581
4582 /**
4583 * @brief Tx Event callback.
4584 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4585 * the configuration information for the specified FDCAN.
4586 * @param TxEventFifoITs indicates which Tx Event FIFO interrupts are signaled.
4587 * This parameter can be any combination of @arg FDCAN_Tx_Event_Fifo_Interrupts.
4588 * @retval None
4589 */
HAL_FDCAN_TxEventFifoCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t TxEventFifoITs)4590 __weak void HAL_FDCAN_TxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t TxEventFifoITs)
4591 {
4592 /* Prevent unused argument(s) compilation warning */
4593 UNUSED(hfdcan);
4594 UNUSED(TxEventFifoITs);
4595
4596 /* NOTE : This function Should not be modified, when the callback is needed,
4597 the HAL_FDCAN_TxEventFifoCallback could be implemented in the user file
4598 */
4599 }
4600
4601 /**
4602 * @brief Rx FIFO 0 callback.
4603 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4604 * the configuration information for the specified FDCAN.
4605 * @param RxFifo0ITs indicates which Rx FIFO 0 interrupts are signaled.
4606 * This parameter can be any combination of @arg FDCAN_Rx_Fifo0_Interrupts.
4607 * @retval None
4608 */
HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef * hfdcan,uint32_t RxFifo0ITs)4609 __weak void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
4610 {
4611 /* Prevent unused argument(s) compilation warning */
4612 UNUSED(hfdcan);
4613 UNUSED(RxFifo0ITs);
4614
4615 /* NOTE : This function Should not be modified, when the callback is needed,
4616 the HAL_FDCAN_RxFifo0Callback could be implemented in the user file
4617 */
4618 }
4619
4620 /**
4621 * @brief Rx FIFO 1 callback.
4622 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4623 * the configuration information for the specified FDCAN.
4624 * @param RxFifo1ITs indicates which Rx FIFO 1 interrupts are signaled.
4625 * This parameter can be any combination of @arg FDCAN_Rx_Fifo1_Interrupts.
4626 * @retval None
4627 */
HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef * hfdcan,uint32_t RxFifo1ITs)4628 __weak void HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo1ITs)
4629 {
4630 /* Prevent unused argument(s) compilation warning */
4631 UNUSED(hfdcan);
4632 UNUSED(RxFifo1ITs);
4633
4634 /* NOTE : This function Should not be modified, when the callback is needed,
4635 the HAL_FDCAN_RxFifo1Callback could be implemented in the user file
4636 */
4637 }
4638
4639 /**
4640 * @brief Tx FIFO Empty callback.
4641 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4642 * the configuration information for the specified FDCAN.
4643 * @retval None
4644 */
HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef * hfdcan)4645 __weak void HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef *hfdcan)
4646 {
4647 /* Prevent unused argument(s) compilation warning */
4648 UNUSED(hfdcan);
4649
4650 /* NOTE : This function Should not be modified, when the callback is needed,
4651 the HAL_FDCAN_TxFifoEmptyCallback could be implemented in the user file
4652 */
4653 }
4654
4655 /**
4656 * @brief Transmission Complete callback.
4657 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4658 * the configuration information for the specified FDCAN.
4659 * @param BufferIndexes Indexes of the transmitted buffers.
4660 * This parameter can be any combination of @arg FDCAN_Tx_location.
4661 * @retval None
4662 */
HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t BufferIndexes)4663 __weak void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes)
4664 {
4665 /* Prevent unused argument(s) compilation warning */
4666 UNUSED(hfdcan);
4667 UNUSED(BufferIndexes);
4668
4669 /* NOTE : This function Should not be modified, when the callback is needed,
4670 the HAL_FDCAN_TxBufferCompleteCallback could be implemented in the user file
4671 */
4672 }
4673
4674 /**
4675 * @brief Transmission Cancellation callback.
4676 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4677 * the configuration information for the specified FDCAN.
4678 * @param BufferIndexes Indexes of the aborted buffers.
4679 * This parameter can be any combination of @arg FDCAN_Tx_location.
4680 * @retval None
4681 */
HAL_FDCAN_TxBufferAbortCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t BufferIndexes)4682 __weak void HAL_FDCAN_TxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes)
4683 {
4684 /* Prevent unused argument(s) compilation warning */
4685 UNUSED(hfdcan);
4686 UNUSED(BufferIndexes);
4687
4688 /* NOTE : This function Should not be modified, when the callback is needed,
4689 the HAL_FDCAN_TxBufferAbortCallback could be implemented in the user file
4690 */
4691 }
4692
4693 /**
4694 * @brief Rx Buffer New Message callback.
4695 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4696 * the configuration information for the specified FDCAN.
4697 * @retval None
4698 */
HAL_FDCAN_RxBufferNewMessageCallback(FDCAN_HandleTypeDef * hfdcan)4699 __weak void HAL_FDCAN_RxBufferNewMessageCallback(FDCAN_HandleTypeDef *hfdcan)
4700 {
4701 /* Prevent unused argument(s) compilation warning */
4702 UNUSED(hfdcan);
4703
4704 /* NOTE : This function Should not be modified, when the callback is needed,
4705 the HAL_FDCAN_RxBufferNewMessageCallback could be implemented in the user file
4706 */
4707 }
4708
4709 /**
4710 * @brief Timestamp Wraparound callback.
4711 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4712 * the configuration information for the specified FDCAN.
4713 * @retval None
4714 */
HAL_FDCAN_TimestampWraparoundCallback(FDCAN_HandleTypeDef * hfdcan)4715 __weak void HAL_FDCAN_TimestampWraparoundCallback(FDCAN_HandleTypeDef *hfdcan)
4716 {
4717 /* Prevent unused argument(s) compilation warning */
4718 UNUSED(hfdcan);
4719
4720 /* NOTE : This function Should not be modified, when the callback is needed,
4721 the HAL_FDCAN_TimestampWraparoundCallback could be implemented in the user file
4722 */
4723 }
4724
4725 /**
4726 * @brief Timeout Occurred callback.
4727 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4728 * the configuration information for the specified FDCAN.
4729 * @retval None
4730 */
HAL_FDCAN_TimeoutOccurredCallback(FDCAN_HandleTypeDef * hfdcan)4731 __weak void HAL_FDCAN_TimeoutOccurredCallback(FDCAN_HandleTypeDef *hfdcan)
4732 {
4733 /* Prevent unused argument(s) compilation warning */
4734 UNUSED(hfdcan);
4735
4736 /* NOTE : This function Should not be modified, when the callback is needed,
4737 the HAL_FDCAN_TimeoutOccurredCallback could be implemented in the user file
4738 */
4739 }
4740
4741 /**
4742 * @brief High Priority Message callback.
4743 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4744 * the configuration information for the specified FDCAN.
4745 * @retval None
4746 */
HAL_FDCAN_HighPriorityMessageCallback(FDCAN_HandleTypeDef * hfdcan)4747 __weak void HAL_FDCAN_HighPriorityMessageCallback(FDCAN_HandleTypeDef *hfdcan)
4748 {
4749 /* Prevent unused argument(s) compilation warning */
4750 UNUSED(hfdcan);
4751
4752 /* NOTE : This function Should not be modified, when the callback is needed,
4753 the HAL_FDCAN_HighPriorityMessageCallback could be implemented in the user file
4754 */
4755 }
4756
4757 /**
4758 * @brief Error callback.
4759 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4760 * the configuration information for the specified FDCAN.
4761 * @retval None
4762 */
HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef * hfdcan)4763 __weak void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan)
4764 {
4765 /* Prevent unused argument(s) compilation warning */
4766 UNUSED(hfdcan);
4767
4768 /* NOTE : This function Should not be modified, when the callback is needed,
4769 the HAL_FDCAN_ErrorCallback could be implemented in the user file
4770 */
4771 }
4772
4773 /**
4774 * @brief Error status callback.
4775 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4776 * the configuration information for the specified FDCAN.
4777 * @param ErrorStatusITs indicates which Error Status interrupts are signaled.
4778 * This parameter can be any combination of @arg FDCAN_Error_Status_Interrupts.
4779 * @retval None
4780 */
HAL_FDCAN_ErrorStatusCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t ErrorStatusITs)4781 __weak void HAL_FDCAN_ErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t ErrorStatusITs)
4782 {
4783 /* Prevent unused argument(s) compilation warning */
4784 UNUSED(hfdcan);
4785 UNUSED(ErrorStatusITs);
4786
4787 /* NOTE : This function Should not be modified, when the callback is needed,
4788 the HAL_FDCAN_ErrorStatusCallback could be implemented in the user file
4789 */
4790 }
4791
4792 /**
4793 * @brief TT Schedule Synchronization callback.
4794 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4795 * the configuration information for the specified FDCAN.
4796 * @param TTSchedSyncITs indicates which TT Schedule Synchronization interrupts are signaled.
4797 * This parameter can be any combination of @arg FDCAN_TTScheduleSynchronization_Interrupts.
4798 * @retval None
4799 */
HAL_FDCAN_TT_ScheduleSyncCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t TTSchedSyncITs)4800 __weak void HAL_FDCAN_TT_ScheduleSyncCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t TTSchedSyncITs)
4801 {
4802 /* Prevent unused argument(s) compilation warning */
4803 UNUSED(hfdcan);
4804 UNUSED(TTSchedSyncITs);
4805
4806 /* NOTE : This function Should not be modified, when the callback is needed,
4807 the HAL_FDCAN_TT_ScheduleSyncCallback could be implemented in the user file
4808 */
4809 }
4810
4811 /**
4812 * @brief TT Time Mark callback.
4813 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4814 * the configuration information for the specified FDCAN.
4815 * @param TTTimeMarkITs indicates which TT Schedule Synchronization interrupts are signaled.
4816 * This parameter can be any combination of @arg FDCAN_TTTimeMark_Interrupts.
4817 * @retval None
4818 */
HAL_FDCAN_TT_TimeMarkCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t TTTimeMarkITs)4819 __weak void HAL_FDCAN_TT_TimeMarkCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t TTTimeMarkITs)
4820 {
4821 /* Prevent unused argument(s) compilation warning */
4822 UNUSED(hfdcan);
4823 UNUSED(TTTimeMarkITs);
4824
4825 /* NOTE : This function Should not be modified, when the callback is needed,
4826 the HAL_FDCAN_TT_TimeMarkCallback could be implemented in the user file
4827 */
4828 }
4829
4830 /**
4831 * @brief TT Stop Watch callback.
4832 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4833 * the configuration information for the specified FDCAN.
4834 * @param SWTime Time Value captured at the Stop Watch Trigger pin (fdcan1_swt) falling/rising
4835 * edge (as configured via HAL_FDCAN_TTConfigStopWatch).
4836 * This parameter is a number between 0 and 0xFFFF.
4837 * @param SWCycleCount Cycle count value captured together with SWTime.
4838 * This parameter is a number between 0 and 0x3F.
4839 * @retval None
4840 */
HAL_FDCAN_TT_StopWatchCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t SWTime,uint32_t SWCycleCount)4841 __weak void HAL_FDCAN_TT_StopWatchCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t SWTime, uint32_t SWCycleCount)
4842 {
4843 /* Prevent unused argument(s) compilation warning */
4844 UNUSED(hfdcan);
4845 UNUSED(SWTime);
4846 UNUSED(SWCycleCount);
4847
4848 /* NOTE : This function Should not be modified, when the callback is needed,
4849 the HAL_FDCAN_TT_StopWatchCallback could be implemented in the user file
4850 */
4851 }
4852
4853 /**
4854 * @brief TT Global Time callback.
4855 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4856 * the configuration information for the specified FDCAN.
4857 * @param TTGlobTimeITs indicates which TT Global Time interrupts are signaled.
4858 * This parameter can be any combination of @arg FDCAN_TTGlobalTime_Interrupts.
4859 * @retval None
4860 */
HAL_FDCAN_TT_GlobalTimeCallback(FDCAN_HandleTypeDef * hfdcan,uint32_t TTGlobTimeITs)4861 __weak void HAL_FDCAN_TT_GlobalTimeCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t TTGlobTimeITs)
4862 {
4863 /* Prevent unused argument(s) compilation warning */
4864 UNUSED(hfdcan);
4865 UNUSED(TTGlobTimeITs);
4866
4867 /* NOTE : This function Should not be modified, when the callback is needed,
4868 the HAL_FDCAN_TT_GlobalTimeCallback could be implemented in the user file
4869 */
4870 }
4871
4872 /**
4873 * @}
4874 */
4875
4876 /** @defgroup FDCAN_Exported_Functions_Group7 Peripheral State functions
4877 * @brief FDCAN Peripheral State functions
4878 *
4879 @verbatim
4880 ==============================================================================
4881 ##### Peripheral State functions #####
4882 ==============================================================================
4883 [..]
4884 This subsection provides functions allowing to :
4885 (+) HAL_FDCAN_GetState() : Return the FDCAN state.
4886 (+) HAL_FDCAN_GetError() : Return the FDCAN error code if any.
4887
4888 @endverbatim
4889 * @{
4890 */
4891 /**
4892 * @brief Return the FDCAN state
4893 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4894 * the configuration information for the specified FDCAN.
4895 * @retval HAL state
4896 */
HAL_FDCAN_GetState(FDCAN_HandleTypeDef * hfdcan)4897 HAL_FDCAN_StateTypeDef HAL_FDCAN_GetState(FDCAN_HandleTypeDef *hfdcan)
4898 {
4899 /* Return FDCAN state */
4900 return hfdcan->State;
4901 }
4902
4903 /**
4904 * @brief Return the FDCAN error code
4905 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4906 * the configuration information for the specified FDCAN.
4907 * @retval FDCAN Error Code
4908 */
HAL_FDCAN_GetError(FDCAN_HandleTypeDef * hfdcan)4909 uint32_t HAL_FDCAN_GetError(FDCAN_HandleTypeDef *hfdcan)
4910 {
4911 /* Return FDCAN error code */
4912 return hfdcan->ErrorCode;
4913 }
4914
4915 /**
4916 * @}
4917 */
4918
4919 /**
4920 * @}
4921 */
4922
4923 /** @addtogroup FDCAN_Private_Functions
4924 * @{
4925 */
4926
4927 /**
4928 * @brief Calculate each RAM block start address and size
4929 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
4930 * the configuration information for the specified FDCAN.
4931 * @retval HAL status
4932 */
FDCAN_CalcultateRamBlockAddresses(FDCAN_HandleTypeDef * hfdcan)4933 static HAL_StatusTypeDef FDCAN_CalcultateRamBlockAddresses(FDCAN_HandleTypeDef *hfdcan)
4934 {
4935 uint32_t RAMcounter;
4936 uint32_t StartAddress;
4937
4938 StartAddress = hfdcan->Init.MessageRAMOffset;
4939
4940 /* Standard filter list start address */
4941 MODIFY_REG(hfdcan->Instance->SIDFC, FDCAN_SIDFC_FLSSA, (StartAddress << FDCAN_SIDFC_FLSSA_Pos));
4942
4943 /* Standard filter elements number */
4944 MODIFY_REG(hfdcan->Instance->SIDFC, FDCAN_SIDFC_LSS, (hfdcan->Init.StdFiltersNbr << FDCAN_SIDFC_LSS_Pos));
4945
4946 /* Extended filter list start address */
4947 StartAddress += hfdcan->Init.StdFiltersNbr;
4948 MODIFY_REG(hfdcan->Instance->XIDFC, FDCAN_XIDFC_FLESA, (StartAddress << FDCAN_XIDFC_FLESA_Pos));
4949
4950 /* Extended filter elements number */
4951 MODIFY_REG(hfdcan->Instance->XIDFC, FDCAN_XIDFC_LSE, (hfdcan->Init.ExtFiltersNbr << FDCAN_XIDFC_LSE_Pos));
4952
4953 /* Rx FIFO 0 start address */
4954 StartAddress += (hfdcan->Init.ExtFiltersNbr * 2U);
4955 MODIFY_REG(hfdcan->Instance->RXF0C, FDCAN_RXF0C_F0SA, (StartAddress << FDCAN_RXF0C_F0SA_Pos));
4956
4957 /* Rx FIFO 0 elements number */
4958 MODIFY_REG(hfdcan->Instance->RXF0C, FDCAN_RXF0C_F0S, (hfdcan->Init.RxFifo0ElmtsNbr << FDCAN_RXF0C_F0S_Pos));
4959
4960 /* Rx FIFO 1 start address */
4961 StartAddress += (hfdcan->Init.RxFifo0ElmtsNbr * hfdcan->Init.RxFifo0ElmtSize);
4962 MODIFY_REG(hfdcan->Instance->RXF1C, FDCAN_RXF1C_F1SA, (StartAddress << FDCAN_RXF1C_F1SA_Pos));
4963
4964 /* Rx FIFO 1 elements number */
4965 MODIFY_REG(hfdcan->Instance->RXF1C, FDCAN_RXF1C_F1S, (hfdcan->Init.RxFifo1ElmtsNbr << FDCAN_RXF1C_F1S_Pos));
4966
4967 /* Rx buffer list start address */
4968 StartAddress += (hfdcan->Init.RxFifo1ElmtsNbr * hfdcan->Init.RxFifo1ElmtSize);
4969 MODIFY_REG(hfdcan->Instance->RXBC, FDCAN_RXBC_RBSA, (StartAddress << FDCAN_RXBC_RBSA_Pos));
4970
4971 /* Tx event FIFO start address */
4972 StartAddress += (hfdcan->Init.RxBuffersNbr * hfdcan->Init.RxBufferSize);
4973 MODIFY_REG(hfdcan->Instance->TXEFC, FDCAN_TXEFC_EFSA, (StartAddress << FDCAN_TXEFC_EFSA_Pos));
4974
4975 /* Tx event FIFO elements number */
4976 MODIFY_REG(hfdcan->Instance->TXEFC, FDCAN_TXEFC_EFS, (hfdcan->Init.TxEventsNbr << FDCAN_TXEFC_EFS_Pos));
4977
4978 /* Tx buffer list start address */
4979 StartAddress += (hfdcan->Init.TxEventsNbr * 2U);
4980 MODIFY_REG(hfdcan->Instance->TXBC, FDCAN_TXBC_TBSA, (StartAddress << FDCAN_TXBC_TBSA_Pos));
4981
4982 /* Dedicated Tx buffers number */
4983 MODIFY_REG(hfdcan->Instance->TXBC, FDCAN_TXBC_NDTB, (hfdcan->Init.TxBuffersNbr << FDCAN_TXBC_NDTB_Pos));
4984
4985 /* Tx FIFO/queue elements number */
4986 MODIFY_REG(hfdcan->Instance->TXBC, FDCAN_TXBC_TFQS, (hfdcan->Init.TxFifoQueueElmtsNbr << FDCAN_TXBC_TFQS_Pos));
4987
4988 hfdcan->msgRam.StandardFilterSA = SRAMCAN_BASE + (hfdcan->Init.MessageRAMOffset * 4U);
4989 hfdcan->msgRam.ExtendedFilterSA = hfdcan->msgRam.StandardFilterSA + (hfdcan->Init.StdFiltersNbr * 4U);
4990 hfdcan->msgRam.RxFIFO0SA = hfdcan->msgRam.ExtendedFilterSA + (hfdcan->Init.ExtFiltersNbr * 2U * 4U);
4991 hfdcan->msgRam.RxFIFO1SA = hfdcan->msgRam.RxFIFO0SA + (hfdcan->Init.RxFifo0ElmtsNbr * hfdcan->Init.RxFifo0ElmtSize * 4U);
4992 hfdcan->msgRam.RxBufferSA = hfdcan->msgRam.RxFIFO1SA + (hfdcan->Init.RxFifo1ElmtsNbr * hfdcan->Init.RxFifo1ElmtSize * 4U);
4993 hfdcan->msgRam.TxEventFIFOSA = hfdcan->msgRam.RxBufferSA + (hfdcan->Init.RxBuffersNbr * hfdcan->Init.RxBufferSize * 4U);
4994 hfdcan->msgRam.TxBufferSA = hfdcan->msgRam.TxEventFIFOSA + (hfdcan->Init.TxEventsNbr * 2U * 4U);
4995 hfdcan->msgRam.TxFIFOQSA = hfdcan->msgRam.TxBufferSA + (hfdcan->Init.TxBuffersNbr * hfdcan->Init.TxElmtSize * 4U);
4996
4997 hfdcan->msgRam.EndAddress = hfdcan->msgRam.TxFIFOQSA + (hfdcan->Init.TxFifoQueueElmtsNbr * hfdcan->Init.TxElmtSize * 4U);
4998
4999 if (hfdcan->msgRam.EndAddress > FDCAN_MESSAGE_RAM_END_ADDRESS) /* Last address of the Message RAM */
5000 {
5001 /* Update error code.
5002 Message RAM overflow */
5003 hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;
5004
5005 /* Change FDCAN state */
5006 hfdcan->State = HAL_FDCAN_STATE_ERROR;
5007
5008 return HAL_ERROR;
5009 }
5010 else
5011 {
5012 /* Flush the allocated Message RAM area */
5013 for (RAMcounter = hfdcan->msgRam.StandardFilterSA; RAMcounter < hfdcan->msgRam.EndAddress; RAMcounter += 4U)
5014 {
5015 *(uint32_t *)(RAMcounter) = 0x00000000;
5016 }
5017 }
5018
5019 /* Return function status */
5020 return HAL_OK;
5021 }
5022
5023 /**
5024 * @brief Copy Tx message to the message RAM.
5025 * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains
5026 * the configuration information for the specified FDCAN.
5027 * @param pTxHeader pointer to a FDCAN_TxHeaderTypeDef structure.
5028 * @param pTxData pointer to a buffer containing the payload of the Tx frame.
5029 * @param BufferIndex index of the buffer to be configured.
5030 * @retval HAL status
5031 */
FDCAN_CopyMessageToRAM(FDCAN_HandleTypeDef * hfdcan,FDCAN_TxHeaderTypeDef * pTxHeader,uint8_t * pTxData,uint32_t BufferIndex)5032 static void FDCAN_CopyMessageToRAM(FDCAN_HandleTypeDef *hfdcan, FDCAN_TxHeaderTypeDef *pTxHeader, uint8_t *pTxData, uint32_t BufferIndex)
5033 {
5034 uint32_t TxElementW1;
5035 uint32_t TxElementW2;
5036 uint32_t *TxAddress;
5037 uint32_t ByteCounter;
5038
5039 /* Build first word of Tx header element */
5040 if (pTxHeader->IdType == FDCAN_STANDARD_ID)
5041 {
5042 TxElementW1 = (pTxHeader->ErrorStateIndicator |
5043 FDCAN_STANDARD_ID |
5044 pTxHeader->TxFrameType |
5045 (pTxHeader->Identifier << 18));
5046 }
5047 else /* pTxHeader->IdType == FDCAN_EXTENDED_ID */
5048 {
5049 TxElementW1 = (pTxHeader->ErrorStateIndicator |
5050 FDCAN_EXTENDED_ID |
5051 pTxHeader->TxFrameType |
5052 pTxHeader->Identifier);
5053 }
5054
5055 /* Build second word of Tx header element */
5056 TxElementW2 = ((pTxHeader->MessageMarker << 24) |
5057 pTxHeader->TxEventFifoControl |
5058 pTxHeader->FDFormat |
5059 pTxHeader->BitRateSwitch |
5060 pTxHeader->DataLength);
5061
5062 /* Calculate Tx element address */
5063 TxAddress = (uint32_t *)(hfdcan->msgRam.TxBufferSA + (BufferIndex * hfdcan->Init.TxElmtSize * 4U));
5064
5065 /* Write Tx element header to the message RAM */
5066 *TxAddress = TxElementW1;
5067 TxAddress++;
5068 *TxAddress = TxElementW2;
5069 TxAddress++;
5070
5071 /* Write Tx payload to the message RAM */
5072 for (ByteCounter = 0; ByteCounter < DLCtoBytes[pTxHeader->DataLength >> 16]; ByteCounter += 4U)
5073 {
5074 *TxAddress = (((uint32_t)pTxData[ByteCounter + 3U] << 24) |
5075 ((uint32_t)pTxData[ByteCounter + 2U] << 16) |
5076 ((uint32_t)pTxData[ByteCounter + 1U] << 8) |
5077 (uint32_t)pTxData[ByteCounter]);
5078 TxAddress++;
5079 }
5080 }
5081
5082 /**
5083 * @}
5084 */
5085 #endif /* HAL_FDCAN_MODULE_ENABLED */
5086 /**
5087 * @}
5088 */
5089
5090 /**
5091 * @}
5092 */
5093
5094 #endif /* FDCAN1 */
5095