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