1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hal_can.c
4 * @author MCD Application Team
5 * @brief This file provides firmware functions to manage the following
6 * functionalities of the Controller Area Network (CAN) peripheral:
7 * + Initialization and de-initialization functions
8 * + IO operation functions
9 * + Peripheral Control functions
10 * + Peripheral State and Error functions
11 *
12 ******************************************************************************
13 * @attention
14 *
15 * Copyright (c) 2016 STMicroelectronics.
16 * All rights reserved.
17 *
18 * This software is licensed under terms that can be found in the LICENSE file
19 * in the root directory of this software component.
20 * If no LICENSE file comes with this software, it is provided AS-IS.
21 *
22 ******************************************************************************
23 @verbatim
24 ==============================================================================
25 ##### User NOTE #####
26 ==============================================================================
27 [..]
28 (#) This HAL CAN driver is deprecated, it contains some CAN Tx/Rx FIFO management limitations.
29 Another HAL CAN driver version has been designed with new API's, to fix these limitations.
30
31 ==============================================================================
32 ##### How to use this driver #####
33 ==============================================================================
34 [..]
35 (#) Enable the CAN controller interface clock using
36 __HAL_RCC_CAN1_CLK_ENABLE() for CAN1, __HAL_RCC_CAN2_CLK_ENABLE() for CAN2
37 and __HAL_RCC_CAN3_CLK_ENABLE() for CAN3
38 -@- In case you are using CAN2 only, you have to enable the CAN1 clock.
39
40 (#) CAN pins configuration
41 (++) Enable the clock for the CAN GPIOs using the following function:
42 __GPIOx_CLK_ENABLE()
43 (++) Connect and configure the involved CAN pins to AF9 using the
44 following function HAL_GPIO_Init()
45
46 (#) Initialize and configure the CAN using CAN_Init() function.
47
48 (#) Transmit the desired CAN frame using HAL_CAN_Transmit() function.
49
50 (#) Or transmit the desired CAN frame using HAL_CAN_Transmit_IT() function.
51
52 (#) Receive a CAN frame using HAL_CAN_Receive() function.
53
54 (#) Or receive a CAN frame using HAL_CAN_Receive_IT() function.
55
56 *** Polling mode IO operation ***
57 =================================
58 [..]
59 (+) Start the CAN peripheral transmission and wait the end of this operation
60 using HAL_CAN_Transmit(), at this stage user can specify the value of timeout
61 according to his end application
62 (+) Start the CAN peripheral reception and wait the end of this operation
63 using HAL_CAN_Receive(), at this stage user can specify the value of timeout
64 according to his end application
65
66 *** Interrupt mode IO operation ***
67 ===================================
68 [..]
69 (+) Start the CAN peripheral transmission using HAL_CAN_Transmit_IT()
70 (+) Start the CAN peripheral reception using HAL_CAN_Receive_IT()
71 (+) Use HAL_CAN_IRQHandler() called under the used CAN Interrupt subroutine
72 (+) At CAN end of transmission HAL_CAN_TxCpltCallback() function is executed and user can
73 add his own code by customization of function pointer HAL_CAN_TxCpltCallback
74 (+) In case of CAN Error, HAL_CAN_ErrorCallback() function is executed and user can
75 add his own code by customization of function pointer HAL_CAN_ErrorCallback
76
77 *** CAN HAL driver macros list ***
78 =============================================
79 [..]
80 Below the list of most used macros in CAN HAL driver.
81
82 (+) __HAL_CAN_ENABLE_IT: Enable the specified CAN interrupts
83 (+) __HAL_CAN_DISABLE_IT: Disable the specified CAN interrupts
84 (+) __HAL_CAN_GET_IT_SOURCE: Check if the specified CAN interrupt source is enabled or disabled
85 (+) __HAL_CAN_CLEAR_FLAG: Clear the CAN's pending flags
86 (+) __HAL_CAN_GET_FLAG: Get the selected CAN's flag status
87
88 [..]
89 (@) You can refer to the CAN Legacy HAL driver header file for more useful macros
90
91 @endverbatim
92
93 ******************************************************************************
94 */
95
96 /* Includes ------------------------------------------------------------------*/
97 #include "stm32f4xx_hal.h"
98
99 /** @addtogroup STM32F4xx_HAL_Driver
100 * @{
101 */
102
103 /** @defgroup CAN CAN
104 * @brief CAN driver modules
105 * @{
106 */
107
108 #ifdef HAL_CAN_LEGACY_MODULE_ENABLED
109
110 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\
111 defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\
112 defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||\
113 defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) ||\
114 defined(STM32F423xx)
115
116 #ifdef HAL_CAN_MODULE_ENABLED
117 /* Select HAL CAN module in stm32f4xx_hal_conf.h file:
118 (#) HAL_CAN_MODULE_ENABLED for new HAL CAN driver fixing FIFO limitations
119 (#) HAL_CAN_LEGACY_MODULE_ENABLED for legacy HAL CAN driver */
120 #error 'The HAL CAN driver cannot be used with its legacy, Please ensure to enable only one HAL CAN module at once in stm32f4xx_hal_conf.h file'
121 #endif /* HAL_CAN_MODULE_ENABLED */
122
123 #warning 'Legacy HAL CAN driver is enabled! It can be used with known limitations, refer to the release notes. However it is recommended to use rather the new HAL CAN driver'
124
125 /* Private typedef -----------------------------------------------------------*/
126 /* Private define ------------------------------------------------------------*/
127 /** @addtogroup CAN_Private_Constants
128 * @{
129 */
130 #define CAN_TIMEOUT_VALUE 10U
131 /**
132 * @}
133 */
134 /* Private macro -------------------------------------------------------------*/
135 /* Private variables ---------------------------------------------------------*/
136 /* Private function prototypes -----------------------------------------------*/
137 /** @addtogroup CAN_Private_Functions
138 * @{
139 */
140 static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber);
141 static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan);
142 /**
143 * @}
144 */
145
146 /* Exported functions --------------------------------------------------------*/
147 /** @defgroup CAN_Exported_Functions CAN Exported Functions
148 * @{
149 */
150
151 /** @defgroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions
152 * @brief Initialization and Configuration functions
153 *
154 @verbatim
155 ==============================================================================
156 ##### Initialization and de-initialization functions #####
157 ==============================================================================
158 [..] This section provides functions allowing to:
159 (+) Initialize and configure the CAN.
160 (+) De-initialize the CAN.
161
162 @endverbatim
163 * @{
164 */
165
166 /**
167 * @brief Initializes the CAN peripheral according to the specified
168 * parameters in the CAN_InitStruct.
169 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
170 * the configuration information for the specified CAN.
171 * @retval HAL status
172 */
HAL_CAN_Init(CAN_HandleTypeDef * hcan)173 HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan)
174 {
175 uint32_t InitStatus = CAN_INITSTATUS_FAILED;
176 uint32_t tickstart = 0U;
177
178 /* Check CAN handle */
179 if(hcan == NULL)
180 {
181 return HAL_ERROR;
182 }
183
184 /* Check the parameters */
185 assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
186 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TTCM));
187 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ABOM));
188 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AWUM));
189 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.NART));
190 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.RFLM));
191 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TXFP));
192 assert_param(IS_CAN_MODE(hcan->Init.Mode));
193 assert_param(IS_CAN_SJW(hcan->Init.SJW));
194 assert_param(IS_CAN_BS1(hcan->Init.BS1));
195 assert_param(IS_CAN_BS2(hcan->Init.BS2));
196 assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler));
197
198
199 if(hcan->State == HAL_CAN_STATE_RESET)
200 {
201 /* Allocate lock resource and initialize it */
202 hcan->Lock = HAL_UNLOCKED;
203 /* Init the low level hardware */
204 HAL_CAN_MspInit(hcan);
205 }
206
207 /* Initialize the CAN state*/
208 hcan->State = HAL_CAN_STATE_BUSY;
209
210 /* Exit from sleep mode */
211 hcan->Instance->MCR &= (~(uint32_t)CAN_MCR_SLEEP);
212
213 /* Request initialisation */
214 hcan->Instance->MCR |= CAN_MCR_INRQ ;
215
216 /* Get tick */
217 tickstart = HAL_GetTick();
218
219 /* Wait the acknowledge */
220 while((hcan->Instance->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
221 {
222 if((HAL_GetTick() - tickstart ) > CAN_TIMEOUT_VALUE)
223 {
224 hcan->State= HAL_CAN_STATE_TIMEOUT;
225 /* Process unlocked */
226 __HAL_UNLOCK(hcan);
227 return HAL_TIMEOUT;
228 }
229 }
230
231 /* Check acknowledge */
232 if ((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
233 {
234 /* Set the time triggered communication mode */
235 if (hcan->Init.TTCM == ENABLE)
236 {
237 hcan->Instance->MCR |= CAN_MCR_TTCM;
238 }
239 else
240 {
241 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_TTCM;
242 }
243
244 /* Set the automatic bus-off management */
245 if (hcan->Init.ABOM == ENABLE)
246 {
247 hcan->Instance->MCR |= CAN_MCR_ABOM;
248 }
249 else
250 {
251 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_ABOM;
252 }
253
254 /* Set the automatic wake-up mode */
255 if (hcan->Init.AWUM == ENABLE)
256 {
257 hcan->Instance->MCR |= CAN_MCR_AWUM;
258 }
259 else
260 {
261 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_AWUM;
262 }
263
264 /* Set the no automatic retransmission */
265 if (hcan->Init.NART == ENABLE)
266 {
267 hcan->Instance->MCR |= CAN_MCR_NART;
268 }
269 else
270 {
271 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_NART;
272 }
273
274 /* Set the receive FIFO locked mode */
275 if (hcan->Init.RFLM == ENABLE)
276 {
277 hcan->Instance->MCR |= CAN_MCR_RFLM;
278 }
279 else
280 {
281 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_RFLM;
282 }
283
284 /* Set the transmit FIFO priority */
285 if (hcan->Init.TXFP == ENABLE)
286 {
287 hcan->Instance->MCR |= CAN_MCR_TXFP;
288 }
289 else
290 {
291 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_TXFP;
292 }
293
294 /* Set the bit timing register */
295 hcan->Instance->BTR = (uint32_t)((uint32_t)hcan->Init.Mode) | \
296 ((uint32_t)hcan->Init.SJW) | \
297 ((uint32_t)hcan->Init.BS1) | \
298 ((uint32_t)hcan->Init.BS2) | \
299 ((uint32_t)hcan->Init.Prescaler - 1U);
300
301 /* Request leave initialisation */
302 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_INRQ;
303
304 /* Get tick */
305 tickstart = HAL_GetTick();
306
307 /* Wait the acknowledge */
308 while((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
309 {
310 if((HAL_GetTick() - tickstart ) > CAN_TIMEOUT_VALUE)
311 {
312 hcan->State= HAL_CAN_STATE_TIMEOUT;
313 /* Process unlocked */
314 __HAL_UNLOCK(hcan);
315 return HAL_TIMEOUT;
316 }
317 }
318
319 /* Check acknowledged */
320 if ((hcan->Instance->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
321 {
322 InitStatus = CAN_INITSTATUS_SUCCESS;
323 }
324 }
325
326 if(InitStatus == CAN_INITSTATUS_SUCCESS)
327 {
328 /* Set CAN error code to none */
329 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
330
331 /* Initialize the CAN state */
332 hcan->State = HAL_CAN_STATE_READY;
333
334 /* Return function status */
335 return HAL_OK;
336 }
337 else
338 {
339 /* Initialize the CAN state */
340 hcan->State = HAL_CAN_STATE_ERROR;
341
342 /* Return function status */
343 return HAL_ERROR;
344 }
345 }
346
347 /**
348 * @brief Configures the CAN reception filter according to the specified
349 * parameters in the CAN_FilterInitStruct.
350 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
351 * the configuration information for the specified CAN.
352 * @param sFilterConfig pointer to a CAN_FilterConfTypeDef structure that
353 * contains the filter configuration information.
354 * @retval None
355 */
HAL_CAN_ConfigFilter(CAN_HandleTypeDef * hcan,CAN_FilterConfTypeDef * sFilterConfig)356 HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef* hcan, CAN_FilterConfTypeDef* sFilterConfig)
357 {
358 uint32_t filternbrbitpos = 0U;
359 CAN_TypeDef *can_ip;
360
361 /* Prevent unused argument(s) compilation warning */
362 UNUSED(hcan);
363
364 /* Check the parameters */
365 assert_param(IS_CAN_FILTER_NUMBER(sFilterConfig->FilterNumber));
366 assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode));
367 assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale));
368 assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment));
369 assert_param(IS_FUNCTIONAL_STATE(sFilterConfig->FilterActivation));
370 assert_param(IS_CAN_BANKNUMBER(sFilterConfig->BankNumber));
371
372 filternbrbitpos = 1U << sFilterConfig->FilterNumber;
373 #if defined (CAN3)
374 /* Check the CAN instance */
375 if(hcan->Instance == CAN3)
376 {
377 can_ip = CAN3;
378 }
379 else
380 {
381 can_ip = CAN1;
382 }
383 #else
384 can_ip = CAN1;
385 #endif
386
387 /* Initialisation mode for the filter */
388 can_ip->FMR |= (uint32_t)CAN_FMR_FINIT;
389
390 #if defined (CAN2)
391 /* Select the start slave bank */
392 can_ip->FMR &= ~((uint32_t)CAN_FMR_CAN2SB);
393 can_ip->FMR |= (uint32_t)(sFilterConfig->BankNumber << 8U);
394 #endif
395
396 /* Filter Deactivation */
397 can_ip->FA1R &= ~(uint32_t)filternbrbitpos;
398
399 /* Filter Scale */
400 if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT)
401 {
402 /* 16-bit scale for the filter */
403 can_ip->FS1R &= ~(uint32_t)filternbrbitpos;
404
405 /* First 16-bit identifier and First 16-bit mask */
406 /* Or First 16-bit identifier and Second 16-bit identifier */
407 can_ip->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
408 ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16U) |
409 (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
410
411 /* Second 16-bit identifier and Second 16-bit mask */
412 /* Or Third 16-bit identifier and Fourth 16-bit identifier */
413 can_ip->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
414 ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
415 (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh);
416 }
417
418 if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
419 {
420 /* 32-bit scale for the filter */
421 can_ip->FS1R |= filternbrbitpos;
422
423 /* 32-bit identifier or First 32-bit identifier */
424 can_ip->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
425 ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh) << 16U) |
426 (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
427 /* 32-bit mask or Second 32-bit identifier */
428 can_ip->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
429 ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
430 (0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow);
431 }
432
433 /* Filter Mode */
434 if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
435 {
436 /*Id/Mask mode for the filter*/
437 can_ip->FM1R &= ~(uint32_t)filternbrbitpos;
438 }
439 else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
440 {
441 /*Identifier list mode for the filter*/
442 can_ip->FM1R |= (uint32_t)filternbrbitpos;
443 }
444
445 /* Filter FIFO assignment */
446 if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
447 {
448 /* FIFO 0 assignation for the filter */
449 can_ip->FFA1R &= ~(uint32_t)filternbrbitpos;
450 }
451
452 if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO1)
453 {
454 /* FIFO 1 assignation for the filter */
455 can_ip->FFA1R |= (uint32_t)filternbrbitpos;
456 }
457
458 /* Filter activation */
459 if (sFilterConfig->FilterActivation == ENABLE)
460 {
461 can_ip->FA1R |= filternbrbitpos;
462 }
463
464 /* Leave the initialisation mode for the filter */
465 can_ip->FMR &= ~((uint32_t)CAN_FMR_FINIT);
466
467 /* Return function status */
468 return HAL_OK;
469 }
470
471 /**
472 * @brief Deinitializes the CANx peripheral registers to their default reset values.
473 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
474 * the configuration information for the specified CAN.
475 * @retval HAL status
476 */
HAL_CAN_DeInit(CAN_HandleTypeDef * hcan)477 HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef* hcan)
478 {
479 /* Check CAN handle */
480 if(hcan == NULL)
481 {
482 return HAL_ERROR;
483 }
484
485 /* Check the parameters */
486 assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
487
488 /* Change CAN state */
489 hcan->State = HAL_CAN_STATE_BUSY;
490
491 /* DeInit the low level hardware */
492 HAL_CAN_MspDeInit(hcan);
493
494 /* Change CAN state */
495 hcan->State = HAL_CAN_STATE_RESET;
496
497 /* Release Lock */
498 __HAL_UNLOCK(hcan);
499
500 /* Return function status */
501 return HAL_OK;
502 }
503
504 /**
505 * @brief Initializes the CAN MSP.
506 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
507 * the configuration information for the specified CAN.
508 * @retval None
509 */
HAL_CAN_MspInit(CAN_HandleTypeDef * hcan)510 __weak void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
511 {
512 /* Prevent unused argument(s) compilation warning */
513 UNUSED(hcan);
514 /* NOTE : This function Should not be modified, when the callback is needed,
515 the HAL_CAN_MspInit could be implemented in the user file
516 */
517 }
518
519 /**
520 * @brief DeInitializes the CAN MSP.
521 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
522 * the configuration information for the specified CAN.
523 * @retval None
524 */
HAL_CAN_MspDeInit(CAN_HandleTypeDef * hcan)525 __weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
526 {
527 /* Prevent unused argument(s) compilation warning */
528 UNUSED(hcan);
529 /* NOTE : This function Should not be modified, when the callback is needed,
530 the HAL_CAN_MspDeInit could be implemented in the user file
531 */
532 }
533
534 /**
535 * @}
536 */
537
538 /** @defgroup CAN_Exported_Functions_Group2 IO operation functions
539 * @brief IO operation functions
540 *
541 @verbatim
542 ==============================================================================
543 ##### IO operation functions #####
544 ==============================================================================
545 [..] This section provides functions allowing to:
546 (+) Transmit a CAN frame message.
547 (+) Receive a CAN frame message.
548 (+) Enter CAN peripheral in sleep mode.
549 (+) Wake up the CAN peripheral from sleep mode.
550
551 @endverbatim
552 * @{
553 */
554
555 /**
556 * @brief Initiates and transmits a CAN frame message.
557 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
558 * the configuration information for the specified CAN.
559 * @param Timeout Specify Timeout value
560 * @retval HAL status
561 */
HAL_CAN_Transmit(CAN_HandleTypeDef * hcan,uint32_t Timeout)562 HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout)
563 {
564 uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
565 uint32_t tickstart = 0U;
566
567 /* Check the parameters */
568 assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
569 assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
570 assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
571
572 if(((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) || \
573 ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) || \
574 ((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2))
575 {
576 /* Process locked */
577 __HAL_LOCK(hcan);
578
579 /* Change CAN state */
580 switch(hcan->State)
581 {
582 case(HAL_CAN_STATE_BUSY_RX0):
583 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
584 break;
585 case(HAL_CAN_STATE_BUSY_RX1):
586 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
587 break;
588 case(HAL_CAN_STATE_BUSY_RX0_RX1):
589 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
590 break;
591 default: /* HAL_CAN_STATE_READY */
592 hcan->State = HAL_CAN_STATE_BUSY_TX;
593 break;
594 }
595
596 /* Select one empty transmit mailbox */
597 if ((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
598 {
599 transmitmailbox = CAN_TXMAILBOX_0;
600 }
601 else if ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
602 {
603 transmitmailbox = CAN_TXMAILBOX_1;
604 }
605 else
606 {
607 transmitmailbox = CAN_TXMAILBOX_2;
608 }
609
610 /* Set up the Id */
611 hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
612 if (hcan->pTxMsg->IDE == CAN_ID_STD)
613 {
614 assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
615 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << 21U) | \
616 hcan->pTxMsg->RTR);
617 }
618 else
619 {
620 assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
621 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << 3U) | \
622 hcan->pTxMsg->IDE | \
623 hcan->pTxMsg->RTR);
624 }
625
626 /* Set up the DLC */
627 hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
628 hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0U;
629 hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
630
631 /* Set up the data field */
632 hcan->Instance->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)hcan->pTxMsg->Data[3U] << 24U) |
633 ((uint32_t)hcan->pTxMsg->Data[2U] << 16U) |
634 ((uint32_t)hcan->pTxMsg->Data[1U] << 8U) |
635 ((uint32_t)hcan->pTxMsg->Data[0U]));
636 hcan->Instance->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)hcan->pTxMsg->Data[7U] << 24U) |
637 ((uint32_t)hcan->pTxMsg->Data[6U] << 16U) |
638 ((uint32_t)hcan->pTxMsg->Data[5U] << 8U) |
639 ((uint32_t)hcan->pTxMsg->Data[4U]));
640 /* Request transmission */
641 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
642
643 /* Get tick */
644 tickstart = HAL_GetTick();
645
646 /* Check End of transmission flag */
647 while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
648 {
649 /* Check for the Timeout */
650 if(Timeout != HAL_MAX_DELAY)
651 {
652 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
653 {
654 hcan->State = HAL_CAN_STATE_TIMEOUT;
655
656 __HAL_CAN_CANCEL_TRANSMIT(hcan, transmitmailbox);
657
658 /* Process unlocked */
659 __HAL_UNLOCK(hcan);
660 return HAL_TIMEOUT;
661 }
662 }
663 }
664
665 /* Change CAN state */
666 switch(hcan->State)
667 {
668 case(HAL_CAN_STATE_BUSY_TX_RX0):
669 hcan->State = HAL_CAN_STATE_BUSY_RX0;
670 break;
671 case(HAL_CAN_STATE_BUSY_TX_RX1):
672 hcan->State = HAL_CAN_STATE_BUSY_RX1;
673 break;
674 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
675 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
676 break;
677 default: /* HAL_CAN_STATE_BUSY_TX */
678 hcan->State = HAL_CAN_STATE_READY;
679 break;
680 }
681
682 /* Process unlocked */
683 __HAL_UNLOCK(hcan);
684
685 /* Return function status */
686 return HAL_OK;
687 }
688 else
689 {
690 /* Change CAN state */
691 hcan->State = HAL_CAN_STATE_ERROR;
692
693 /* Return function status */
694 return HAL_ERROR;
695 }
696 }
697
698 /**
699 * @brief Initiates and transmits a CAN frame message.
700 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
701 * the configuration information for the specified CAN.
702 * @retval HAL status
703 */
HAL_CAN_Transmit_IT(CAN_HandleTypeDef * hcan)704 HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
705 {
706 uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
707
708 /* Check the parameters */
709 assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
710 assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
711 assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
712
713 if(((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) || \
714 ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) || \
715 ((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2))
716 {
717 /* Process Locked */
718 __HAL_LOCK(hcan);
719
720 /* Select one empty transmit mailbox */
721 if((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
722 {
723 transmitmailbox = CAN_TXMAILBOX_0;
724 }
725 else if((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
726 {
727 transmitmailbox = CAN_TXMAILBOX_1;
728 }
729 else
730 {
731 transmitmailbox = CAN_TXMAILBOX_2;
732 }
733
734 /* Set up the Id */
735 hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
736 if(hcan->pTxMsg->IDE == CAN_ID_STD)
737 {
738 assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
739 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << 21U) | \
740 hcan->pTxMsg->RTR);
741 }
742 else
743 {
744 assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
745 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << 3U) | \
746 hcan->pTxMsg->IDE | \
747 hcan->pTxMsg->RTR);
748 }
749
750 /* Set up the DLC */
751 hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
752 hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0U;
753 hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
754
755 /* Set up the data field */
756 hcan->Instance->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)hcan->pTxMsg->Data[3U] << 24U) |
757 ((uint32_t)hcan->pTxMsg->Data[2U] << 16U) |
758 ((uint32_t)hcan->pTxMsg->Data[1U] << 8U) |
759 ((uint32_t)hcan->pTxMsg->Data[0U]));
760 hcan->Instance->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)hcan->pTxMsg->Data[7U] << 24U) |
761 ((uint32_t)hcan->pTxMsg->Data[6U] << 16U) |
762 ((uint32_t)hcan->pTxMsg->Data[5U] << 8U) |
763 ((uint32_t)hcan->pTxMsg->Data[4U]));
764
765 /* Change CAN state */
766 switch(hcan->State)
767 {
768 case(HAL_CAN_STATE_BUSY_RX0):
769 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
770 break;
771 case(HAL_CAN_STATE_BUSY_RX1):
772 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
773 break;
774 case(HAL_CAN_STATE_BUSY_RX0_RX1):
775 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
776 break;
777 default: /* HAL_CAN_STATE_READY */
778 hcan->State = HAL_CAN_STATE_BUSY_TX;
779 break;
780 }
781
782 /* Set CAN error code to none */
783 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
784
785 /* Process Unlocked */
786 __HAL_UNLOCK(hcan);
787
788 /* Request transmission */
789 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
790
791 /* Enable Error warning, Error passive, Bus-off,
792 Last error and Error Interrupts */
793 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
794 CAN_IT_EPV |
795 CAN_IT_BOF |
796 CAN_IT_LEC |
797 CAN_IT_ERR |
798 CAN_IT_TME);
799 }
800 else
801 {
802 /* Change CAN state */
803 hcan->State = HAL_CAN_STATE_ERROR;
804
805 /* Return function status */
806 return HAL_ERROR;
807 }
808
809 return HAL_OK;
810 }
811
812 /**
813 * @brief Receives a correct CAN frame.
814 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
815 * the configuration information for the specified CAN.
816 * @param FIFONumber FIFO Number value
817 * @param Timeout Specify Timeout value
818 * @retval HAL status
819 */
HAL_CAN_Receive(CAN_HandleTypeDef * hcan,uint8_t FIFONumber,uint32_t Timeout)820 HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef* hcan, uint8_t FIFONumber, uint32_t Timeout)
821 {
822 uint32_t tickstart = 0U;
823 CanRxMsgTypeDef* pRxMsg = NULL;
824
825 /* Check the parameters */
826 assert_param(IS_CAN_FIFO(FIFONumber));
827
828 /* Check if CAN state is not busy for RX FIFO0 */
829 if ((FIFONumber == CAN_FIFO0) && ((hcan->State == HAL_CAN_STATE_BUSY_RX0) || \
830 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0) || \
831 (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
832 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
833 {
834 return HAL_BUSY;
835 }
836
837 /* Check if CAN state is not busy for RX FIFO1 */
838 if ((FIFONumber == CAN_FIFO1) && ((hcan->State == HAL_CAN_STATE_BUSY_RX1) || \
839 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX1) || \
840 (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
841 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
842 {
843 return HAL_BUSY;
844 }
845
846 /* Process locked */
847 __HAL_LOCK(hcan);
848
849 /* Change CAN state */
850 if (FIFONumber == CAN_FIFO0)
851 {
852 switch(hcan->State)
853 {
854 case(HAL_CAN_STATE_BUSY_TX):
855 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
856 break;
857 case(HAL_CAN_STATE_BUSY_RX1):
858 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
859 break;
860 case(HAL_CAN_STATE_BUSY_TX_RX1):
861 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
862 break;
863 default: /* HAL_CAN_STATE_READY */
864 hcan->State = HAL_CAN_STATE_BUSY_RX0;
865 break;
866 }
867 }
868 else /* FIFONumber == CAN_FIFO1 */
869 {
870 switch(hcan->State)
871 {
872 case(HAL_CAN_STATE_BUSY_TX):
873 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
874 break;
875 case(HAL_CAN_STATE_BUSY_RX0):
876 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
877 break;
878 case(HAL_CAN_STATE_BUSY_TX_RX0):
879 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
880 break;
881 default: /* HAL_CAN_STATE_READY */
882 hcan->State = HAL_CAN_STATE_BUSY_RX1;
883 break;
884 }
885 }
886
887 /* Get tick */
888 tickstart = HAL_GetTick();
889
890 /* Check pending message */
891 while(__HAL_CAN_MSG_PENDING(hcan, FIFONumber) == 0U)
892 {
893 /* Check for the Timeout */
894 if(Timeout != HAL_MAX_DELAY)
895 {
896 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
897 {
898 hcan->State = HAL_CAN_STATE_TIMEOUT;
899 /* Process unlocked */
900 __HAL_UNLOCK(hcan);
901 return HAL_TIMEOUT;
902 }
903 }
904 }
905
906 /* Set RxMsg pointer */
907 if(FIFONumber == CAN_FIFO0)
908 {
909 pRxMsg = hcan->pRxMsg;
910 }
911 else /* FIFONumber == CAN_FIFO1 */
912 {
913 pRxMsg = hcan->pRx1Msg;
914 }
915
916 /* Get the Id */
917 pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
918 if (pRxMsg->IDE == CAN_ID_STD)
919 {
920 pRxMsg->StdId = 0x000007FFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21U);
921 }
922 else
923 {
924 pRxMsg->ExtId = 0x1FFFFFFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3U);
925 }
926
927 pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
928 /* Get the DLC */
929 pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
930 /* Get the FMI */
931 pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8U);
932 /* Get the FIFONumber */
933 pRxMsg->FIFONumber = FIFONumber;
934 /* Get the data field */
935 pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
936 pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8U);
937 pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16U);
938 pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24U);
939 pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
940 pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8U);
941 pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16U);
942 pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24U);
943
944 /* Release the FIFO */
945 if(FIFONumber == CAN_FIFO0)
946 {
947 /* Release FIFO0 */
948 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
949 }
950 else /* FIFONumber == CAN_FIFO1 */
951 {
952 /* Release FIFO1 */
953 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
954 }
955
956 /* Change CAN state */
957 if (FIFONumber == CAN_FIFO0)
958 {
959 switch(hcan->State)
960 {
961 case(HAL_CAN_STATE_BUSY_TX_RX0):
962 hcan->State = HAL_CAN_STATE_BUSY_TX;
963 break;
964 case(HAL_CAN_STATE_BUSY_RX0_RX1):
965 hcan->State = HAL_CAN_STATE_BUSY_RX1;
966 break;
967 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
968 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
969 break;
970 default: /* HAL_CAN_STATE_BUSY_RX0 */
971 hcan->State = HAL_CAN_STATE_READY;
972 break;
973 }
974 }
975 else /* FIFONumber == CAN_FIFO1 */
976 {
977 switch(hcan->State)
978 {
979 case(HAL_CAN_STATE_BUSY_TX_RX1):
980 hcan->State = HAL_CAN_STATE_BUSY_TX;
981 break;
982 case(HAL_CAN_STATE_BUSY_RX0_RX1):
983 hcan->State = HAL_CAN_STATE_BUSY_RX0;
984 break;
985 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
986 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
987 break;
988 default: /* HAL_CAN_STATE_BUSY_RX1 */
989 hcan->State = HAL_CAN_STATE_READY;
990 break;
991 }
992 }
993
994 /* Process unlocked */
995 __HAL_UNLOCK(hcan);
996
997 /* Return function status */
998 return HAL_OK;
999 }
1000
1001 /**
1002 * @brief Receives a correct CAN frame.
1003 * @param hcan Pointer to a CAN_HandleTypeDef structure that contains
1004 * the configuration information for the specified CAN.
1005 * @param FIFONumber Specify the FIFO number
1006 * @retval HAL status
1007 */
HAL_CAN_Receive_IT(CAN_HandleTypeDef * hcan,uint8_t FIFONumber)1008 HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
1009 {
1010 /* Check the parameters */
1011 assert_param(IS_CAN_FIFO(FIFONumber));
1012
1013 /* Check if CAN state is not busy for RX FIFO0 */
1014 if((FIFONumber == CAN_FIFO0) && ((hcan->State == HAL_CAN_STATE_BUSY_RX0) || \
1015 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0) || \
1016 (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
1017 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
1018 {
1019 return HAL_BUSY;
1020 }
1021
1022 /* Check if CAN state is not busy for RX FIFO1 */
1023 if((FIFONumber == CAN_FIFO1) && ((hcan->State == HAL_CAN_STATE_BUSY_RX1) || \
1024 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX1) || \
1025 (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
1026 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
1027 {
1028 return HAL_BUSY;
1029 }
1030
1031 /* Process locked */
1032 __HAL_LOCK(hcan);
1033
1034 /* Change CAN state */
1035 if(FIFONumber == CAN_FIFO0)
1036 {
1037 switch(hcan->State)
1038 {
1039 case(HAL_CAN_STATE_BUSY_TX):
1040 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
1041 break;
1042 case(HAL_CAN_STATE_BUSY_RX1):
1043 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
1044 break;
1045 case(HAL_CAN_STATE_BUSY_TX_RX1):
1046 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
1047 break;
1048 default: /* HAL_CAN_STATE_READY */
1049 hcan->State = HAL_CAN_STATE_BUSY_RX0;
1050 break;
1051 }
1052 }
1053 else /* FIFONumber == CAN_FIFO1 */
1054 {
1055 switch(hcan->State)
1056 {
1057 case(HAL_CAN_STATE_BUSY_TX):
1058 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
1059 break;
1060 case(HAL_CAN_STATE_BUSY_RX0):
1061 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
1062 break;
1063 case(HAL_CAN_STATE_BUSY_TX_RX0):
1064 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
1065 break;
1066 default: /* HAL_CAN_STATE_READY */
1067 hcan->State = HAL_CAN_STATE_BUSY_RX1;
1068 break;
1069 }
1070 }
1071 /* Set CAN error code to none */
1072 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
1073
1074 /* Enable interrupts: */
1075 /* - Enable Error warning Interrupt */
1076 /* - Enable Error passive Interrupt */
1077 /* - Enable Bus-off Interrupt */
1078 /* - Enable Last error code Interrupt */
1079 /* - Enable Error Interrupt */
1080 /* - Enable Transmit mailbox empty Interrupt */
1081 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
1082 CAN_IT_EPV |
1083 CAN_IT_BOF |
1084 CAN_IT_LEC |
1085 CAN_IT_ERR |
1086 CAN_IT_TME);
1087
1088 /* Process unlocked */
1089 __HAL_UNLOCK(hcan);
1090
1091 if(FIFONumber == CAN_FIFO0)
1092 {
1093 /* Enable FIFO 0 overrun and message pending Interrupt */
1094 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FOV0 | CAN_IT_FMP0);
1095 }
1096 else
1097 {
1098 /* Enable FIFO 1 overrun and message pending Interrupt */
1099 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FOV1 | CAN_IT_FMP1);
1100 }
1101
1102 /* Return function status */
1103 return HAL_OK;
1104 }
1105
1106 /**
1107 * @brief Enters the Sleep (low power) mode.
1108 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1109 * the configuration information for the specified CAN.
1110 * @retval HAL status.
1111 */
HAL_CAN_Sleep(CAN_HandleTypeDef * hcan)1112 HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef* hcan)
1113 {
1114 uint32_t tickstart = 0U;
1115
1116 /* Process locked */
1117 __HAL_LOCK(hcan);
1118
1119 /* Change CAN state */
1120 hcan->State = HAL_CAN_STATE_BUSY;
1121
1122 /* Request Sleep mode */
1123 hcan->Instance->MCR = (((hcan->Instance->MCR) & (uint32_t)(~(uint32_t)CAN_MCR_INRQ)) | CAN_MCR_SLEEP);
1124
1125 /* Sleep mode status */
1126 if ((hcan->Instance->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) != CAN_MSR_SLAK)
1127 {
1128 /* Process unlocked */
1129 __HAL_UNLOCK(hcan);
1130
1131 /* Return function status */
1132 return HAL_ERROR;
1133 }
1134
1135 /* Get tick */
1136 tickstart = HAL_GetTick();
1137
1138 /* Wait the acknowledge */
1139 while((hcan->Instance->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) != CAN_MSR_SLAK)
1140 {
1141 if((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
1142 {
1143 hcan->State = HAL_CAN_STATE_TIMEOUT;
1144 /* Process unlocked */
1145 __HAL_UNLOCK(hcan);
1146 return HAL_TIMEOUT;
1147 }
1148 }
1149
1150 /* Change CAN state */
1151 hcan->State = HAL_CAN_STATE_READY;
1152
1153 /* Process unlocked */
1154 __HAL_UNLOCK(hcan);
1155
1156 /* Return function status */
1157 return HAL_OK;
1158 }
1159
1160 /**
1161 * @brief Wakes up the CAN peripheral from sleep mode, after that the CAN peripheral
1162 * is in the normal mode.
1163 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1164 * the configuration information for the specified CAN.
1165 * @retval HAL status.
1166 */
HAL_CAN_WakeUp(CAN_HandleTypeDef * hcan)1167 HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef* hcan)
1168 {
1169 uint32_t tickstart = 0U;
1170
1171 /* Process locked */
1172 __HAL_LOCK(hcan);
1173
1174 /* Change CAN state */
1175 hcan->State = HAL_CAN_STATE_BUSY;
1176
1177 /* Wake up request */
1178 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_SLEEP;
1179
1180 /* Get tick */
1181 tickstart = HAL_GetTick();
1182
1183 /* Sleep mode status */
1184 while((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
1185 {
1186 if((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
1187 {
1188 hcan->State= HAL_CAN_STATE_TIMEOUT;
1189 /* Process unlocked */
1190 __HAL_UNLOCK(hcan);
1191 return HAL_TIMEOUT;
1192 }
1193 }
1194 if((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
1195 {
1196 /* Process unlocked */
1197 __HAL_UNLOCK(hcan);
1198
1199 /* Return function status */
1200 return HAL_ERROR;
1201 }
1202
1203 /* Change CAN state */
1204 hcan->State = HAL_CAN_STATE_READY;
1205
1206 /* Process unlocked */
1207 __HAL_UNLOCK(hcan);
1208
1209 /* Return function status */
1210 return HAL_OK;
1211 }
1212
1213 /**
1214 * @brief Handles CAN interrupt request
1215 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1216 * the configuration information for the specified CAN.
1217 * @retval None
1218 */
HAL_CAN_IRQHandler(CAN_HandleTypeDef * hcan)1219 void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan)
1220 {
1221 uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U;
1222 uint32_t errorcode = HAL_CAN_ERROR_NONE;
1223
1224 /* Check Overrun flag for FIFO0 */
1225 tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV0);
1226 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FOV0);
1227 if(tmp1 && tmp2)
1228 {
1229 /* Set CAN error code to FOV0 error */
1230 errorcode |= HAL_CAN_ERROR_FOV0;
1231
1232 /* Clear FIFO0 Overrun Flag */
1233 __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV0);
1234 }
1235 /* Check Overrun flag for FIFO1 */
1236 tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV1);
1237 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FOV1);
1238
1239 if(tmp1 && tmp2)
1240 {
1241 /* Set CAN error code to FOV1 error */
1242 errorcode |= HAL_CAN_ERROR_FOV1;
1243
1244 /* Clear FIFO1 Overrun Flag */
1245 __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV1);
1246 }
1247
1248 /* Check End of transmission flag */
1249 if(__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_TME))
1250 {
1251 tmp1 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_0);
1252 tmp2 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_1);
1253 tmp3 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_2);
1254 if(tmp1 || tmp2 || tmp3)
1255 {
1256 tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK0);
1257 tmp2 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK1);
1258 tmp3 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK2);
1259 /* Check Transmit success */
1260 if(tmp1 || tmp2 || tmp3)
1261 {
1262 /* Call transmit function */
1263 CAN_Transmit_IT(hcan);
1264 }
1265 else /* Transmit failure */
1266 {
1267 /* Set CAN error code to TXFAIL error */
1268 errorcode |= HAL_CAN_ERROR_TXFAIL;
1269 }
1270
1271 /* Clear transmission status flags (RQCPx and TXOKx) */
1272 SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP0 | CAN_TSR_RQCP1 | CAN_TSR_RQCP2 | \
1273 CAN_FLAG_TXOK0 | CAN_FLAG_TXOK1 | CAN_FLAG_TXOK2);
1274 }
1275 }
1276
1277 tmp1 = __HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0);
1278 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0);
1279 /* Check End of reception flag for FIFO0 */
1280 if((tmp1 != 0U) && tmp2)
1281 {
1282 /* Call receive function */
1283 CAN_Receive_IT(hcan, CAN_FIFO0);
1284 }
1285
1286 tmp1 = __HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1);
1287 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1);
1288 /* Check End of reception flag for FIFO1 */
1289 if((tmp1 != 0U) && tmp2)
1290 {
1291 /* Call receive function */
1292 CAN_Receive_IT(hcan, CAN_FIFO1);
1293 }
1294
1295 /* Set error code in handle */
1296 hcan->ErrorCode |= errorcode;
1297
1298 tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EWG);
1299 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EWG);
1300 tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
1301 /* Check Error Warning Flag */
1302 if(tmp1 && tmp2 && tmp3)
1303 {
1304 /* Set CAN error code to EWG error */
1305 hcan->ErrorCode |= HAL_CAN_ERROR_EWG;
1306 }
1307
1308 tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EPV);
1309 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EPV);
1310 tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
1311 /* Check Error Passive Flag */
1312 if(tmp1 && tmp2 && tmp3)
1313 {
1314 /* Set CAN error code to EPV error */
1315 hcan->ErrorCode |= HAL_CAN_ERROR_EPV;
1316 }
1317
1318 tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_BOF);
1319 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_BOF);
1320 tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
1321 /* Check Bus-Off Flag */
1322 if(tmp1 && tmp2 && tmp3)
1323 {
1324 /* Set CAN error code to BOF error */
1325 hcan->ErrorCode |= HAL_CAN_ERROR_BOF;
1326 }
1327
1328 tmp1 = HAL_IS_BIT_CLR(hcan->Instance->ESR, CAN_ESR_LEC);
1329 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_LEC);
1330 tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
1331 /* Check Last error code Flag */
1332 if((!tmp1) && tmp2 && tmp3)
1333 {
1334 tmp1 = (hcan->Instance->ESR) & CAN_ESR_LEC;
1335 switch(tmp1)
1336 {
1337 case(CAN_ESR_LEC_0):
1338 /* Set CAN error code to STF error */
1339 hcan->ErrorCode |= HAL_CAN_ERROR_STF;
1340 break;
1341 case(CAN_ESR_LEC_1):
1342 /* Set CAN error code to FOR error */
1343 hcan->ErrorCode |= HAL_CAN_ERROR_FOR;
1344 break;
1345 case(CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
1346 /* Set CAN error code to ACK error */
1347 hcan->ErrorCode |= HAL_CAN_ERROR_ACK;
1348 break;
1349 case(CAN_ESR_LEC_2):
1350 /* Set CAN error code to BR error */
1351 hcan->ErrorCode |= HAL_CAN_ERROR_BR;
1352 break;
1353 case(CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
1354 /* Set CAN error code to BD error */
1355 hcan->ErrorCode |= HAL_CAN_ERROR_BD;
1356 break;
1357 case(CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
1358 /* Set CAN error code to CRC error */
1359 hcan->ErrorCode |= HAL_CAN_ERROR_CRC;
1360 break;
1361 default:
1362 break;
1363 }
1364
1365 /* Clear Last error code Flag */
1366 hcan->Instance->ESR &= ~(CAN_ESR_LEC);
1367 }
1368
1369 /* Call the Error call Back in case of Errors */
1370 if(hcan->ErrorCode != HAL_CAN_ERROR_NONE)
1371 {
1372 /* Clear ERRI Flag */
1373 hcan->Instance->MSR = CAN_MSR_ERRI;
1374 /* Set the CAN state ready to be able to start again the process */
1375 hcan->State = HAL_CAN_STATE_READY;
1376
1377 /* Disable interrupts: */
1378 /* - Disable Error warning Interrupt */
1379 /* - Disable Error passive Interrupt */
1380 /* - Disable Bus-off Interrupt */
1381 /* - Disable Last error code Interrupt */
1382 /* - Disable Error Interrupt */
1383 /* - Disable FIFO 0 message pending Interrupt */
1384 /* - Disable FIFO 0 Overrun Interrupt */
1385 /* - Disable FIFO 1 message pending Interrupt */
1386 /* - Disable FIFO 1 Overrun Interrupt */
1387 /* - Disable Transmit mailbox empty Interrupt */
1388 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
1389 CAN_IT_EPV |
1390 CAN_IT_BOF |
1391 CAN_IT_LEC |
1392 CAN_IT_ERR |
1393 CAN_IT_FMP0|
1394 CAN_IT_FOV0|
1395 CAN_IT_FMP1|
1396 CAN_IT_FOV1|
1397 CAN_IT_TME);
1398
1399 /* Call Error callback function */
1400 HAL_CAN_ErrorCallback(hcan);
1401 }
1402 }
1403
1404 /**
1405 * @brief Transmission complete callback in non blocking mode
1406 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1407 * the configuration information for the specified CAN.
1408 * @retval None
1409 */
HAL_CAN_TxCpltCallback(CAN_HandleTypeDef * hcan)1410 __weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)
1411 {
1412 /* Prevent unused argument(s) compilation warning */
1413 UNUSED(hcan);
1414 /* NOTE : This function Should not be modified, when the callback is needed,
1415 the HAL_CAN_TxCpltCallback could be implemented in the user file
1416 */
1417 }
1418
1419 /**
1420 * @brief Transmission complete callback in non blocking mode
1421 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1422 * the configuration information for the specified CAN.
1423 * @retval None
1424 */
HAL_CAN_RxCpltCallback(CAN_HandleTypeDef * hcan)1425 __weak void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
1426 {
1427 /* Prevent unused argument(s) compilation warning */
1428 UNUSED(hcan);
1429 /* NOTE : This function Should not be modified, when the callback is needed,
1430 the HAL_CAN_RxCpltCallback could be implemented in the user file
1431 */
1432 }
1433
1434 /**
1435 * @brief Error CAN callback.
1436 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1437 * the configuration information for the specified CAN.
1438 * @retval None
1439 */
HAL_CAN_ErrorCallback(CAN_HandleTypeDef * hcan)1440 __weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
1441 {
1442 /* Prevent unused argument(s) compilation warning */
1443 UNUSED(hcan);
1444 /* NOTE : This function Should not be modified, when the callback is needed,
1445 the HAL_CAN_ErrorCallback could be implemented in the user file
1446 */
1447 }
1448
1449 /**
1450 * @}
1451 */
1452
1453 /** @defgroup CAN_Exported_Functions_Group3 Peripheral State and Error functions
1454 * @brief CAN Peripheral State functions
1455 *
1456 @verbatim
1457 ==============================================================================
1458 ##### Peripheral State and Error functions #####
1459 ==============================================================================
1460 [..]
1461 This subsection provides functions allowing to :
1462 (+) Check the CAN state.
1463 (+) Check CAN Errors detected during interrupt process
1464
1465 @endverbatim
1466 * @{
1467 */
1468
1469 /**
1470 * @brief return the CAN state
1471 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1472 * the configuration information for the specified CAN.
1473 * @retval HAL state
1474 */
HAL_CAN_GetState(CAN_HandleTypeDef * hcan)1475 HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan)
1476 {
1477 /* Return CAN state */
1478 return hcan->State;
1479 }
1480
1481 /**
1482 * @brief Return the CAN error code
1483 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1484 * the configuration information for the specified CAN.
1485 * @retval CAN Error Code
1486 */
HAL_CAN_GetError(CAN_HandleTypeDef * hcan)1487 uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan)
1488 {
1489 return hcan->ErrorCode;
1490 }
1491
1492 /**
1493 * @}
1494 */
1495 /**
1496 * @brief Initiates and transmits a CAN frame message.
1497 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1498 * the configuration information for the specified CAN.
1499 * @retval HAL status
1500 */
CAN_Transmit_IT(CAN_HandleTypeDef * hcan)1501 static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
1502 {
1503 /* Disable Transmit mailbox empty Interrupt */
1504 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_TME);
1505
1506 if(hcan->State == HAL_CAN_STATE_BUSY_TX)
1507 {
1508 /* Disable Error warning, Error passive, Bus-off, Last error code
1509 and Error Interrupts */
1510 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
1511 CAN_IT_EPV |
1512 CAN_IT_BOF |
1513 CAN_IT_LEC |
1514 CAN_IT_ERR );
1515 }
1516
1517 /* Change CAN state */
1518 switch(hcan->State)
1519 {
1520 case(HAL_CAN_STATE_BUSY_TX_RX0):
1521 hcan->State = HAL_CAN_STATE_BUSY_RX0;
1522 break;
1523 case(HAL_CAN_STATE_BUSY_TX_RX1):
1524 hcan->State = HAL_CAN_STATE_BUSY_RX1;
1525 break;
1526 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
1527 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
1528 break;
1529 default: /* HAL_CAN_STATE_BUSY_TX */
1530 hcan->State = HAL_CAN_STATE_READY;
1531 break;
1532 }
1533
1534 /* Transmission complete callback */
1535 HAL_CAN_TxCpltCallback(hcan);
1536
1537 return HAL_OK;
1538 }
1539
1540 /**
1541 * @brief Receives a correct CAN frame.
1542 * @param hcan Pointer to a CAN_HandleTypeDef structure that contains
1543 * the configuration information for the specified CAN.
1544 * @param FIFONumber Specify the FIFO number
1545 * @retval HAL status
1546 * @retval None
1547 */
CAN_Receive_IT(CAN_HandleTypeDef * hcan,uint8_t FIFONumber)1548 static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
1549 {
1550 uint32_t tmp1 = 0U;
1551 CanRxMsgTypeDef* pRxMsg = NULL;
1552
1553 /* Set RxMsg pointer */
1554 if(FIFONumber == CAN_FIFO0)
1555 {
1556 pRxMsg = hcan->pRxMsg;
1557 }
1558 else /* FIFONumber == CAN_FIFO1 */
1559 {
1560 pRxMsg = hcan->pRx1Msg;
1561 }
1562
1563 /* Get the Id */
1564 pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
1565 if (pRxMsg->IDE == CAN_ID_STD)
1566 {
1567 pRxMsg->StdId = 0x000007FFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21U);
1568 }
1569 else
1570 {
1571 pRxMsg->ExtId = 0x1FFFFFFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3U);
1572 }
1573
1574 pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
1575 /* Get the DLC */
1576 pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
1577 /* Get the FIFONumber */
1578 pRxMsg->FIFONumber = FIFONumber;
1579 /* Get the FMI */
1580 pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8U);
1581 /* Get the data field */
1582 pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
1583 pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8U);
1584 pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16U);
1585 pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24U);
1586 pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
1587 pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8U);
1588 pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16U);
1589 pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24U);
1590 /* Release the FIFO */
1591 /* Release FIFO0 */
1592 if (FIFONumber == CAN_FIFO0)
1593 {
1594 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
1595
1596 /* Disable FIFO 0 overrun and message pending Interrupt */
1597 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FOV0 | CAN_IT_FMP0);
1598 }
1599 /* Release FIFO1 */
1600 else /* FIFONumber == CAN_FIFO1 */
1601 {
1602 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
1603
1604 /* Disable FIFO 1 overrun and message pending Interrupt */
1605 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FOV1 | CAN_IT_FMP1);
1606 }
1607
1608 tmp1 = hcan->State;
1609 if((tmp1 == HAL_CAN_STATE_BUSY_RX0) || (tmp1 == HAL_CAN_STATE_BUSY_RX1))
1610 {
1611 /* Disable Error warning, Error passive, Bus-off, Last error code
1612 and Error Interrupts */
1613 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
1614 CAN_IT_EPV |
1615 CAN_IT_BOF |
1616 CAN_IT_LEC |
1617 CAN_IT_ERR);
1618 }
1619
1620 /* Change CAN state */
1621 if (FIFONumber == CAN_FIFO0)
1622 {
1623 switch(hcan->State)
1624 {
1625 case(HAL_CAN_STATE_BUSY_TX_RX0):
1626 hcan->State = HAL_CAN_STATE_BUSY_TX;
1627 break;
1628 case(HAL_CAN_STATE_BUSY_RX0_RX1):
1629 hcan->State = HAL_CAN_STATE_BUSY_RX1;
1630 break;
1631 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
1632 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
1633 break;
1634 default: /* HAL_CAN_STATE_BUSY_RX0 */
1635 hcan->State = HAL_CAN_STATE_READY;
1636 break;
1637 }
1638 }
1639 else /* FIFONumber == CAN_FIFO1 */
1640 {
1641 switch(hcan->State)
1642 {
1643 case(HAL_CAN_STATE_BUSY_TX_RX1):
1644 hcan->State = HAL_CAN_STATE_BUSY_TX;
1645 break;
1646 case(HAL_CAN_STATE_BUSY_RX0_RX1):
1647 hcan->State = HAL_CAN_STATE_BUSY_RX0;
1648 break;
1649 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
1650 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
1651 break;
1652 default: /* HAL_CAN_STATE_BUSY_RX1 */
1653 hcan->State = HAL_CAN_STATE_READY;
1654 break;
1655 }
1656 }
1657
1658 /* Receive complete callback */
1659 HAL_CAN_RxCpltCallback(hcan);
1660
1661 /* Return function status */
1662 return HAL_OK;
1663 }
1664
1665 /**
1666 * @}
1667 */
1668 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx ||\
1669 STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx ||\
1670 STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */
1671
1672 #endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
1673 /**
1674 * @}
1675 */
1676
1677 /**
1678 * @}
1679 */
1680