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