1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_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   *           + Configuration functions
10   *           + Control functions
11   *           + Interrupts management
12   *           + Callbacks functions
13   *           + Peripheral State and Error functions
14   *
15   ******************************************************************************
16   * @attention
17   *
18   * Copyright (c) 2016 STMicroelectronics.
19   * All rights reserved.
20   *
21   * This software is licensed under terms that can be found in the LICENSE file
22   * in the root directory of this software component.
23   * If no LICENSE file comes with this software, it is provided AS-IS.
24   *
25   ******************************************************************************
26   @verbatim
27   ==============================================================================
28                         ##### How to use this driver #####
29   ==============================================================================
30     [..]
31       (#) Initialize the CAN low level resources by implementing the
32           HAL_CAN_MspInit():
33          (++) Enable the CAN interface clock using __HAL_RCC_CANx_CLK_ENABLE()
34          (++) Configure CAN pins
35              (+++) Enable the clock for the CAN GPIOs
36              (+++) Configure CAN pins as alternate function open-drain
37          (++) In case of using interrupts (e.g. HAL_CAN_ActivateNotification())
38              (+++) Configure the CAN interrupt priority using
39                    HAL_NVIC_SetPriority()
40              (+++) Enable the CAN IRQ handler using HAL_NVIC_EnableIRQ()
41              (+++) In CAN IRQ handler, call HAL_CAN_IRQHandler()
42 
43       (#) Initialize the CAN peripheral using HAL_CAN_Init() function. This
44           function resorts to HAL_CAN_MspInit() for low-level initialization.
45 
46       (#) Configure the reception filters using the following configuration
47           functions:
48             (++) HAL_CAN_ConfigFilter()
49 
50       (#) Start the CAN module using HAL_CAN_Start() function. At this level
51           the node is active on the bus: it receive messages, and can send
52           messages.
53 
54       (#) To manage messages transmission, the following Tx control functions
55           can be used:
56             (++) HAL_CAN_AddTxMessage() to request transmission of a new
57                  message.
58             (++) HAL_CAN_AbortTxRequest() to abort transmission of a pending
59                  message.
60             (++) HAL_CAN_GetTxMailboxesFreeLevel() to get the number of free Tx
61                  mailboxes.
62             (++) HAL_CAN_IsTxMessagePending() to check if a message is pending
63                  in a Tx mailbox.
64             (++) HAL_CAN_GetTxTimestamp() to get the timestamp of Tx message
65                  sent, if time triggered communication mode is enabled.
66 
67       (#) When a message is received into the CAN Rx FIFOs, it can be retrieved
68           using the HAL_CAN_GetRxMessage() function. The function
69           HAL_CAN_GetRxFifoFillLevel() allows to know how many Rx message are
70           stored in the Rx Fifo.
71 
72       (#) Calling the HAL_CAN_Stop() function stops the CAN module.
73 
74       (#) The deinitialization is achieved with HAL_CAN_DeInit() function.
75 
76 
77       *** Polling mode operation ***
78       ==============================
79     [..]
80       (#) Reception:
81             (++) Monitor reception of message using HAL_CAN_GetRxFifoFillLevel()
82                  until at least one message is received.
83             (++) Then get the message using HAL_CAN_GetRxMessage().
84 
85       (#) Transmission:
86             (++) Monitor the Tx mailboxes availability until at least one Tx
87                  mailbox is free, using HAL_CAN_GetTxMailboxesFreeLevel().
88             (++) Then request transmission of a message using
89                  HAL_CAN_AddTxMessage().
90 
91 
92       *** Interrupt mode operation ***
93       ================================
94     [..]
95       (#) Notifications are activated using HAL_CAN_ActivateNotification()
96           function. Then, the process can be controlled through the
97           available user callbacks: HAL_CAN_xxxCallback(), using same APIs
98           HAL_CAN_GetRxMessage() and HAL_CAN_AddTxMessage().
99 
100       (#) Notifications can be deactivated using
101           HAL_CAN_DeactivateNotification() function.
102 
103       (#) Special care should be taken for CAN_IT_RX_FIFO0_MSG_PENDING and
104           CAN_IT_RX_FIFO1_MSG_PENDING notifications. These notifications trig
105           the callbacks HAL_CAN_RxFIFO0MsgPendingCallback() and
106           HAL_CAN_RxFIFO1MsgPendingCallback(). User has two possible options
107           here.
108             (++) Directly get the Rx message in the callback, using
109                  HAL_CAN_GetRxMessage().
110             (++) Or deactivate the notification in the callback without
111                  getting the Rx message. The Rx message can then be got later
112                  using HAL_CAN_GetRxMessage(). Once the Rx message have been
113                  read, the notification can be activated again.
114 
115 
116       *** Sleep mode ***
117       ==================
118     [..]
119       (#) The CAN peripheral can be put in sleep mode (low power), using
120           HAL_CAN_RequestSleep(). The sleep mode will be entered as soon as the
121           current CAN activity (transmission or reception of a CAN frame) will
122           be completed.
123 
124       (#) A notification can be activated to be informed when the sleep mode
125           will be entered.
126 
127       (#) It can be checked if the sleep mode is entered using
128           HAL_CAN_IsSleepActive().
129           Note that the CAN state (accessible from the API HAL_CAN_GetState())
130           is HAL_CAN_STATE_SLEEP_PENDING as soon as the sleep mode request is
131           submitted (the sleep mode is not yet entered), and become
132           HAL_CAN_STATE_SLEEP_ACTIVE when the sleep mode is effective.
133 
134       (#) The wake-up from sleep mode can be triggered by two ways:
135             (++) Using HAL_CAN_WakeUp(). When returning from this function,
136                  the sleep mode is exited (if return status is HAL_OK).
137             (++) When a start of Rx CAN frame is detected by the CAN peripheral,
138                  if automatic wake up mode is enabled.
139 
140   *** Callback registration ***
141   =============================================
142 
143   The compilation define  USE_HAL_CAN_REGISTER_CALLBACKS when set to 1
144   allows the user to configure dynamically the driver callbacks.
145   Use Function HAL_CAN_RegisterCallback() to register an interrupt callback.
146 
147   Function HAL_CAN_RegisterCallback() allows to register following callbacks:
148     (+) TxMailbox0CompleteCallback   : Tx Mailbox 0 Complete Callback.
149     (+) TxMailbox1CompleteCallback   : Tx Mailbox 1 Complete Callback.
150     (+) TxMailbox2CompleteCallback   : Tx Mailbox 2 Complete Callback.
151     (+) TxMailbox0AbortCallback      : Tx Mailbox 0 Abort Callback.
152     (+) TxMailbox1AbortCallback      : Tx Mailbox 1 Abort Callback.
153     (+) TxMailbox2AbortCallback      : Tx Mailbox 2 Abort Callback.
154     (+) RxFifo0MsgPendingCallback    : Rx Fifo 0 Message Pending Callback.
155     (+) RxFifo0FullCallback          : Rx Fifo 0 Full Callback.
156     (+) RxFifo1MsgPendingCallback    : Rx Fifo 1 Message Pending Callback.
157     (+) RxFifo1FullCallback          : Rx Fifo 1 Full Callback.
158     (+) SleepCallback                : Sleep Callback.
159     (+) WakeUpFromRxMsgCallback      : Wake Up From Rx Message Callback.
160     (+) ErrorCallback                : Error Callback.
161     (+) MspInitCallback              : CAN MspInit.
162     (+) MspDeInitCallback            : CAN MspDeInit.
163   This function takes as parameters the HAL peripheral handle, the Callback ID
164   and a pointer to the user callback function.
165 
166   Use function HAL_CAN_UnRegisterCallback() to reset a callback to the default
167   weak function.
168   HAL_CAN_UnRegisterCallback takes as parameters the HAL peripheral handle,
169   and the Callback ID.
170   This function allows to reset following callbacks:
171     (+) TxMailbox0CompleteCallback   : Tx Mailbox 0 Complete Callback.
172     (+) TxMailbox1CompleteCallback   : Tx Mailbox 1 Complete Callback.
173     (+) TxMailbox2CompleteCallback   : Tx Mailbox 2 Complete Callback.
174     (+) TxMailbox0AbortCallback      : Tx Mailbox 0 Abort Callback.
175     (+) TxMailbox1AbortCallback      : Tx Mailbox 1 Abort Callback.
176     (+) TxMailbox2AbortCallback      : Tx Mailbox 2 Abort Callback.
177     (+) RxFifo0MsgPendingCallback    : Rx Fifo 0 Message Pending Callback.
178     (+) RxFifo0FullCallback          : Rx Fifo 0 Full Callback.
179     (+) RxFifo1MsgPendingCallback    : Rx Fifo 1 Message Pending Callback.
180     (+) RxFifo1FullCallback          : Rx Fifo 1 Full Callback.
181     (+) SleepCallback                : Sleep Callback.
182     (+) WakeUpFromRxMsgCallback      : Wake Up From Rx Message Callback.
183     (+) ErrorCallback                : Error Callback.
184     (+) MspInitCallback              : CAN MspInit.
185     (+) MspDeInitCallback            : CAN MspDeInit.
186 
187   By default, after the HAL_CAN_Init() and when the state is HAL_CAN_STATE_RESET,
188   all callbacks are set to the corresponding weak functions:
189   example HAL_CAN_ErrorCallback().
190   Exception done for MspInit and MspDeInit functions that are
191   reset to the legacy weak function in the HAL_CAN_Init()/ HAL_CAN_DeInit() only when
192   these callbacks are null (not registered beforehand).
193   if not, MspInit or MspDeInit are not null, the HAL_CAN_Init()/ HAL_CAN_DeInit()
194   keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
195 
196   Callbacks can be registered/unregistered in HAL_CAN_STATE_READY state only.
197   Exception done MspInit/MspDeInit that can be registered/unregistered
198   in HAL_CAN_STATE_READY or HAL_CAN_STATE_RESET state,
199   thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
200   In that case first register the MspInit/MspDeInit user callbacks
201   using HAL_CAN_RegisterCallback() before calling HAL_CAN_DeInit()
202   or HAL_CAN_Init() function.
203 
204   When The compilation define USE_HAL_CAN_REGISTER_CALLBACKS is set to 0 or
205   not defined, the callback registration feature is not available and all callbacks
206   are set to the corresponding weak functions.
207 
208   @endverbatim
209   ******************************************************************************
210   */
211 
212 /* Includes ------------------------------------------------------------------*/
213 #include "stm32f4xx_hal.h"
214 
215 /** @addtogroup STM32F4xx_HAL_Driver
216   * @{
217   */
218 
219 #if defined(CAN1)
220 
221 /** @defgroup CAN CAN
222   * @brief CAN driver modules
223   * @{
224   */
225 
226 #ifdef HAL_CAN_MODULE_ENABLED
227 
228 #ifdef HAL_CAN_LEGACY_MODULE_ENABLED
229   #error "The CAN driver cannot be used with its legacy, Please enable only one CAN module at once"
230 #endif
231 
232 /* Private typedef -----------------------------------------------------------*/
233 /* Private define ------------------------------------------------------------*/
234 /** @defgroup CAN_Private_Constants CAN Private Constants
235   * @{
236   */
237 #define CAN_TIMEOUT_VALUE 10U
238 /**
239   * @}
240   */
241 /* Private macro -------------------------------------------------------------*/
242 /* Private variables ---------------------------------------------------------*/
243 /* Private function prototypes -----------------------------------------------*/
244 /* Exported functions --------------------------------------------------------*/
245 
246 /** @defgroup CAN_Exported_Functions CAN Exported Functions
247   * @{
248   */
249 
250 /** @defgroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions
251  *  @brief    Initialization and Configuration functions
252  *
253 @verbatim
254   ==============================================================================
255               ##### Initialization and de-initialization functions #####
256   ==============================================================================
257     [..]  This section provides functions allowing to:
258       (+) HAL_CAN_Init                       : Initialize and configure the CAN.
259       (+) HAL_CAN_DeInit                     : De-initialize the CAN.
260       (+) HAL_CAN_MspInit                    : Initialize the CAN MSP.
261       (+) HAL_CAN_MspDeInit                  : DeInitialize the CAN MSP.
262 
263 @endverbatim
264   * @{
265   */
266 
267 /**
268   * @brief  Initializes the CAN peripheral according to the specified
269   *         parameters in the CAN_InitStruct.
270   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
271   *         the configuration information for the specified CAN.
272   * @retval HAL status
273   */
HAL_CAN_Init(CAN_HandleTypeDef * hcan)274 HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef *hcan)
275 {
276   uint32_t tickstart;
277 
278   /* Check CAN handle */
279   if (hcan == NULL)
280   {
281     return HAL_ERROR;
282   }
283 
284   /* Check the parameters */
285   assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
286   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TimeTriggeredMode));
287   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AutoBusOff));
288   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AutoWakeUp));
289   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AutoRetransmission));
290   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ReceiveFifoLocked));
291   assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TransmitFifoPriority));
292   assert_param(IS_CAN_MODE(hcan->Init.Mode));
293   assert_param(IS_CAN_SJW(hcan->Init.SyncJumpWidth));
294   assert_param(IS_CAN_BS1(hcan->Init.TimeSeg1));
295   assert_param(IS_CAN_BS2(hcan->Init.TimeSeg2));
296   assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler));
297 
298 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
299   if (hcan->State == HAL_CAN_STATE_RESET)
300   {
301     /* Reset callbacks to legacy functions */
302     hcan->RxFifo0MsgPendingCallback  =  HAL_CAN_RxFifo0MsgPendingCallback;  /* Legacy weak RxFifo0MsgPendingCallback  */
303     hcan->RxFifo0FullCallback        =  HAL_CAN_RxFifo0FullCallback;        /* Legacy weak RxFifo0FullCallback        */
304     hcan->RxFifo1MsgPendingCallback  =  HAL_CAN_RxFifo1MsgPendingCallback;  /* Legacy weak RxFifo1MsgPendingCallback  */
305     hcan->RxFifo1FullCallback        =  HAL_CAN_RxFifo1FullCallback;        /* Legacy weak RxFifo1FullCallback        */
306     hcan->TxMailbox0CompleteCallback =  HAL_CAN_TxMailbox0CompleteCallback; /* Legacy weak TxMailbox0CompleteCallback */
307     hcan->TxMailbox1CompleteCallback =  HAL_CAN_TxMailbox1CompleteCallback; /* Legacy weak TxMailbox1CompleteCallback */
308     hcan->TxMailbox2CompleteCallback =  HAL_CAN_TxMailbox2CompleteCallback; /* Legacy weak TxMailbox2CompleteCallback */
309     hcan->TxMailbox0AbortCallback    =  HAL_CAN_TxMailbox0AbortCallback;    /* Legacy weak TxMailbox0AbortCallback    */
310     hcan->TxMailbox1AbortCallback    =  HAL_CAN_TxMailbox1AbortCallback;    /* Legacy weak TxMailbox1AbortCallback    */
311     hcan->TxMailbox2AbortCallback    =  HAL_CAN_TxMailbox2AbortCallback;    /* Legacy weak TxMailbox2AbortCallback    */
312     hcan->SleepCallback              =  HAL_CAN_SleepCallback;              /* Legacy weak SleepCallback              */
313     hcan->WakeUpFromRxMsgCallback    =  HAL_CAN_WakeUpFromRxMsgCallback;    /* Legacy weak WakeUpFromRxMsgCallback    */
314     hcan->ErrorCallback              =  HAL_CAN_ErrorCallback;              /* Legacy weak ErrorCallback              */
315 
316     if (hcan->MspInitCallback == NULL)
317     {
318       hcan->MspInitCallback = HAL_CAN_MspInit; /* Legacy weak MspInit */
319     }
320 
321     /* Init the low level hardware: CLOCK, NVIC */
322     hcan->MspInitCallback(hcan);
323   }
324 
325 #else
326   if (hcan->State == HAL_CAN_STATE_RESET)
327   {
328     /* Init the low level hardware: CLOCK, NVIC */
329     HAL_CAN_MspInit(hcan);
330   }
331 #endif /* (USE_HAL_CAN_REGISTER_CALLBACKS) */
332 
333   /* Request initialisation */
334   SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
335 
336   /* Get tick */
337   tickstart = HAL_GetTick();
338 
339   /* Wait initialisation acknowledge */
340   while ((hcan->Instance->MSR & CAN_MSR_INAK) == 0U)
341   {
342     if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
343     {
344       /* Update error code */
345       hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
346 
347       /* Change CAN state */
348       hcan->State = HAL_CAN_STATE_ERROR;
349 
350       return HAL_ERROR;
351     }
352   }
353 
354   /* Exit from sleep mode */
355   CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
356 
357   /* Get tick */
358   tickstart = HAL_GetTick();
359 
360   /* Check Sleep mode leave acknowledge */
361   while ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U)
362   {
363     if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
364     {
365       /* Update error code */
366       hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
367 
368       /* Change CAN state */
369       hcan->State = HAL_CAN_STATE_ERROR;
370 
371       return HAL_ERROR;
372     }
373   }
374 
375   /* Set the time triggered communication mode */
376   if (hcan->Init.TimeTriggeredMode == ENABLE)
377   {
378     SET_BIT(hcan->Instance->MCR, CAN_MCR_TTCM);
379   }
380   else
381   {
382     CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_TTCM);
383   }
384 
385   /* Set the automatic bus-off management */
386   if (hcan->Init.AutoBusOff == ENABLE)
387   {
388     SET_BIT(hcan->Instance->MCR, CAN_MCR_ABOM);
389   }
390   else
391   {
392     CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_ABOM);
393   }
394 
395   /* Set the automatic wake-up mode */
396   if (hcan->Init.AutoWakeUp == ENABLE)
397   {
398     SET_BIT(hcan->Instance->MCR, CAN_MCR_AWUM);
399   }
400   else
401   {
402     CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_AWUM);
403   }
404 
405   /* Set the automatic retransmission */
406   if (hcan->Init.AutoRetransmission == ENABLE)
407   {
408     CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_NART);
409   }
410   else
411   {
412     SET_BIT(hcan->Instance->MCR, CAN_MCR_NART);
413   }
414 
415   /* Set the receive FIFO locked mode */
416   if (hcan->Init.ReceiveFifoLocked == ENABLE)
417   {
418     SET_BIT(hcan->Instance->MCR, CAN_MCR_RFLM);
419   }
420   else
421   {
422     CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_RFLM);
423   }
424 
425   /* Set the transmit FIFO priority */
426   if (hcan->Init.TransmitFifoPriority == ENABLE)
427   {
428     SET_BIT(hcan->Instance->MCR, CAN_MCR_TXFP);
429   }
430   else
431   {
432     CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_TXFP);
433   }
434 
435   /* Set the bit timing register */
436   WRITE_REG(hcan->Instance->BTR, (uint32_t)(hcan->Init.Mode           |
437                                             hcan->Init.SyncJumpWidth  |
438                                             hcan->Init.TimeSeg1       |
439                                             hcan->Init.TimeSeg2       |
440                                             (hcan->Init.Prescaler - 1U)));
441 
442   /* Initialize the error code */
443   hcan->ErrorCode = HAL_CAN_ERROR_NONE;
444 
445   /* Initialize the CAN state */
446   hcan->State = HAL_CAN_STATE_READY;
447 
448   /* Return function status */
449   return HAL_OK;
450 }
451 
452 /**
453   * @brief  Deinitializes the CAN peripheral registers to their default
454   *         reset values.
455   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
456   *         the configuration information for the specified CAN.
457   * @retval HAL status
458   */
HAL_CAN_DeInit(CAN_HandleTypeDef * hcan)459 HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef *hcan)
460 {
461   /* Check CAN handle */
462   if (hcan == NULL)
463   {
464     return HAL_ERROR;
465   }
466 
467   /* Check the parameters */
468   assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
469 
470   /* Stop the CAN module */
471   (void)HAL_CAN_Stop(hcan);
472 
473 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
474   if (hcan->MspDeInitCallback == NULL)
475   {
476     hcan->MspDeInitCallback = HAL_CAN_MspDeInit; /* Legacy weak MspDeInit */
477   }
478 
479   /* DeInit the low level hardware: CLOCK, NVIC */
480   hcan->MspDeInitCallback(hcan);
481 
482 #else
483   /* DeInit the low level hardware: CLOCK, NVIC */
484   HAL_CAN_MspDeInit(hcan);
485 #endif /* (USE_HAL_CAN_REGISTER_CALLBACKS) */
486 
487   /* Reset the CAN peripheral */
488   SET_BIT(hcan->Instance->MCR, CAN_MCR_RESET);
489 
490   /* Reset the CAN ErrorCode */
491   hcan->ErrorCode = HAL_CAN_ERROR_NONE;
492 
493   /* Change CAN state */
494   hcan->State = HAL_CAN_STATE_RESET;
495 
496   /* Return function status */
497   return HAL_OK;
498 }
499 
500 /**
501   * @brief  Initializes the CAN MSP.
502   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
503   *         the configuration information for the specified CAN.
504   * @retval None
505   */
HAL_CAN_MspInit(CAN_HandleTypeDef * hcan)506 __weak void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan)
507 {
508   /* Prevent unused argument(s) compilation warning */
509   UNUSED(hcan);
510 
511   /* NOTE : This function Should not be modified, when the callback is needed,
512             the HAL_CAN_MspInit could be implemented in the user file
513    */
514 }
515 
516 /**
517   * @brief  DeInitializes the CAN MSP.
518   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
519   *         the configuration information for the specified CAN.
520   * @retval None
521   */
HAL_CAN_MspDeInit(CAN_HandleTypeDef * hcan)522 __weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef *hcan)
523 {
524   /* Prevent unused argument(s) compilation warning */
525   UNUSED(hcan);
526 
527   /* NOTE : This function Should not be modified, when the callback is needed,
528             the HAL_CAN_MspDeInit could be implemented in the user file
529    */
530 }
531 
532 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
533 /**
534   * @brief  Register a CAN CallBack.
535   *         To be used instead of the weak predefined callback
536   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
537   *         the configuration information for CAN module
538   * @param  CallbackID ID of the callback to be registered
539   *         This parameter can be one of the following values:
540   *           @arg @ref HAL_CAN_TX_MAILBOX0_COMPLETE_CB_ID Tx Mailbox 0 Complete callback ID
541   *           @arg @ref HAL_CAN_TX_MAILBOX1_COMPLETE_CB_ID Tx Mailbox 1 Complete callback ID
542   *           @arg @ref HAL_CAN_TX_MAILBOX2_COMPLETE_CB_ID Tx Mailbox 2 Complete callback ID
543   *           @arg @ref HAL_CAN_TX_MAILBOX0_ABORT_CB_ID Tx Mailbox 0 Abort callback ID
544   *           @arg @ref HAL_CAN_TX_MAILBOX1_ABORT_CB_ID Tx Mailbox 1 Abort callback ID
545   *           @arg @ref HAL_CAN_TX_MAILBOX2_ABORT_CB_ID Tx Mailbox 2 Abort callback ID
546   *           @arg @ref HAL_CAN_RX_FIFO0_MSG_PENDING_CB_ID Rx Fifo 0 message pending callback ID
547   *           @arg @ref HAL_CAN_RX_FIFO0_FULL_CB_ID Rx Fifo 0 full callback ID
548   *           @arg @ref HAL_CAN_RX_FIFO1_MSG_PENDING_CB_ID Rx Fifo 1 message pending callback ID
549   *           @arg @ref HAL_CAN_RX_FIFO1_FULL_CB_ID Rx Fifo 1 full callback ID
550   *           @arg @ref HAL_CAN_SLEEP_CB_ID Sleep callback ID
551   *           @arg @ref HAL_CAN_WAKEUP_FROM_RX_MSG_CB_ID Wake Up from Rx message callback ID
552   *           @arg @ref HAL_CAN_ERROR_CB_ID Error callback ID
553   *           @arg @ref HAL_CAN_MSPINIT_CB_ID MspInit callback ID
554   *           @arg @ref HAL_CAN_MSPDEINIT_CB_ID MspDeInit callback ID
555   * @param  pCallback pointer to the Callback function
556   * @retval HAL status
557   */
HAL_CAN_RegisterCallback(CAN_HandleTypeDef * hcan,HAL_CAN_CallbackIDTypeDef CallbackID,void (* pCallback)(CAN_HandleTypeDef * _hcan))558 HAL_StatusTypeDef HAL_CAN_RegisterCallback(CAN_HandleTypeDef *hcan, HAL_CAN_CallbackIDTypeDef CallbackID, void (* pCallback)(CAN_HandleTypeDef *_hcan))
559 {
560   HAL_StatusTypeDef status = HAL_OK;
561 
562   if (pCallback == NULL)
563   {
564     /* Update the error code */
565     hcan->ErrorCode |= HAL_CAN_ERROR_INVALID_CALLBACK;
566 
567     return HAL_ERROR;
568   }
569 
570   if (hcan->State == HAL_CAN_STATE_READY)
571   {
572     switch (CallbackID)
573     {
574       case HAL_CAN_TX_MAILBOX0_COMPLETE_CB_ID :
575         hcan->TxMailbox0CompleteCallback = pCallback;
576         break;
577 
578       case HAL_CAN_TX_MAILBOX1_COMPLETE_CB_ID :
579         hcan->TxMailbox1CompleteCallback = pCallback;
580         break;
581 
582       case HAL_CAN_TX_MAILBOX2_COMPLETE_CB_ID :
583         hcan->TxMailbox2CompleteCallback = pCallback;
584         break;
585 
586       case HAL_CAN_TX_MAILBOX0_ABORT_CB_ID :
587         hcan->TxMailbox0AbortCallback = pCallback;
588         break;
589 
590       case HAL_CAN_TX_MAILBOX1_ABORT_CB_ID :
591         hcan->TxMailbox1AbortCallback = pCallback;
592         break;
593 
594       case HAL_CAN_TX_MAILBOX2_ABORT_CB_ID :
595         hcan->TxMailbox2AbortCallback = pCallback;
596         break;
597 
598       case HAL_CAN_RX_FIFO0_MSG_PENDING_CB_ID :
599         hcan->RxFifo0MsgPendingCallback = pCallback;
600         break;
601 
602       case HAL_CAN_RX_FIFO0_FULL_CB_ID :
603         hcan->RxFifo0FullCallback = pCallback;
604         break;
605 
606       case HAL_CAN_RX_FIFO1_MSG_PENDING_CB_ID :
607         hcan->RxFifo1MsgPendingCallback = pCallback;
608         break;
609 
610       case HAL_CAN_RX_FIFO1_FULL_CB_ID :
611         hcan->RxFifo1FullCallback = pCallback;
612         break;
613 
614       case HAL_CAN_SLEEP_CB_ID :
615         hcan->SleepCallback = pCallback;
616         break;
617 
618       case HAL_CAN_WAKEUP_FROM_RX_MSG_CB_ID :
619         hcan->WakeUpFromRxMsgCallback = pCallback;
620         break;
621 
622       case HAL_CAN_ERROR_CB_ID :
623         hcan->ErrorCallback = pCallback;
624         break;
625 
626       case HAL_CAN_MSPINIT_CB_ID :
627         hcan->MspInitCallback = pCallback;
628         break;
629 
630       case HAL_CAN_MSPDEINIT_CB_ID :
631         hcan->MspDeInitCallback = pCallback;
632         break;
633 
634       default :
635         /* Update the error code */
636         hcan->ErrorCode |= HAL_CAN_ERROR_INVALID_CALLBACK;
637 
638         /* Return error status */
639         status =  HAL_ERROR;
640         break;
641     }
642   }
643   else if (hcan->State == HAL_CAN_STATE_RESET)
644   {
645     switch (CallbackID)
646     {
647       case HAL_CAN_MSPINIT_CB_ID :
648         hcan->MspInitCallback = pCallback;
649         break;
650 
651       case HAL_CAN_MSPDEINIT_CB_ID :
652         hcan->MspDeInitCallback = pCallback;
653         break;
654 
655       default :
656         /* Update the error code */
657         hcan->ErrorCode |= HAL_CAN_ERROR_INVALID_CALLBACK;
658 
659         /* Return error status */
660         status =  HAL_ERROR;
661         break;
662     }
663   }
664   else
665   {
666     /* Update the error code */
667     hcan->ErrorCode |= HAL_CAN_ERROR_INVALID_CALLBACK;
668 
669     /* Return error status */
670     status =  HAL_ERROR;
671   }
672 
673   return status;
674 }
675 
676 /**
677   * @brief  Unregister a CAN CallBack.
678   *         CAN callback is redirected to the weak predefined callback
679   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
680   *         the configuration information for CAN module
681   * @param  CallbackID ID of the callback to be unregistered
682   *         This parameter can be one of the following values:
683   *           @arg @ref HAL_CAN_TX_MAILBOX0_COMPLETE_CB_ID Tx Mailbox 0 Complete callback ID
684   *           @arg @ref HAL_CAN_TX_MAILBOX1_COMPLETE_CB_ID Tx Mailbox 1 Complete callback ID
685   *           @arg @ref HAL_CAN_TX_MAILBOX2_COMPLETE_CB_ID Tx Mailbox 2 Complete callback ID
686   *           @arg @ref HAL_CAN_TX_MAILBOX0_ABORT_CB_ID Tx Mailbox 0 Abort callback ID
687   *           @arg @ref HAL_CAN_TX_MAILBOX1_ABORT_CB_ID Tx Mailbox 1 Abort callback ID
688   *           @arg @ref HAL_CAN_TX_MAILBOX2_ABORT_CB_ID Tx Mailbox 2 Abort callback ID
689   *           @arg @ref HAL_CAN_RX_FIFO0_MSG_PENDING_CB_ID Rx Fifo 0 message pending callback ID
690   *           @arg @ref HAL_CAN_RX_FIFO0_FULL_CB_ID Rx Fifo 0 full callback ID
691   *           @arg @ref HAL_CAN_RX_FIFO1_MSG_PENDING_CB_ID Rx Fifo 1 message pending callback ID
692   *           @arg @ref HAL_CAN_RX_FIFO1_FULL_CB_ID Rx Fifo 1 full callback ID
693   *           @arg @ref HAL_CAN_SLEEP_CB_ID Sleep callback ID
694   *           @arg @ref HAL_CAN_WAKEUP_FROM_RX_MSG_CB_ID Wake Up from Rx message callback ID
695   *           @arg @ref HAL_CAN_ERROR_CB_ID Error callback ID
696   *           @arg @ref HAL_CAN_MSPINIT_CB_ID MspInit callback ID
697   *           @arg @ref HAL_CAN_MSPDEINIT_CB_ID MspDeInit callback ID
698   * @retval HAL status
699   */
HAL_CAN_UnRegisterCallback(CAN_HandleTypeDef * hcan,HAL_CAN_CallbackIDTypeDef CallbackID)700 HAL_StatusTypeDef HAL_CAN_UnRegisterCallback(CAN_HandleTypeDef *hcan, HAL_CAN_CallbackIDTypeDef CallbackID)
701 {
702   HAL_StatusTypeDef status = HAL_OK;
703 
704   if (hcan->State == HAL_CAN_STATE_READY)
705   {
706     switch (CallbackID)
707     {
708       case HAL_CAN_TX_MAILBOX0_COMPLETE_CB_ID :
709         hcan->TxMailbox0CompleteCallback = HAL_CAN_TxMailbox0CompleteCallback;
710         break;
711 
712       case HAL_CAN_TX_MAILBOX1_COMPLETE_CB_ID :
713         hcan->TxMailbox1CompleteCallback = HAL_CAN_TxMailbox1CompleteCallback;
714         break;
715 
716       case HAL_CAN_TX_MAILBOX2_COMPLETE_CB_ID :
717         hcan->TxMailbox2CompleteCallback = HAL_CAN_TxMailbox2CompleteCallback;
718         break;
719 
720       case HAL_CAN_TX_MAILBOX0_ABORT_CB_ID :
721         hcan->TxMailbox0AbortCallback = HAL_CAN_TxMailbox0AbortCallback;
722         break;
723 
724       case HAL_CAN_TX_MAILBOX1_ABORT_CB_ID :
725         hcan->TxMailbox1AbortCallback = HAL_CAN_TxMailbox1AbortCallback;
726         break;
727 
728       case HAL_CAN_TX_MAILBOX2_ABORT_CB_ID :
729         hcan->TxMailbox2AbortCallback = HAL_CAN_TxMailbox2AbortCallback;
730         break;
731 
732       case HAL_CAN_RX_FIFO0_MSG_PENDING_CB_ID :
733         hcan->RxFifo0MsgPendingCallback = HAL_CAN_RxFifo0MsgPendingCallback;
734         break;
735 
736       case HAL_CAN_RX_FIFO0_FULL_CB_ID :
737         hcan->RxFifo0FullCallback = HAL_CAN_RxFifo0FullCallback;
738         break;
739 
740       case HAL_CAN_RX_FIFO1_MSG_PENDING_CB_ID :
741         hcan->RxFifo1MsgPendingCallback = HAL_CAN_RxFifo1MsgPendingCallback;
742         break;
743 
744       case HAL_CAN_RX_FIFO1_FULL_CB_ID :
745         hcan->RxFifo1FullCallback = HAL_CAN_RxFifo1FullCallback;
746         break;
747 
748       case HAL_CAN_SLEEP_CB_ID :
749         hcan->SleepCallback = HAL_CAN_SleepCallback;
750         break;
751 
752       case HAL_CAN_WAKEUP_FROM_RX_MSG_CB_ID :
753         hcan->WakeUpFromRxMsgCallback = HAL_CAN_WakeUpFromRxMsgCallback;
754         break;
755 
756       case HAL_CAN_ERROR_CB_ID :
757         hcan->ErrorCallback = HAL_CAN_ErrorCallback;
758         break;
759 
760       case HAL_CAN_MSPINIT_CB_ID :
761         hcan->MspInitCallback = HAL_CAN_MspInit;
762         break;
763 
764       case HAL_CAN_MSPDEINIT_CB_ID :
765         hcan->MspDeInitCallback = HAL_CAN_MspDeInit;
766         break;
767 
768       default :
769         /* Update the error code */
770         hcan->ErrorCode |= HAL_CAN_ERROR_INVALID_CALLBACK;
771 
772         /* Return error status */
773         status =  HAL_ERROR;
774         break;
775     }
776   }
777   else if (hcan->State == HAL_CAN_STATE_RESET)
778   {
779     switch (CallbackID)
780     {
781       case HAL_CAN_MSPINIT_CB_ID :
782         hcan->MspInitCallback = HAL_CAN_MspInit;
783         break;
784 
785       case HAL_CAN_MSPDEINIT_CB_ID :
786         hcan->MspDeInitCallback = HAL_CAN_MspDeInit;
787         break;
788 
789       default :
790         /* Update the error code */
791         hcan->ErrorCode |= HAL_CAN_ERROR_INVALID_CALLBACK;
792 
793         /* Return error status */
794         status =  HAL_ERROR;
795         break;
796     }
797   }
798   else
799   {
800     /* Update the error code */
801     hcan->ErrorCode |= HAL_CAN_ERROR_INVALID_CALLBACK;
802 
803     /* Return error status */
804     status =  HAL_ERROR;
805   }
806 
807   return status;
808 }
809 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
810 
811 /**
812   * @}
813   */
814 
815 /** @defgroup CAN_Exported_Functions_Group2 Configuration functions
816  *  @brief    Configuration functions.
817  *
818 @verbatim
819   ==============================================================================
820               ##### Configuration functions #####
821   ==============================================================================
822     [..]  This section provides functions allowing to:
823       (+) HAL_CAN_ConfigFilter            : Configure the CAN reception filters
824 
825 @endverbatim
826   * @{
827   */
828 
829 /**
830   * @brief  Configures the CAN reception filter according to the specified
831   *         parameters in the CAN_FilterInitStruct.
832   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
833   *         the configuration information for the specified CAN.
834   * @param  sFilterConfig pointer to a CAN_FilterTypeDef structure that
835   *         contains the filter configuration information.
836   * @retval None
837   */
HAL_CAN_ConfigFilter(CAN_HandleTypeDef * hcan,CAN_FilterTypeDef * sFilterConfig)838 HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef *hcan, CAN_FilterTypeDef *sFilterConfig)
839 {
840   uint32_t filternbrbitpos;
841   CAN_TypeDef *can_ip = hcan->Instance;
842   HAL_CAN_StateTypeDef state = hcan->State;
843 
844   if ((state == HAL_CAN_STATE_READY) ||
845       (state == HAL_CAN_STATE_LISTENING))
846   {
847     /* Check the parameters */
848     assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterIdHigh));
849     assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterIdLow));
850     assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterMaskIdHigh));
851     assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterMaskIdLow));
852     assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode));
853     assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale));
854     assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment));
855     assert_param(IS_CAN_FILTER_ACTIVATION(sFilterConfig->FilterActivation));
856 
857 #if defined(CAN3)
858     /* Check the CAN instance */
859     if (hcan->Instance == CAN3)
860     {
861       /* CAN3 is single instance with 14 dedicated filters banks */
862 
863       /* Check the parameters */
864       assert_param(IS_CAN_FILTER_BANK_SINGLE(sFilterConfig->FilterBank));
865     }
866     else
867     {
868       /* CAN1 and CAN2 are dual instances with 28 common filters banks */
869       /* Select master instance to access the filter banks */
870       can_ip = CAN1;
871 
872       /* Check the parameters */
873       assert_param(IS_CAN_FILTER_BANK_DUAL(sFilterConfig->FilterBank));
874       assert_param(IS_CAN_FILTER_BANK_DUAL(sFilterConfig->SlaveStartFilterBank));
875     }
876 #elif defined(CAN2)
877     /* CAN1 and CAN2 are dual instances with 28 common filters banks */
878     /* Select master instance to access the filter banks */
879     can_ip = CAN1;
880 
881     /* Check the parameters */
882     assert_param(IS_CAN_FILTER_BANK_DUAL(sFilterConfig->FilterBank));
883     assert_param(IS_CAN_FILTER_BANK_DUAL(sFilterConfig->SlaveStartFilterBank));
884 #else
885     /* CAN1 is single instance with 14 dedicated filters banks */
886 
887     /* Check the parameters */
888     assert_param(IS_CAN_FILTER_BANK_SINGLE(sFilterConfig->FilterBank));
889 #endif
890 
891     /* Initialisation mode for the filter */
892     SET_BIT(can_ip->FMR, CAN_FMR_FINIT);
893 
894 #if defined(CAN3)
895     /* Check the CAN instance */
896     if (can_ip == CAN1)
897     {
898       /* Select the start filter number of CAN2 slave instance */
899       CLEAR_BIT(can_ip->FMR, CAN_FMR_CAN2SB);
900       SET_BIT(can_ip->FMR, sFilterConfig->SlaveStartFilterBank << CAN_FMR_CAN2SB_Pos);
901     }
902 
903 #elif defined(CAN2)
904     /* Select the start filter number of CAN2 slave instance */
905     CLEAR_BIT(can_ip->FMR, CAN_FMR_CAN2SB);
906     SET_BIT(can_ip->FMR, sFilterConfig->SlaveStartFilterBank << CAN_FMR_CAN2SB_Pos);
907 
908 #endif
909     /* Convert filter number into bit position */
910     filternbrbitpos = (uint32_t)1 << (sFilterConfig->FilterBank & 0x1FU);
911 
912     /* Filter Deactivation */
913     CLEAR_BIT(can_ip->FA1R, filternbrbitpos);
914 
915     /* Filter Scale */
916     if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT)
917     {
918       /* 16-bit scale for the filter */
919       CLEAR_BIT(can_ip->FS1R, filternbrbitpos);
920 
921       /* First 16-bit identifier and First 16-bit mask */
922       /* Or First 16-bit identifier and Second 16-bit identifier */
923       can_ip->sFilterRegister[sFilterConfig->FilterBank].FR1 =
924         ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16U) |
925         (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
926 
927       /* Second 16-bit identifier and Second 16-bit mask */
928       /* Or Third 16-bit identifier and Fourth 16-bit identifier */
929       can_ip->sFilterRegister[sFilterConfig->FilterBank].FR2 =
930         ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
931         (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh);
932     }
933 
934     if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
935     {
936       /* 32-bit scale for the filter */
937       SET_BIT(can_ip->FS1R, filternbrbitpos);
938 
939       /* 32-bit identifier or First 32-bit identifier */
940       can_ip->sFilterRegister[sFilterConfig->FilterBank].FR1 =
941         ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh) << 16U) |
942         (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
943 
944       /* 32-bit mask or Second 32-bit identifier */
945       can_ip->sFilterRegister[sFilterConfig->FilterBank].FR2 =
946         ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
947         (0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow);
948     }
949 
950     /* Filter Mode */
951     if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
952     {
953       /* Id/Mask mode for the filter*/
954       CLEAR_BIT(can_ip->FM1R, filternbrbitpos);
955     }
956     else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
957     {
958       /* Identifier list mode for the filter*/
959       SET_BIT(can_ip->FM1R, filternbrbitpos);
960     }
961 
962     /* Filter FIFO assignment */
963     if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
964     {
965       /* FIFO 0 assignation for the filter */
966       CLEAR_BIT(can_ip->FFA1R, filternbrbitpos);
967     }
968     else
969     {
970       /* FIFO 1 assignation for the filter */
971       SET_BIT(can_ip->FFA1R, filternbrbitpos);
972     }
973 
974     /* Filter activation */
975     if (sFilterConfig->FilterActivation == CAN_FILTER_ENABLE)
976     {
977       SET_BIT(can_ip->FA1R, filternbrbitpos);
978     }
979 
980     /* Leave the initialisation mode for the filter */
981     CLEAR_BIT(can_ip->FMR, CAN_FMR_FINIT);
982 
983     /* Return function status */
984     return HAL_OK;
985   }
986   else
987   {
988     /* Update error code */
989     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
990 
991     return HAL_ERROR;
992   }
993 }
994 
995 /**
996   * @}
997   */
998 
999 /** @defgroup CAN_Exported_Functions_Group3 Control functions
1000  *  @brief    Control functions
1001  *
1002 @verbatim
1003   ==============================================================================
1004                       ##### Control functions #####
1005   ==============================================================================
1006     [..]  This section provides functions allowing to:
1007       (+) HAL_CAN_Start                    : Start the CAN module
1008       (+) HAL_CAN_Stop                     : Stop the CAN module
1009       (+) HAL_CAN_RequestSleep             : Request sleep mode entry.
1010       (+) HAL_CAN_WakeUp                   : Wake up from sleep mode.
1011       (+) HAL_CAN_IsSleepActive            : Check is sleep mode is active.
1012       (+) HAL_CAN_AddTxMessage             : Add a message to the Tx mailboxes
1013                                              and activate the corresponding
1014                                              transmission request
1015       (+) HAL_CAN_AbortTxRequest           : Abort transmission request
1016       (+) HAL_CAN_GetTxMailboxesFreeLevel  : Return Tx mailboxes free level
1017       (+) HAL_CAN_IsTxMessagePending       : Check if a transmission request is
1018                                              pending on the selected Tx mailbox
1019       (+) HAL_CAN_GetRxMessage             : Get a CAN frame from the Rx FIFO
1020       (+) HAL_CAN_GetRxFifoFillLevel       : Return Rx FIFO fill level
1021 
1022 @endverbatim
1023   * @{
1024   */
1025 
1026 /**
1027   * @brief  Start the CAN module.
1028   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1029   *         the configuration information for the specified CAN.
1030   * @retval HAL status
1031   */
HAL_CAN_Start(CAN_HandleTypeDef * hcan)1032 HAL_StatusTypeDef HAL_CAN_Start(CAN_HandleTypeDef *hcan)
1033 {
1034   uint32_t tickstart;
1035 
1036   if (hcan->State == HAL_CAN_STATE_READY)
1037   {
1038     /* Change CAN peripheral state */
1039     hcan->State = HAL_CAN_STATE_LISTENING;
1040 
1041     /* Request leave initialisation */
1042     CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
1043 
1044     /* Get tick */
1045     tickstart = HAL_GetTick();
1046 
1047     /* Wait the acknowledge */
1048     while ((hcan->Instance->MSR & CAN_MSR_INAK) != 0U)
1049     {
1050       /* Check for the Timeout */
1051       if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
1052       {
1053         /* Update error code */
1054         hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
1055 
1056         /* Change CAN state */
1057         hcan->State = HAL_CAN_STATE_ERROR;
1058 
1059         return HAL_ERROR;
1060       }
1061     }
1062 
1063     /* Reset the CAN ErrorCode */
1064     hcan->ErrorCode = HAL_CAN_ERROR_NONE;
1065 
1066     /* Return function status */
1067     return HAL_OK;
1068   }
1069   else
1070   {
1071     /* Update error code */
1072     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_READY;
1073 
1074     return HAL_ERROR;
1075   }
1076 }
1077 
1078 /**
1079   * @brief  Stop the CAN module and enable access to configuration registers.
1080   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1081   *         the configuration information for the specified CAN.
1082   * @retval HAL status
1083   */
HAL_CAN_Stop(CAN_HandleTypeDef * hcan)1084 HAL_StatusTypeDef HAL_CAN_Stop(CAN_HandleTypeDef *hcan)
1085 {
1086   uint32_t tickstart;
1087 
1088   if (hcan->State == HAL_CAN_STATE_LISTENING)
1089   {
1090     /* Request initialisation */
1091     SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
1092 
1093     /* Get tick */
1094     tickstart = HAL_GetTick();
1095 
1096     /* Wait the acknowledge */
1097     while ((hcan->Instance->MSR & CAN_MSR_INAK) == 0U)
1098     {
1099       /* Check for the Timeout */
1100       if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
1101       {
1102         /* Update error code */
1103         hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
1104 
1105         /* Change CAN state */
1106         hcan->State = HAL_CAN_STATE_ERROR;
1107 
1108         return HAL_ERROR;
1109       }
1110     }
1111 
1112     /* Exit from sleep mode */
1113     CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
1114 
1115     /* Change CAN peripheral state */
1116     hcan->State = HAL_CAN_STATE_READY;
1117 
1118     /* Return function status */
1119     return HAL_OK;
1120   }
1121   else
1122   {
1123     /* Update error code */
1124     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_STARTED;
1125 
1126     return HAL_ERROR;
1127   }
1128 }
1129 
1130 /**
1131   * @brief  Request the sleep mode (low power) entry.
1132   *         When returning from this function, Sleep mode will be entered
1133   *         as soon as the current CAN activity (transmission or reception
1134   *         of a CAN frame) has been completed.
1135   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1136   *         the configuration information for the specified CAN.
1137   * @retval HAL status.
1138   */
HAL_CAN_RequestSleep(CAN_HandleTypeDef * hcan)1139 HAL_StatusTypeDef HAL_CAN_RequestSleep(CAN_HandleTypeDef *hcan)
1140 {
1141   HAL_CAN_StateTypeDef state = hcan->State;
1142 
1143   if ((state == HAL_CAN_STATE_READY) ||
1144       (state == HAL_CAN_STATE_LISTENING))
1145   {
1146     /* Request Sleep mode */
1147     SET_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
1148 
1149     /* Return function status */
1150     return HAL_OK;
1151   }
1152   else
1153   {
1154     /* Update error code */
1155     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1156 
1157     /* Return function status */
1158     return HAL_ERROR;
1159   }
1160 }
1161 
1162 /**
1163   * @brief  Wake up from sleep mode.
1164   *         When returning with HAL_OK status from this function, Sleep mode
1165   *         is exited.
1166   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1167   *         the configuration information for the specified CAN.
1168   * @retval HAL status.
1169   */
HAL_CAN_WakeUp(CAN_HandleTypeDef * hcan)1170 HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef *hcan)
1171 {
1172   __IO uint32_t count = 0;
1173   uint32_t timeout = 1000000U;
1174   HAL_CAN_StateTypeDef state = hcan->State;
1175 
1176   if ((state == HAL_CAN_STATE_READY) ||
1177       (state == HAL_CAN_STATE_LISTENING))
1178   {
1179     /* Wake up request */
1180     CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
1181 
1182     /* Wait sleep mode is exited */
1183     do
1184     {
1185       /* Increment counter */
1186       count++;
1187 
1188       /* Check if timeout is reached */
1189       if (count > timeout)
1190       {
1191         /* Update error code */
1192         hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
1193 
1194         return HAL_ERROR;
1195       }
1196     }
1197     while ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U);
1198 
1199     /* Return function status */
1200     return HAL_OK;
1201   }
1202   else
1203   {
1204     /* Update error code */
1205     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1206 
1207     return HAL_ERROR;
1208   }
1209 }
1210 
1211 /**
1212   * @brief  Check is sleep mode is active.
1213   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1214   *         the configuration information for the specified CAN.
1215   * @retval Status
1216   *          - 0 : Sleep mode is not active.
1217   *          - 1 : Sleep mode is active.
1218   */
HAL_CAN_IsSleepActive(CAN_HandleTypeDef * hcan)1219 uint32_t HAL_CAN_IsSleepActive(CAN_HandleTypeDef *hcan)
1220 {
1221   uint32_t status = 0U;
1222   HAL_CAN_StateTypeDef state = hcan->State;
1223 
1224   if ((state == HAL_CAN_STATE_READY) ||
1225       (state == HAL_CAN_STATE_LISTENING))
1226   {
1227     /* Check Sleep mode */
1228     if ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U)
1229     {
1230       status = 1U;
1231     }
1232   }
1233 
1234   /* Return function status */
1235   return status;
1236 }
1237 
1238 /**
1239   * @brief  Add a message to the first free Tx mailbox and activate the
1240   *         corresponding transmission request.
1241   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1242   *         the configuration information for the specified CAN.
1243   * @param  pHeader pointer to a CAN_TxHeaderTypeDef structure.
1244   * @param  aData array containing the payload of the Tx frame.
1245   * @param  pTxMailbox pointer to a variable where the function will return
1246   *         the TxMailbox used to store the Tx message.
1247   *         This parameter can be a value of @arg CAN_Tx_Mailboxes.
1248   * @retval HAL status
1249   */
HAL_CAN_AddTxMessage(CAN_HandleTypeDef * hcan,CAN_TxHeaderTypeDef * pHeader,uint8_t aData[],uint32_t * pTxMailbox)1250 HAL_StatusTypeDef HAL_CAN_AddTxMessage(CAN_HandleTypeDef *hcan, CAN_TxHeaderTypeDef *pHeader, uint8_t aData[], uint32_t *pTxMailbox)
1251 {
1252   uint32_t transmitmailbox;
1253   HAL_CAN_StateTypeDef state = hcan->State;
1254   uint32_t tsr = READ_REG(hcan->Instance->TSR);
1255 
1256   /* Check the parameters */
1257   assert_param(IS_CAN_IDTYPE(pHeader->IDE));
1258   assert_param(IS_CAN_RTR(pHeader->RTR));
1259   assert_param(IS_CAN_DLC(pHeader->DLC));
1260   if (pHeader->IDE == CAN_ID_STD)
1261   {
1262     assert_param(IS_CAN_STDID(pHeader->StdId));
1263   }
1264   else
1265   {
1266     assert_param(IS_CAN_EXTID(pHeader->ExtId));
1267   }
1268   assert_param(IS_FUNCTIONAL_STATE(pHeader->TransmitGlobalTime));
1269 
1270   if ((state == HAL_CAN_STATE_READY) ||
1271       (state == HAL_CAN_STATE_LISTENING))
1272   {
1273     /* Check that all the Tx mailboxes are not full */
1274     if (((tsr & CAN_TSR_TME0) != 0U) ||
1275         ((tsr & CAN_TSR_TME1) != 0U) ||
1276         ((tsr & CAN_TSR_TME2) != 0U))
1277     {
1278       /* Select an empty transmit mailbox */
1279       transmitmailbox = (tsr & CAN_TSR_CODE) >> CAN_TSR_CODE_Pos;
1280 
1281       /* Check transmit mailbox value */
1282       if (transmitmailbox > 2U)
1283       {
1284         /* Update error code */
1285         hcan->ErrorCode |= HAL_CAN_ERROR_INTERNAL;
1286 
1287         return HAL_ERROR;
1288       }
1289 
1290       /* Store the Tx mailbox */
1291       *pTxMailbox = (uint32_t)1 << transmitmailbox;
1292 
1293       /* Set up the Id */
1294       if (pHeader->IDE == CAN_ID_STD)
1295       {
1296         hcan->Instance->sTxMailBox[transmitmailbox].TIR = ((pHeader->StdId << CAN_TI0R_STID_Pos) |
1297                                                            pHeader->RTR);
1298       }
1299       else
1300       {
1301         hcan->Instance->sTxMailBox[transmitmailbox].TIR = ((pHeader->ExtId << CAN_TI0R_EXID_Pos) |
1302                                                            pHeader->IDE |
1303                                                            pHeader->RTR);
1304       }
1305 
1306       /* Set up the DLC */
1307       hcan->Instance->sTxMailBox[transmitmailbox].TDTR = (pHeader->DLC);
1308 
1309       /* Set up the Transmit Global Time mode */
1310       if (pHeader->TransmitGlobalTime == ENABLE)
1311       {
1312         SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TDTR, CAN_TDT0R_TGT);
1313       }
1314 
1315       /* Set up the data field */
1316       WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR,
1317                 ((uint32_t)aData[7] << CAN_TDH0R_DATA7_Pos) |
1318                 ((uint32_t)aData[6] << CAN_TDH0R_DATA6_Pos) |
1319                 ((uint32_t)aData[5] << CAN_TDH0R_DATA5_Pos) |
1320                 ((uint32_t)aData[4] << CAN_TDH0R_DATA4_Pos));
1321       WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR,
1322                 ((uint32_t)aData[3] << CAN_TDL0R_DATA3_Pos) |
1323                 ((uint32_t)aData[2] << CAN_TDL0R_DATA2_Pos) |
1324                 ((uint32_t)aData[1] << CAN_TDL0R_DATA1_Pos) |
1325                 ((uint32_t)aData[0] << CAN_TDL0R_DATA0_Pos));
1326 
1327       /* Request transmission */
1328       SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TIR, CAN_TI0R_TXRQ);
1329 
1330       /* Return function status */
1331       return HAL_OK;
1332     }
1333     else
1334     {
1335       /* Update error code */
1336       hcan->ErrorCode |= HAL_CAN_ERROR_PARAM;
1337 
1338       return HAL_ERROR;
1339     }
1340   }
1341   else
1342   {
1343     /* Update error code */
1344     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1345 
1346     return HAL_ERROR;
1347   }
1348 }
1349 
1350 /**
1351   * @brief  Abort transmission requests
1352   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1353   *         the configuration information for the specified CAN.
1354   * @param  TxMailboxes List of the Tx Mailboxes to abort.
1355   *         This parameter can be any combination of @arg CAN_Tx_Mailboxes.
1356   * @retval HAL status
1357   */
HAL_CAN_AbortTxRequest(CAN_HandleTypeDef * hcan,uint32_t TxMailboxes)1358 HAL_StatusTypeDef HAL_CAN_AbortTxRequest(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes)
1359 {
1360   HAL_CAN_StateTypeDef state = hcan->State;
1361 
1362   /* Check function parameters */
1363   assert_param(IS_CAN_TX_MAILBOX_LIST(TxMailboxes));
1364 
1365   if ((state == HAL_CAN_STATE_READY) ||
1366       (state == HAL_CAN_STATE_LISTENING))
1367   {
1368     /* Check Tx Mailbox 0 */
1369     if ((TxMailboxes & CAN_TX_MAILBOX0) != 0U)
1370     {
1371       /* Add cancellation request for Tx Mailbox 0 */
1372       SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ0);
1373     }
1374 
1375     /* Check Tx Mailbox 1 */
1376     if ((TxMailboxes & CAN_TX_MAILBOX1) != 0U)
1377     {
1378       /* Add cancellation request for Tx Mailbox 1 */
1379       SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ1);
1380     }
1381 
1382     /* Check Tx Mailbox 2 */
1383     if ((TxMailboxes & CAN_TX_MAILBOX2) != 0U)
1384     {
1385       /* Add cancellation request for Tx Mailbox 2 */
1386       SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ2);
1387     }
1388 
1389     /* Return function status */
1390     return HAL_OK;
1391   }
1392   else
1393   {
1394     /* Update error code */
1395     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1396 
1397     return HAL_ERROR;
1398   }
1399 }
1400 
1401 /**
1402   * @brief  Return Tx Mailboxes free level: number of free Tx Mailboxes.
1403   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1404   *         the configuration information for the specified CAN.
1405   * @retval Number of free Tx Mailboxes.
1406   */
HAL_CAN_GetTxMailboxesFreeLevel(CAN_HandleTypeDef * hcan)1407 uint32_t HAL_CAN_GetTxMailboxesFreeLevel(CAN_HandleTypeDef *hcan)
1408 {
1409   uint32_t freelevel = 0U;
1410   HAL_CAN_StateTypeDef state = hcan->State;
1411 
1412   if ((state == HAL_CAN_STATE_READY) ||
1413       (state == HAL_CAN_STATE_LISTENING))
1414   {
1415     /* Check Tx Mailbox 0 status */
1416     if ((hcan->Instance->TSR & CAN_TSR_TME0) != 0U)
1417     {
1418       freelevel++;
1419     }
1420 
1421     /* Check Tx Mailbox 1 status */
1422     if ((hcan->Instance->TSR & CAN_TSR_TME1) != 0U)
1423     {
1424       freelevel++;
1425     }
1426 
1427     /* Check Tx Mailbox 2 status */
1428     if ((hcan->Instance->TSR & CAN_TSR_TME2) != 0U)
1429     {
1430       freelevel++;
1431     }
1432   }
1433 
1434   /* Return Tx Mailboxes free level */
1435   return freelevel;
1436 }
1437 
1438 /**
1439   * @brief  Check if a transmission request is pending on the selected Tx
1440   *         Mailboxes.
1441   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1442   *         the configuration information for the specified CAN.
1443   * @param  TxMailboxes List of Tx Mailboxes to check.
1444   *         This parameter can be any combination of @arg CAN_Tx_Mailboxes.
1445   * @retval Status
1446   *          - 0 : No pending transmission request on any selected Tx Mailboxes.
1447   *          - 1 : Pending transmission request on at least one of the selected
1448   *                Tx Mailbox.
1449   */
HAL_CAN_IsTxMessagePending(CAN_HandleTypeDef * hcan,uint32_t TxMailboxes)1450 uint32_t HAL_CAN_IsTxMessagePending(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes)
1451 {
1452   uint32_t status = 0U;
1453   HAL_CAN_StateTypeDef state = hcan->State;
1454 
1455   /* Check function parameters */
1456   assert_param(IS_CAN_TX_MAILBOX_LIST(TxMailboxes));
1457 
1458   if ((state == HAL_CAN_STATE_READY) ||
1459       (state == HAL_CAN_STATE_LISTENING))
1460   {
1461     /* Check pending transmission request on the selected Tx Mailboxes */
1462     if ((hcan->Instance->TSR & (TxMailboxes << CAN_TSR_TME0_Pos)) != (TxMailboxes << CAN_TSR_TME0_Pos))
1463     {
1464       status = 1U;
1465     }
1466   }
1467 
1468   /* Return status */
1469   return status;
1470 }
1471 
1472 /**
1473   * @brief  Return timestamp of Tx message sent, if time triggered communication
1474             mode is enabled.
1475   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1476   *         the configuration information for the specified CAN.
1477   * @param  TxMailbox Tx Mailbox where the timestamp of message sent will be
1478   *         read.
1479   *         This parameter can be one value of @arg CAN_Tx_Mailboxes.
1480   * @retval Timestamp of message sent from Tx Mailbox.
1481   */
HAL_CAN_GetTxTimestamp(CAN_HandleTypeDef * hcan,uint32_t TxMailbox)1482 uint32_t HAL_CAN_GetTxTimestamp(CAN_HandleTypeDef *hcan, uint32_t TxMailbox)
1483 {
1484   uint32_t timestamp = 0U;
1485   uint32_t transmitmailbox;
1486   HAL_CAN_StateTypeDef state = hcan->State;
1487 
1488   /* Check function parameters */
1489   assert_param(IS_CAN_TX_MAILBOX(TxMailbox));
1490 
1491   if ((state == HAL_CAN_STATE_READY) ||
1492       (state == HAL_CAN_STATE_LISTENING))
1493   {
1494     /* Select the Tx mailbox */
1495     transmitmailbox = POSITION_VAL(TxMailbox);
1496 
1497     /* Get timestamp */
1498     timestamp = (hcan->Instance->sTxMailBox[transmitmailbox].TDTR & CAN_TDT0R_TIME) >> CAN_TDT0R_TIME_Pos;
1499   }
1500 
1501   /* Return the timestamp */
1502   return timestamp;
1503 }
1504 
1505 /**
1506   * @brief  Get an CAN frame from the Rx FIFO zone into the message RAM.
1507   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1508   *         the configuration information for the specified CAN.
1509   * @param  RxFifo Fifo number of the received message to be read.
1510   *         This parameter can be a value of @arg CAN_receive_FIFO_number.
1511   * @param  pHeader pointer to a CAN_RxHeaderTypeDef structure where the header
1512   *         of the Rx frame will be stored.
1513   * @param  aData array where the payload of the Rx frame will be stored.
1514   * @retval HAL status
1515   */
HAL_CAN_GetRxMessage(CAN_HandleTypeDef * hcan,uint32_t RxFifo,CAN_RxHeaderTypeDef * pHeader,uint8_t aData[])1516 HAL_StatusTypeDef HAL_CAN_GetRxMessage(CAN_HandleTypeDef *hcan, uint32_t RxFifo, CAN_RxHeaderTypeDef *pHeader, uint8_t aData[])
1517 {
1518   HAL_CAN_StateTypeDef state = hcan->State;
1519 
1520   assert_param(IS_CAN_RX_FIFO(RxFifo));
1521 
1522   if ((state == HAL_CAN_STATE_READY) ||
1523       (state == HAL_CAN_STATE_LISTENING))
1524   {
1525     /* Check the Rx FIFO */
1526     if (RxFifo == CAN_RX_FIFO0) /* Rx element is assigned to Rx FIFO 0 */
1527     {
1528       /* Check that the Rx FIFO 0 is not empty */
1529       if ((hcan->Instance->RF0R & CAN_RF0R_FMP0) == 0U)
1530       {
1531         /* Update error code */
1532         hcan->ErrorCode |= HAL_CAN_ERROR_PARAM;
1533 
1534         return HAL_ERROR;
1535       }
1536     }
1537     else /* Rx element is assigned to Rx FIFO 1 */
1538     {
1539       /* Check that the Rx FIFO 1 is not empty */
1540       if ((hcan->Instance->RF1R & CAN_RF1R_FMP1) == 0U)
1541       {
1542         /* Update error code */
1543         hcan->ErrorCode |= HAL_CAN_ERROR_PARAM;
1544 
1545         return HAL_ERROR;
1546       }
1547     }
1548 
1549     /* Get the header */
1550     pHeader->IDE = CAN_RI0R_IDE & hcan->Instance->sFIFOMailBox[RxFifo].RIR;
1551     if (pHeader->IDE == CAN_ID_STD)
1552     {
1553       pHeader->StdId = (CAN_RI0R_STID & hcan->Instance->sFIFOMailBox[RxFifo].RIR) >> CAN_TI0R_STID_Pos;
1554     }
1555     else
1556     {
1557       pHeader->ExtId = ((CAN_RI0R_EXID | CAN_RI0R_STID) & hcan->Instance->sFIFOMailBox[RxFifo].RIR) >> CAN_RI0R_EXID_Pos;
1558     }
1559     pHeader->RTR = (CAN_RI0R_RTR & hcan->Instance->sFIFOMailBox[RxFifo].RIR);
1560     pHeader->DLC = (CAN_RDT0R_DLC & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_DLC_Pos;
1561     pHeader->FilterMatchIndex = (CAN_RDT0R_FMI & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_FMI_Pos;
1562     pHeader->Timestamp = (CAN_RDT0R_TIME & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_TIME_Pos;
1563 
1564     /* Get the data */
1565     aData[0] = (uint8_t)((CAN_RDL0R_DATA0 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA0_Pos);
1566     aData[1] = (uint8_t)((CAN_RDL0R_DATA1 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA1_Pos);
1567     aData[2] = (uint8_t)((CAN_RDL0R_DATA2 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA2_Pos);
1568     aData[3] = (uint8_t)((CAN_RDL0R_DATA3 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA3_Pos);
1569     aData[4] = (uint8_t)((CAN_RDH0R_DATA4 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA4_Pos);
1570     aData[5] = (uint8_t)((CAN_RDH0R_DATA5 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA5_Pos);
1571     aData[6] = (uint8_t)((CAN_RDH0R_DATA6 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA6_Pos);
1572     aData[7] = (uint8_t)((CAN_RDH0R_DATA7 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA7_Pos);
1573 
1574     /* Release the FIFO */
1575     if (RxFifo == CAN_RX_FIFO0) /* Rx element is assigned to Rx FIFO 0 */
1576     {
1577       /* Release RX FIFO 0 */
1578       SET_BIT(hcan->Instance->RF0R, CAN_RF0R_RFOM0);
1579     }
1580     else /* Rx element is assigned to Rx FIFO 1 */
1581     {
1582       /* Release RX FIFO 1 */
1583       SET_BIT(hcan->Instance->RF1R, CAN_RF1R_RFOM1);
1584     }
1585 
1586     /* Return function status */
1587     return HAL_OK;
1588   }
1589   else
1590   {
1591     /* Update error code */
1592     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1593 
1594     return HAL_ERROR;
1595   }
1596 }
1597 
1598 /**
1599   * @brief  Return Rx FIFO fill level.
1600   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1601   *         the configuration information for the specified CAN.
1602   * @param  RxFifo Rx FIFO.
1603   *         This parameter can be a value of @arg CAN_receive_FIFO_number.
1604   * @retval Number of messages available in Rx FIFO.
1605   */
HAL_CAN_GetRxFifoFillLevel(CAN_HandleTypeDef * hcan,uint32_t RxFifo)1606 uint32_t HAL_CAN_GetRxFifoFillLevel(CAN_HandleTypeDef *hcan, uint32_t RxFifo)
1607 {
1608   uint32_t filllevel = 0U;
1609   HAL_CAN_StateTypeDef state = hcan->State;
1610 
1611   /* Check function parameters */
1612   assert_param(IS_CAN_RX_FIFO(RxFifo));
1613 
1614   if ((state == HAL_CAN_STATE_READY) ||
1615       (state == HAL_CAN_STATE_LISTENING))
1616   {
1617     if (RxFifo == CAN_RX_FIFO0)
1618     {
1619       filllevel = hcan->Instance->RF0R & CAN_RF0R_FMP0;
1620     }
1621     else /* RxFifo == CAN_RX_FIFO1 */
1622     {
1623       filllevel = hcan->Instance->RF1R & CAN_RF1R_FMP1;
1624     }
1625   }
1626 
1627   /* Return Rx FIFO fill level */
1628   return filllevel;
1629 }
1630 
1631 /**
1632   * @}
1633   */
1634 
1635 /** @defgroup CAN_Exported_Functions_Group4 Interrupts management
1636  *  @brief    Interrupts management
1637  *
1638 @verbatim
1639   ==============================================================================
1640                        ##### Interrupts management #####
1641   ==============================================================================
1642     [..]  This section provides functions allowing to:
1643       (+) HAL_CAN_ActivateNotification      : Enable interrupts
1644       (+) HAL_CAN_DeactivateNotification    : Disable interrupts
1645       (+) HAL_CAN_IRQHandler                : Handles CAN interrupt request
1646 
1647 @endverbatim
1648   * @{
1649   */
1650 
1651 /**
1652   * @brief  Enable interrupts.
1653   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1654   *         the configuration information for the specified CAN.
1655   * @param  ActiveITs indicates which interrupts will be enabled.
1656   *         This parameter can be any combination of @arg CAN_Interrupts.
1657   * @retval HAL status
1658   */
HAL_CAN_ActivateNotification(CAN_HandleTypeDef * hcan,uint32_t ActiveITs)1659 HAL_StatusTypeDef HAL_CAN_ActivateNotification(CAN_HandleTypeDef *hcan, uint32_t ActiveITs)
1660 {
1661   HAL_CAN_StateTypeDef state = hcan->State;
1662 
1663   /* Check function parameters */
1664   assert_param(IS_CAN_IT(ActiveITs));
1665 
1666   if ((state == HAL_CAN_STATE_READY) ||
1667       (state == HAL_CAN_STATE_LISTENING))
1668   {
1669     /* Enable the selected interrupts */
1670     __HAL_CAN_ENABLE_IT(hcan, ActiveITs);
1671 
1672     /* Return function status */
1673     return HAL_OK;
1674   }
1675   else
1676   {
1677     /* Update error code */
1678     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1679 
1680     return HAL_ERROR;
1681   }
1682 }
1683 
1684 /**
1685   * @brief  Disable interrupts.
1686   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1687   *         the configuration information for the specified CAN.
1688   * @param  InactiveITs indicates which interrupts will be disabled.
1689   *         This parameter can be any combination of @arg CAN_Interrupts.
1690   * @retval HAL status
1691   */
HAL_CAN_DeactivateNotification(CAN_HandleTypeDef * hcan,uint32_t InactiveITs)1692 HAL_StatusTypeDef HAL_CAN_DeactivateNotification(CAN_HandleTypeDef *hcan, uint32_t InactiveITs)
1693 {
1694   HAL_CAN_StateTypeDef state = hcan->State;
1695 
1696   /* Check function parameters */
1697   assert_param(IS_CAN_IT(InactiveITs));
1698 
1699   if ((state == HAL_CAN_STATE_READY) ||
1700       (state == HAL_CAN_STATE_LISTENING))
1701   {
1702     /* Disable the selected interrupts */
1703     __HAL_CAN_DISABLE_IT(hcan, InactiveITs);
1704 
1705     /* Return function status */
1706     return HAL_OK;
1707   }
1708   else
1709   {
1710     /* Update error code */
1711     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1712 
1713     return HAL_ERROR;
1714   }
1715 }
1716 
1717 /**
1718   * @brief  Handles CAN interrupt request
1719   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1720   *         the configuration information for the specified CAN.
1721   * @retval None
1722   */
HAL_CAN_IRQHandler(CAN_HandleTypeDef * hcan)1723 void HAL_CAN_IRQHandler(CAN_HandleTypeDef *hcan)
1724 {
1725   uint32_t errorcode = HAL_CAN_ERROR_NONE;
1726   uint32_t interrupts = READ_REG(hcan->Instance->IER);
1727   uint32_t msrflags = READ_REG(hcan->Instance->MSR);
1728   uint32_t tsrflags = READ_REG(hcan->Instance->TSR);
1729   uint32_t rf0rflags = READ_REG(hcan->Instance->RF0R);
1730   uint32_t rf1rflags = READ_REG(hcan->Instance->RF1R);
1731   uint32_t esrflags = READ_REG(hcan->Instance->ESR);
1732 
1733   /* Transmit Mailbox empty interrupt management *****************************/
1734   if ((interrupts & CAN_IT_TX_MAILBOX_EMPTY) != 0U)
1735   {
1736     /* Transmit Mailbox 0 management *****************************************/
1737     if ((tsrflags & CAN_TSR_RQCP0) != 0U)
1738     {
1739       /* Clear the Transmission Complete flag (and TXOK0,ALST0,TERR0 bits) */
1740       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP0);
1741 
1742       if ((tsrflags & CAN_TSR_TXOK0) != 0U)
1743       {
1744         /* Transmission Mailbox 0 complete callback */
1745 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1746         /* Call registered callback*/
1747         hcan->TxMailbox0CompleteCallback(hcan);
1748 #else
1749         /* Call weak (surcharged) callback */
1750         HAL_CAN_TxMailbox0CompleteCallback(hcan);
1751 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1752       }
1753       else
1754       {
1755         if ((tsrflags & CAN_TSR_ALST0) != 0U)
1756         {
1757           /* Update error code */
1758           errorcode |= HAL_CAN_ERROR_TX_ALST0;
1759         }
1760         else if ((tsrflags & CAN_TSR_TERR0) != 0U)
1761         {
1762           /* Update error code */
1763           errorcode |= HAL_CAN_ERROR_TX_TERR0;
1764         }
1765         else
1766         {
1767           /* Transmission Mailbox 0 abort callback */
1768 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1769           /* Call registered callback*/
1770           hcan->TxMailbox0AbortCallback(hcan);
1771 #else
1772           /* Call weak (surcharged) callback */
1773           HAL_CAN_TxMailbox0AbortCallback(hcan);
1774 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1775         }
1776       }
1777     }
1778 
1779     /* Transmit Mailbox 1 management *****************************************/
1780     if ((tsrflags & CAN_TSR_RQCP1) != 0U)
1781     {
1782       /* Clear the Transmission Complete flag (and TXOK1,ALST1,TERR1 bits) */
1783       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP1);
1784 
1785       if ((tsrflags & CAN_TSR_TXOK1) != 0U)
1786       {
1787         /* Transmission Mailbox 1 complete callback */
1788 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1789         /* Call registered callback*/
1790         hcan->TxMailbox1CompleteCallback(hcan);
1791 #else
1792         /* Call weak (surcharged) callback */
1793         HAL_CAN_TxMailbox1CompleteCallback(hcan);
1794 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1795       }
1796       else
1797       {
1798         if ((tsrflags & CAN_TSR_ALST1) != 0U)
1799         {
1800           /* Update error code */
1801           errorcode |= HAL_CAN_ERROR_TX_ALST1;
1802         }
1803         else if ((tsrflags & CAN_TSR_TERR1) != 0U)
1804         {
1805           /* Update error code */
1806           errorcode |= HAL_CAN_ERROR_TX_TERR1;
1807         }
1808         else
1809         {
1810           /* Transmission Mailbox 1 abort callback */
1811 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1812           /* Call registered callback*/
1813           hcan->TxMailbox1AbortCallback(hcan);
1814 #else
1815           /* Call weak (surcharged) callback */
1816           HAL_CAN_TxMailbox1AbortCallback(hcan);
1817 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1818         }
1819       }
1820     }
1821 
1822     /* Transmit Mailbox 2 management *****************************************/
1823     if ((tsrflags & CAN_TSR_RQCP2) != 0U)
1824     {
1825       /* Clear the Transmission Complete flag (and TXOK2,ALST2,TERR2 bits) */
1826       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP2);
1827 
1828       if ((tsrflags & CAN_TSR_TXOK2) != 0U)
1829       {
1830         /* Transmission Mailbox 2 complete callback */
1831 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1832         /* Call registered callback*/
1833         hcan->TxMailbox2CompleteCallback(hcan);
1834 #else
1835         /* Call weak (surcharged) callback */
1836         HAL_CAN_TxMailbox2CompleteCallback(hcan);
1837 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1838       }
1839       else
1840       {
1841         if ((tsrflags & CAN_TSR_ALST2) != 0U)
1842         {
1843           /* Update error code */
1844           errorcode |= HAL_CAN_ERROR_TX_ALST2;
1845         }
1846         else if ((tsrflags & CAN_TSR_TERR2) != 0U)
1847         {
1848           /* Update error code */
1849           errorcode |= HAL_CAN_ERROR_TX_TERR2;
1850         }
1851         else
1852         {
1853           /* Transmission Mailbox 2 abort callback */
1854 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1855           /* Call registered callback*/
1856           hcan->TxMailbox2AbortCallback(hcan);
1857 #else
1858           /* Call weak (surcharged) callback */
1859           HAL_CAN_TxMailbox2AbortCallback(hcan);
1860 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1861         }
1862       }
1863     }
1864   }
1865 
1866   /* Receive FIFO 0 overrun interrupt management *****************************/
1867   if ((interrupts & CAN_IT_RX_FIFO0_OVERRUN) != 0U)
1868   {
1869     if ((rf0rflags & CAN_RF0R_FOVR0) != 0U)
1870     {
1871       /* Set CAN error code to Rx Fifo 0 overrun error */
1872       errorcode |= HAL_CAN_ERROR_RX_FOV0;
1873 
1874       /* Clear FIFO0 Overrun Flag */
1875       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV0);
1876     }
1877   }
1878 
1879   /* Receive FIFO 0 full interrupt management ********************************/
1880   if ((interrupts & CAN_IT_RX_FIFO0_FULL) != 0U)
1881   {
1882     if ((rf0rflags & CAN_RF0R_FULL0) != 0U)
1883     {
1884       /* Clear FIFO 0 full Flag */
1885       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF0);
1886 
1887       /* Receive FIFO 0 full Callback */
1888 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1889       /* Call registered callback*/
1890       hcan->RxFifo0FullCallback(hcan);
1891 #else
1892       /* Call weak (surcharged) callback */
1893       HAL_CAN_RxFifo0FullCallback(hcan);
1894 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1895     }
1896   }
1897 
1898   /* Receive FIFO 0 message pending interrupt management *********************/
1899   if ((interrupts & CAN_IT_RX_FIFO0_MSG_PENDING) != 0U)
1900   {
1901     /* Check if message is still pending */
1902     if ((hcan->Instance->RF0R & CAN_RF0R_FMP0) != 0U)
1903     {
1904       /* Receive FIFO 0 message pending Callback */
1905 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1906       /* Call registered callback*/
1907       hcan->RxFifo0MsgPendingCallback(hcan);
1908 #else
1909       /* Call weak (surcharged) callback */
1910       HAL_CAN_RxFifo0MsgPendingCallback(hcan);
1911 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1912     }
1913   }
1914 
1915   /* Receive FIFO 1 overrun interrupt management *****************************/
1916   if ((interrupts & CAN_IT_RX_FIFO1_OVERRUN) != 0U)
1917   {
1918     if ((rf1rflags & CAN_RF1R_FOVR1) != 0U)
1919     {
1920       /* Set CAN error code to Rx Fifo 1 overrun error */
1921       errorcode |= HAL_CAN_ERROR_RX_FOV1;
1922 
1923       /* Clear FIFO1 Overrun Flag */
1924       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV1);
1925     }
1926   }
1927 
1928   /* Receive FIFO 1 full interrupt management ********************************/
1929   if ((interrupts & CAN_IT_RX_FIFO1_FULL) != 0U)
1930   {
1931     if ((rf1rflags & CAN_RF1R_FULL1) != 0U)
1932     {
1933       /* Clear FIFO 1 full Flag */
1934       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF1);
1935 
1936       /* Receive FIFO 1 full Callback */
1937 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1938       /* Call registered callback*/
1939       hcan->RxFifo1FullCallback(hcan);
1940 #else
1941       /* Call weak (surcharged) callback */
1942       HAL_CAN_RxFifo1FullCallback(hcan);
1943 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1944     }
1945   }
1946 
1947   /* Receive FIFO 1 message pending interrupt management *********************/
1948   if ((interrupts & CAN_IT_RX_FIFO1_MSG_PENDING) != 0U)
1949   {
1950     /* Check if message is still pending */
1951     if ((hcan->Instance->RF1R & CAN_RF1R_FMP1) != 0U)
1952     {
1953       /* Receive FIFO 1 message pending Callback */
1954 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1955       /* Call registered callback*/
1956       hcan->RxFifo1MsgPendingCallback(hcan);
1957 #else
1958       /* Call weak (surcharged) callback */
1959       HAL_CAN_RxFifo1MsgPendingCallback(hcan);
1960 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1961     }
1962   }
1963 
1964   /* Sleep interrupt management *********************************************/
1965   if ((interrupts & CAN_IT_SLEEP_ACK) != 0U)
1966   {
1967     if ((msrflags & CAN_MSR_SLAKI) != 0U)
1968     {
1969       /* Clear Sleep interrupt Flag */
1970       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_SLAKI);
1971 
1972       /* Sleep Callback */
1973 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1974       /* Call registered callback*/
1975       hcan->SleepCallback(hcan);
1976 #else
1977       /* Call weak (surcharged) callback */
1978       HAL_CAN_SleepCallback(hcan);
1979 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1980     }
1981   }
1982 
1983   /* WakeUp interrupt management *********************************************/
1984   if ((interrupts & CAN_IT_WAKEUP) != 0U)
1985   {
1986     if ((msrflags & CAN_MSR_WKUI) != 0U)
1987     {
1988       /* Clear WakeUp Flag */
1989       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_WKU);
1990 
1991       /* WakeUp Callback */
1992 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1993       /* Call registered callback*/
1994       hcan->WakeUpFromRxMsgCallback(hcan);
1995 #else
1996       /* Call weak (surcharged) callback */
1997       HAL_CAN_WakeUpFromRxMsgCallback(hcan);
1998 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1999     }
2000   }
2001 
2002   /* Error interrupts management *********************************************/
2003   if ((interrupts & CAN_IT_ERROR) != 0U)
2004   {
2005     if ((msrflags & CAN_MSR_ERRI) != 0U)
2006     {
2007       /* Check Error Warning Flag */
2008       if (((interrupts & CAN_IT_ERROR_WARNING) != 0U) &&
2009           ((esrflags & CAN_ESR_EWGF) != 0U))
2010       {
2011         /* Set CAN error code to Error Warning */
2012         errorcode |= HAL_CAN_ERROR_EWG;
2013 
2014         /* No need for clear of Error Warning Flag as read-only */
2015       }
2016 
2017       /* Check Error Passive Flag */
2018       if (((interrupts & CAN_IT_ERROR_PASSIVE) != 0U) &&
2019           ((esrflags & CAN_ESR_EPVF) != 0U))
2020       {
2021         /* Set CAN error code to Error Passive */
2022         errorcode |= HAL_CAN_ERROR_EPV;
2023 
2024         /* No need for clear of Error Passive Flag as read-only */
2025       }
2026 
2027       /* Check Bus-off Flag */
2028       if (((interrupts & CAN_IT_BUSOFF) != 0U) &&
2029           ((esrflags & CAN_ESR_BOFF) != 0U))
2030       {
2031         /* Set CAN error code to Bus-Off */
2032         errorcode |= HAL_CAN_ERROR_BOF;
2033 
2034         /* No need for clear of Error Bus-Off as read-only */
2035       }
2036 
2037       /* Check Last Error Code Flag */
2038       if (((interrupts & CAN_IT_LAST_ERROR_CODE) != 0U) &&
2039           ((esrflags & CAN_ESR_LEC) != 0U))
2040       {
2041         switch (esrflags & CAN_ESR_LEC)
2042         {
2043           case (CAN_ESR_LEC_0):
2044             /* Set CAN error code to Stuff error */
2045             errorcode |= HAL_CAN_ERROR_STF;
2046             break;
2047           case (CAN_ESR_LEC_1):
2048             /* Set CAN error code to Form error */
2049             errorcode |= HAL_CAN_ERROR_FOR;
2050             break;
2051           case (CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
2052             /* Set CAN error code to Acknowledgement error */
2053             errorcode |= HAL_CAN_ERROR_ACK;
2054             break;
2055           case (CAN_ESR_LEC_2):
2056             /* Set CAN error code to Bit recessive error */
2057             errorcode |= HAL_CAN_ERROR_BR;
2058             break;
2059           case (CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
2060             /* Set CAN error code to Bit Dominant error */
2061             errorcode |= HAL_CAN_ERROR_BD;
2062             break;
2063           case (CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
2064             /* Set CAN error code to CRC error */
2065             errorcode |= HAL_CAN_ERROR_CRC;
2066             break;
2067           default:
2068             break;
2069         }
2070 
2071         /* Clear Last error code Flag */
2072         CLEAR_BIT(hcan->Instance->ESR, CAN_ESR_LEC);
2073       }
2074     }
2075 
2076     /* Clear ERRI Flag */
2077     __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_ERRI);
2078   }
2079 
2080   /* Call the Error call Back in case of Errors */
2081   if (errorcode != HAL_CAN_ERROR_NONE)
2082   {
2083     /* Update error code in handle */
2084     hcan->ErrorCode |= errorcode;
2085 
2086     /* Call Error callback function */
2087 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
2088     /* Call registered callback*/
2089     hcan->ErrorCallback(hcan);
2090 #else
2091     /* Call weak (surcharged) callback */
2092     HAL_CAN_ErrorCallback(hcan);
2093 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
2094   }
2095 }
2096 
2097 /**
2098   * @}
2099   */
2100 
2101 /** @defgroup CAN_Exported_Functions_Group5 Callback functions
2102  *  @brief   CAN Callback functions
2103  *
2104 @verbatim
2105   ==============================================================================
2106                           ##### Callback functions #####
2107   ==============================================================================
2108     [..]
2109     This subsection provides the following callback functions:
2110       (+) HAL_CAN_TxMailbox0CompleteCallback
2111       (+) HAL_CAN_TxMailbox1CompleteCallback
2112       (+) HAL_CAN_TxMailbox2CompleteCallback
2113       (+) HAL_CAN_TxMailbox0AbortCallback
2114       (+) HAL_CAN_TxMailbox1AbortCallback
2115       (+) HAL_CAN_TxMailbox2AbortCallback
2116       (+) HAL_CAN_RxFifo0MsgPendingCallback
2117       (+) HAL_CAN_RxFifo0FullCallback
2118       (+) HAL_CAN_RxFifo1MsgPendingCallback
2119       (+) HAL_CAN_RxFifo1FullCallback
2120       (+) HAL_CAN_SleepCallback
2121       (+) HAL_CAN_WakeUpFromRxMsgCallback
2122       (+) HAL_CAN_ErrorCallback
2123 
2124 @endverbatim
2125   * @{
2126   */
2127 
2128 /**
2129   * @brief  Transmission Mailbox 0 complete callback.
2130   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2131   *         the configuration information for the specified CAN.
2132   * @retval None
2133   */
HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef * hcan)2134 __weak void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan)
2135 {
2136   /* Prevent unused argument(s) compilation warning */
2137   UNUSED(hcan);
2138 
2139   /* NOTE : This function Should not be modified, when the callback is needed,
2140             the HAL_CAN_TxMailbox0CompleteCallback could be implemented in the
2141             user file
2142    */
2143 }
2144 
2145 /**
2146   * @brief  Transmission Mailbox 1 complete callback.
2147   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2148   *         the configuration information for the specified CAN.
2149   * @retval None
2150   */
HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef * hcan)2151 __weak void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan)
2152 {
2153   /* Prevent unused argument(s) compilation warning */
2154   UNUSED(hcan);
2155 
2156   /* NOTE : This function Should not be modified, when the callback is needed,
2157             the HAL_CAN_TxMailbox1CompleteCallback could be implemented in the
2158             user file
2159    */
2160 }
2161 
2162 /**
2163   * @brief  Transmission Mailbox 2 complete callback.
2164   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2165   *         the configuration information for the specified CAN.
2166   * @retval None
2167   */
HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef * hcan)2168 __weak void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan)
2169 {
2170   /* Prevent unused argument(s) compilation warning */
2171   UNUSED(hcan);
2172 
2173   /* NOTE : This function Should not be modified, when the callback is needed,
2174             the HAL_CAN_TxMailbox2CompleteCallback could be implemented in the
2175             user file
2176    */
2177 }
2178 
2179 /**
2180   * @brief  Transmission Mailbox 0 Cancellation callback.
2181   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
2182   *         the configuration information for the specified CAN.
2183   * @retval None
2184   */
HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef * hcan)2185 __weak void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan)
2186 {
2187   /* Prevent unused argument(s) compilation warning */
2188   UNUSED(hcan);
2189 
2190   /* NOTE : This function Should not be modified, when the callback is needed,
2191             the HAL_CAN_TxMailbox0AbortCallback could be implemented in the
2192             user file
2193    */
2194 }
2195 
2196 /**
2197   * @brief  Transmission Mailbox 1 Cancellation callback.
2198   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
2199   *         the configuration information for the specified CAN.
2200   * @retval None
2201   */
HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef * hcan)2202 __weak void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan)
2203 {
2204   /* Prevent unused argument(s) compilation warning */
2205   UNUSED(hcan);
2206 
2207   /* NOTE : This function Should not be modified, when the callback is needed,
2208             the HAL_CAN_TxMailbox1AbortCallback could be implemented in the
2209             user file
2210    */
2211 }
2212 
2213 /**
2214   * @brief  Transmission Mailbox 2 Cancellation callback.
2215   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
2216   *         the configuration information for the specified CAN.
2217   * @retval None
2218   */
HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef * hcan)2219 __weak void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan)
2220 {
2221   /* Prevent unused argument(s) compilation warning */
2222   UNUSED(hcan);
2223 
2224   /* NOTE : This function Should not be modified, when the callback is needed,
2225             the HAL_CAN_TxMailbox2AbortCallback could be implemented in the
2226             user file
2227    */
2228 }
2229 
2230 /**
2231   * @brief  Rx FIFO 0 message pending callback.
2232   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2233   *         the configuration information for the specified CAN.
2234   * @retval None
2235   */
HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef * hcan)2236 __weak void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
2237 {
2238   /* Prevent unused argument(s) compilation warning */
2239   UNUSED(hcan);
2240 
2241   /* NOTE : This function Should not be modified, when the callback is needed,
2242             the HAL_CAN_RxFifo0MsgPendingCallback could be implemented in the
2243             user file
2244    */
2245 }
2246 
2247 /**
2248   * @brief  Rx FIFO 0 full callback.
2249   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2250   *         the configuration information for the specified CAN.
2251   * @retval None
2252   */
HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef * hcan)2253 __weak void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan)
2254 {
2255   /* Prevent unused argument(s) compilation warning */
2256   UNUSED(hcan);
2257 
2258   /* NOTE : This function Should not be modified, when the callback is needed,
2259             the HAL_CAN_RxFifo0FullCallback could be implemented in the user
2260             file
2261    */
2262 }
2263 
2264 /**
2265   * @brief  Rx FIFO 1 message pending callback.
2266   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2267   *         the configuration information for the specified CAN.
2268   * @retval None
2269   */
HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef * hcan)2270 __weak void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan)
2271 {
2272   /* Prevent unused argument(s) compilation warning */
2273   UNUSED(hcan);
2274 
2275   /* NOTE : This function Should not be modified, when the callback is needed,
2276             the HAL_CAN_RxFifo1MsgPendingCallback could be implemented in the
2277             user file
2278    */
2279 }
2280 
2281 /**
2282   * @brief  Rx FIFO 1 full callback.
2283   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2284   *         the configuration information for the specified CAN.
2285   * @retval None
2286   */
HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef * hcan)2287 __weak void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan)
2288 {
2289   /* Prevent unused argument(s) compilation warning */
2290   UNUSED(hcan);
2291 
2292   /* NOTE : This function Should not be modified, when the callback is needed,
2293             the HAL_CAN_RxFifo1FullCallback could be implemented in the user
2294             file
2295    */
2296 }
2297 
2298 /**
2299   * @brief  Sleep callback.
2300   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2301   *         the configuration information for the specified CAN.
2302   * @retval None
2303   */
HAL_CAN_SleepCallback(CAN_HandleTypeDef * hcan)2304 __weak void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan)
2305 {
2306   /* Prevent unused argument(s) compilation warning */
2307   UNUSED(hcan);
2308 
2309   /* NOTE : This function Should not be modified, when the callback is needed,
2310             the HAL_CAN_SleepCallback could be implemented in the user file
2311    */
2312 }
2313 
2314 /**
2315   * @brief  WakeUp from Rx message callback.
2316   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2317   *         the configuration information for the specified CAN.
2318   * @retval None
2319   */
HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef * hcan)2320 __weak void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan)
2321 {
2322   /* Prevent unused argument(s) compilation warning */
2323   UNUSED(hcan);
2324 
2325   /* NOTE : This function Should not be modified, when the callback is needed,
2326             the HAL_CAN_WakeUpFromRxMsgCallback could be implemented in the
2327             user file
2328    */
2329 }
2330 
2331 /**
2332   * @brief  Error CAN callback.
2333   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2334   *         the configuration information for the specified CAN.
2335   * @retval None
2336   */
HAL_CAN_ErrorCallback(CAN_HandleTypeDef * hcan)2337 __weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
2338 {
2339   /* Prevent unused argument(s) compilation warning */
2340   UNUSED(hcan);
2341 
2342   /* NOTE : This function Should not be modified, when the callback is needed,
2343             the HAL_CAN_ErrorCallback could be implemented in the user file
2344    */
2345 }
2346 
2347 /**
2348   * @}
2349   */
2350 
2351 /** @defgroup CAN_Exported_Functions_Group6 Peripheral State and Error functions
2352  *  @brief   CAN Peripheral State functions
2353  *
2354 @verbatim
2355   ==============================================================================
2356             ##### Peripheral State and Error functions #####
2357   ==============================================================================
2358     [..]
2359     This subsection provides functions allowing to :
2360       (+) HAL_CAN_GetState()  : Return the CAN state.
2361       (+) HAL_CAN_GetError()  : Return the CAN error codes if any.
2362       (+) HAL_CAN_ResetError(): Reset the CAN error codes if any.
2363 
2364 @endverbatim
2365   * @{
2366   */
2367 
2368 /**
2369   * @brief  Return the CAN state.
2370   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2371   *         the configuration information for the specified CAN.
2372   * @retval HAL state
2373   */
HAL_CAN_GetState(CAN_HandleTypeDef * hcan)2374 HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef *hcan)
2375 {
2376   HAL_CAN_StateTypeDef state = hcan->State;
2377 
2378   if ((state == HAL_CAN_STATE_READY) ||
2379       (state == HAL_CAN_STATE_LISTENING))
2380   {
2381     /* Check sleep mode acknowledge flag */
2382     if ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U)
2383     {
2384       /* Sleep mode is active */
2385       state = HAL_CAN_STATE_SLEEP_ACTIVE;
2386     }
2387     /* Check sleep mode request flag */
2388     else if ((hcan->Instance->MCR & CAN_MCR_SLEEP) != 0U)
2389     {
2390       /* Sleep mode request is pending */
2391       state = HAL_CAN_STATE_SLEEP_PENDING;
2392     }
2393     else
2394     {
2395       /* Neither sleep mode request nor sleep mode acknowledge */
2396     }
2397   }
2398 
2399   /* Return CAN state */
2400   return state;
2401 }
2402 
2403 /**
2404   * @brief  Return the CAN error code.
2405   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2406   *         the configuration information for the specified CAN.
2407   * @retval CAN Error Code
2408   */
HAL_CAN_GetError(CAN_HandleTypeDef * hcan)2409 uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan)
2410 {
2411   /* Return CAN error code */
2412   return hcan->ErrorCode;
2413 }
2414 
2415 /**
2416   * @brief  Reset the CAN error code.
2417   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2418   *         the configuration information for the specified CAN.
2419   * @retval HAL status
2420   */
HAL_CAN_ResetError(CAN_HandleTypeDef * hcan)2421 HAL_StatusTypeDef HAL_CAN_ResetError(CAN_HandleTypeDef *hcan)
2422 {
2423   HAL_StatusTypeDef status = HAL_OK;
2424   HAL_CAN_StateTypeDef state = hcan->State;
2425 
2426   if ((state == HAL_CAN_STATE_READY) ||
2427       (state == HAL_CAN_STATE_LISTENING))
2428   {
2429     /* Reset CAN error code */
2430     hcan->ErrorCode = 0U;
2431   }
2432   else
2433   {
2434     /* Update error code */
2435     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
2436 
2437     status = HAL_ERROR;
2438   }
2439 
2440   /* Return the status */
2441   return status;
2442 }
2443 
2444 /**
2445   * @}
2446   */
2447 
2448 /**
2449   * @}
2450   */
2451 
2452 #endif /* HAL_CAN_MODULE_ENABLED */
2453 
2454 /**
2455   * @}
2456   */
2457 
2458 #endif /* CAN1 */
2459 
2460 /**
2461   * @}
2462   */
2463