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