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