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