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