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