1 /**
2   ******************************************************************************
3   * @file    stm32f0xx_hal_can.c
4   * @author  MCD Application Team
5   * @brief   CAN HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Controller Area Network (CAN) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + Configuration functions
10   *           + Control functions
11   *           + Interrupts management
12   *           + Callbacks functions
13   *           + Peripheral State and Error functions
14   *
15   ******************************************************************************
16   * @attention
17   *
18   * Copyright (c) 2016 STMicroelectronics.
19   * All rights reserved.
20   *
21   * This software is licensed under terms that can be found in the LICENSE file
22   * in the root directory of this software component.
23   * If no LICENSE file comes with this software, it is provided AS-IS.
24   *
25   ******************************************************************************
26   @verbatim
27   ==============================================================================
28                         ##### How to use this driver #####
29   ==============================================================================
30     [..]
31       (#) Initialize the CAN low level resources by implementing the
32           HAL_CAN_MspInit():
33          (++) Enable the CAN interface clock using __HAL_RCC_CANx_CLK_ENABLE()
34          (++) Configure CAN pins
35              (+++) Enable the clock for the CAN GPIOs
36              (+++) Configure CAN pins as alternate function open-drain
37          (++) In case of using interrupts (e.g. HAL_CAN_ActivateNotification())
38              (+++) Configure the CAN interrupt priority using
39                    HAL_NVIC_SetPriority()
40              (+++) Enable the CAN IRQ handler using HAL_NVIC_EnableIRQ()
41              (+++) In CAN IRQ handler, call HAL_CAN_IRQHandler()
42 
43       (#) Initialize the CAN peripheral using HAL_CAN_Init() function. This
44           function resorts to HAL_CAN_MspInit() for low-level initialization.
45 
46       (#) Configure the reception filters using the following configuration
47           functions:
48             (++) HAL_CAN_ConfigFilter()
49 
50       (#) Start the CAN module using HAL_CAN_Start() function. At this level
51           the node is active on the bus: it receive messages, and can send
52           messages.
53 
54       (#) To manage messages transmission, the following Tx control functions
55           can be used:
56             (++) HAL_CAN_AddTxMessage() to request transmission of a new
57                  message.
58             (++) HAL_CAN_AbortTxRequest() to abort transmission of a pending
59                  message.
60             (++) HAL_CAN_GetTxMailboxesFreeLevel() to get the number of free Tx
61                  mailboxes.
62             (++) HAL_CAN_IsTxMessagePending() to check if a message is pending
63                  in a Tx mailbox.
64             (++) HAL_CAN_GetTxTimestamp() to get the timestamp of Tx message
65                  sent, if time triggered communication mode is enabled.
66 
67       (#) When a message is received into the CAN Rx FIFOs, it can be retrieved
68           using the HAL_CAN_GetRxMessage() function. The function
69           HAL_CAN_GetRxFifoFillLevel() allows to know how many Rx message are
70           stored in the Rx Fifo.
71 
72       (#) Calling the HAL_CAN_Stop() function stops the CAN module.
73 
74       (#) The deinitialization is achieved with HAL_CAN_DeInit() function.
75 
76 
77       *** Polling mode operation ***
78       ==============================
79     [..]
80       (#) Reception:
81             (++) Monitor reception of message using HAL_CAN_GetRxFifoFillLevel()
82                  until at least one message is received.
83             (++) Then get the message using HAL_CAN_GetRxMessage().
84 
85       (#) Transmission:
86             (++) Monitor the Tx mailboxes availability until at least one Tx
87                  mailbox is free, using HAL_CAN_GetTxMailboxesFreeLevel().
88             (++) Then request transmission of a message using
89                  HAL_CAN_AddTxMessage().
90 
91 
92       *** Interrupt mode operation ***
93       ================================
94     [..]
95       (#) Notifications are activated using HAL_CAN_ActivateNotification()
96           function. Then, the process can be controlled through the
97           available user callbacks: HAL_CAN_xxxCallback(), using same APIs
98           HAL_CAN_GetRxMessage() and HAL_CAN_AddTxMessage().
99 
100       (#) Notifications can be deactivated using
101           HAL_CAN_DeactivateNotification() function.
102 
103       (#) Special care should be taken for CAN_IT_RX_FIFO0_MSG_PENDING and
104           CAN_IT_RX_FIFO1_MSG_PENDING notifications. These notifications trig
105           the callbacks HAL_CAN_RxFIFO0MsgPendingCallback() and
106           HAL_CAN_RxFIFO1MsgPendingCallback(). User has two possible options
107           here.
108             (++) Directly get the Rx message in the callback, using
109                  HAL_CAN_GetRxMessage().
110             (++) Or deactivate the notification in the callback without
111                  getting the Rx message. The Rx message can then be got later
112                  using HAL_CAN_GetRxMessage(). Once the Rx message have been
113                  read, the notification can be activated again.
114 
115 
116       *** Sleep mode ***
117       ==================
118     [..]
119       (#) The CAN peripheral can be put in sleep mode (low power), using
120           HAL_CAN_RequestSleep(). The sleep mode will be entered as soon as the
121           current CAN activity (transmission or reception of a CAN frame) will
122           be completed.
123 
124       (#) A notification can be activated to be informed when the sleep mode
125           will be entered.
126 
127       (#) It can be checked if the sleep mode is entered using
128           HAL_CAN_IsSleepActive().
129           Note that the CAN state (accessible from the API HAL_CAN_GetState())
130           is HAL_CAN_STATE_SLEEP_PENDING as soon as the sleep mode request is
131           submitted (the sleep mode is not yet entered), and become
132           HAL_CAN_STATE_SLEEP_ACTIVE when the sleep mode is effective.
133 
134       (#) The wake-up from sleep mode can be triggered by two ways:
135             (++) Using HAL_CAN_WakeUp(). When returning from this function,
136                  the sleep mode is exited (if return status is HAL_OK).
137             (++) When a start of Rx CAN frame is detected by the CAN peripheral,
138                  if automatic wake up mode is enabled.
139 
140   *** Callback registration ***
141   =============================================
142 
143   The compilation define  USE_HAL_CAN_REGISTER_CALLBACKS when set to 1
144   allows the user to configure dynamically the driver callbacks.
145   Use Function HAL_CAN_RegisterCallback() to register an interrupt callback.
146 
147   Function HAL_CAN_RegisterCallback() allows to register following callbacks:
148     (+) TxMailbox0CompleteCallback   : Tx Mailbox 0 Complete Callback.
149     (+) TxMailbox1CompleteCallback   : Tx Mailbox 1 Complete Callback.
150     (+) TxMailbox2CompleteCallback   : Tx Mailbox 2 Complete Callback.
151     (+) TxMailbox0AbortCallback      : Tx Mailbox 0 Abort Callback.
152     (+) TxMailbox1AbortCallback      : Tx Mailbox 1 Abort Callback.
153     (+) TxMailbox2AbortCallback      : Tx Mailbox 2 Abort Callback.
154     (+) RxFifo0MsgPendingCallback    : Rx Fifo 0 Message Pending Callback.
155     (+) RxFifo0FullCallback          : Rx Fifo 0 Full Callback.
156     (+) RxFifo1MsgPendingCallback    : Rx Fifo 1 Message Pending Callback.
157     (+) RxFifo1FullCallback          : Rx Fifo 1 Full Callback.
158     (+) SleepCallback                : Sleep Callback.
159     (+) WakeUpFromRxMsgCallback      : Wake Up From Rx Message Callback.
160     (+) ErrorCallback                : Error Callback.
161     (+) MspInitCallback              : CAN MspInit.
162     (+) MspDeInitCallback            : CAN MspDeInit.
163   This function takes as parameters the HAL peripheral handle, the Callback ID
164   and a pointer to the user callback function.
165 
166   Use function HAL_CAN_UnRegisterCallback() to reset a callback to the default
167   weak function.
168   HAL_CAN_UnRegisterCallback takes as parameters the HAL peripheral handle,
169   and the Callback ID.
170   This function allows to reset following callbacks:
171     (+) TxMailbox0CompleteCallback   : Tx Mailbox 0 Complete Callback.
172     (+) TxMailbox1CompleteCallback   : Tx Mailbox 1 Complete Callback.
173     (+) TxMailbox2CompleteCallback   : Tx Mailbox 2 Complete Callback.
174     (+) TxMailbox0AbortCallback      : Tx Mailbox 0 Abort Callback.
175     (+) TxMailbox1AbortCallback      : Tx Mailbox 1 Abort Callback.
176     (+) TxMailbox2AbortCallback      : Tx Mailbox 2 Abort Callback.
177     (+) RxFifo0MsgPendingCallback    : Rx Fifo 0 Message Pending Callback.
178     (+) RxFifo0FullCallback          : Rx Fifo 0 Full Callback.
179     (+) RxFifo1MsgPendingCallback    : Rx Fifo 1 Message Pending Callback.
180     (+) RxFifo1FullCallback          : Rx Fifo 1 Full Callback.
181     (+) SleepCallback                : Sleep Callback.
182     (+) WakeUpFromRxMsgCallback      : Wake Up From Rx Message Callback.
183     (+) ErrorCallback                : Error Callback.
184     (+) MspInitCallback              : CAN MspInit.
185     (+) MspDeInitCallback            : CAN MspDeInit.
186 
187   By default, after the HAL_CAN_Init() and when the state is HAL_CAN_STATE_RESET,
188   all callbacks are set to the corresponding weak functions:
189   example HAL_CAN_ErrorCallback().
190   Exception done for MspInit and MspDeInit functions that are
191   reset to the legacy weak function in the HAL_CAN_Init()/ HAL_CAN_DeInit() only when
192   these callbacks are null (not registered beforehand).
193   if not, MspInit or MspDeInit are not null, the HAL_CAN_Init()/ HAL_CAN_DeInit()
194   keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
195 
196   Callbacks can be registered/unregistered in HAL_CAN_STATE_READY state only.
197   Exception done MspInit/MspDeInit that can be registered/unregistered
198   in HAL_CAN_STATE_READY or HAL_CAN_STATE_RESET state,
199   thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
200   In that case first register the MspInit/MspDeInit user callbacks
201   using HAL_CAN_RegisterCallback() before calling HAL_CAN_DeInit()
202   or HAL_CAN_Init() function.
203 
204   When The compilation define USE_HAL_CAN_REGISTER_CALLBACKS is set to 0 or
205   not defined, the callback registration feature is not available and all callbacks
206   are set to the corresponding weak functions.
207 
208   @endverbatim
209   ******************************************************************************
210   */
211 
212 /* Includes ------------------------------------------------------------------*/
213 #include "stm32f0xx_hal.h"
214 
215 /** @addtogroup STM32F0xx_HAL_Driver
216   * @{
217   */
218 
219 #if defined(CAN)
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     /* CAN is single instance with 14 dedicated filters banks */
859 
860     /* Check the parameters */
861     assert_param(IS_CAN_FILTER_BANK_SINGLE(sFilterConfig->FilterBank));
862 
863     /* Initialisation mode for the filter */
864     SET_BIT(can_ip->FMR, CAN_FMR_FINIT);
865 
866     /* Convert filter number into bit position */
867     filternbrbitpos = (uint32_t)1 << (sFilterConfig->FilterBank & 0x1FU);
868 
869     /* Filter Deactivation */
870     CLEAR_BIT(can_ip->FA1R, filternbrbitpos);
871 
872     /* Filter Scale */
873     if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT)
874     {
875       /* 16-bit scale for the filter */
876       CLEAR_BIT(can_ip->FS1R, filternbrbitpos);
877 
878       /* First 16-bit identifier and First 16-bit mask */
879       /* Or First 16-bit identifier and Second 16-bit identifier */
880       can_ip->sFilterRegister[sFilterConfig->FilterBank].FR1 =
881         ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16U) |
882         (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
883 
884       /* Second 16-bit identifier and Second 16-bit mask */
885       /* Or Third 16-bit identifier and Fourth 16-bit identifier */
886       can_ip->sFilterRegister[sFilterConfig->FilterBank].FR2 =
887         ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
888         (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh);
889     }
890 
891     if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
892     {
893       /* 32-bit scale for the filter */
894       SET_BIT(can_ip->FS1R, filternbrbitpos);
895 
896       /* 32-bit identifier or First 32-bit identifier */
897       can_ip->sFilterRegister[sFilterConfig->FilterBank].FR1 =
898         ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh) << 16U) |
899         (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
900 
901       /* 32-bit mask or Second 32-bit identifier */
902       can_ip->sFilterRegister[sFilterConfig->FilterBank].FR2 =
903         ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
904         (0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow);
905     }
906 
907     /* Filter Mode */
908     if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
909     {
910       /* Id/Mask mode for the filter*/
911       CLEAR_BIT(can_ip->FM1R, filternbrbitpos);
912     }
913     else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
914     {
915       /* Identifier list mode for the filter*/
916       SET_BIT(can_ip->FM1R, filternbrbitpos);
917     }
918 
919     /* Filter FIFO assignment */
920     if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
921     {
922       /* FIFO 0 assignation for the filter */
923       CLEAR_BIT(can_ip->FFA1R, filternbrbitpos);
924     }
925     else
926     {
927       /* FIFO 1 assignation for the filter */
928       SET_BIT(can_ip->FFA1R, filternbrbitpos);
929     }
930 
931     /* Filter activation */
932     if (sFilterConfig->FilterActivation == CAN_FILTER_ENABLE)
933     {
934       SET_BIT(can_ip->FA1R, filternbrbitpos);
935     }
936 
937     /* Leave the initialisation mode for the filter */
938     CLEAR_BIT(can_ip->FMR, CAN_FMR_FINIT);
939 
940     /* Return function status */
941     return HAL_OK;
942   }
943   else
944   {
945     /* Update error code */
946     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
947 
948     return HAL_ERROR;
949   }
950 }
951 
952 /**
953   * @}
954   */
955 
956 /** @defgroup CAN_Exported_Functions_Group3 Control functions
957  *  @brief    Control functions
958  *
959 @verbatim
960   ==============================================================================
961                       ##### Control functions #####
962   ==============================================================================
963     [..]  This section provides functions allowing to:
964       (+) HAL_CAN_Start                    : Start the CAN module
965       (+) HAL_CAN_Stop                     : Stop the CAN module
966       (+) HAL_CAN_RequestSleep             : Request sleep mode entry.
967       (+) HAL_CAN_WakeUp                   : Wake up from sleep mode.
968       (+) HAL_CAN_IsSleepActive            : Check is sleep mode is active.
969       (+) HAL_CAN_AddTxMessage             : Add a message to the Tx mailboxes
970                                              and activate the corresponding
971                                              transmission request
972       (+) HAL_CAN_AbortTxRequest           : Abort transmission request
973       (+) HAL_CAN_GetTxMailboxesFreeLevel  : Return Tx mailboxes free level
974       (+) HAL_CAN_IsTxMessagePending       : Check if a transmission request is
975                                              pending on the selected Tx mailbox
976       (+) HAL_CAN_GetRxMessage             : Get a CAN frame from the Rx FIFO
977       (+) HAL_CAN_GetRxFifoFillLevel       : Return Rx FIFO fill level
978 
979 @endverbatim
980   * @{
981   */
982 
983 /**
984   * @brief  Start the CAN module.
985   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
986   *         the configuration information for the specified CAN.
987   * @retval HAL status
988   */
HAL_CAN_Start(CAN_HandleTypeDef * hcan)989 HAL_StatusTypeDef HAL_CAN_Start(CAN_HandleTypeDef *hcan)
990 {
991   uint32_t tickstart;
992 
993   if (hcan->State == HAL_CAN_STATE_READY)
994   {
995     /* Change CAN peripheral state */
996     hcan->State = HAL_CAN_STATE_LISTENING;
997 
998     /* Request leave initialisation */
999     CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
1000 
1001     /* Get tick */
1002     tickstart = HAL_GetTick();
1003 
1004     /* Wait the acknowledge */
1005     while ((hcan->Instance->MSR & CAN_MSR_INAK) != 0U)
1006     {
1007       /* Check for the Timeout */
1008       if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
1009       {
1010         /* Update error code */
1011         hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
1012 
1013         /* Change CAN state */
1014         hcan->State = HAL_CAN_STATE_ERROR;
1015 
1016         return HAL_ERROR;
1017       }
1018     }
1019 
1020     /* Reset the CAN ErrorCode */
1021     hcan->ErrorCode = HAL_CAN_ERROR_NONE;
1022 
1023     /* Return function status */
1024     return HAL_OK;
1025   }
1026   else
1027   {
1028     /* Update error code */
1029     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_READY;
1030 
1031     return HAL_ERROR;
1032   }
1033 }
1034 
1035 /**
1036   * @brief  Stop the CAN module and enable access to configuration registers.
1037   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1038   *         the configuration information for the specified CAN.
1039   * @retval HAL status
1040   */
HAL_CAN_Stop(CAN_HandleTypeDef * hcan)1041 HAL_StatusTypeDef HAL_CAN_Stop(CAN_HandleTypeDef *hcan)
1042 {
1043   uint32_t tickstart;
1044 
1045   if (hcan->State == HAL_CAN_STATE_LISTENING)
1046   {
1047     /* Request initialisation */
1048     SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
1049 
1050     /* Get tick */
1051     tickstart = HAL_GetTick();
1052 
1053     /* Wait the acknowledge */
1054     while ((hcan->Instance->MSR & CAN_MSR_INAK) == 0U)
1055     {
1056       /* Check for the Timeout */
1057       if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
1058       {
1059         /* Update error code */
1060         hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
1061 
1062         /* Change CAN state */
1063         hcan->State = HAL_CAN_STATE_ERROR;
1064 
1065         return HAL_ERROR;
1066       }
1067     }
1068 
1069     /* Exit from sleep mode */
1070     CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
1071 
1072     /* Change CAN peripheral state */
1073     hcan->State = HAL_CAN_STATE_READY;
1074 
1075     /* Return function status */
1076     return HAL_OK;
1077   }
1078   else
1079   {
1080     /* Update error code */
1081     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_STARTED;
1082 
1083     return HAL_ERROR;
1084   }
1085 }
1086 
1087 /**
1088   * @brief  Request the sleep mode (low power) entry.
1089   *         When returning from this function, Sleep mode will be entered
1090   *         as soon as the current CAN activity (transmission or reception
1091   *         of a CAN frame) has been completed.
1092   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1093   *         the configuration information for the specified CAN.
1094   * @retval HAL status.
1095   */
HAL_CAN_RequestSleep(CAN_HandleTypeDef * hcan)1096 HAL_StatusTypeDef HAL_CAN_RequestSleep(CAN_HandleTypeDef *hcan)
1097 {
1098   HAL_CAN_StateTypeDef state = hcan->State;
1099 
1100   if ((state == HAL_CAN_STATE_READY) ||
1101       (state == HAL_CAN_STATE_LISTENING))
1102   {
1103     /* Request Sleep mode */
1104     SET_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
1105 
1106     /* Return function status */
1107     return HAL_OK;
1108   }
1109   else
1110   {
1111     /* Update error code */
1112     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1113 
1114     /* Return function status */
1115     return HAL_ERROR;
1116   }
1117 }
1118 
1119 /**
1120   * @brief  Wake up from sleep mode.
1121   *         When returning with HAL_OK status from this function, Sleep mode
1122   *         is exited.
1123   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1124   *         the configuration information for the specified CAN.
1125   * @retval HAL status.
1126   */
HAL_CAN_WakeUp(CAN_HandleTypeDef * hcan)1127 HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef *hcan)
1128 {
1129   __IO uint32_t count = 0;
1130   uint32_t timeout = 1000000U;
1131   HAL_CAN_StateTypeDef state = hcan->State;
1132 
1133   if ((state == HAL_CAN_STATE_READY) ||
1134       (state == HAL_CAN_STATE_LISTENING))
1135   {
1136     /* Wake up request */
1137     CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
1138 
1139     /* Wait sleep mode is exited */
1140     do
1141     {
1142       /* Increment counter */
1143       count++;
1144 
1145       /* Check if timeout is reached */
1146       if (count > timeout)
1147       {
1148         /* Update error code */
1149         hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
1150 
1151         return HAL_ERROR;
1152       }
1153     }
1154     while ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U);
1155 
1156     /* Return function status */
1157     return HAL_OK;
1158   }
1159   else
1160   {
1161     /* Update error code */
1162     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1163 
1164     return HAL_ERROR;
1165   }
1166 }
1167 
1168 /**
1169   * @brief  Check is sleep mode is active.
1170   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1171   *         the configuration information for the specified CAN.
1172   * @retval Status
1173   *          - 0 : Sleep mode is not active.
1174   *          - 1 : Sleep mode is active.
1175   */
HAL_CAN_IsSleepActive(const CAN_HandleTypeDef * hcan)1176 uint32_t HAL_CAN_IsSleepActive(const CAN_HandleTypeDef *hcan)
1177 {
1178   uint32_t status = 0U;
1179   HAL_CAN_StateTypeDef state = hcan->State;
1180 
1181   if ((state == HAL_CAN_STATE_READY) ||
1182       (state == HAL_CAN_STATE_LISTENING))
1183   {
1184     /* Check Sleep mode */
1185     if ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U)
1186     {
1187       status = 1U;
1188     }
1189   }
1190 
1191   /* Return function status */
1192   return status;
1193 }
1194 
1195 /**
1196   * @brief  Add a message to the first free Tx mailbox and activate the
1197   *         corresponding transmission request.
1198   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1199   *         the configuration information for the specified CAN.
1200   * @param  pHeader pointer to a CAN_TxHeaderTypeDef structure.
1201   * @param  aData array containing the payload of the Tx frame.
1202   * @param  pTxMailbox pointer to a variable where the function will return
1203   *         the TxMailbox used to store the Tx message.
1204   *         This parameter can be a value of @arg CAN_Tx_Mailboxes.
1205   * @retval HAL status
1206   */
HAL_CAN_AddTxMessage(CAN_HandleTypeDef * hcan,const CAN_TxHeaderTypeDef * pHeader,const uint8_t aData[],uint32_t * pTxMailbox)1207 HAL_StatusTypeDef HAL_CAN_AddTxMessage(CAN_HandleTypeDef *hcan, const CAN_TxHeaderTypeDef *pHeader,
1208                                        const uint8_t aData[], uint32_t *pTxMailbox)
1209 {
1210   uint32_t transmitmailbox;
1211   HAL_CAN_StateTypeDef state = hcan->State;
1212   uint32_t tsr = READ_REG(hcan->Instance->TSR);
1213 
1214   /* Check the parameters */
1215   assert_param(IS_CAN_IDTYPE(pHeader->IDE));
1216   assert_param(IS_CAN_RTR(pHeader->RTR));
1217   assert_param(IS_CAN_DLC(pHeader->DLC));
1218   if (pHeader->IDE == CAN_ID_STD)
1219   {
1220     assert_param(IS_CAN_STDID(pHeader->StdId));
1221   }
1222   else
1223   {
1224     assert_param(IS_CAN_EXTID(pHeader->ExtId));
1225   }
1226   assert_param(IS_FUNCTIONAL_STATE(pHeader->TransmitGlobalTime));
1227 
1228   if ((state == HAL_CAN_STATE_READY) ||
1229       (state == HAL_CAN_STATE_LISTENING))
1230   {
1231     /* Check that all the Tx mailboxes are not full */
1232     if (((tsr & CAN_TSR_TME0) != 0U) ||
1233         ((tsr & CAN_TSR_TME1) != 0U) ||
1234         ((tsr & CAN_TSR_TME2) != 0U))
1235     {
1236       /* Select an empty transmit mailbox */
1237       transmitmailbox = (tsr & CAN_TSR_CODE) >> CAN_TSR_CODE_Pos;
1238 
1239       /* Store the Tx mailbox */
1240       *pTxMailbox = (uint32_t)1 << transmitmailbox;
1241 
1242       /* Set up the Id */
1243       if (pHeader->IDE == CAN_ID_STD)
1244       {
1245         hcan->Instance->sTxMailBox[transmitmailbox].TIR = ((pHeader->StdId << CAN_TI0R_STID_Pos) |
1246                                                            pHeader->RTR);
1247       }
1248       else
1249       {
1250         hcan->Instance->sTxMailBox[transmitmailbox].TIR = ((pHeader->ExtId << CAN_TI0R_EXID_Pos) |
1251                                                            pHeader->IDE |
1252                                                            pHeader->RTR);
1253       }
1254 
1255       /* Set up the DLC */
1256       hcan->Instance->sTxMailBox[transmitmailbox].TDTR = (pHeader->DLC);
1257 
1258       /* Set up the Transmit Global Time mode */
1259       if (pHeader->TransmitGlobalTime == ENABLE)
1260       {
1261         SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TDTR, CAN_TDT0R_TGT);
1262       }
1263 
1264       /* Set up the data field */
1265       WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR,
1266                 ((uint32_t)aData[7] << CAN_TDH0R_DATA7_Pos) |
1267                 ((uint32_t)aData[6] << CAN_TDH0R_DATA6_Pos) |
1268                 ((uint32_t)aData[5] << CAN_TDH0R_DATA5_Pos) |
1269                 ((uint32_t)aData[4] << CAN_TDH0R_DATA4_Pos));
1270       WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR,
1271                 ((uint32_t)aData[3] << CAN_TDL0R_DATA3_Pos) |
1272                 ((uint32_t)aData[2] << CAN_TDL0R_DATA2_Pos) |
1273                 ((uint32_t)aData[1] << CAN_TDL0R_DATA1_Pos) |
1274                 ((uint32_t)aData[0] << CAN_TDL0R_DATA0_Pos));
1275 
1276       /* Request transmission */
1277       SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TIR, CAN_TI0R_TXRQ);
1278 
1279       /* Return function status */
1280       return HAL_OK;
1281     }
1282     else
1283     {
1284       /* Update error code */
1285       hcan->ErrorCode |= HAL_CAN_ERROR_PARAM;
1286 
1287       return HAL_ERROR;
1288     }
1289   }
1290   else
1291   {
1292     /* Update error code */
1293     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1294 
1295     return HAL_ERROR;
1296   }
1297 }
1298 
1299 /**
1300   * @brief  Abort transmission requests
1301   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1302   *         the configuration information for the specified CAN.
1303   * @param  TxMailboxes List of the Tx Mailboxes to abort.
1304   *         This parameter can be any combination of @arg CAN_Tx_Mailboxes.
1305   * @retval HAL status
1306   */
HAL_CAN_AbortTxRequest(CAN_HandleTypeDef * hcan,uint32_t TxMailboxes)1307 HAL_StatusTypeDef HAL_CAN_AbortTxRequest(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes)
1308 {
1309   HAL_CAN_StateTypeDef state = hcan->State;
1310 
1311   /* Check function parameters */
1312   assert_param(IS_CAN_TX_MAILBOX_LIST(TxMailboxes));
1313 
1314   if ((state == HAL_CAN_STATE_READY) ||
1315       (state == HAL_CAN_STATE_LISTENING))
1316   {
1317     /* Check Tx Mailbox 0 */
1318     if ((TxMailboxes & CAN_TX_MAILBOX0) != 0U)
1319     {
1320       /* Add cancellation request for Tx Mailbox 0 */
1321       SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ0);
1322     }
1323 
1324     /* Check Tx Mailbox 1 */
1325     if ((TxMailboxes & CAN_TX_MAILBOX1) != 0U)
1326     {
1327       /* Add cancellation request for Tx Mailbox 1 */
1328       SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ1);
1329     }
1330 
1331     /* Check Tx Mailbox 2 */
1332     if ((TxMailboxes & CAN_TX_MAILBOX2) != 0U)
1333     {
1334       /* Add cancellation request for Tx Mailbox 2 */
1335       SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ2);
1336     }
1337 
1338     /* Return function status */
1339     return HAL_OK;
1340   }
1341   else
1342   {
1343     /* Update error code */
1344     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1345 
1346     return HAL_ERROR;
1347   }
1348 }
1349 
1350 /**
1351   * @brief  Return Tx Mailboxes free level: number of free Tx Mailboxes.
1352   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1353   *         the configuration information for the specified CAN.
1354   * @retval Number of free Tx Mailboxes.
1355   */
HAL_CAN_GetTxMailboxesFreeLevel(const CAN_HandleTypeDef * hcan)1356 uint32_t HAL_CAN_GetTxMailboxesFreeLevel(const CAN_HandleTypeDef *hcan)
1357 {
1358   uint32_t freelevel = 0U;
1359   HAL_CAN_StateTypeDef state = hcan->State;
1360 
1361   if ((state == HAL_CAN_STATE_READY) ||
1362       (state == HAL_CAN_STATE_LISTENING))
1363   {
1364     /* Check Tx Mailbox 0 status */
1365     if ((hcan->Instance->TSR & CAN_TSR_TME0) != 0U)
1366     {
1367       freelevel++;
1368     }
1369 
1370     /* Check Tx Mailbox 1 status */
1371     if ((hcan->Instance->TSR & CAN_TSR_TME1) != 0U)
1372     {
1373       freelevel++;
1374     }
1375 
1376     /* Check Tx Mailbox 2 status */
1377     if ((hcan->Instance->TSR & CAN_TSR_TME2) != 0U)
1378     {
1379       freelevel++;
1380     }
1381   }
1382 
1383   /* Return Tx Mailboxes free level */
1384   return freelevel;
1385 }
1386 
1387 /**
1388   * @brief  Check if a transmission request is pending on the selected Tx
1389   *         Mailboxes.
1390   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1391   *         the configuration information for the specified CAN.
1392   * @param  TxMailboxes List of Tx Mailboxes to check.
1393   *         This parameter can be any combination of @arg CAN_Tx_Mailboxes.
1394   * @retval Status
1395   *          - 0 : No pending transmission request on any selected Tx Mailboxes.
1396   *          - 1 : Pending transmission request on at least one of the selected
1397   *                Tx Mailbox.
1398   */
HAL_CAN_IsTxMessagePending(const CAN_HandleTypeDef * hcan,uint32_t TxMailboxes)1399 uint32_t HAL_CAN_IsTxMessagePending(const CAN_HandleTypeDef *hcan, uint32_t TxMailboxes)
1400 {
1401   uint32_t status = 0U;
1402   HAL_CAN_StateTypeDef state = hcan->State;
1403 
1404   /* Check function parameters */
1405   assert_param(IS_CAN_TX_MAILBOX_LIST(TxMailboxes));
1406 
1407   if ((state == HAL_CAN_STATE_READY) ||
1408       (state == HAL_CAN_STATE_LISTENING))
1409   {
1410     /* Check pending transmission request on the selected Tx Mailboxes */
1411     if ((hcan->Instance->TSR & (TxMailboxes << CAN_TSR_TME0_Pos)) != (TxMailboxes << CAN_TSR_TME0_Pos))
1412     {
1413       status = 1U;
1414     }
1415   }
1416 
1417   /* Return status */
1418   return status;
1419 }
1420 
1421 /**
1422   * @brief  Return timestamp of Tx message sent, if time triggered communication
1423             mode is enabled.
1424   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1425   *         the configuration information for the specified CAN.
1426   * @param  TxMailbox Tx Mailbox where the timestamp of message sent will be
1427   *         read.
1428   *         This parameter can be one value of @arg CAN_Tx_Mailboxes.
1429   * @retval Timestamp of message sent from Tx Mailbox.
1430   */
HAL_CAN_GetTxTimestamp(const CAN_HandleTypeDef * hcan,uint32_t TxMailbox)1431 uint32_t HAL_CAN_GetTxTimestamp(const CAN_HandleTypeDef *hcan, uint32_t TxMailbox)
1432 {
1433   uint32_t timestamp = 0U;
1434   uint32_t transmitmailbox;
1435   HAL_CAN_StateTypeDef state = hcan->State;
1436 
1437   /* Check function parameters */
1438   assert_param(IS_CAN_TX_MAILBOX(TxMailbox));
1439 
1440   if ((state == HAL_CAN_STATE_READY) ||
1441       (state == HAL_CAN_STATE_LISTENING))
1442   {
1443     /* Select the Tx mailbox */
1444     /* Select the Tx mailbox */
1445     if (TxMailbox == CAN_TX_MAILBOX0)
1446     {
1447       transmitmailbox = 0U;
1448     }
1449     else if (TxMailbox == CAN_TX_MAILBOX1)
1450     {
1451       transmitmailbox = 1U;
1452     }
1453     else /* (TxMailbox == CAN_TX_MAILBOX2) */
1454     {
1455       transmitmailbox = 2U;
1456     }
1457 
1458     /* Get timestamp */
1459     timestamp = (hcan->Instance->sTxMailBox[transmitmailbox].TDTR & CAN_TDT0R_TIME) >> CAN_TDT0R_TIME_Pos;
1460   }
1461 
1462   /* Return the timestamp */
1463   return timestamp;
1464 }
1465 
1466 /**
1467   * @brief  Get an CAN frame from the Rx FIFO zone into the message RAM.
1468   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1469   *         the configuration information for the specified CAN.
1470   * @param  RxFifo Fifo number of the received message to be read.
1471   *         This parameter can be a value of @arg CAN_receive_FIFO_number.
1472   * @param  pHeader pointer to a CAN_RxHeaderTypeDef structure where the header
1473   *         of the Rx frame will be stored.
1474   * @param  aData array where the payload of the Rx frame will be stored.
1475   * @retval HAL status
1476   */
HAL_CAN_GetRxMessage(CAN_HandleTypeDef * hcan,uint32_t RxFifo,CAN_RxHeaderTypeDef * pHeader,uint8_t aData[])1477 HAL_StatusTypeDef HAL_CAN_GetRxMessage(CAN_HandleTypeDef *hcan, uint32_t RxFifo,
1478                                        CAN_RxHeaderTypeDef *pHeader, uint8_t aData[])
1479 {
1480   HAL_CAN_StateTypeDef state = hcan->State;
1481 
1482   assert_param(IS_CAN_RX_FIFO(RxFifo));
1483 
1484   if ((state == HAL_CAN_STATE_READY) ||
1485       (state == HAL_CAN_STATE_LISTENING))
1486   {
1487     /* Check the Rx FIFO */
1488     if (RxFifo == CAN_RX_FIFO0) /* Rx element is assigned to Rx FIFO 0 */
1489     {
1490       /* Check that the Rx FIFO 0 is not empty */
1491       if ((hcan->Instance->RF0R & CAN_RF0R_FMP0) == 0U)
1492       {
1493         /* Update error code */
1494         hcan->ErrorCode |= HAL_CAN_ERROR_PARAM;
1495 
1496         return HAL_ERROR;
1497       }
1498     }
1499     else /* Rx element is assigned to Rx FIFO 1 */
1500     {
1501       /* Check that the Rx FIFO 1 is not empty */
1502       if ((hcan->Instance->RF1R & CAN_RF1R_FMP1) == 0U)
1503       {
1504         /* Update error code */
1505         hcan->ErrorCode |= HAL_CAN_ERROR_PARAM;
1506 
1507         return HAL_ERROR;
1508       }
1509     }
1510 
1511     /* Get the header */
1512     pHeader->IDE = CAN_RI0R_IDE & hcan->Instance->sFIFOMailBox[RxFifo].RIR;
1513     if (pHeader->IDE == CAN_ID_STD)
1514     {
1515       pHeader->StdId = (CAN_RI0R_STID & hcan->Instance->sFIFOMailBox[RxFifo].RIR) >> CAN_TI0R_STID_Pos;
1516     }
1517     else
1518     {
1519       pHeader->ExtId = ((CAN_RI0R_EXID | CAN_RI0R_STID) &
1520                         hcan->Instance->sFIFOMailBox[RxFifo].RIR) >> CAN_RI0R_EXID_Pos;
1521     }
1522     pHeader->RTR = (CAN_RI0R_RTR & hcan->Instance->sFIFOMailBox[RxFifo].RIR);
1523     if (((CAN_RDT0R_DLC & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_DLC_Pos) >= 8U)
1524     {
1525       /* Truncate DLC to 8 if received field is over range */
1526       pHeader->DLC = 8U;
1527     }
1528     else
1529     {
1530       pHeader->DLC = (CAN_RDT0R_DLC & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_DLC_Pos;
1531     }
1532     pHeader->FilterMatchIndex = (CAN_RDT0R_FMI & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_FMI_Pos;
1533     pHeader->Timestamp = (CAN_RDT0R_TIME & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_TIME_Pos;
1534 
1535     /* Get the data */
1536     aData[0] = (uint8_t)((CAN_RDL0R_DATA0 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA0_Pos);
1537     aData[1] = (uint8_t)((CAN_RDL0R_DATA1 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA1_Pos);
1538     aData[2] = (uint8_t)((CAN_RDL0R_DATA2 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA2_Pos);
1539     aData[3] = (uint8_t)((CAN_RDL0R_DATA3 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA3_Pos);
1540     aData[4] = (uint8_t)((CAN_RDH0R_DATA4 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA4_Pos);
1541     aData[5] = (uint8_t)((CAN_RDH0R_DATA5 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA5_Pos);
1542     aData[6] = (uint8_t)((CAN_RDH0R_DATA6 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA6_Pos);
1543     aData[7] = (uint8_t)((CAN_RDH0R_DATA7 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA7_Pos);
1544 
1545     /* Release the FIFO */
1546     if (RxFifo == CAN_RX_FIFO0) /* Rx element is assigned to Rx FIFO 0 */
1547     {
1548       /* Release RX FIFO 0 */
1549       SET_BIT(hcan->Instance->RF0R, CAN_RF0R_RFOM0);
1550     }
1551     else /* Rx element is assigned to Rx FIFO 1 */
1552     {
1553       /* Release RX FIFO 1 */
1554       SET_BIT(hcan->Instance->RF1R, CAN_RF1R_RFOM1);
1555     }
1556 
1557     /* Return function status */
1558     return HAL_OK;
1559   }
1560   else
1561   {
1562     /* Update error code */
1563     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1564 
1565     return HAL_ERROR;
1566   }
1567 }
1568 
1569 /**
1570   * @brief  Return Rx FIFO fill level.
1571   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1572   *         the configuration information for the specified CAN.
1573   * @param  RxFifo Rx FIFO.
1574   *         This parameter can be a value of @arg CAN_receive_FIFO_number.
1575   * @retval Number of messages available in Rx FIFO.
1576   */
HAL_CAN_GetRxFifoFillLevel(const CAN_HandleTypeDef * hcan,uint32_t RxFifo)1577 uint32_t HAL_CAN_GetRxFifoFillLevel(const CAN_HandleTypeDef *hcan, uint32_t RxFifo)
1578 {
1579   uint32_t filllevel = 0U;
1580   HAL_CAN_StateTypeDef state = hcan->State;
1581 
1582   /* Check function parameters */
1583   assert_param(IS_CAN_RX_FIFO(RxFifo));
1584 
1585   if ((state == HAL_CAN_STATE_READY) ||
1586       (state == HAL_CAN_STATE_LISTENING))
1587   {
1588     if (RxFifo == CAN_RX_FIFO0)
1589     {
1590       filllevel = hcan->Instance->RF0R & CAN_RF0R_FMP0;
1591     }
1592     else /* RxFifo == CAN_RX_FIFO1 */
1593     {
1594       filllevel = hcan->Instance->RF1R & CAN_RF1R_FMP1;
1595     }
1596   }
1597 
1598   /* Return Rx FIFO fill level */
1599   return filllevel;
1600 }
1601 
1602 /**
1603   * @}
1604   */
1605 
1606 /** @defgroup CAN_Exported_Functions_Group4 Interrupts management
1607  *  @brief    Interrupts management
1608  *
1609 @verbatim
1610   ==============================================================================
1611                        ##### Interrupts management #####
1612   ==============================================================================
1613     [..]  This section provides functions allowing to:
1614       (+) HAL_CAN_ActivateNotification      : Enable interrupts
1615       (+) HAL_CAN_DeactivateNotification    : Disable interrupts
1616       (+) HAL_CAN_IRQHandler                : Handles CAN interrupt request
1617 
1618 @endverbatim
1619   * @{
1620   */
1621 
1622 /**
1623   * @brief  Enable interrupts.
1624   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1625   *         the configuration information for the specified CAN.
1626   * @param  ActiveITs indicates which interrupts will be enabled.
1627   *         This parameter can be any combination of @arg CAN_Interrupts.
1628   * @retval HAL status
1629   */
HAL_CAN_ActivateNotification(CAN_HandleTypeDef * hcan,uint32_t ActiveITs)1630 HAL_StatusTypeDef HAL_CAN_ActivateNotification(CAN_HandleTypeDef *hcan, uint32_t ActiveITs)
1631 {
1632   HAL_CAN_StateTypeDef state = hcan->State;
1633 
1634   /* Check function parameters */
1635   assert_param(IS_CAN_IT(ActiveITs));
1636 
1637   if ((state == HAL_CAN_STATE_READY) ||
1638       (state == HAL_CAN_STATE_LISTENING))
1639   {
1640     /* Enable the selected interrupts */
1641     __HAL_CAN_ENABLE_IT(hcan, ActiveITs);
1642 
1643     /* Return function status */
1644     return HAL_OK;
1645   }
1646   else
1647   {
1648     /* Update error code */
1649     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1650 
1651     return HAL_ERROR;
1652   }
1653 }
1654 
1655 /**
1656   * @brief  Disable interrupts.
1657   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
1658   *         the configuration information for the specified CAN.
1659   * @param  InactiveITs indicates which interrupts will be disabled.
1660   *         This parameter can be any combination of @arg CAN_Interrupts.
1661   * @retval HAL status
1662   */
HAL_CAN_DeactivateNotification(CAN_HandleTypeDef * hcan,uint32_t InactiveITs)1663 HAL_StatusTypeDef HAL_CAN_DeactivateNotification(CAN_HandleTypeDef *hcan, uint32_t InactiveITs)
1664 {
1665   HAL_CAN_StateTypeDef state = hcan->State;
1666 
1667   /* Check function parameters */
1668   assert_param(IS_CAN_IT(InactiveITs));
1669 
1670   if ((state == HAL_CAN_STATE_READY) ||
1671       (state == HAL_CAN_STATE_LISTENING))
1672   {
1673     /* Disable the selected interrupts */
1674     __HAL_CAN_DISABLE_IT(hcan, InactiveITs);
1675 
1676     /* Return function status */
1677     return HAL_OK;
1678   }
1679   else
1680   {
1681     /* Update error code */
1682     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
1683 
1684     return HAL_ERROR;
1685   }
1686 }
1687 
1688 /**
1689   * @brief  Handles CAN interrupt request
1690   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
1691   *         the configuration information for the specified CAN.
1692   * @retval None
1693   */
HAL_CAN_IRQHandler(CAN_HandleTypeDef * hcan)1694 void HAL_CAN_IRQHandler(CAN_HandleTypeDef *hcan)
1695 {
1696   uint32_t errorcode = HAL_CAN_ERROR_NONE;
1697   uint32_t interrupts = READ_REG(hcan->Instance->IER);
1698   uint32_t msrflags = READ_REG(hcan->Instance->MSR);
1699   uint32_t tsrflags = READ_REG(hcan->Instance->TSR);
1700   uint32_t rf0rflags = READ_REG(hcan->Instance->RF0R);
1701   uint32_t rf1rflags = READ_REG(hcan->Instance->RF1R);
1702   uint32_t esrflags = READ_REG(hcan->Instance->ESR);
1703 
1704   /* Transmit Mailbox empty interrupt management *****************************/
1705   if ((interrupts & CAN_IT_TX_MAILBOX_EMPTY) != 0U)
1706   {
1707     /* Transmit Mailbox 0 management *****************************************/
1708     if ((tsrflags & CAN_TSR_RQCP0) != 0U)
1709     {
1710       /* Clear the Transmission Complete flag (and TXOK0,ALST0,TERR0 bits) */
1711       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP0);
1712 
1713       if ((tsrflags & CAN_TSR_TXOK0) != 0U)
1714       {
1715         /* Transmission Mailbox 0 complete callback */
1716 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1717         /* Call registered callback*/
1718         hcan->TxMailbox0CompleteCallback(hcan);
1719 #else
1720         /* Call weak (surcharged) callback */
1721         HAL_CAN_TxMailbox0CompleteCallback(hcan);
1722 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1723       }
1724       else
1725       {
1726         if ((tsrflags & CAN_TSR_ALST0) != 0U)
1727         {
1728           /* Update error code */
1729           errorcode |= HAL_CAN_ERROR_TX_ALST0;
1730         }
1731         else if ((tsrflags & CAN_TSR_TERR0) != 0U)
1732         {
1733           /* Update error code */
1734           errorcode |= HAL_CAN_ERROR_TX_TERR0;
1735         }
1736         else
1737         {
1738           /* Transmission Mailbox 0 abort callback */
1739 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1740           /* Call registered callback*/
1741           hcan->TxMailbox0AbortCallback(hcan);
1742 #else
1743           /* Call weak (surcharged) callback */
1744           HAL_CAN_TxMailbox0AbortCallback(hcan);
1745 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1746         }
1747       }
1748     }
1749 
1750     /* Transmit Mailbox 1 management *****************************************/
1751     if ((tsrflags & CAN_TSR_RQCP1) != 0U)
1752     {
1753       /* Clear the Transmission Complete flag (and TXOK1,ALST1,TERR1 bits) */
1754       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP1);
1755 
1756       if ((tsrflags & CAN_TSR_TXOK1) != 0U)
1757       {
1758         /* Transmission Mailbox 1 complete callback */
1759 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1760         /* Call registered callback*/
1761         hcan->TxMailbox1CompleteCallback(hcan);
1762 #else
1763         /* Call weak (surcharged) callback */
1764         HAL_CAN_TxMailbox1CompleteCallback(hcan);
1765 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1766       }
1767       else
1768       {
1769         if ((tsrflags & CAN_TSR_ALST1) != 0U)
1770         {
1771           /* Update error code */
1772           errorcode |= HAL_CAN_ERROR_TX_ALST1;
1773         }
1774         else if ((tsrflags & CAN_TSR_TERR1) != 0U)
1775         {
1776           /* Update error code */
1777           errorcode |= HAL_CAN_ERROR_TX_TERR1;
1778         }
1779         else
1780         {
1781           /* Transmission Mailbox 1 abort callback */
1782 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1783           /* Call registered callback*/
1784           hcan->TxMailbox1AbortCallback(hcan);
1785 #else
1786           /* Call weak (surcharged) callback */
1787           HAL_CAN_TxMailbox1AbortCallback(hcan);
1788 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1789         }
1790       }
1791     }
1792 
1793     /* Transmit Mailbox 2 management *****************************************/
1794     if ((tsrflags & CAN_TSR_RQCP2) != 0U)
1795     {
1796       /* Clear the Transmission Complete flag (and TXOK2,ALST2,TERR2 bits) */
1797       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP2);
1798 
1799       if ((tsrflags & CAN_TSR_TXOK2) != 0U)
1800       {
1801         /* Transmission Mailbox 2 complete callback */
1802 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1803         /* Call registered callback*/
1804         hcan->TxMailbox2CompleteCallback(hcan);
1805 #else
1806         /* Call weak (surcharged) callback */
1807         HAL_CAN_TxMailbox2CompleteCallback(hcan);
1808 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1809       }
1810       else
1811       {
1812         if ((tsrflags & CAN_TSR_ALST2) != 0U)
1813         {
1814           /* Update error code */
1815           errorcode |= HAL_CAN_ERROR_TX_ALST2;
1816         }
1817         else if ((tsrflags & CAN_TSR_TERR2) != 0U)
1818         {
1819           /* Update error code */
1820           errorcode |= HAL_CAN_ERROR_TX_TERR2;
1821         }
1822         else
1823         {
1824           /* Transmission Mailbox 2 abort callback */
1825 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1826           /* Call registered callback*/
1827           hcan->TxMailbox2AbortCallback(hcan);
1828 #else
1829           /* Call weak (surcharged) callback */
1830           HAL_CAN_TxMailbox2AbortCallback(hcan);
1831 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1832         }
1833       }
1834     }
1835   }
1836 
1837   /* Receive FIFO 0 overrun interrupt management *****************************/
1838   if ((interrupts & CAN_IT_RX_FIFO0_OVERRUN) != 0U)
1839   {
1840     if ((rf0rflags & CAN_RF0R_FOVR0) != 0U)
1841     {
1842       /* Set CAN error code to Rx Fifo 0 overrun error */
1843       errorcode |= HAL_CAN_ERROR_RX_FOV0;
1844 
1845       /* Clear FIFO0 Overrun Flag */
1846       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV0);
1847     }
1848   }
1849 
1850   /* Receive FIFO 0 full interrupt management ********************************/
1851   if ((interrupts & CAN_IT_RX_FIFO0_FULL) != 0U)
1852   {
1853     if ((rf0rflags & CAN_RF0R_FULL0) != 0U)
1854     {
1855       /* Clear FIFO 0 full Flag */
1856       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF0);
1857 
1858       /* Receive FIFO 0 full Callback */
1859 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1860       /* Call registered callback*/
1861       hcan->RxFifo0FullCallback(hcan);
1862 #else
1863       /* Call weak (surcharged) callback */
1864       HAL_CAN_RxFifo0FullCallback(hcan);
1865 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1866     }
1867   }
1868 
1869   /* Receive FIFO 0 message pending interrupt management *********************/
1870   if ((interrupts & CAN_IT_RX_FIFO0_MSG_PENDING) != 0U)
1871   {
1872     /* Check if message is still pending */
1873     if ((hcan->Instance->RF0R & CAN_RF0R_FMP0) != 0U)
1874     {
1875       /* Receive FIFO 0 message pending Callback */
1876 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1877       /* Call registered callback*/
1878       hcan->RxFifo0MsgPendingCallback(hcan);
1879 #else
1880       /* Call weak (surcharged) callback */
1881       HAL_CAN_RxFifo0MsgPendingCallback(hcan);
1882 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1883     }
1884   }
1885 
1886   /* Receive FIFO 1 overrun interrupt management *****************************/
1887   if ((interrupts & CAN_IT_RX_FIFO1_OVERRUN) != 0U)
1888   {
1889     if ((rf1rflags & CAN_RF1R_FOVR1) != 0U)
1890     {
1891       /* Set CAN error code to Rx Fifo 1 overrun error */
1892       errorcode |= HAL_CAN_ERROR_RX_FOV1;
1893 
1894       /* Clear FIFO1 Overrun Flag */
1895       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV1);
1896     }
1897   }
1898 
1899   /* Receive FIFO 1 full interrupt management ********************************/
1900   if ((interrupts & CAN_IT_RX_FIFO1_FULL) != 0U)
1901   {
1902     if ((rf1rflags & CAN_RF1R_FULL1) != 0U)
1903     {
1904       /* Clear FIFO 1 full Flag */
1905       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF1);
1906 
1907       /* Receive FIFO 1 full Callback */
1908 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1909       /* Call registered callback*/
1910       hcan->RxFifo1FullCallback(hcan);
1911 #else
1912       /* Call weak (surcharged) callback */
1913       HAL_CAN_RxFifo1FullCallback(hcan);
1914 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1915     }
1916   }
1917 
1918   /* Receive FIFO 1 message pending interrupt management *********************/
1919   if ((interrupts & CAN_IT_RX_FIFO1_MSG_PENDING) != 0U)
1920   {
1921     /* Check if message is still pending */
1922     if ((hcan->Instance->RF1R & CAN_RF1R_FMP1) != 0U)
1923     {
1924       /* Receive FIFO 1 message pending Callback */
1925 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1926       /* Call registered callback*/
1927       hcan->RxFifo1MsgPendingCallback(hcan);
1928 #else
1929       /* Call weak (surcharged) callback */
1930       HAL_CAN_RxFifo1MsgPendingCallback(hcan);
1931 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1932     }
1933   }
1934 
1935   /* Sleep interrupt management *********************************************/
1936   if ((interrupts & CAN_IT_SLEEP_ACK) != 0U)
1937   {
1938     if ((msrflags & CAN_MSR_SLAKI) != 0U)
1939     {
1940       /* Clear Sleep interrupt Flag */
1941       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_SLAKI);
1942 
1943       /* Sleep Callback */
1944 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1945       /* Call registered callback*/
1946       hcan->SleepCallback(hcan);
1947 #else
1948       /* Call weak (surcharged) callback */
1949       HAL_CAN_SleepCallback(hcan);
1950 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1951     }
1952   }
1953 
1954   /* WakeUp interrupt management *********************************************/
1955   if ((interrupts & CAN_IT_WAKEUP) != 0U)
1956   {
1957     if ((msrflags & CAN_MSR_WKUI) != 0U)
1958     {
1959       /* Clear WakeUp Flag */
1960       __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_WKU);
1961 
1962       /* WakeUp Callback */
1963 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
1964       /* Call registered callback*/
1965       hcan->WakeUpFromRxMsgCallback(hcan);
1966 #else
1967       /* Call weak (surcharged) callback */
1968       HAL_CAN_WakeUpFromRxMsgCallback(hcan);
1969 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
1970     }
1971   }
1972 
1973   /* Error interrupts management *********************************************/
1974   if ((interrupts & CAN_IT_ERROR) != 0U)
1975   {
1976     if ((msrflags & CAN_MSR_ERRI) != 0U)
1977     {
1978       /* Check Error Warning Flag */
1979       if (((interrupts & CAN_IT_ERROR_WARNING) != 0U) &&
1980           ((esrflags & CAN_ESR_EWGF) != 0U))
1981       {
1982         /* Set CAN error code to Error Warning */
1983         errorcode |= HAL_CAN_ERROR_EWG;
1984 
1985         /* No need for clear of Error Warning Flag as read-only */
1986       }
1987 
1988       /* Check Error Passive Flag */
1989       if (((interrupts & CAN_IT_ERROR_PASSIVE) != 0U) &&
1990           ((esrflags & CAN_ESR_EPVF) != 0U))
1991       {
1992         /* Set CAN error code to Error Passive */
1993         errorcode |= HAL_CAN_ERROR_EPV;
1994 
1995         /* No need for clear of Error Passive Flag as read-only */
1996       }
1997 
1998       /* Check Bus-off Flag */
1999       if (((interrupts & CAN_IT_BUSOFF) != 0U) &&
2000           ((esrflags & CAN_ESR_BOFF) != 0U))
2001       {
2002         /* Set CAN error code to Bus-Off */
2003         errorcode |= HAL_CAN_ERROR_BOF;
2004 
2005         /* No need for clear of Error Bus-Off as read-only */
2006       }
2007 
2008       /* Check Last Error Code Flag */
2009       if (((interrupts & CAN_IT_LAST_ERROR_CODE) != 0U) &&
2010           ((esrflags & CAN_ESR_LEC) != 0U))
2011       {
2012         switch (esrflags & CAN_ESR_LEC)
2013         {
2014           case (CAN_ESR_LEC_0):
2015             /* Set CAN error code to Stuff error */
2016             errorcode |= HAL_CAN_ERROR_STF;
2017             break;
2018           case (CAN_ESR_LEC_1):
2019             /* Set CAN error code to Form error */
2020             errorcode |= HAL_CAN_ERROR_FOR;
2021             break;
2022           case (CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
2023             /* Set CAN error code to Acknowledgement error */
2024             errorcode |= HAL_CAN_ERROR_ACK;
2025             break;
2026           case (CAN_ESR_LEC_2):
2027             /* Set CAN error code to Bit recessive error */
2028             errorcode |= HAL_CAN_ERROR_BR;
2029             break;
2030           case (CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
2031             /* Set CAN error code to Bit Dominant error */
2032             errorcode |= HAL_CAN_ERROR_BD;
2033             break;
2034           case (CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
2035             /* Set CAN error code to CRC error */
2036             errorcode |= HAL_CAN_ERROR_CRC;
2037             break;
2038           default:
2039             break;
2040         }
2041 
2042         /* Clear Last error code Flag */
2043         CLEAR_BIT(hcan->Instance->ESR, CAN_ESR_LEC);
2044       }
2045     }
2046 
2047     /* Clear ERRI Flag */
2048     __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_ERRI);
2049   }
2050 
2051   /* Call the Error call Back in case of Errors */
2052   if (errorcode != HAL_CAN_ERROR_NONE)
2053   {
2054     /* Update error code in handle */
2055     hcan->ErrorCode |= errorcode;
2056 
2057     /* Call Error callback function */
2058 #if USE_HAL_CAN_REGISTER_CALLBACKS == 1
2059     /* Call registered callback*/
2060     hcan->ErrorCallback(hcan);
2061 #else
2062     /* Call weak (surcharged) callback */
2063     HAL_CAN_ErrorCallback(hcan);
2064 #endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
2065   }
2066 }
2067 
2068 /**
2069   * @}
2070   */
2071 
2072 /** @defgroup CAN_Exported_Functions_Group5 Callback functions
2073  *  @brief   CAN Callback functions
2074  *
2075 @verbatim
2076   ==============================================================================
2077                           ##### Callback functions #####
2078   ==============================================================================
2079     [..]
2080     This subsection provides the following callback functions:
2081       (+) HAL_CAN_TxMailbox0CompleteCallback
2082       (+) HAL_CAN_TxMailbox1CompleteCallback
2083       (+) HAL_CAN_TxMailbox2CompleteCallback
2084       (+) HAL_CAN_TxMailbox0AbortCallback
2085       (+) HAL_CAN_TxMailbox1AbortCallback
2086       (+) HAL_CAN_TxMailbox2AbortCallback
2087       (+) HAL_CAN_RxFifo0MsgPendingCallback
2088       (+) HAL_CAN_RxFifo0FullCallback
2089       (+) HAL_CAN_RxFifo1MsgPendingCallback
2090       (+) HAL_CAN_RxFifo1FullCallback
2091       (+) HAL_CAN_SleepCallback
2092       (+) HAL_CAN_WakeUpFromRxMsgCallback
2093       (+) HAL_CAN_ErrorCallback
2094 
2095 @endverbatim
2096   * @{
2097   */
2098 
2099 /**
2100   * @brief  Transmission Mailbox 0 complete callback.
2101   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2102   *         the configuration information for the specified CAN.
2103   * @retval None
2104   */
HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef * hcan)2105 __weak void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan)
2106 {
2107   /* Prevent unused argument(s) compilation warning */
2108   UNUSED(hcan);
2109 
2110   /* NOTE : This function Should not be modified, when the callback is needed,
2111             the HAL_CAN_TxMailbox0CompleteCallback could be implemented in the
2112             user file
2113    */
2114 }
2115 
2116 /**
2117   * @brief  Transmission Mailbox 1 complete callback.
2118   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2119   *         the configuration information for the specified CAN.
2120   * @retval None
2121   */
HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef * hcan)2122 __weak void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan)
2123 {
2124   /* Prevent unused argument(s) compilation warning */
2125   UNUSED(hcan);
2126 
2127   /* NOTE : This function Should not be modified, when the callback is needed,
2128             the HAL_CAN_TxMailbox1CompleteCallback could be implemented in the
2129             user file
2130    */
2131 }
2132 
2133 /**
2134   * @brief  Transmission Mailbox 2 complete callback.
2135   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2136   *         the configuration information for the specified CAN.
2137   * @retval None
2138   */
HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef * hcan)2139 __weak void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan)
2140 {
2141   /* Prevent unused argument(s) compilation warning */
2142   UNUSED(hcan);
2143 
2144   /* NOTE : This function Should not be modified, when the callback is needed,
2145             the HAL_CAN_TxMailbox2CompleteCallback could be implemented in the
2146             user file
2147    */
2148 }
2149 
2150 /**
2151   * @brief  Transmission Mailbox 0 Cancellation callback.
2152   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
2153   *         the configuration information for the specified CAN.
2154   * @retval None
2155   */
HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef * hcan)2156 __weak void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan)
2157 {
2158   /* Prevent unused argument(s) compilation warning */
2159   UNUSED(hcan);
2160 
2161   /* NOTE : This function Should not be modified, when the callback is needed,
2162             the HAL_CAN_TxMailbox0AbortCallback could be implemented in the
2163             user file
2164    */
2165 }
2166 
2167 /**
2168   * @brief  Transmission Mailbox 1 Cancellation callback.
2169   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
2170   *         the configuration information for the specified CAN.
2171   * @retval None
2172   */
HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef * hcan)2173 __weak void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan)
2174 {
2175   /* Prevent unused argument(s) compilation warning */
2176   UNUSED(hcan);
2177 
2178   /* NOTE : This function Should not be modified, when the callback is needed,
2179             the HAL_CAN_TxMailbox1AbortCallback could be implemented in the
2180             user file
2181    */
2182 }
2183 
2184 /**
2185   * @brief  Transmission Mailbox 2 Cancellation callback.
2186   * @param  hcan pointer to an CAN_HandleTypeDef structure that contains
2187   *         the configuration information for the specified CAN.
2188   * @retval None
2189   */
HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef * hcan)2190 __weak void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan)
2191 {
2192   /* Prevent unused argument(s) compilation warning */
2193   UNUSED(hcan);
2194 
2195   /* NOTE : This function Should not be modified, when the callback is needed,
2196             the HAL_CAN_TxMailbox2AbortCallback could be implemented in the
2197             user file
2198    */
2199 }
2200 
2201 /**
2202   * @brief  Rx FIFO 0 message pending callback.
2203   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2204   *         the configuration information for the specified CAN.
2205   * @retval None
2206   */
HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef * hcan)2207 __weak void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
2208 {
2209   /* Prevent unused argument(s) compilation warning */
2210   UNUSED(hcan);
2211 
2212   /* NOTE : This function Should not be modified, when the callback is needed,
2213             the HAL_CAN_RxFifo0MsgPendingCallback could be implemented in the
2214             user file
2215    */
2216 }
2217 
2218 /**
2219   * @brief  Rx FIFO 0 full callback.
2220   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2221   *         the configuration information for the specified CAN.
2222   * @retval None
2223   */
HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef * hcan)2224 __weak void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan)
2225 {
2226   /* Prevent unused argument(s) compilation warning */
2227   UNUSED(hcan);
2228 
2229   /* NOTE : This function Should not be modified, when the callback is needed,
2230             the HAL_CAN_RxFifo0FullCallback could be implemented in the user
2231             file
2232    */
2233 }
2234 
2235 /**
2236   * @brief  Rx FIFO 1 message pending callback.
2237   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2238   *         the configuration information for the specified CAN.
2239   * @retval None
2240   */
HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef * hcan)2241 __weak void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan)
2242 {
2243   /* Prevent unused argument(s) compilation warning */
2244   UNUSED(hcan);
2245 
2246   /* NOTE : This function Should not be modified, when the callback is needed,
2247             the HAL_CAN_RxFifo1MsgPendingCallback could be implemented in the
2248             user file
2249    */
2250 }
2251 
2252 /**
2253   * @brief  Rx FIFO 1 full callback.
2254   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2255   *         the configuration information for the specified CAN.
2256   * @retval None
2257   */
HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef * hcan)2258 __weak void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan)
2259 {
2260   /* Prevent unused argument(s) compilation warning */
2261   UNUSED(hcan);
2262 
2263   /* NOTE : This function Should not be modified, when the callback is needed,
2264             the HAL_CAN_RxFifo1FullCallback could be implemented in the user
2265             file
2266    */
2267 }
2268 
2269 /**
2270   * @brief  Sleep callback.
2271   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2272   *         the configuration information for the specified CAN.
2273   * @retval None
2274   */
HAL_CAN_SleepCallback(CAN_HandleTypeDef * hcan)2275 __weak void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan)
2276 {
2277   /* Prevent unused argument(s) compilation warning */
2278   UNUSED(hcan);
2279 
2280   /* NOTE : This function Should not be modified, when the callback is needed,
2281             the HAL_CAN_SleepCallback could be implemented in the user file
2282    */
2283 }
2284 
2285 /**
2286   * @brief  WakeUp from Rx message callback.
2287   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2288   *         the configuration information for the specified CAN.
2289   * @retval None
2290   */
HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef * hcan)2291 __weak void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan)
2292 {
2293   /* Prevent unused argument(s) compilation warning */
2294   UNUSED(hcan);
2295 
2296   /* NOTE : This function Should not be modified, when the callback is needed,
2297             the HAL_CAN_WakeUpFromRxMsgCallback could be implemented in the
2298             user file
2299    */
2300 }
2301 
2302 /**
2303   * @brief  Error CAN callback.
2304   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2305   *         the configuration information for the specified CAN.
2306   * @retval None
2307   */
HAL_CAN_ErrorCallback(CAN_HandleTypeDef * hcan)2308 __weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
2309 {
2310   /* Prevent unused argument(s) compilation warning */
2311   UNUSED(hcan);
2312 
2313   /* NOTE : This function Should not be modified, when the callback is needed,
2314             the HAL_CAN_ErrorCallback could be implemented in the user file
2315    */
2316 }
2317 
2318 /**
2319   * @}
2320   */
2321 
2322 /** @defgroup CAN_Exported_Functions_Group6 Peripheral State and Error functions
2323  *  @brief   CAN Peripheral State functions
2324  *
2325 @verbatim
2326   ==============================================================================
2327             ##### Peripheral State and Error functions #####
2328   ==============================================================================
2329     [..]
2330     This subsection provides functions allowing to :
2331       (+) HAL_CAN_GetState()  : Return the CAN state.
2332       (+) HAL_CAN_GetError()  : Return the CAN error codes if any.
2333       (+) HAL_CAN_ResetError(): Reset the CAN error codes if any.
2334 
2335 @endverbatim
2336   * @{
2337   */
2338 
2339 /**
2340   * @brief  Return the CAN state.
2341   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2342   *         the configuration information for the specified CAN.
2343   * @retval HAL state
2344   */
HAL_CAN_GetState(const CAN_HandleTypeDef * hcan)2345 HAL_CAN_StateTypeDef HAL_CAN_GetState(const CAN_HandleTypeDef *hcan)
2346 {
2347   HAL_CAN_StateTypeDef state = hcan->State;
2348 
2349   if ((state == HAL_CAN_STATE_READY) ||
2350       (state == HAL_CAN_STATE_LISTENING))
2351   {
2352     /* Check sleep mode acknowledge flag */
2353     if ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U)
2354     {
2355       /* Sleep mode is active */
2356       state = HAL_CAN_STATE_SLEEP_ACTIVE;
2357     }
2358     /* Check sleep mode request flag */
2359     else if ((hcan->Instance->MCR & CAN_MCR_SLEEP) != 0U)
2360     {
2361       /* Sleep mode request is pending */
2362       state = HAL_CAN_STATE_SLEEP_PENDING;
2363     }
2364     else
2365     {
2366       /* Neither sleep mode request nor sleep mode acknowledge */
2367     }
2368   }
2369 
2370   /* Return CAN state */
2371   return state;
2372 }
2373 
2374 /**
2375   * @brief  Return the CAN error code.
2376   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2377   *         the configuration information for the specified CAN.
2378   * @retval CAN Error Code
2379   */
HAL_CAN_GetError(const CAN_HandleTypeDef * hcan)2380 uint32_t HAL_CAN_GetError(const CAN_HandleTypeDef *hcan)
2381 {
2382   /* Return CAN error code */
2383   return hcan->ErrorCode;
2384 }
2385 
2386 /**
2387   * @brief  Reset the CAN error code.
2388   * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
2389   *         the configuration information for the specified CAN.
2390   * @retval HAL status
2391   */
HAL_CAN_ResetError(CAN_HandleTypeDef * hcan)2392 HAL_StatusTypeDef HAL_CAN_ResetError(CAN_HandleTypeDef *hcan)
2393 {
2394   HAL_StatusTypeDef status = HAL_OK;
2395   HAL_CAN_StateTypeDef state = hcan->State;
2396 
2397   if ((state == HAL_CAN_STATE_READY) ||
2398       (state == HAL_CAN_STATE_LISTENING))
2399   {
2400     /* Reset CAN error code */
2401     hcan->ErrorCode = 0U;
2402   }
2403   else
2404   {
2405     /* Update error code */
2406     hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
2407 
2408     status = HAL_ERROR;
2409   }
2410 
2411   /* Return the status */
2412   return status;
2413 }
2414 
2415 /**
2416   * @}
2417   */
2418 
2419 /**
2420   * @}
2421   */
2422 
2423 #endif /* HAL_CAN_MODULE_ENABLED */
2424 
2425 /**
2426   * @}
2427   */
2428 
2429 #endif /* CAN */
2430 
2431 /**
2432   * @}
2433   */
2434