1 /**
2   ******************************************************************************
3   * @file    stm32l4xx_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) 2017 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 "stm32l4xx_hal.h"
214 
215 /** @addtogroup STM32L4xx_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 /* HAL_CAN_LEGACY_MODULE_ENABLED */
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,
559                                            void (* pCallback)(CAN_HandleTypeDef *_hcan))
560 {
561   HAL_StatusTypeDef status = HAL_OK;
562 
563   if (pCallback == NULL)
564   {
565     /* Update the error code */
566     hcan->ErrorCode |= HAL_CAN_ERROR_INVALID_CALLBACK;
567 
568     return HAL_ERROR;
569   }
570 
571   if (hcan->State == HAL_CAN_STATE_READY)
572   {
573     switch (CallbackID)
574     {
575       case HAL_CAN_TX_MAILBOX0_COMPLETE_CB_ID :
576         hcan->TxMailbox0CompleteCallback = pCallback;
577         break;
578 
579       case HAL_CAN_TX_MAILBOX1_COMPLETE_CB_ID :
580         hcan->TxMailbox1CompleteCallback = pCallback;
581         break;
582 
583       case HAL_CAN_TX_MAILBOX2_COMPLETE_CB_ID :
584         hcan->TxMailbox2CompleteCallback = pCallback;
585         break;
586 
587       case HAL_CAN_TX_MAILBOX0_ABORT_CB_ID :
588         hcan->TxMailbox0AbortCallback = pCallback;
589         break;
590 
591       case HAL_CAN_TX_MAILBOX1_ABORT_CB_ID :
592         hcan->TxMailbox1AbortCallback = pCallback;
593         break;
594 
595       case HAL_CAN_TX_MAILBOX2_ABORT_CB_ID :
596         hcan->TxMailbox2AbortCallback = pCallback;
597         break;
598 
599       case HAL_CAN_RX_FIFO0_MSG_PENDING_CB_ID :
600         hcan->RxFifo0MsgPendingCallback = pCallback;
601         break;
602 
603       case HAL_CAN_RX_FIFO0_FULL_CB_ID :
604         hcan->RxFifo0FullCallback = pCallback;
605         break;
606 
607       case HAL_CAN_RX_FIFO1_MSG_PENDING_CB_ID :
608         hcan->RxFifo1MsgPendingCallback = pCallback;
609         break;
610 
611       case HAL_CAN_RX_FIFO1_FULL_CB_ID :
612         hcan->RxFifo1FullCallback = pCallback;
613         break;
614 
615       case HAL_CAN_SLEEP_CB_ID :
616         hcan->SleepCallback = pCallback;
617         break;
618 
619       case HAL_CAN_WAKEUP_FROM_RX_MSG_CB_ID :
620         hcan->WakeUpFromRxMsgCallback = pCallback;
621         break;
622 
623       case HAL_CAN_ERROR_CB_ID :
624         hcan->ErrorCallback = pCallback;
625         break;
626 
627       case HAL_CAN_MSPINIT_CB_ID :
628         hcan->MspInitCallback = pCallback;
629         break;
630 
631       case HAL_CAN_MSPDEINIT_CB_ID :
632         hcan->MspDeInitCallback = pCallback;
633         break;
634 
635       default :
636         /* Update the error code */
637         hcan->ErrorCode |= HAL_CAN_ERROR_INVALID_CALLBACK;
638 
639         /* Return error status */
640         status =  HAL_ERROR;
641         break;
642     }
643   }
644   else if (hcan->State == HAL_CAN_STATE_RESET)
645   {
646     switch (CallbackID)
647     {
648       case HAL_CAN_MSPINIT_CB_ID :
649         hcan->MspInitCallback = pCallback;
650         break;
651 
652       case HAL_CAN_MSPDEINIT_CB_ID :
653         hcan->MspDeInitCallback = pCallback;
654         break;
655 
656       default :
657         /* Update the error code */
658         hcan->ErrorCode |= HAL_CAN_ERROR_INVALID_CALLBACK;
659 
660         /* Return error status */
661         status =  HAL_ERROR;
662         break;
663     }
664   }
665   else
666   {
667     /* Update the error code */
668     hcan->ErrorCode |= HAL_CAN_ERROR_INVALID_CALLBACK;
669 
670     /* Return error status */
671     status =  HAL_ERROR;
672   }
673 
674   return status;
675 }
676 
677 /**
678   * @brief  Unregister a CAN CallBack.
679   *         CAN callback is redirected to the weak predefined callback
680   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
681   *         the configuration information for CAN module
682   * @param  CallbackID ID of the callback to be unregistered
683   *         This parameter can be one of the following values:
684   *           @arg @ref HAL_CAN_TX_MAILBOX0_COMPLETE_CB_ID Tx Mailbox 0 Complete callback ID
685   *           @arg @ref HAL_CAN_TX_MAILBOX1_COMPLETE_CB_ID Tx Mailbox 1 Complete callback ID
686   *           @arg @ref HAL_CAN_TX_MAILBOX2_COMPLETE_CB_ID Tx Mailbox 2 Complete callback ID
687   *           @arg @ref HAL_CAN_TX_MAILBOX0_ABORT_CB_ID Tx Mailbox 0 Abort callback ID
688   *           @arg @ref HAL_CAN_TX_MAILBOX1_ABORT_CB_ID Tx Mailbox 1 Abort callback ID
689   *           @arg @ref HAL_CAN_TX_MAILBOX2_ABORT_CB_ID Tx Mailbox 2 Abort callback ID
690   *           @arg @ref HAL_CAN_RX_FIFO0_MSG_PENDING_CB_ID Rx Fifo 0 message pending callback ID
691   *           @arg @ref HAL_CAN_RX_FIFO0_FULL_CB_ID Rx Fifo 0 full callback ID
692   *           @arg @ref HAL_CAN_RX_FIFO1_MSG_PENDING_CB_ID Rx Fifo 1 message pending callback ID
693   *           @arg @ref HAL_CAN_RX_FIFO1_FULL_CB_ID Rx Fifo 1 full callback ID
694   *           @arg @ref HAL_CAN_SLEEP_CB_ID Sleep callback ID
695   *           @arg @ref HAL_CAN_WAKEUP_FROM_RX_MSG_CB_ID Wake Up from Rx message callback ID
696   *           @arg @ref HAL_CAN_ERROR_CB_ID Error callback ID
697   *           @arg @ref HAL_CAN_MSPINIT_CB_ID MspInit callback ID
698   *           @arg @ref HAL_CAN_MSPDEINIT_CB_ID MspDeInit callback ID
699   * @retval HAL status
700   */
HAL_CAN_UnRegisterCallback(CAN_HandleTypeDef * hcan,HAL_CAN_CallbackIDTypeDef CallbackID)701 HAL_StatusTypeDef HAL_CAN_UnRegisterCallback(CAN_HandleTypeDef *hcan, HAL_CAN_CallbackIDTypeDef CallbackID)
702 {
703   HAL_StatusTypeDef status = HAL_OK;
704 
705   if (hcan->State == HAL_CAN_STATE_READY)
706   {
707     switch (CallbackID)
708     {
709       case HAL_CAN_TX_MAILBOX0_COMPLETE_CB_ID :
710         hcan->TxMailbox0CompleteCallback = HAL_CAN_TxMailbox0CompleteCallback;
711         break;
712 
713       case HAL_CAN_TX_MAILBOX1_COMPLETE_CB_ID :
714         hcan->TxMailbox1CompleteCallback = HAL_CAN_TxMailbox1CompleteCallback;
715         break;
716 
717       case HAL_CAN_TX_MAILBOX2_COMPLETE_CB_ID :
718         hcan->TxMailbox2CompleteCallback = HAL_CAN_TxMailbox2CompleteCallback;
719         break;
720 
721       case HAL_CAN_TX_MAILBOX0_ABORT_CB_ID :
722         hcan->TxMailbox0AbortCallback = HAL_CAN_TxMailbox0AbortCallback;
723         break;
724 
725       case HAL_CAN_TX_MAILBOX1_ABORT_CB_ID :
726         hcan->TxMailbox1AbortCallback = HAL_CAN_TxMailbox1AbortCallback;
727         break;
728 
729       case HAL_CAN_TX_MAILBOX2_ABORT_CB_ID :
730         hcan->TxMailbox2AbortCallback = HAL_CAN_TxMailbox2AbortCallback;
731         break;
732 
733       case HAL_CAN_RX_FIFO0_MSG_PENDING_CB_ID :
734         hcan->RxFifo0MsgPendingCallback = HAL_CAN_RxFifo0MsgPendingCallback;
735         break;
736 
737       case HAL_CAN_RX_FIFO0_FULL_CB_ID :
738         hcan->RxFifo0FullCallback = HAL_CAN_RxFifo0FullCallback;
739         break;
740 
741       case HAL_CAN_RX_FIFO1_MSG_PENDING_CB_ID :
742         hcan->RxFifo1MsgPendingCallback = HAL_CAN_RxFifo1MsgPendingCallback;
743         break;
744 
745       case HAL_CAN_RX_FIFO1_FULL_CB_ID :
746         hcan->RxFifo1FullCallback = HAL_CAN_RxFifo1FullCallback;
747         break;
748 
749       case HAL_CAN_SLEEP_CB_ID :
750         hcan->SleepCallback = HAL_CAN_SleepCallback;
751         break;
752 
753       case HAL_CAN_WAKEUP_FROM_RX_MSG_CB_ID :
754         hcan->WakeUpFromRxMsgCallback = HAL_CAN_WakeUpFromRxMsgCallback;
755         break;
756 
757       case HAL_CAN_ERROR_CB_ID :
758         hcan->ErrorCallback = HAL_CAN_ErrorCallback;
759         break;
760 
761       case HAL_CAN_MSPINIT_CB_ID :
762         hcan->MspInitCallback = HAL_CAN_MspInit;
763         break;
764 
765       case HAL_CAN_MSPDEINIT_CB_ID :
766         hcan->MspDeInitCallback = HAL_CAN_MspDeInit;
767         break;
768 
769       default :
770         /* Update the error code */
771         hcan->ErrorCode |= HAL_CAN_ERROR_INVALID_CALLBACK;
772 
773         /* Return error status */
774         status =  HAL_ERROR;
775         break;
776     }
777   }
778   else if (hcan->State == HAL_CAN_STATE_RESET)
779   {
780     switch (CallbackID)
781     {
782       case HAL_CAN_MSPINIT_CB_ID :
783         hcan->MspInitCallback = HAL_CAN_MspInit;
784         break;
785 
786       case HAL_CAN_MSPDEINIT_CB_ID :
787         hcan->MspDeInitCallback = HAL_CAN_MspDeInit;
788         break;
789 
790       default :
791         /* Update the error code */
792         hcan->ErrorCode |= HAL_CAN_ERROR_INVALID_CALLBACK;
793 
794         /* Return error status */
795         status =  HAL_ERROR;
796         break;
797     }
798   }
799   else
800   {
801     /* Update the error code */
802     hcan->ErrorCode |= HAL_CAN_ERROR_INVALID_CALLBACK;
803 
804     /* Return error status */
805     status =  HAL_ERROR;
806   }
807 
808   return status;
809 }
810 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
811 
812 /**
813   * @}
814   */
815 
816 /** @defgroup CAN_Exported_Functions_Group2 Configuration functions
817  *  @brief    Configuration functions.
818  *
819 @verbatim
820   ==============================================================================
821               ##### Configuration functions #####
822   ==============================================================================
823     [..]  This section provides functions allowing to:
824       (+) HAL_CAN_ConfigFilter            : Configure the CAN reception filters
825 
826 @endverbatim
827   * @{
828   */
829 
830 /**
831   * @brief  Configures the CAN reception filter according to the specified
832   *         parameters in the CAN_FilterInitStruct.
833   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
834   *         the configuration information for the specified CAN.
835   * @param  sFilterConfig pointer to a CAN_FilterTypeDef structure that
836   *         contains the filter configuration information.
837   * @retval None
838   */
HAL_CAN_ConfigFilter(CAN_HandleTypeDef * hcan,const CAN_FilterTypeDef * sFilterConfig)839 HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef *hcan, const CAN_FilterTypeDef *sFilterConfig)
840 {
841   uint32_t filternbrbitpos;
842   CAN_TypeDef *can_ip = hcan->Instance;
843   HAL_CAN_StateTypeDef state = hcan->State;
844 
845   if ((state == HAL_CAN_STATE_READY) ||
846       (state == HAL_CAN_STATE_LISTENING))
847   {
848     /* Check the parameters */
849     assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterIdHigh));
850     assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterIdLow));
851     assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterMaskIdHigh));
852     assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterMaskIdLow));
853     assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode));
854     assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale));
855     assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment));
856     assert_param(IS_CAN_FILTER_ACTIVATION(sFilterConfig->FilterActivation));
857 
858 #if   defined(CAN2)
859     /* CAN1 and CAN2 are dual instances with 28 common filters banks */
860     /* Select master instance to access the filter banks */
861     can_ip = CAN1;
862 
863     /* Check the parameters */
864     assert_param(IS_CAN_FILTER_BANK_DUAL(sFilterConfig->FilterBank));
865     assert_param(IS_CAN_FILTER_BANK_DUAL(sFilterConfig->SlaveStartFilterBank));
866 #else
867     /* CAN1 is single instance with 14 dedicated filters banks */
868 
869     /* Check the parameters */
870     assert_param(IS_CAN_FILTER_BANK_SINGLE(sFilterConfig->FilterBank));
871 #endif
872 
873     /* Initialisation mode for the filter */
874     SET_BIT(can_ip->FMR, CAN_FMR_FINIT);
875 
876 #if   defined(CAN2)
877     /* Select the start filter number of CAN2 slave instance */
878     CLEAR_BIT(can_ip->FMR, CAN_FMR_CAN2SB);
879     SET_BIT(can_ip->FMR, sFilterConfig->SlaveStartFilterBank << CAN_FMR_CAN2SB_Pos);
880 
881 #endif
882     /* Convert filter number into bit position */
883     filternbrbitpos = (uint32_t)1 << (sFilterConfig->FilterBank & 0x1FU);
884 
885     /* Filter Deactivation */
886     CLEAR_BIT(can_ip->FA1R, filternbrbitpos);
887 
888     /* Filter Scale */
889     if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT)
890     {
891       /* 16-bit scale for the filter */
892       CLEAR_BIT(can_ip->FS1R, filternbrbitpos);
893 
894       /* First 16-bit identifier and First 16-bit mask */
895       /* Or First 16-bit identifier and Second 16-bit identifier */
896       can_ip->sFilterRegister[sFilterConfig->FilterBank].FR1 =
897         ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16U) |
898         (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
899 
900       /* Second 16-bit identifier and Second 16-bit mask */
901       /* Or Third 16-bit identifier and Fourth 16-bit identifier */
902       can_ip->sFilterRegister[sFilterConfig->FilterBank].FR2 =
903         ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
904         (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh);
905     }
906 
907     if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
908     {
909       /* 32-bit scale for the filter */
910       SET_BIT(can_ip->FS1R, filternbrbitpos);
911 
912       /* 32-bit identifier or First 32-bit identifier */
913       can_ip->sFilterRegister[sFilterConfig->FilterBank].FR1 =
914         ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh) << 16U) |
915         (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
916 
917       /* 32-bit mask or Second 32-bit identifier */
918       can_ip->sFilterRegister[sFilterConfig->FilterBank].FR2 =
919         ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
920         (0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow);
921     }
922 
923     /* Filter Mode */
924     if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
925     {
926       /* Id/Mask mode for the filter*/
927       CLEAR_BIT(can_ip->FM1R, filternbrbitpos);
928     }
929     else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
930     {
931       /* Identifier list mode for the filter*/
932       SET_BIT(can_ip->FM1R, filternbrbitpos);
933     }
934 
935     /* Filter FIFO assignment */
936     if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
937     {
938       /* FIFO 0 assignation for the filter */
939       CLEAR_BIT(can_ip->FFA1R, filternbrbitpos);
940     }
941     else
942     {
943       /* FIFO 1 assignation for the filter */
944       SET_BIT(can_ip->FFA1R, filternbrbitpos);
945     }
946 
947     /* Filter activation */
948     if (sFilterConfig->FilterActivation == CAN_FILTER_ENABLE)
949     {
950       SET_BIT(can_ip->FA1R, filternbrbitpos);
951     }
952 
953     /* Leave the initialisation mode for the filter */
954     CLEAR_BIT(can_ip->FMR, CAN_FMR_FINIT);
955 
956     /* Return function status */
957     return HAL_OK;
958   }
959   else
960   {
961     /* Update error code */
962     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
963 
964     return HAL_ERROR;
965   }
966 }
967 
968 /**
969   * @}
970   */
971 
972 /** @defgroup CAN_Exported_Functions_Group3 Control functions
973  *  @brief    Control functions
974  *
975 @verbatim
976   ==============================================================================
977                       ##### Control functions #####
978   ==============================================================================
979     [..]  This section provides functions allowing to:
980       (+) HAL_CAN_Start                    : Start the CAN module
981       (+) HAL_CAN_Stop                     : Stop the CAN module
982       (+) HAL_CAN_RequestSleep             : Request sleep mode entry.
983       (+) HAL_CAN_WakeUp                   : Wake up from sleep mode.
984       (+) HAL_CAN_IsSleepActive            : Check is sleep mode is active.
985       (+) HAL_CAN_AddTxMessage             : Add a message to the Tx mailboxes
986                                              and activate the corresponding
987                                              transmission request
988       (+) HAL_CAN_AbortTxRequest           : Abort transmission request
989       (+) HAL_CAN_GetTxMailboxesFreeLevel  : Return Tx mailboxes free level
990       (+) HAL_CAN_IsTxMessagePending       : Check if a transmission request is
991                                              pending on the selected Tx mailbox
992       (+) HAL_CAN_GetRxMessage             : Get a CAN frame from the Rx FIFO
993       (+) HAL_CAN_GetRxFifoFillLevel       : Return Rx FIFO fill level
994 
995 @endverbatim
996   * @{
997   */
998 
999 /**
1000   * @brief  Start the CAN module.
1001   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1002   *         the configuration information for the specified CAN.
1003   * @retval HAL status
1004   */
HAL_CAN_Start(CAN_HandleTypeDef * hcan)1005 HAL_StatusTypeDef HAL_CAN_Start(CAN_HandleTypeDef *hcan)
1006 {
1007   uint32_t tickstart;
1008 
1009   if (hcan->State == HAL_CAN_STATE_READY)
1010   {
1011     /* Change CAN peripheral state */
1012     hcan->State = HAL_CAN_STATE_LISTENING;
1013 
1014     /* Request leave initialisation */
1015     CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
1016 
1017     /* Get tick */
1018     tickstart = HAL_GetTick();
1019 
1020     /* Wait the acknowledge */
1021     while ((hcan->Instance->MSR & CAN_MSR_INAK) != 0U)
1022     {
1023       /* Check for the Timeout */
1024       if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
1025       {
1026         /* Update error code */
1027         hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
1028 
1029         /* Change CAN state */
1030         hcan->State = HAL_CAN_STATE_ERROR;
1031 
1032         return HAL_ERROR;
1033       }
1034     }
1035 
1036     /* Reset the CAN ErrorCode */
1037     hcan->ErrorCode = HAL_CAN_ERROR_NONE;
1038 
1039     /* Return function status */
1040     return HAL_OK;
1041   }
1042   else
1043   {
1044     /* Update error code */
1045     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_READY;
1046 
1047     return HAL_ERROR;
1048   }
1049 }
1050 
1051 /**
1052   * @brief  Stop the CAN module and enable access to configuration registers.
1053   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1054   *         the configuration information for the specified CAN.
1055   * @retval HAL status
1056   */
HAL_CAN_Stop(CAN_HandleTypeDef * hcan)1057 HAL_StatusTypeDef HAL_CAN_Stop(CAN_HandleTypeDef *hcan)
1058 {
1059   uint32_t tickstart;
1060 
1061   if (hcan->State == HAL_CAN_STATE_LISTENING)
1062   {
1063     /* Request initialisation */
1064     SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
1065 
1066     /* Get tick */
1067     tickstart = HAL_GetTick();
1068 
1069     /* Wait the acknowledge */
1070     while ((hcan->Instance->MSR & CAN_MSR_INAK) == 0U)
1071     {
1072       /* Check for the Timeout */
1073       if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
1074       {
1075         /* Update error code */
1076         hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
1077 
1078         /* Change CAN state */
1079         hcan->State = HAL_CAN_STATE_ERROR;
1080 
1081         return HAL_ERROR;
1082       }
1083     }
1084 
1085     /* Exit from sleep mode */
1086     CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
1087 
1088     /* Change CAN peripheral state */
1089     hcan->State = HAL_CAN_STATE_READY;
1090 
1091     /* Return function status */
1092     return HAL_OK;
1093   }
1094   else
1095   {
1096     /* Update error code */
1097     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_STARTED;
1098 
1099     return HAL_ERROR;
1100   }
1101 }
1102 
1103 /**
1104   * @brief  Request the sleep mode (low power) entry.
1105   *         When returning from this function, Sleep mode will be entered
1106   *         as soon as the current CAN activity (transmission or reception
1107   *         of a CAN frame) has been completed.
1108   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1109   *         the configuration information for the specified CAN.
1110   * @retval HAL status.
1111   */
HAL_CAN_RequestSleep(CAN_HandleTypeDef * hcan)1112 HAL_StatusTypeDef HAL_CAN_RequestSleep(CAN_HandleTypeDef *hcan)
1113 {
1114   HAL_CAN_StateTypeDef state = hcan->State;
1115 
1116   if ((state == HAL_CAN_STATE_READY) ||
1117       (state == HAL_CAN_STATE_LISTENING))
1118   {
1119     /* Request Sleep mode */
1120     SET_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
1121 
1122     /* Return function status */
1123     return HAL_OK;
1124   }
1125   else
1126   {
1127     /* Update error code */
1128     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1129 
1130     /* Return function status */
1131     return HAL_ERROR;
1132   }
1133 }
1134 
1135 /**
1136   * @brief  Wake up from sleep mode.
1137   *         When returning with HAL_OK status from this function, Sleep mode
1138   *         is exited.
1139   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1140   *         the configuration information for the specified CAN.
1141   * @retval HAL status.
1142   */
HAL_CAN_WakeUp(CAN_HandleTypeDef * hcan)1143 HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef *hcan)
1144 {
1145   __IO uint32_t count = 0;
1146   uint32_t timeout = 1000000U;
1147   HAL_CAN_StateTypeDef state = hcan->State;
1148 
1149   if ((state == HAL_CAN_STATE_READY) ||
1150       (state == HAL_CAN_STATE_LISTENING))
1151   {
1152     /* Wake up request */
1153     CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
1154 
1155     /* Wait sleep mode is exited */
1156     do
1157     {
1158       /* Increment counter */
1159       count++;
1160 
1161       /* Check if timeout is reached */
1162       if (count > timeout)
1163       {
1164         /* Update error code */
1165         hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
1166 
1167         return HAL_ERROR;
1168       }
1169     }
1170     while ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U);
1171 
1172     /* Return function status */
1173     return HAL_OK;
1174   }
1175   else
1176   {
1177     /* Update error code */
1178     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1179 
1180     return HAL_ERROR;
1181   }
1182 }
1183 
1184 /**
1185   * @brief  Check is sleep mode is active.
1186   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1187   *         the configuration information for the specified CAN.
1188   * @retval Status
1189   *          - 0 : Sleep mode is not active.
1190   *          - 1 : Sleep mode is active.
1191   */
HAL_CAN_IsSleepActive(const CAN_HandleTypeDef * hcan)1192 uint32_t HAL_CAN_IsSleepActive(const CAN_HandleTypeDef *hcan)
1193 {
1194   uint32_t status = 0U;
1195   HAL_CAN_StateTypeDef state = hcan->State;
1196 
1197   if ((state == HAL_CAN_STATE_READY) ||
1198       (state == HAL_CAN_STATE_LISTENING))
1199   {
1200     /* Check Sleep mode */
1201     if ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U)
1202     {
1203       status = 1U;
1204     }
1205   }
1206 
1207   /* Return function status */
1208   return status;
1209 }
1210 
1211 /**
1212   * @brief  Add a message to the first free Tx mailbox and activate the
1213   *         corresponding transmission request.
1214   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1215   *         the configuration information for the specified CAN.
1216   * @param  pHeader pointer to a CAN_TxHeaderTypeDef structure.
1217   * @param  aData array containing the payload of the Tx frame.
1218   * @param  pTxMailbox pointer to a variable where the function will return
1219   *         the TxMailbox used to store the Tx message.
1220   *         This parameter can be a value of @arg CAN_Tx_Mailboxes.
1221   * @retval HAL status
1222   */
HAL_CAN_AddTxMessage(CAN_HandleTypeDef * hcan,const CAN_TxHeaderTypeDef * pHeader,const uint8_t aData[],uint32_t * pTxMailbox)1223 HAL_StatusTypeDef HAL_CAN_AddTxMessage(CAN_HandleTypeDef *hcan, const CAN_TxHeaderTypeDef *pHeader,
1224                                        const uint8_t aData[], uint32_t *pTxMailbox)
1225 {
1226   uint32_t transmitmailbox;
1227   HAL_CAN_StateTypeDef state = hcan->State;
1228   uint32_t tsr = READ_REG(hcan->Instance->TSR);
1229 
1230   /* Check the parameters */
1231   assert_param(IS_CAN_IDTYPE(pHeader->IDE));
1232   assert_param(IS_CAN_RTR(pHeader->RTR));
1233   assert_param(IS_CAN_DLC(pHeader->DLC));
1234   if (pHeader->IDE == CAN_ID_STD)
1235   {
1236     assert_param(IS_CAN_STDID(pHeader->StdId));
1237   }
1238   else
1239   {
1240     assert_param(IS_CAN_EXTID(pHeader->ExtId));
1241   }
1242   assert_param(IS_FUNCTIONAL_STATE(pHeader->TransmitGlobalTime));
1243 
1244   if ((state == HAL_CAN_STATE_READY) ||
1245       (state == HAL_CAN_STATE_LISTENING))
1246   {
1247     /* Check that all the Tx mailboxes are not full */
1248     if (((tsr & CAN_TSR_TME0) != 0U) ||
1249         ((tsr & CAN_TSR_TME1) != 0U) ||
1250         ((tsr & CAN_TSR_TME2) != 0U))
1251     {
1252       /* Select an empty transmit mailbox */
1253       transmitmailbox = (tsr & CAN_TSR_CODE) >> CAN_TSR_CODE_Pos;
1254 
1255       /* Store the Tx mailbox */
1256       *pTxMailbox = (uint32_t)1 << transmitmailbox;
1257 
1258       /* Set up the Id */
1259       if (pHeader->IDE == CAN_ID_STD)
1260       {
1261         hcan->Instance->sTxMailBox[transmitmailbox].TIR = ((pHeader->StdId << CAN_TI0R_STID_Pos) |
1262                                                            pHeader->RTR);
1263       }
1264       else
1265       {
1266         hcan->Instance->sTxMailBox[transmitmailbox].TIR = ((pHeader->ExtId << CAN_TI0R_EXID_Pos) |
1267                                                            pHeader->IDE |
1268                                                            pHeader->RTR);
1269       }
1270 
1271       /* Set up the DLC */
1272       hcan->Instance->sTxMailBox[transmitmailbox].TDTR = (pHeader->DLC);
1273 
1274       /* Set up the Transmit Global Time mode */
1275       if (pHeader->TransmitGlobalTime == ENABLE)
1276       {
1277         SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TDTR, CAN_TDT0R_TGT);
1278       }
1279 
1280       /* Set up the data field */
1281       WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR,
1282                 ((uint32_t)aData[7] << CAN_TDH0R_DATA7_Pos) |
1283                 ((uint32_t)aData[6] << CAN_TDH0R_DATA6_Pos) |
1284                 ((uint32_t)aData[5] << CAN_TDH0R_DATA5_Pos) |
1285                 ((uint32_t)aData[4] << CAN_TDH0R_DATA4_Pos));
1286       WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR,
1287                 ((uint32_t)aData[3] << CAN_TDL0R_DATA3_Pos) |
1288                 ((uint32_t)aData[2] << CAN_TDL0R_DATA2_Pos) |
1289                 ((uint32_t)aData[1] << CAN_TDL0R_DATA1_Pos) |
1290                 ((uint32_t)aData[0] << CAN_TDL0R_DATA0_Pos));
1291 
1292       /* Request transmission */
1293       SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TIR, CAN_TI0R_TXRQ);
1294 
1295       /* Return function status */
1296       return HAL_OK;
1297     }
1298     else
1299     {
1300       /* Update error code */
1301       hcan->ErrorCode |= HAL_CAN_ERROR_PARAM;
1302 
1303       return HAL_ERROR;
1304     }
1305   }
1306   else
1307   {
1308     /* Update error code */
1309     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1310 
1311     return HAL_ERROR;
1312   }
1313 }
1314 
1315 /**
1316   * @brief  Abort transmission requests
1317   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1318   *         the configuration information for the specified CAN.
1319   * @param  TxMailboxes List of the Tx Mailboxes to abort.
1320   *         This parameter can be any combination of @arg CAN_Tx_Mailboxes.
1321   * @retval HAL status
1322   */
HAL_CAN_AbortTxRequest(CAN_HandleTypeDef * hcan,uint32_t TxMailboxes)1323 HAL_StatusTypeDef HAL_CAN_AbortTxRequest(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes)
1324 {
1325   HAL_CAN_StateTypeDef state = hcan->State;
1326 
1327   /* Check function parameters */
1328   assert_param(IS_CAN_TX_MAILBOX_LIST(TxMailboxes));
1329 
1330   if ((state == HAL_CAN_STATE_READY) ||
1331       (state == HAL_CAN_STATE_LISTENING))
1332   {
1333     /* Check Tx Mailbox 0 */
1334     if ((TxMailboxes & CAN_TX_MAILBOX0) != 0U)
1335     {
1336       /* Add cancellation request for Tx Mailbox 0 */
1337       SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ0);
1338     }
1339 
1340     /* Check Tx Mailbox 1 */
1341     if ((TxMailboxes & CAN_TX_MAILBOX1) != 0U)
1342     {
1343       /* Add cancellation request for Tx Mailbox 1 */
1344       SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ1);
1345     }
1346 
1347     /* Check Tx Mailbox 2 */
1348     if ((TxMailboxes & CAN_TX_MAILBOX2) != 0U)
1349     {
1350       /* Add cancellation request for Tx Mailbox 2 */
1351       SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ2);
1352     }
1353 
1354     /* Return function status */
1355     return HAL_OK;
1356   }
1357   else
1358   {
1359     /* Update error code */
1360     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1361 
1362     return HAL_ERROR;
1363   }
1364 }
1365 
1366 /**
1367   * @brief  Return Tx Mailboxes free level: number of free Tx Mailboxes.
1368   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1369   *         the configuration information for the specified CAN.
1370   * @retval Number of free Tx Mailboxes.
1371   */
HAL_CAN_GetTxMailboxesFreeLevel(const CAN_HandleTypeDef * hcan)1372 uint32_t HAL_CAN_GetTxMailboxesFreeLevel(const CAN_HandleTypeDef *hcan)
1373 {
1374   uint32_t freelevel = 0U;
1375   HAL_CAN_StateTypeDef state = hcan->State;
1376 
1377   if ((state == HAL_CAN_STATE_READY) ||
1378       (state == HAL_CAN_STATE_LISTENING))
1379   {
1380     /* Check Tx Mailbox 0 status */
1381     if ((hcan->Instance->TSR & CAN_TSR_TME0) != 0U)
1382     {
1383       freelevel++;
1384     }
1385 
1386     /* Check Tx Mailbox 1 status */
1387     if ((hcan->Instance->TSR & CAN_TSR_TME1) != 0U)
1388     {
1389       freelevel++;
1390     }
1391 
1392     /* Check Tx Mailbox 2 status */
1393     if ((hcan->Instance->TSR & CAN_TSR_TME2) != 0U)
1394     {
1395       freelevel++;
1396     }
1397   }
1398 
1399   /* Return Tx Mailboxes free level */
1400   return freelevel;
1401 }
1402 
1403 /**
1404   * @brief  Check if a transmission request is pending on the selected Tx
1405   *         Mailboxes.
1406   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1407   *         the configuration information for the specified CAN.
1408   * @param  TxMailboxes List of Tx Mailboxes to check.
1409   *         This parameter can be any combination of @arg CAN_Tx_Mailboxes.
1410   * @retval Status
1411   *          - 0 : No pending transmission request on any selected Tx Mailboxes.
1412   *          - 1 : Pending transmission request on at least one of the selected
1413   *                Tx Mailbox.
1414   */
HAL_CAN_IsTxMessagePending(const CAN_HandleTypeDef * hcan,uint32_t TxMailboxes)1415 uint32_t HAL_CAN_IsTxMessagePending(const CAN_HandleTypeDef *hcan, uint32_t TxMailboxes)
1416 {
1417   uint32_t status = 0U;
1418   HAL_CAN_StateTypeDef state = hcan->State;
1419 
1420   /* Check function parameters */
1421   assert_param(IS_CAN_TX_MAILBOX_LIST(TxMailboxes));
1422 
1423   if ((state == HAL_CAN_STATE_READY) ||
1424       (state == HAL_CAN_STATE_LISTENING))
1425   {
1426     /* Check pending transmission request on the selected Tx Mailboxes */
1427     if ((hcan->Instance->TSR & (TxMailboxes << CAN_TSR_TME0_Pos)) != (TxMailboxes << CAN_TSR_TME0_Pos))
1428     {
1429       status = 1U;
1430     }
1431   }
1432 
1433   /* Return status */
1434   return status;
1435 }
1436 
1437 /**
1438   * @brief  Return timestamp of Tx message sent, if time triggered communication
1439             mode is enabled.
1440   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1441   *         the configuration information for the specified CAN.
1442   * @param  TxMailbox Tx Mailbox where the timestamp of message sent will be
1443   *         read.
1444   *         This parameter can be one value of @arg CAN_Tx_Mailboxes.
1445   * @retval Timestamp of message sent from Tx Mailbox.
1446   */
HAL_CAN_GetTxTimestamp(const CAN_HandleTypeDef * hcan,uint32_t TxMailbox)1447 uint32_t HAL_CAN_GetTxTimestamp(const CAN_HandleTypeDef *hcan, uint32_t TxMailbox)
1448 {
1449   uint32_t timestamp = 0U;
1450   uint32_t transmitmailbox;
1451   HAL_CAN_StateTypeDef state = hcan->State;
1452 
1453   /* Check function parameters */
1454   assert_param(IS_CAN_TX_MAILBOX(TxMailbox));
1455 
1456   if ((state == HAL_CAN_STATE_READY) ||
1457       (state == HAL_CAN_STATE_LISTENING))
1458   {
1459     /* Select the Tx mailbox */
1460     transmitmailbox = POSITION_VAL(TxMailbox);
1461 
1462     /* Get timestamp */
1463     timestamp = (hcan->Instance->sTxMailBox[transmitmailbox].TDTR & CAN_TDT0R_TIME) >> CAN_TDT0R_TIME_Pos;
1464   }
1465 
1466   /* Return the timestamp */
1467   return timestamp;
1468 }
1469 
1470 /**
1471   * @brief  Get an CAN frame from the Rx FIFO zone into the message RAM.
1472   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1473   *         the configuration information for the specified CAN.
1474   * @param  RxFifo Fifo number of the received message to be read.
1475   *         This parameter can be a value of @arg CAN_receive_FIFO_number.
1476   * @param  pHeader pointer to a CAN_RxHeaderTypeDef structure where the header
1477   *         of the Rx frame will be stored.
1478   * @param  aData array where the payload of the Rx frame will be stored.
1479   * @retval HAL status
1480   */
HAL_CAN_GetRxMessage(CAN_HandleTypeDef * hcan,uint32_t RxFifo,CAN_RxHeaderTypeDef * pHeader,uint8_t aData[])1481 HAL_StatusTypeDef HAL_CAN_GetRxMessage(CAN_HandleTypeDef *hcan, uint32_t RxFifo,
1482                                        CAN_RxHeaderTypeDef *pHeader, uint8_t aData[])
1483 {
1484   HAL_CAN_StateTypeDef state = hcan->State;
1485 
1486   assert_param(IS_CAN_RX_FIFO(RxFifo));
1487 
1488   if ((state == HAL_CAN_STATE_READY) ||
1489       (state == HAL_CAN_STATE_LISTENING))
1490   {
1491     /* Check the Rx FIFO */
1492     if (RxFifo == CAN_RX_FIFO0) /* Rx element is assigned to Rx FIFO 0 */
1493     {
1494       /* Check that the Rx FIFO 0 is not empty */
1495       if ((hcan->Instance->RF0R & CAN_RF0R_FMP0) == 0U)
1496       {
1497         /* Update error code */
1498         hcan->ErrorCode |= HAL_CAN_ERROR_PARAM;
1499 
1500         return HAL_ERROR;
1501       }
1502     }
1503     else /* Rx element is assigned to Rx FIFO 1 */
1504     {
1505       /* Check that the Rx FIFO 1 is not empty */
1506       if ((hcan->Instance->RF1R & CAN_RF1R_FMP1) == 0U)
1507       {
1508         /* Update error code */
1509         hcan->ErrorCode |= HAL_CAN_ERROR_PARAM;
1510 
1511         return HAL_ERROR;
1512       }
1513     }
1514 
1515     /* Get the header */
1516     pHeader->IDE = CAN_RI0R_IDE & hcan->Instance->sFIFOMailBox[RxFifo].RIR;
1517     if (pHeader->IDE == CAN_ID_STD)
1518     {
1519       pHeader->StdId = (CAN_RI0R_STID & hcan->Instance->sFIFOMailBox[RxFifo].RIR) >> CAN_TI0R_STID_Pos;
1520     }
1521     else
1522     {
1523       pHeader->ExtId = ((CAN_RI0R_EXID | CAN_RI0R_STID) &
1524                         hcan->Instance->sFIFOMailBox[RxFifo].RIR) >> CAN_RI0R_EXID_Pos;
1525     }
1526     pHeader->RTR = (CAN_RI0R_RTR & hcan->Instance->sFIFOMailBox[RxFifo].RIR);
1527     if (((CAN_RDT0R_DLC & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_DLC_Pos) >= 8U)
1528     {
1529       /* Truncate DLC to 8 if received field is over range */
1530       pHeader->DLC = 8U;
1531     }
1532     else
1533     {
1534       pHeader->DLC = (CAN_RDT0R_DLC & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_DLC_Pos;
1535     }
1536     pHeader->FilterMatchIndex = (CAN_RDT0R_FMI & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_FMI_Pos;
1537     pHeader->Timestamp = (CAN_RDT0R_TIME & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_TIME_Pos;
1538 
1539     /* Get the data */
1540     aData[0] = (uint8_t)((CAN_RDL0R_DATA0 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA0_Pos);
1541     aData[1] = (uint8_t)((CAN_RDL0R_DATA1 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA1_Pos);
1542     aData[2] = (uint8_t)((CAN_RDL0R_DATA2 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA2_Pos);
1543     aData[3] = (uint8_t)((CAN_RDL0R_DATA3 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA3_Pos);
1544     aData[4] = (uint8_t)((CAN_RDH0R_DATA4 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA4_Pos);
1545     aData[5] = (uint8_t)((CAN_RDH0R_DATA5 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA5_Pos);
1546     aData[6] = (uint8_t)((CAN_RDH0R_DATA6 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA6_Pos);
1547     aData[7] = (uint8_t)((CAN_RDH0R_DATA7 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA7_Pos);
1548 
1549     /* Release the FIFO */
1550     if (RxFifo == CAN_RX_FIFO0) /* Rx element is assigned to Rx FIFO 0 */
1551     {
1552       /* Release RX FIFO 0 */
1553       SET_BIT(hcan->Instance->RF0R, CAN_RF0R_RFOM0);
1554     }
1555     else /* Rx element is assigned to Rx FIFO 1 */
1556     {
1557       /* Release RX FIFO 1 */
1558       SET_BIT(hcan->Instance->RF1R, CAN_RF1R_RFOM1);
1559     }
1560 
1561     /* Return function status */
1562     return HAL_OK;
1563   }
1564   else
1565   {
1566     /* Update error code */
1567     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1568 
1569     return HAL_ERROR;
1570   }
1571 }
1572 
1573 /**
1574   * @brief  Return Rx FIFO fill level.
1575   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1576   *         the configuration information for the specified CAN.
1577   * @param  RxFifo Rx FIFO.
1578   *         This parameter can be a value of @arg CAN_receive_FIFO_number.
1579   * @retval Number of messages available in Rx FIFO.
1580   */
HAL_CAN_GetRxFifoFillLevel(const CAN_HandleTypeDef * hcan,uint32_t RxFifo)1581 uint32_t HAL_CAN_GetRxFifoFillLevel(const CAN_HandleTypeDef *hcan, uint32_t RxFifo)
1582 {
1583   uint32_t filllevel = 0U;
1584   HAL_CAN_StateTypeDef state = hcan->State;
1585 
1586   /* Check function parameters */
1587   assert_param(IS_CAN_RX_FIFO(RxFifo));
1588 
1589   if ((state == HAL_CAN_STATE_READY) ||
1590       (state == HAL_CAN_STATE_LISTENING))
1591   {
1592     if (RxFifo == CAN_RX_FIFO0)
1593     {
1594       filllevel = hcan->Instance->RF0R & CAN_RF0R_FMP0;
1595     }
1596     else /* RxFifo == CAN_RX_FIFO1 */
1597     {
1598       filllevel = hcan->Instance->RF1R & CAN_RF1R_FMP1;
1599     }
1600   }
1601 
1602   /* Return Rx FIFO fill level */
1603   return filllevel;
1604 }
1605 
1606 /**
1607   * @}
1608   */
1609 
1610 /** @defgroup CAN_Exported_Functions_Group4 Interrupts management
1611  *  @brief    Interrupts management
1612  *
1613 @verbatim
1614   ==============================================================================
1615                        ##### Interrupts management #####
1616   ==============================================================================
1617     [..]  This section provides functions allowing to:
1618       (+) HAL_CAN_ActivateNotification      : Enable interrupts
1619       (+) HAL_CAN_DeactivateNotification    : Disable interrupts
1620       (+) HAL_CAN_IRQHandler                : Handles CAN interrupt request
1621 
1622 @endverbatim
1623   * @{
1624   */
1625 
1626 /**
1627   * @brief  Enable interrupts.
1628   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1629   *         the configuration information for the specified CAN.
1630   * @param  ActiveITs indicates which interrupts will be enabled.
1631   *         This parameter can be any combination of @arg CAN_Interrupts.
1632   * @retval HAL status
1633   */
HAL_CAN_ActivateNotification(CAN_HandleTypeDef * hcan,uint32_t ActiveITs)1634 HAL_StatusTypeDef HAL_CAN_ActivateNotification(CAN_HandleTypeDef *hcan, uint32_t ActiveITs)
1635 {
1636   HAL_CAN_StateTypeDef state = hcan->State;
1637 
1638   /* Check function parameters */
1639   assert_param(IS_CAN_IT(ActiveITs));
1640 
1641   if ((state == HAL_CAN_STATE_READY) ||
1642       (state == HAL_CAN_STATE_LISTENING))
1643   {
1644     /* Enable the selected interrupts */
1645     __HAL_CAN_ENABLE_IT(hcan, ActiveITs);
1646 
1647     /* Return function status */
1648     return HAL_OK;
1649   }
1650   else
1651   {
1652     /* Update error code */
1653     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1654 
1655     return HAL_ERROR;
1656   }
1657 }
1658 
1659 /**
1660   * @brief  Disable interrupts.
1661   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1662   *         the configuration information for the specified CAN.
1663   * @param  InactiveITs indicates which interrupts will be disabled.
1664   *         This parameter can be any combination of @arg CAN_Interrupts.
1665   * @retval HAL status
1666   */
HAL_CAN_DeactivateNotification(CAN_HandleTypeDef * hcan,uint32_t InactiveITs)1667 HAL_StatusTypeDef HAL_CAN_DeactivateNotification(CAN_HandleTypeDef *hcan, uint32_t InactiveITs)
1668 {
1669   HAL_CAN_StateTypeDef state = hcan->State;
1670 
1671   /* Check function parameters */
1672   assert_param(IS_CAN_IT(InactiveITs));
1673 
1674   if ((state == HAL_CAN_STATE_READY) ||
1675       (state == HAL_CAN_STATE_LISTENING))
1676   {
1677     /* Disable the selected interrupts */
1678     __HAL_CAN_DISABLE_IT(hcan, InactiveITs);
1679 
1680     /* Return function status */
1681     return HAL_OK;
1682   }
1683   else
1684   {
1685     /* Update error code */
1686     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1687 
1688     return HAL_ERROR;
1689   }
1690 }
1691 
1692 /**
1693   * @brief  Handles CAN interrupt request
1694   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1695   *         the configuration information for the specified CAN.
1696   * @retval None
1697   */
HAL_CAN_IRQHandler(CAN_HandleTypeDef * hcan)1698 void HAL_CAN_IRQHandler(CAN_HandleTypeDef *hcan)
1699 {
1700   uint32_t errorcode = HAL_CAN_ERROR_NONE;
1701   uint32_t interrupts = READ_REG(hcan->Instance->IER);
1702   uint32_t msrflags = READ_REG(hcan->Instance->MSR);
1703   uint32_t tsrflags = READ_REG(hcan->Instance->TSR);
1704   uint32_t rf0rflags = READ_REG(hcan->Instance->RF0R);
1705   uint32_t rf1rflags = READ_REG(hcan->Instance->RF1R);
1706   uint32_t esrflags = READ_REG(hcan->Instance->ESR);
1707 
1708   /* Transmit Mailbox empty interrupt management *****************************/
1709   if ((interrupts & CAN_IT_TX_MAILBOX_EMPTY) != 0U)
1710   {
1711     /* Transmit Mailbox 0 management *****************************************/
1712     if ((tsrflags & CAN_TSR_RQCP0) != 0U)
1713     {
1714       /* Clear the Transmission Complete flag (and TXOK0,ALST0,TERR0 bits) */
1715       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP0);
1716 
1717       if ((tsrflags & CAN_TSR_TXOK0) != 0U)
1718       {
1719         /* Transmission Mailbox 0 complete callback */
1720 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1721         /* Call registered callback*/
1722         hcan->TxMailbox0CompleteCallback(hcan);
1723 #else
1724         /* Call weak (surcharged) callback */
1725         HAL_CAN_TxMailbox0CompleteCallback(hcan);
1726 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1727       }
1728       else
1729       {
1730         if ((tsrflags & CAN_TSR_ALST0) != 0U)
1731         {
1732           /* Update error code */
1733           errorcode |= HAL_CAN_ERROR_TX_ALST0;
1734         }
1735         else if ((tsrflags & CAN_TSR_TERR0) != 0U)
1736         {
1737           /* Update error code */
1738           errorcode |= HAL_CAN_ERROR_TX_TERR0;
1739         }
1740         else
1741         {
1742           /* Transmission Mailbox 0 abort callback */
1743 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1744           /* Call registered callback*/
1745           hcan->TxMailbox0AbortCallback(hcan);
1746 #else
1747           /* Call weak (surcharged) callback */
1748           HAL_CAN_TxMailbox0AbortCallback(hcan);
1749 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1750         }
1751       }
1752     }
1753 
1754     /* Transmit Mailbox 1 management *****************************************/
1755     if ((tsrflags & CAN_TSR_RQCP1) != 0U)
1756     {
1757       /* Clear the Transmission Complete flag (and TXOK1,ALST1,TERR1 bits) */
1758       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP1);
1759 
1760       if ((tsrflags & CAN_TSR_TXOK1) != 0U)
1761       {
1762         /* Transmission Mailbox 1 complete callback */
1763 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1764         /* Call registered callback*/
1765         hcan->TxMailbox1CompleteCallback(hcan);
1766 #else
1767         /* Call weak (surcharged) callback */
1768         HAL_CAN_TxMailbox1CompleteCallback(hcan);
1769 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1770       }
1771       else
1772       {
1773         if ((tsrflags & CAN_TSR_ALST1) != 0U)
1774         {
1775           /* Update error code */
1776           errorcode |= HAL_CAN_ERROR_TX_ALST1;
1777         }
1778         else if ((tsrflags & CAN_TSR_TERR1) != 0U)
1779         {
1780           /* Update error code */
1781           errorcode |= HAL_CAN_ERROR_TX_TERR1;
1782         }
1783         else
1784         {
1785           /* Transmission Mailbox 1 abort callback */
1786 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1787           /* Call registered callback*/
1788           hcan->TxMailbox1AbortCallback(hcan);
1789 #else
1790           /* Call weak (surcharged) callback */
1791           HAL_CAN_TxMailbox1AbortCallback(hcan);
1792 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1793         }
1794       }
1795     }
1796 
1797     /* Transmit Mailbox 2 management *****************************************/
1798     if ((tsrflags & CAN_TSR_RQCP2) != 0U)
1799     {
1800       /* Clear the Transmission Complete flag (and TXOK2,ALST2,TERR2 bits) */
1801       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP2);
1802 
1803       if ((tsrflags & CAN_TSR_TXOK2) != 0U)
1804       {
1805         /* Transmission Mailbox 2 complete callback */
1806 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1807         /* Call registered callback*/
1808         hcan->TxMailbox2CompleteCallback(hcan);
1809 #else
1810         /* Call weak (surcharged) callback */
1811         HAL_CAN_TxMailbox2CompleteCallback(hcan);
1812 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1813       }
1814       else
1815       {
1816         if ((tsrflags & CAN_TSR_ALST2) != 0U)
1817         {
1818           /* Update error code */
1819           errorcode |= HAL_CAN_ERROR_TX_ALST2;
1820         }
1821         else if ((tsrflags & CAN_TSR_TERR2) != 0U)
1822         {
1823           /* Update error code */
1824           errorcode |= HAL_CAN_ERROR_TX_TERR2;
1825         }
1826         else
1827         {
1828           /* Transmission Mailbox 2 abort callback */
1829 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1830           /* Call registered callback*/
1831           hcan->TxMailbox2AbortCallback(hcan);
1832 #else
1833           /* Call weak (surcharged) callback */
1834           HAL_CAN_TxMailbox2AbortCallback(hcan);
1835 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1836         }
1837       }
1838     }
1839   }
1840 
1841   /* Receive FIFO 0 overrun interrupt management *****************************/
1842   if ((interrupts & CAN_IT_RX_FIFO0_OVERRUN) != 0U)
1843   {
1844     if ((rf0rflags & CAN_RF0R_FOVR0) != 0U)
1845     {
1846       /* Set CAN error code to Rx Fifo 0 overrun error */
1847       errorcode |= HAL_CAN_ERROR_RX_FOV0;
1848 
1849       /* Clear FIFO0 Overrun Flag */
1850       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV0);
1851     }
1852   }
1853 
1854   /* Receive FIFO 0 full interrupt management ********************************/
1855   if ((interrupts & CAN_IT_RX_FIFO0_FULL) != 0U)
1856   {
1857     if ((rf0rflags & CAN_RF0R_FULL0) != 0U)
1858     {
1859       /* Clear FIFO 0 full Flag */
1860       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF0);
1861 
1862       /* Receive FIFO 0 full Callback */
1863 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1864       /* Call registered callback*/
1865       hcan->RxFifo0FullCallback(hcan);
1866 #else
1867       /* Call weak (surcharged) callback */
1868       HAL_CAN_RxFifo0FullCallback(hcan);
1869 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1870     }
1871   }
1872 
1873   /* Receive FIFO 0 message pending interrupt management *********************/
1874   if ((interrupts & CAN_IT_RX_FIFO0_MSG_PENDING) != 0U)
1875   {
1876     /* Check if message is still pending */
1877     if ((hcan->Instance->RF0R & CAN_RF0R_FMP0) != 0U)
1878     {
1879       /* Receive FIFO 0 message pending Callback */
1880 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1881       /* Call registered callback*/
1882       hcan->RxFifo0MsgPendingCallback(hcan);
1883 #else
1884       /* Call weak (surcharged) callback */
1885       HAL_CAN_RxFifo0MsgPendingCallback(hcan);
1886 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1887     }
1888   }
1889 
1890   /* Receive FIFO 1 overrun interrupt management *****************************/
1891   if ((interrupts & CAN_IT_RX_FIFO1_OVERRUN) != 0U)
1892   {
1893     if ((rf1rflags & CAN_RF1R_FOVR1) != 0U)
1894     {
1895       /* Set CAN error code to Rx Fifo 1 overrun error */
1896       errorcode |= HAL_CAN_ERROR_RX_FOV1;
1897 
1898       /* Clear FIFO1 Overrun Flag */
1899       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV1);
1900     }
1901   }
1902 
1903   /* Receive FIFO 1 full interrupt management ********************************/
1904   if ((interrupts & CAN_IT_RX_FIFO1_FULL) != 0U)
1905   {
1906     if ((rf1rflags & CAN_RF1R_FULL1) != 0U)
1907     {
1908       /* Clear FIFO 1 full Flag */
1909       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF1);
1910 
1911       /* Receive FIFO 1 full Callback */
1912 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1913       /* Call registered callback*/
1914       hcan->RxFifo1FullCallback(hcan);
1915 #else
1916       /* Call weak (surcharged) callback */
1917       HAL_CAN_RxFifo1FullCallback(hcan);
1918 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1919     }
1920   }
1921 
1922   /* Receive FIFO 1 message pending interrupt management *********************/
1923   if ((interrupts & CAN_IT_RX_FIFO1_MSG_PENDING) != 0U)
1924   {
1925     /* Check if message is still pending */
1926     if ((hcan->Instance->RF1R & CAN_RF1R_FMP1) != 0U)
1927     {
1928       /* Receive FIFO 1 message pending Callback */
1929 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1930       /* Call registered callback*/
1931       hcan->RxFifo1MsgPendingCallback(hcan);
1932 #else
1933       /* Call weak (surcharged) callback */
1934       HAL_CAN_RxFifo1MsgPendingCallback(hcan);
1935 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1936     }
1937   }
1938 
1939   /* Sleep interrupt management *********************************************/
1940   if ((interrupts & CAN_IT_SLEEP_ACK) != 0U)
1941   {
1942     if ((msrflags & CAN_MSR_SLAKI) != 0U)
1943     {
1944       /* Clear Sleep interrupt Flag */
1945       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_SLAKI);
1946 
1947       /* Sleep Callback */
1948 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1949       /* Call registered callback*/
1950       hcan->SleepCallback(hcan);
1951 #else
1952       /* Call weak (surcharged) callback */
1953       HAL_CAN_SleepCallback(hcan);
1954 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1955     }
1956   }
1957 
1958   /* WakeUp interrupt management *********************************************/
1959   if ((interrupts & CAN_IT_WAKEUP) != 0U)
1960   {
1961     if ((msrflags & CAN_MSR_WKUI) != 0U)
1962     {
1963       /* Clear WakeUp Flag */
1964       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_WKU);
1965 
1966       /* WakeUp Callback */
1967 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1968       /* Call registered callback*/
1969       hcan->WakeUpFromRxMsgCallback(hcan);
1970 #else
1971       /* Call weak (surcharged) callback */
1972       HAL_CAN_WakeUpFromRxMsgCallback(hcan);
1973 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1974     }
1975   }
1976 
1977   /* Error interrupts management *********************************************/
1978   if ((interrupts & CAN_IT_ERROR) != 0U)
1979   {
1980     if ((msrflags & CAN_MSR_ERRI) != 0U)
1981     {
1982       /* Check Error Warning Flag */
1983       if (((interrupts & CAN_IT_ERROR_WARNING) != 0U) &&
1984           ((esrflags & CAN_ESR_EWGF) != 0U))
1985       {
1986         /* Set CAN error code to Error Warning */
1987         errorcode |= HAL_CAN_ERROR_EWG;
1988 
1989         /* No need for clear of Error Warning Flag as read-only */
1990       }
1991 
1992       /* Check Error Passive Flag */
1993       if (((interrupts & CAN_IT_ERROR_PASSIVE) != 0U) &&
1994           ((esrflags & CAN_ESR_EPVF) != 0U))
1995       {
1996         /* Set CAN error code to Error Passive */
1997         errorcode |= HAL_CAN_ERROR_EPV;
1998 
1999         /* No need for clear of Error Passive Flag as read-only */
2000       }
2001 
2002       /* Check Bus-off Flag */
2003       if (((interrupts & CAN_IT_BUSOFF) != 0U) &&
2004           ((esrflags & CAN_ESR_BOFF) != 0U))
2005       {
2006         /* Set CAN error code to Bus-Off */
2007         errorcode |= HAL_CAN_ERROR_BOF;
2008 
2009         /* No need for clear of Error Bus-Off as read-only */
2010       }
2011 
2012       /* Check Last Error Code Flag */
2013       if (((interrupts & CAN_IT_LAST_ERROR_CODE) != 0U) &&
2014           ((esrflags & CAN_ESR_LEC) != 0U))
2015       {
2016         switch (esrflags & CAN_ESR_LEC)
2017         {
2018           case (CAN_ESR_LEC_0):
2019             /* Set CAN error code to Stuff error */
2020             errorcode |= HAL_CAN_ERROR_STF;
2021             break;
2022           case (CAN_ESR_LEC_1):
2023             /* Set CAN error code to Form error */
2024             errorcode |= HAL_CAN_ERROR_FOR;
2025             break;
2026           case (CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
2027             /* Set CAN error code to Acknowledgement error */
2028             errorcode |= HAL_CAN_ERROR_ACK;
2029             break;
2030           case (CAN_ESR_LEC_2):
2031             /* Set CAN error code to Bit recessive error */
2032             errorcode |= HAL_CAN_ERROR_BR;
2033             break;
2034           case (CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
2035             /* Set CAN error code to Bit Dominant error */
2036             errorcode |= HAL_CAN_ERROR_BD;
2037             break;
2038           case (CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
2039             /* Set CAN error code to CRC error */
2040             errorcode |= HAL_CAN_ERROR_CRC;
2041             break;
2042           default:
2043             break;
2044         }
2045 
2046         /* Clear Last error code Flag */
2047         CLEAR_BIT(hcan->Instance->ESR, CAN_ESR_LEC);
2048       }
2049     }
2050 
2051     /* Clear ERRI Flag */
2052     __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_ERRI);
2053   }
2054 
2055   /* Call the Error call Back in case of Errors */
2056   if (errorcode != HAL_CAN_ERROR_NONE)
2057   {
2058     /* Update error code in handle */
2059     hcan->ErrorCode |= errorcode;
2060 
2061     /* Call Error callback function */
2062 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
2063     /* Call registered callback*/
2064     hcan->ErrorCallback(hcan);
2065 #else
2066     /* Call weak (surcharged) callback */
2067     HAL_CAN_ErrorCallback(hcan);
2068 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
2069   }
2070 }
2071 
2072 /**
2073   * @}
2074   */
2075 
2076 /** @defgroup CAN_Exported_Functions_Group5 Callback functions
2077  *  @brief   CAN Callback functions
2078  *
2079 @verbatim
2080   ==============================================================================
2081                           ##### Callback functions #####
2082   ==============================================================================
2083     [..]
2084     This subsection provides the following callback functions:
2085       (+) HAL_CAN_TxMailbox0CompleteCallback
2086       (+) HAL_CAN_TxMailbox1CompleteCallback
2087       (+) HAL_CAN_TxMailbox2CompleteCallback
2088       (+) HAL_CAN_TxMailbox0AbortCallback
2089       (+) HAL_CAN_TxMailbox1AbortCallback
2090       (+) HAL_CAN_TxMailbox2AbortCallback
2091       (+) HAL_CAN_RxFifo0MsgPendingCallback
2092       (+) HAL_CAN_RxFifo0FullCallback
2093       (+) HAL_CAN_RxFifo1MsgPendingCallback
2094       (+) HAL_CAN_RxFifo1FullCallback
2095       (+) HAL_CAN_SleepCallback
2096       (+) HAL_CAN_WakeUpFromRxMsgCallback
2097       (+) HAL_CAN_ErrorCallback
2098 
2099 @endverbatim
2100   * @{
2101   */
2102 
2103 /**
2104   * @brief  Transmission Mailbox 0 complete callback.
2105   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2106   *         the configuration information for the specified CAN.
2107   * @retval None
2108   */
HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef * hcan)2109 __weak void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan)
2110 {
2111   /* Prevent unused argument(s) compilation warning */
2112   UNUSED(hcan);
2113 
2114   /* NOTE : This function Should not be modified, when the callback is needed,
2115             the HAL_CAN_TxMailbox0CompleteCallback could be implemented in the
2116             user file
2117    */
2118 }
2119 
2120 /**
2121   * @brief  Transmission Mailbox 1 complete callback.
2122   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2123   *         the configuration information for the specified CAN.
2124   * @retval None
2125   */
HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef * hcan)2126 __weak void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan)
2127 {
2128   /* Prevent unused argument(s) compilation warning */
2129   UNUSED(hcan);
2130 
2131   /* NOTE : This function Should not be modified, when the callback is needed,
2132             the HAL_CAN_TxMailbox1CompleteCallback could be implemented in the
2133             user file
2134    */
2135 }
2136 
2137 /**
2138   * @brief  Transmission Mailbox 2 complete callback.
2139   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2140   *         the configuration information for the specified CAN.
2141   * @retval None
2142   */
HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef * hcan)2143 __weak void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan)
2144 {
2145   /* Prevent unused argument(s) compilation warning */
2146   UNUSED(hcan);
2147 
2148   /* NOTE : This function Should not be modified, when the callback is needed,
2149             the HAL_CAN_TxMailbox2CompleteCallback could be implemented in the
2150             user file
2151    */
2152 }
2153 
2154 /**
2155   * @brief  Transmission Mailbox 0 Cancellation callback.
2156   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
2157   *         the configuration information for the specified CAN.
2158   * @retval None
2159   */
HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef * hcan)2160 __weak void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan)
2161 {
2162   /* Prevent unused argument(s) compilation warning */
2163   UNUSED(hcan);
2164 
2165   /* NOTE : This function Should not be modified, when the callback is needed,
2166             the HAL_CAN_TxMailbox0AbortCallback could be implemented in the
2167             user file
2168    */
2169 }
2170 
2171 /**
2172   * @brief  Transmission Mailbox 1 Cancellation callback.
2173   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
2174   *         the configuration information for the specified CAN.
2175   * @retval None
2176   */
HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef * hcan)2177 __weak void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan)
2178 {
2179   /* Prevent unused argument(s) compilation warning */
2180   UNUSED(hcan);
2181 
2182   /* NOTE : This function Should not be modified, when the callback is needed,
2183             the HAL_CAN_TxMailbox1AbortCallback could be implemented in the
2184             user file
2185    */
2186 }
2187 
2188 /**
2189   * @brief  Transmission Mailbox 2 Cancellation callback.
2190   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
2191   *         the configuration information for the specified CAN.
2192   * @retval None
2193   */
HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef * hcan)2194 __weak void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan)
2195 {
2196   /* Prevent unused argument(s) compilation warning */
2197   UNUSED(hcan);
2198 
2199   /* NOTE : This function Should not be modified, when the callback is needed,
2200             the HAL_CAN_TxMailbox2AbortCallback could be implemented in the
2201             user file
2202    */
2203 }
2204 
2205 /**
2206   * @brief  Rx FIFO 0 message pending callback.
2207   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2208   *         the configuration information for the specified CAN.
2209   * @retval None
2210   */
HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef * hcan)2211 __weak void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
2212 {
2213   /* Prevent unused argument(s) compilation warning */
2214   UNUSED(hcan);
2215 
2216   /* NOTE : This function Should not be modified, when the callback is needed,
2217             the HAL_CAN_RxFifo0MsgPendingCallback could be implemented in the
2218             user file
2219    */
2220 }
2221 
2222 /**
2223   * @brief  Rx FIFO 0 full callback.
2224   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2225   *         the configuration information for the specified CAN.
2226   * @retval None
2227   */
HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef * hcan)2228 __weak void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan)
2229 {
2230   /* Prevent unused argument(s) compilation warning */
2231   UNUSED(hcan);
2232 
2233   /* NOTE : This function Should not be modified, when the callback is needed,
2234             the HAL_CAN_RxFifo0FullCallback could be implemented in the user
2235             file
2236    */
2237 }
2238 
2239 /**
2240   * @brief  Rx FIFO 1 message pending callback.
2241   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2242   *         the configuration information for the specified CAN.
2243   * @retval None
2244   */
HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef * hcan)2245 __weak void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan)
2246 {
2247   /* Prevent unused argument(s) compilation warning */
2248   UNUSED(hcan);
2249 
2250   /* NOTE : This function Should not be modified, when the callback is needed,
2251             the HAL_CAN_RxFifo1MsgPendingCallback could be implemented in the
2252             user file
2253    */
2254 }
2255 
2256 /**
2257   * @brief  Rx FIFO 1 full callback.
2258   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2259   *         the configuration information for the specified CAN.
2260   * @retval None
2261   */
HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef * hcan)2262 __weak void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan)
2263 {
2264   /* Prevent unused argument(s) compilation warning */
2265   UNUSED(hcan);
2266 
2267   /* NOTE : This function Should not be modified, when the callback is needed,
2268             the HAL_CAN_RxFifo1FullCallback could be implemented in the user
2269             file
2270    */
2271 }
2272 
2273 /**
2274   * @brief  Sleep callback.
2275   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2276   *         the configuration information for the specified CAN.
2277   * @retval None
2278   */
HAL_CAN_SleepCallback(CAN_HandleTypeDef * hcan)2279 __weak void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan)
2280 {
2281   /* Prevent unused argument(s) compilation warning */
2282   UNUSED(hcan);
2283 
2284   /* NOTE : This function Should not be modified, when the callback is needed,
2285             the HAL_CAN_SleepCallback could be implemented in the user file
2286    */
2287 }
2288 
2289 /**
2290   * @brief  WakeUp from Rx message callback.
2291   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2292   *         the configuration information for the specified CAN.
2293   * @retval None
2294   */
HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef * hcan)2295 __weak void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan)
2296 {
2297   /* Prevent unused argument(s) compilation warning */
2298   UNUSED(hcan);
2299 
2300   /* NOTE : This function Should not be modified, when the callback is needed,
2301             the HAL_CAN_WakeUpFromRxMsgCallback could be implemented in the
2302             user file
2303    */
2304 }
2305 
2306 /**
2307   * @brief  Error CAN callback.
2308   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2309   *         the configuration information for the specified CAN.
2310   * @retval None
2311   */
HAL_CAN_ErrorCallback(CAN_HandleTypeDef * hcan)2312 __weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
2313 {
2314   /* Prevent unused argument(s) compilation warning */
2315   UNUSED(hcan);
2316 
2317   /* NOTE : This function Should not be modified, when the callback is needed,
2318             the HAL_CAN_ErrorCallback could be implemented in the user file
2319    */
2320 }
2321 
2322 /**
2323   * @}
2324   */
2325 
2326 /** @defgroup CAN_Exported_Functions_Group6 Peripheral State and Error functions
2327  *  @brief   CAN Peripheral State functions
2328  *
2329 @verbatim
2330   ==============================================================================
2331             ##### Peripheral State and Error functions #####
2332   ==============================================================================
2333     [..]
2334     This subsection provides functions allowing to :
2335       (+) HAL_CAN_GetState()  : Return the CAN state.
2336       (+) HAL_CAN_GetError()  : Return the CAN error codes if any.
2337       (+) HAL_CAN_ResetError(): Reset the CAN error codes if any.
2338 
2339 @endverbatim
2340   * @{
2341   */
2342 
2343 /**
2344   * @brief  Return the CAN state.
2345   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2346   *         the configuration information for the specified CAN.
2347   * @retval HAL state
2348   */
HAL_CAN_GetState(const CAN_HandleTypeDef * hcan)2349 HAL_CAN_StateTypeDef HAL_CAN_GetState(const CAN_HandleTypeDef *hcan)
2350 {
2351   HAL_CAN_StateTypeDef state = hcan->State;
2352 
2353   if ((state == HAL_CAN_STATE_READY) ||
2354       (state == HAL_CAN_STATE_LISTENING))
2355   {
2356     /* Check sleep mode acknowledge flag */
2357     if ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U)
2358     {
2359       /* Sleep mode is active */
2360       state = HAL_CAN_STATE_SLEEP_ACTIVE;
2361     }
2362     /* Check sleep mode request flag */
2363     else if ((hcan->Instance->MCR & CAN_MCR_SLEEP) != 0U)
2364     {
2365       /* Sleep mode request is pending */
2366       state = HAL_CAN_STATE_SLEEP_PENDING;
2367     }
2368     else
2369     {
2370       /* Neither sleep mode request nor sleep mode acknowledge */
2371     }
2372   }
2373 
2374   /* Return CAN state */
2375   return state;
2376 }
2377 
2378 /**
2379   * @brief  Return the CAN error code.
2380   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2381   *         the configuration information for the specified CAN.
2382   * @retval CAN Error Code
2383   */
HAL_CAN_GetError(const CAN_HandleTypeDef * hcan)2384 uint32_t HAL_CAN_GetError(const CAN_HandleTypeDef *hcan)
2385 {
2386   /* Return CAN error code */
2387   return hcan->ErrorCode;
2388 }
2389 
2390 /**
2391   * @brief  Reset the CAN error code.
2392   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2393   *         the configuration information for the specified CAN.
2394   * @retval HAL status
2395   */
HAL_CAN_ResetError(CAN_HandleTypeDef * hcan)2396 HAL_StatusTypeDef HAL_CAN_ResetError(CAN_HandleTypeDef *hcan)
2397 {
2398   HAL_StatusTypeDef status = HAL_OK;
2399   HAL_CAN_StateTypeDef state = hcan->State;
2400 
2401   if ((state == HAL_CAN_STATE_READY) ||
2402       (state == HAL_CAN_STATE_LISTENING))
2403   {
2404     /* Reset CAN error code */
2405     hcan->ErrorCode = 0U;
2406   }
2407   else
2408   {
2409     /* Update error code */
2410     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
2411 
2412     status = HAL_ERROR;
2413   }
2414 
2415   /* Return the status */
2416   return status;
2417 }
2418 
2419 /**
2420   * @}
2421   */
2422 
2423 /**
2424   * @}
2425   */
2426 
2427 #endif /* HAL_CAN_MODULE_ENABLED */
2428 
2429 /**
2430   * @}
2431   */
2432 
2433 #endif /* CAN1 */
2434 
2435 /**
2436   * @}
2437   */
2438