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     pHeader->DLC = (CAN_RDT0R_DLC & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_DLC_Pos;
1528     pHeader->FilterMatchIndex = (CAN_RDT0R_FMI & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_FMI_Pos;
1529     pHeader->Timestamp = (CAN_RDT0R_TIME & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_TIME_Pos;
1530 
1531     /* Get the data */
1532     aData[0] = (uint8_t)((CAN_RDL0R_DATA0 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA0_Pos);
1533     aData[1] = (uint8_t)((CAN_RDL0R_DATA1 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA1_Pos);
1534     aData[2] = (uint8_t)((CAN_RDL0R_DATA2 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA2_Pos);
1535     aData[3] = (uint8_t)((CAN_RDL0R_DATA3 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA3_Pos);
1536     aData[4] = (uint8_t)((CAN_RDH0R_DATA4 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA4_Pos);
1537     aData[5] = (uint8_t)((CAN_RDH0R_DATA5 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA5_Pos);
1538     aData[6] = (uint8_t)((CAN_RDH0R_DATA6 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA6_Pos);
1539     aData[7] = (uint8_t)((CAN_RDH0R_DATA7 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA7_Pos);
1540 
1541     /* Release the FIFO */
1542     if (RxFifo == CAN_RX_FIFO0) /* Rx element is assigned to Rx FIFO 0 */
1543     {
1544       /* Release RX FIFO 0 */
1545       SET_BIT(hcan->Instance->RF0R, CAN_RF0R_RFOM0);
1546     }
1547     else /* Rx element is assigned to Rx FIFO 1 */
1548     {
1549       /* Release RX FIFO 1 */
1550       SET_BIT(hcan->Instance->RF1R, CAN_RF1R_RFOM1);
1551     }
1552 
1553     /* Return function status */
1554     return HAL_OK;
1555   }
1556   else
1557   {
1558     /* Update error code */
1559     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1560 
1561     return HAL_ERROR;
1562   }
1563 }
1564 
1565 /**
1566   * @brief  Return Rx FIFO fill level.
1567   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1568   *         the configuration information for the specified CAN.
1569   * @param  RxFifo Rx FIFO.
1570   *         This parameter can be a value of @arg CAN_receive_FIFO_number.
1571   * @retval Number of messages available in Rx FIFO.
1572   */
HAL_CAN_GetRxFifoFillLevel(const CAN_HandleTypeDef * hcan,uint32_t RxFifo)1573 uint32_t HAL_CAN_GetRxFifoFillLevel(const CAN_HandleTypeDef *hcan, uint32_t RxFifo)
1574 {
1575   uint32_t filllevel = 0U;
1576   HAL_CAN_StateTypeDef state = hcan->State;
1577 
1578   /* Check function parameters */
1579   assert_param(IS_CAN_RX_FIFO(RxFifo));
1580 
1581   if ((state == HAL_CAN_STATE_READY) ||
1582       (state == HAL_CAN_STATE_LISTENING))
1583   {
1584     if (RxFifo == CAN_RX_FIFO0)
1585     {
1586       filllevel = hcan->Instance->RF0R & CAN_RF0R_FMP0;
1587     }
1588     else /* RxFifo == CAN_RX_FIFO1 */
1589     {
1590       filllevel = hcan->Instance->RF1R & CAN_RF1R_FMP1;
1591     }
1592   }
1593 
1594   /* Return Rx FIFO fill level */
1595   return filllevel;
1596 }
1597 
1598 /**
1599   * @}
1600   */
1601 
1602 /** @defgroup CAN_Exported_Functions_Group4 Interrupts management
1603  *  @brief    Interrupts management
1604  *
1605 @verbatim
1606   ==============================================================================
1607                        ##### Interrupts management #####
1608   ==============================================================================
1609     [..]  This section provides functions allowing to:
1610       (+) HAL_CAN_ActivateNotification      : Enable interrupts
1611       (+) HAL_CAN_DeactivateNotification    : Disable interrupts
1612       (+) HAL_CAN_IRQHandler                : Handles CAN interrupt request
1613 
1614 @endverbatim
1615   * @{
1616   */
1617 
1618 /**
1619   * @brief  Enable interrupts.
1620   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1621   *         the configuration information for the specified CAN.
1622   * @param  ActiveITs indicates which interrupts will be enabled.
1623   *         This parameter can be any combination of @arg CAN_Interrupts.
1624   * @retval HAL status
1625   */
HAL_CAN_ActivateNotification(CAN_HandleTypeDef * hcan,uint32_t ActiveITs)1626 HAL_StatusTypeDef HAL_CAN_ActivateNotification(CAN_HandleTypeDef *hcan, uint32_t ActiveITs)
1627 {
1628   HAL_CAN_StateTypeDef state = hcan->State;
1629 
1630   /* Check function parameters */
1631   assert_param(IS_CAN_IT(ActiveITs));
1632 
1633   if ((state == HAL_CAN_STATE_READY) ||
1634       (state == HAL_CAN_STATE_LISTENING))
1635   {
1636     /* Enable the selected interrupts */
1637     __HAL_CAN_ENABLE_IT(hcan, ActiveITs);
1638 
1639     /* Return function status */
1640     return HAL_OK;
1641   }
1642   else
1643   {
1644     /* Update error code */
1645     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1646 
1647     return HAL_ERROR;
1648   }
1649 }
1650 
1651 /**
1652   * @brief  Disable interrupts.
1653   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1654   *         the configuration information for the specified CAN.
1655   * @param  InactiveITs indicates which interrupts will be disabled.
1656   *         This parameter can be any combination of @arg CAN_Interrupts.
1657   * @retval HAL status
1658   */
HAL_CAN_DeactivateNotification(CAN_HandleTypeDef * hcan,uint32_t InactiveITs)1659 HAL_StatusTypeDef HAL_CAN_DeactivateNotification(CAN_HandleTypeDef *hcan, uint32_t InactiveITs)
1660 {
1661   HAL_CAN_StateTypeDef state = hcan->State;
1662 
1663   /* Check function parameters */
1664   assert_param(IS_CAN_IT(InactiveITs));
1665 
1666   if ((state == HAL_CAN_STATE_READY) ||
1667       (state == HAL_CAN_STATE_LISTENING))
1668   {
1669     /* Disable the selected interrupts */
1670     __HAL_CAN_DISABLE_IT(hcan, InactiveITs);
1671 
1672     /* Return function status */
1673     return HAL_OK;
1674   }
1675   else
1676   {
1677     /* Update error code */
1678     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1679 
1680     return HAL_ERROR;
1681   }
1682 }
1683 
1684 /**
1685   * @brief  Handles CAN interrupt request
1686   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1687   *         the configuration information for the specified CAN.
1688   * @retval None
1689   */
HAL_CAN_IRQHandler(CAN_HandleTypeDef * hcan)1690 void HAL_CAN_IRQHandler(CAN_HandleTypeDef *hcan)
1691 {
1692   uint32_t errorcode = HAL_CAN_ERROR_NONE;
1693   uint32_t interrupts = READ_REG(hcan->Instance->IER);
1694   uint32_t msrflags = READ_REG(hcan->Instance->MSR);
1695   uint32_t tsrflags = READ_REG(hcan->Instance->TSR);
1696   uint32_t rf0rflags = READ_REG(hcan->Instance->RF0R);
1697   uint32_t rf1rflags = READ_REG(hcan->Instance->RF1R);
1698   uint32_t esrflags = READ_REG(hcan->Instance->ESR);
1699 
1700   /* Transmit Mailbox empty interrupt management *****************************/
1701   if ((interrupts & CAN_IT_TX_MAILBOX_EMPTY) != 0U)
1702   {
1703     /* Transmit Mailbox 0 management *****************************************/
1704     if ((tsrflags & CAN_TSR_RQCP0) != 0U)
1705     {
1706       /* Clear the Transmission Complete flag (and TXOK0,ALST0,TERR0 bits) */
1707       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP0);
1708 
1709       if ((tsrflags & CAN_TSR_TXOK0) != 0U)
1710       {
1711         /* Transmission Mailbox 0 complete callback */
1712 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1713         /* Call registered callback*/
1714         hcan->TxMailbox0CompleteCallback(hcan);
1715 #else
1716         /* Call weak (surcharged) callback */
1717         HAL_CAN_TxMailbox0CompleteCallback(hcan);
1718 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1719       }
1720       else
1721       {
1722         if ((tsrflags & CAN_TSR_ALST0) != 0U)
1723         {
1724           /* Update error code */
1725           errorcode |= HAL_CAN_ERROR_TX_ALST0;
1726         }
1727         else if ((tsrflags & CAN_TSR_TERR0) != 0U)
1728         {
1729           /* Update error code */
1730           errorcode |= HAL_CAN_ERROR_TX_TERR0;
1731         }
1732         else
1733         {
1734           /* Transmission Mailbox 0 abort callback */
1735 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1736           /* Call registered callback*/
1737           hcan->TxMailbox0AbortCallback(hcan);
1738 #else
1739           /* Call weak (surcharged) callback */
1740           HAL_CAN_TxMailbox0AbortCallback(hcan);
1741 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1742         }
1743       }
1744     }
1745 
1746     /* Transmit Mailbox 1 management *****************************************/
1747     if ((tsrflags & CAN_TSR_RQCP1) != 0U)
1748     {
1749       /* Clear the Transmission Complete flag (and TXOK1,ALST1,TERR1 bits) */
1750       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP1);
1751 
1752       if ((tsrflags & CAN_TSR_TXOK1) != 0U)
1753       {
1754         /* Transmission Mailbox 1 complete callback */
1755 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1756         /* Call registered callback*/
1757         hcan->TxMailbox1CompleteCallback(hcan);
1758 #else
1759         /* Call weak (surcharged) callback */
1760         HAL_CAN_TxMailbox1CompleteCallback(hcan);
1761 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1762       }
1763       else
1764       {
1765         if ((tsrflags & CAN_TSR_ALST1) != 0U)
1766         {
1767           /* Update error code */
1768           errorcode |= HAL_CAN_ERROR_TX_ALST1;
1769         }
1770         else if ((tsrflags & CAN_TSR_TERR1) != 0U)
1771         {
1772           /* Update error code */
1773           errorcode |= HAL_CAN_ERROR_TX_TERR1;
1774         }
1775         else
1776         {
1777           /* Transmission Mailbox 1 abort callback */
1778 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1779           /* Call registered callback*/
1780           hcan->TxMailbox1AbortCallback(hcan);
1781 #else
1782           /* Call weak (surcharged) callback */
1783           HAL_CAN_TxMailbox1AbortCallback(hcan);
1784 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1785         }
1786       }
1787     }
1788 
1789     /* Transmit Mailbox 2 management *****************************************/
1790     if ((tsrflags & CAN_TSR_RQCP2) != 0U)
1791     {
1792       /* Clear the Transmission Complete flag (and TXOK2,ALST2,TERR2 bits) */
1793       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP2);
1794 
1795       if ((tsrflags & CAN_TSR_TXOK2) != 0U)
1796       {
1797         /* Transmission Mailbox 2 complete callback */
1798 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1799         /* Call registered callback*/
1800         hcan->TxMailbox2CompleteCallback(hcan);
1801 #else
1802         /* Call weak (surcharged) callback */
1803         HAL_CAN_TxMailbox2CompleteCallback(hcan);
1804 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1805       }
1806       else
1807       {
1808         if ((tsrflags & CAN_TSR_ALST2) != 0U)
1809         {
1810           /* Update error code */
1811           errorcode |= HAL_CAN_ERROR_TX_ALST2;
1812         }
1813         else if ((tsrflags & CAN_TSR_TERR2) != 0U)
1814         {
1815           /* Update error code */
1816           errorcode |= HAL_CAN_ERROR_TX_TERR2;
1817         }
1818         else
1819         {
1820           /* Transmission Mailbox 2 abort callback */
1821 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1822           /* Call registered callback*/
1823           hcan->TxMailbox2AbortCallback(hcan);
1824 #else
1825           /* Call weak (surcharged) callback */
1826           HAL_CAN_TxMailbox2AbortCallback(hcan);
1827 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1828         }
1829       }
1830     }
1831   }
1832 
1833   /* Receive FIFO 0 overrun interrupt management *****************************/
1834   if ((interrupts & CAN_IT_RX_FIFO0_OVERRUN) != 0U)
1835   {
1836     if ((rf0rflags & CAN_RF0R_FOVR0) != 0U)
1837     {
1838       /* Set CAN error code to Rx Fifo 0 overrun error */
1839       errorcode |= HAL_CAN_ERROR_RX_FOV0;
1840 
1841       /* Clear FIFO0 Overrun Flag */
1842       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV0);
1843     }
1844   }
1845 
1846   /* Receive FIFO 0 full interrupt management ********************************/
1847   if ((interrupts & CAN_IT_RX_FIFO0_FULL) != 0U)
1848   {
1849     if ((rf0rflags & CAN_RF0R_FULL0) != 0U)
1850     {
1851       /* Clear FIFO 0 full Flag */
1852       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF0);
1853 
1854       /* Receive FIFO 0 full Callback */
1855 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1856       /* Call registered callback*/
1857       hcan->RxFifo0FullCallback(hcan);
1858 #else
1859       /* Call weak (surcharged) callback */
1860       HAL_CAN_RxFifo0FullCallback(hcan);
1861 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1862     }
1863   }
1864 
1865   /* Receive FIFO 0 message pending interrupt management *********************/
1866   if ((interrupts & CAN_IT_RX_FIFO0_MSG_PENDING) != 0U)
1867   {
1868     /* Check if message is still pending */
1869     if ((hcan->Instance->RF0R & CAN_RF0R_FMP0) != 0U)
1870     {
1871       /* Receive FIFO 0 message pending Callback */
1872 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1873       /* Call registered callback*/
1874       hcan->RxFifo0MsgPendingCallback(hcan);
1875 #else
1876       /* Call weak (surcharged) callback */
1877       HAL_CAN_RxFifo0MsgPendingCallback(hcan);
1878 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1879     }
1880   }
1881 
1882   /* Receive FIFO 1 overrun interrupt management *****************************/
1883   if ((interrupts & CAN_IT_RX_FIFO1_OVERRUN) != 0U)
1884   {
1885     if ((rf1rflags & CAN_RF1R_FOVR1) != 0U)
1886     {
1887       /* Set CAN error code to Rx Fifo 1 overrun error */
1888       errorcode |= HAL_CAN_ERROR_RX_FOV1;
1889 
1890       /* Clear FIFO1 Overrun Flag */
1891       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV1);
1892     }
1893   }
1894 
1895   /* Receive FIFO 1 full interrupt management ********************************/
1896   if ((interrupts & CAN_IT_RX_FIFO1_FULL) != 0U)
1897   {
1898     if ((rf1rflags & CAN_RF1R_FULL1) != 0U)
1899     {
1900       /* Clear FIFO 1 full Flag */
1901       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF1);
1902 
1903       /* Receive FIFO 1 full Callback */
1904 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1905       /* Call registered callback*/
1906       hcan->RxFifo1FullCallback(hcan);
1907 #else
1908       /* Call weak (surcharged) callback */
1909       HAL_CAN_RxFifo1FullCallback(hcan);
1910 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1911     }
1912   }
1913 
1914   /* Receive FIFO 1 message pending interrupt management *********************/
1915   if ((interrupts & CAN_IT_RX_FIFO1_MSG_PENDING) != 0U)
1916   {
1917     /* Check if message is still pending */
1918     if ((hcan->Instance->RF1R & CAN_RF1R_FMP1) != 0U)
1919     {
1920       /* Receive FIFO 1 message pending Callback */
1921 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1922       /* Call registered callback*/
1923       hcan->RxFifo1MsgPendingCallback(hcan);
1924 #else
1925       /* Call weak (surcharged) callback */
1926       HAL_CAN_RxFifo1MsgPendingCallback(hcan);
1927 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1928     }
1929   }
1930 
1931   /* Sleep interrupt management *********************************************/
1932   if ((interrupts & CAN_IT_SLEEP_ACK) != 0U)
1933   {
1934     if ((msrflags & CAN_MSR_SLAKI) != 0U)
1935     {
1936       /* Clear Sleep interrupt Flag */
1937       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_SLAKI);
1938 
1939       /* Sleep Callback */
1940 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1941       /* Call registered callback*/
1942       hcan->SleepCallback(hcan);
1943 #else
1944       /* Call weak (surcharged) callback */
1945       HAL_CAN_SleepCallback(hcan);
1946 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1947     }
1948   }
1949 
1950   /* WakeUp interrupt management *********************************************/
1951   if ((interrupts & CAN_IT_WAKEUP) != 0U)
1952   {
1953     if ((msrflags & CAN_MSR_WKUI) != 0U)
1954     {
1955       /* Clear WakeUp Flag */
1956       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_WKU);
1957 
1958       /* WakeUp Callback */
1959 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1960       /* Call registered callback*/
1961       hcan->WakeUpFromRxMsgCallback(hcan);
1962 #else
1963       /* Call weak (surcharged) callback */
1964       HAL_CAN_WakeUpFromRxMsgCallback(hcan);
1965 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1966     }
1967   }
1968 
1969   /* Error interrupts management *********************************************/
1970   if ((interrupts & CAN_IT_ERROR) != 0U)
1971   {
1972     if ((msrflags & CAN_MSR_ERRI) != 0U)
1973     {
1974       /* Check Error Warning Flag */
1975       if (((interrupts & CAN_IT_ERROR_WARNING) != 0U) &&
1976           ((esrflags & CAN_ESR_EWGF) != 0U))
1977       {
1978         /* Set CAN error code to Error Warning */
1979         errorcode |= HAL_CAN_ERROR_EWG;
1980 
1981         /* No need for clear of Error Warning Flag as read-only */
1982       }
1983 
1984       /* Check Error Passive Flag */
1985       if (((interrupts & CAN_IT_ERROR_PASSIVE) != 0U) &&
1986           ((esrflags & CAN_ESR_EPVF) != 0U))
1987       {
1988         /* Set CAN error code to Error Passive */
1989         errorcode |= HAL_CAN_ERROR_EPV;
1990 
1991         /* No need for clear of Error Passive Flag as read-only */
1992       }
1993 
1994       /* Check Bus-off Flag */
1995       if (((interrupts & CAN_IT_BUSOFF) != 0U) &&
1996           ((esrflags & CAN_ESR_BOFF) != 0U))
1997       {
1998         /* Set CAN error code to Bus-Off */
1999         errorcode |= HAL_CAN_ERROR_BOF;
2000 
2001         /* No need for clear of Error Bus-Off as read-only */
2002       }
2003 
2004       /* Check Last Error Code Flag */
2005       if (((interrupts & CAN_IT_LAST_ERROR_CODE) != 0U) &&
2006           ((esrflags & CAN_ESR_LEC) != 0U))
2007       {
2008         switch (esrflags & CAN_ESR_LEC)
2009         {
2010           case (CAN_ESR_LEC_0):
2011             /* Set CAN error code to Stuff error */
2012             errorcode |= HAL_CAN_ERROR_STF;
2013             break;
2014           case (CAN_ESR_LEC_1):
2015             /* Set CAN error code to Form error */
2016             errorcode |= HAL_CAN_ERROR_FOR;
2017             break;
2018           case (CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
2019             /* Set CAN error code to Acknowledgement error */
2020             errorcode |= HAL_CAN_ERROR_ACK;
2021             break;
2022           case (CAN_ESR_LEC_2):
2023             /* Set CAN error code to Bit recessive error */
2024             errorcode |= HAL_CAN_ERROR_BR;
2025             break;
2026           case (CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
2027             /* Set CAN error code to Bit Dominant error */
2028             errorcode |= HAL_CAN_ERROR_BD;
2029             break;
2030           case (CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
2031             /* Set CAN error code to CRC error */
2032             errorcode |= HAL_CAN_ERROR_CRC;
2033             break;
2034           default:
2035             break;
2036         }
2037 
2038         /* Clear Last error code Flag */
2039         CLEAR_BIT(hcan->Instance->ESR, CAN_ESR_LEC);
2040       }
2041     }
2042 
2043     /* Clear ERRI Flag */
2044     __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_ERRI);
2045   }
2046 
2047   /* Call the Error call Back in case of Errors */
2048   if (errorcode != HAL_CAN_ERROR_NONE)
2049   {
2050     /* Update error code in handle */
2051     hcan->ErrorCode |= errorcode;
2052 
2053     /* Call Error callback function */
2054 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
2055     /* Call registered callback*/
2056     hcan->ErrorCallback(hcan);
2057 #else
2058     /* Call weak (surcharged) callback */
2059     HAL_CAN_ErrorCallback(hcan);
2060 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
2061   }
2062 }
2063 
2064 /**
2065   * @}
2066   */
2067 
2068 /** @defgroup CAN_Exported_Functions_Group5 Callback functions
2069  *  @brief   CAN Callback functions
2070  *
2071 @verbatim
2072   ==============================================================================
2073                           ##### Callback functions #####
2074   ==============================================================================
2075     [..]
2076     This subsection provides the following callback functions:
2077       (+) HAL_CAN_TxMailbox0CompleteCallback
2078       (+) HAL_CAN_TxMailbox1CompleteCallback
2079       (+) HAL_CAN_TxMailbox2CompleteCallback
2080       (+) HAL_CAN_TxMailbox0AbortCallback
2081       (+) HAL_CAN_TxMailbox1AbortCallback
2082       (+) HAL_CAN_TxMailbox2AbortCallback
2083       (+) HAL_CAN_RxFifo0MsgPendingCallback
2084       (+) HAL_CAN_RxFifo0FullCallback
2085       (+) HAL_CAN_RxFifo1MsgPendingCallback
2086       (+) HAL_CAN_RxFifo1FullCallback
2087       (+) HAL_CAN_SleepCallback
2088       (+) HAL_CAN_WakeUpFromRxMsgCallback
2089       (+) HAL_CAN_ErrorCallback
2090 
2091 @endverbatim
2092   * @{
2093   */
2094 
2095 /**
2096   * @brief  Transmission Mailbox 0 complete callback.
2097   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2098   *         the configuration information for the specified CAN.
2099   * @retval None
2100   */
HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef * hcan)2101 __weak void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan)
2102 {
2103   /* Prevent unused argument(s) compilation warning */
2104   UNUSED(hcan);
2105 
2106   /* NOTE : This function Should not be modified, when the callback is needed,
2107             the HAL_CAN_TxMailbox0CompleteCallback could be implemented in the
2108             user file
2109    */
2110 }
2111 
2112 /**
2113   * @brief  Transmission Mailbox 1 complete callback.
2114   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2115   *         the configuration information for the specified CAN.
2116   * @retval None
2117   */
HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef * hcan)2118 __weak void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan)
2119 {
2120   /* Prevent unused argument(s) compilation warning */
2121   UNUSED(hcan);
2122 
2123   /* NOTE : This function Should not be modified, when the callback is needed,
2124             the HAL_CAN_TxMailbox1CompleteCallback could be implemented in the
2125             user file
2126    */
2127 }
2128 
2129 /**
2130   * @brief  Transmission Mailbox 2 complete callback.
2131   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2132   *         the configuration information for the specified CAN.
2133   * @retval None
2134   */
HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef * hcan)2135 __weak void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan)
2136 {
2137   /* Prevent unused argument(s) compilation warning */
2138   UNUSED(hcan);
2139 
2140   /* NOTE : This function Should not be modified, when the callback is needed,
2141             the HAL_CAN_TxMailbox2CompleteCallback could be implemented in the
2142             user file
2143    */
2144 }
2145 
2146 /**
2147   * @brief  Transmission Mailbox 0 Cancellation callback.
2148   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
2149   *         the configuration information for the specified CAN.
2150   * @retval None
2151   */
HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef * hcan)2152 __weak void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan)
2153 {
2154   /* Prevent unused argument(s) compilation warning */
2155   UNUSED(hcan);
2156 
2157   /* NOTE : This function Should not be modified, when the callback is needed,
2158             the HAL_CAN_TxMailbox0AbortCallback could be implemented in the
2159             user file
2160    */
2161 }
2162 
2163 /**
2164   * @brief  Transmission Mailbox 1 Cancellation callback.
2165   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
2166   *         the configuration information for the specified CAN.
2167   * @retval None
2168   */
HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef * hcan)2169 __weak void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan)
2170 {
2171   /* Prevent unused argument(s) compilation warning */
2172   UNUSED(hcan);
2173 
2174   /* NOTE : This function Should not be modified, when the callback is needed,
2175             the HAL_CAN_TxMailbox1AbortCallback could be implemented in the
2176             user file
2177    */
2178 }
2179 
2180 /**
2181   * @brief  Transmission Mailbox 2 Cancellation callback.
2182   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
2183   *         the configuration information for the specified CAN.
2184   * @retval None
2185   */
HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef * hcan)2186 __weak void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan)
2187 {
2188   /* Prevent unused argument(s) compilation warning */
2189   UNUSED(hcan);
2190 
2191   /* NOTE : This function Should not be modified, when the callback is needed,
2192             the HAL_CAN_TxMailbox2AbortCallback could be implemented in the
2193             user file
2194    */
2195 }
2196 
2197 /**
2198   * @brief  Rx FIFO 0 message pending callback.
2199   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2200   *         the configuration information for the specified CAN.
2201   * @retval None
2202   */
HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef * hcan)2203 __weak void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
2204 {
2205   /* Prevent unused argument(s) compilation warning */
2206   UNUSED(hcan);
2207 
2208   /* NOTE : This function Should not be modified, when the callback is needed,
2209             the HAL_CAN_RxFifo0MsgPendingCallback could be implemented in the
2210             user file
2211    */
2212 }
2213 
2214 /**
2215   * @brief  Rx FIFO 0 full callback.
2216   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2217   *         the configuration information for the specified CAN.
2218   * @retval None
2219   */
HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef * hcan)2220 __weak void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan)
2221 {
2222   /* Prevent unused argument(s) compilation warning */
2223   UNUSED(hcan);
2224 
2225   /* NOTE : This function Should not be modified, when the callback is needed,
2226             the HAL_CAN_RxFifo0FullCallback could be implemented in the user
2227             file
2228    */
2229 }
2230 
2231 /**
2232   * @brief  Rx FIFO 1 message pending callback.
2233   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2234   *         the configuration information for the specified CAN.
2235   * @retval None
2236   */
HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef * hcan)2237 __weak void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan)
2238 {
2239   /* Prevent unused argument(s) compilation warning */
2240   UNUSED(hcan);
2241 
2242   /* NOTE : This function Should not be modified, when the callback is needed,
2243             the HAL_CAN_RxFifo1MsgPendingCallback could be implemented in the
2244             user file
2245    */
2246 }
2247 
2248 /**
2249   * @brief  Rx FIFO 1 full callback.
2250   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2251   *         the configuration information for the specified CAN.
2252   * @retval None
2253   */
HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef * hcan)2254 __weak void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan)
2255 {
2256   /* Prevent unused argument(s) compilation warning */
2257   UNUSED(hcan);
2258 
2259   /* NOTE : This function Should not be modified, when the callback is needed,
2260             the HAL_CAN_RxFifo1FullCallback could be implemented in the user
2261             file
2262    */
2263 }
2264 
2265 /**
2266   * @brief  Sleep callback.
2267   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2268   *         the configuration information for the specified CAN.
2269   * @retval None
2270   */
HAL_CAN_SleepCallback(CAN_HandleTypeDef * hcan)2271 __weak void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan)
2272 {
2273   /* Prevent unused argument(s) compilation warning */
2274   UNUSED(hcan);
2275 
2276   /* NOTE : This function Should not be modified, when the callback is needed,
2277             the HAL_CAN_SleepCallback could be implemented in the user file
2278    */
2279 }
2280 
2281 /**
2282   * @brief  WakeUp from Rx message callback.
2283   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2284   *         the configuration information for the specified CAN.
2285   * @retval None
2286   */
HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef * hcan)2287 __weak void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan)
2288 {
2289   /* Prevent unused argument(s) compilation warning */
2290   UNUSED(hcan);
2291 
2292   /* NOTE : This function Should not be modified, when the callback is needed,
2293             the HAL_CAN_WakeUpFromRxMsgCallback could be implemented in the
2294             user file
2295    */
2296 }
2297 
2298 /**
2299   * @brief  Error CAN callback.
2300   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2301   *         the configuration information for the specified CAN.
2302   * @retval None
2303   */
HAL_CAN_ErrorCallback(CAN_HandleTypeDef * hcan)2304 __weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
2305 {
2306   /* Prevent unused argument(s) compilation warning */
2307   UNUSED(hcan);
2308 
2309   /* NOTE : This function Should not be modified, when the callback is needed,
2310             the HAL_CAN_ErrorCallback could be implemented in the user file
2311    */
2312 }
2313 
2314 /**
2315   * @}
2316   */
2317 
2318 /** @defgroup CAN_Exported_Functions_Group6 Peripheral State and Error functions
2319  *  @brief   CAN Peripheral State functions
2320  *
2321 @verbatim
2322   ==============================================================================
2323             ##### Peripheral State and Error functions #####
2324   ==============================================================================
2325     [..]
2326     This subsection provides functions allowing to :
2327       (+) HAL_CAN_GetState()  : Return the CAN state.
2328       (+) HAL_CAN_GetError()  : Return the CAN error codes if any.
2329       (+) HAL_CAN_ResetError(): Reset the CAN error codes if any.
2330 
2331 @endverbatim
2332   * @{
2333   */
2334 
2335 /**
2336   * @brief  Return the CAN state.
2337   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2338   *         the configuration information for the specified CAN.
2339   * @retval HAL state
2340   */
HAL_CAN_GetState(const CAN_HandleTypeDef * hcan)2341 HAL_CAN_StateTypeDef HAL_CAN_GetState(const CAN_HandleTypeDef *hcan)
2342 {
2343   HAL_CAN_StateTypeDef state = hcan->State;
2344 
2345   if ((state == HAL_CAN_STATE_READY) ||
2346       (state == HAL_CAN_STATE_LISTENING))
2347   {
2348     /* Check sleep mode acknowledge flag */
2349     if ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U)
2350     {
2351       /* Sleep mode is active */
2352       state = HAL_CAN_STATE_SLEEP_ACTIVE;
2353     }
2354     /* Check sleep mode request flag */
2355     else if ((hcan->Instance->MCR & CAN_MCR_SLEEP) != 0U)
2356     {
2357       /* Sleep mode request is pending */
2358       state = HAL_CAN_STATE_SLEEP_PENDING;
2359     }
2360     else
2361     {
2362       /* Neither sleep mode request nor sleep mode acknowledge */
2363     }
2364   }
2365 
2366   /* Return CAN state */
2367   return state;
2368 }
2369 
2370 /**
2371   * @brief  Return the CAN error code.
2372   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2373   *         the configuration information for the specified CAN.
2374   * @retval CAN Error Code
2375   */
HAL_CAN_GetError(const CAN_HandleTypeDef * hcan)2376 uint32_t HAL_CAN_GetError(const CAN_HandleTypeDef *hcan)
2377 {
2378   /* Return CAN error code */
2379   return hcan->ErrorCode;
2380 }
2381 
2382 /**
2383   * @brief  Reset the CAN error code.
2384   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2385   *         the configuration information for the specified CAN.
2386   * @retval HAL status
2387   */
HAL_CAN_ResetError(CAN_HandleTypeDef * hcan)2388 HAL_StatusTypeDef HAL_CAN_ResetError(CAN_HandleTypeDef *hcan)
2389 {
2390   HAL_StatusTypeDef status = HAL_OK;
2391   HAL_CAN_StateTypeDef state = hcan->State;
2392 
2393   if ((state == HAL_CAN_STATE_READY) ||
2394       (state == HAL_CAN_STATE_LISTENING))
2395   {
2396     /* Reset CAN error code */
2397     hcan->ErrorCode = 0U;
2398   }
2399   else
2400   {
2401     /* Update error code */
2402     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
2403 
2404     status = HAL_ERROR;
2405   }
2406 
2407   /* Return the status */
2408   return status;
2409 }
2410 
2411 /**
2412   * @}
2413   */
2414 
2415 /**
2416   * @}
2417   */
2418 
2419 #endif /* HAL_CAN_MODULE_ENABLED */
2420 
2421 /**
2422   * @}
2423   */
2424 
2425 #endif /* CAN1 */
2426 
2427 /**
2428   * @}
2429   */
2430