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