1 /**
2   ******************************************************************************
3   * @file    stm32wbxx_hal_comp.c
4   * @author  MCD Application Team
5   * @brief   COMP HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the COMP peripheral:
8   *           + Initialization and de-initialization functions
9   *           + Peripheral control functions
10   *           + Peripheral state functions
11   *
12   ******************************************************************************
13   * @attention
14   *
15   * Copyright (c) 2019 STMicroelectronics.
16   * All rights reserved.
17   *
18   * This software is licensed under terms that can be found in the LICENSE file
19   * in the root directory of this software component.
20   * If no LICENSE file comes with this software, it is provided AS-IS.
21   *
22   ******************************************************************************
23   @verbatim
24   ==============================================================================
25           ##### COMP Peripheral features #####
26   ==============================================================================
27 
28   [..]
29       The STM32WBxx device family integrates two analog comparators instances:
30       COMP1, COMP2 except for the STM32WB15xx, STM32WB10xx products featuring only
31       one instance: COMP1.
32       In the rest of the file, all comments related to a pair of comparators are not
33       applicable to STM32WB15xx, STM32WB10xx.
34       (#) Comparators input minus (inverting input) and input plus (non inverting input)
35           can be set to internal references or to GPIO pins
36           (refer to GPIO list in reference manual).
37 
38       (#) Comparators output level is available using HAL_COMP_GetOutputLevel()
39           and can be redirected to other peripherals: GPIO pins (in mode
40           alternate functions for comparator), timers.
41           (refer to GPIO list in reference manual).
42 
43       (#) The comparators have interrupt capability through the EXTI controller
44           with wake-up from sleep and stop modes.
45 
46       (#) Pairs of comparators instances can be combined in window mode
47           (2 consecutive instances odd and even COMP<x> and COMP<x+1>).
48 
49           From the corresponding IRQ handler, the right interrupt source can be retrieved
50           using macro __HAL_COMP_COMPx_EXTI_GET_FLAG().
51 
52             ##### How to use this driver #####
53   ==============================================================================
54   [..]
55       This driver provides functions to configure and program the comparator instances
56       of STM32WBxx devices.
57 
58       To use the comparator, perform the following steps:
59 
60       (#)  Initialize the COMP low level resources by implementing the HAL_COMP_MspInit():
61       (++) Configure the GPIO connected to comparator inputs plus and minus in analog mode
62            using HAL_GPIO_Init().
63       (++) If needed, configure the GPIO connected to comparator output in alternate function mode
64            using HAL_GPIO_Init().
65       (++) If required enable the COMP interrupt by configuring and enabling EXTI line in Interrupt mode and
66            selecting the desired sensitivity level using HAL_GPIO_Init() function. After that enable the comparator
67            interrupt vector using HAL_NVIC_EnableIRQ() function.
68 
69       (#) Configure the comparator using HAL_COMP_Init() function:
70       (++) Select the input minus (inverting input)
71       (++) Select the input plus (non-inverting input)
72       (++) Select the hysteresis
73       (++) Select the blanking source
74       (++) Select the output polarity
75       (++) Select the power mode
76       (++) Select the window mode
77 
78       -@@- HAL_COMP_Init() calls internally __HAL_RCC_SYSCFG_CLK_ENABLE()
79           to enable internal control clock of the comparators.
80           However, this is a legacy strategy. In future STM32 families,
81           COMP clock enable must be implemented by user in "HAL_COMP_MspInit()".
82           Therefore, for compatibility anticipation, it is recommended to
83           implement __HAL_RCC_SYSCFG_CLK_ENABLE() in "HAL_COMP_MspInit()".
84 
85       (#) Reconfiguration on-the-fly of comparator can be done by calling again
86           function HAL_COMP_Init() with new input structure parameters values.
87 
88       (#) Enable the comparator using HAL_COMP_Start() function.
89 
90       (#) Use HAL_COMP_TriggerCallback() or HAL_COMP_GetOutputLevel() functions
91           to manage comparator outputs (events and output level).
92 
93       (#) Disable the comparator using HAL_COMP_Stop() function.
94 
95       (#) De-initialize the comparator using HAL_COMP_DeInit() function.
96 
97       (#) For safety purpose, comparator configuration can be locked using HAL_COMP_Lock() function.
98           The only way to unlock the comparator is a device hardware reset.
99 
100     *** Callback registration ***
101     =============================================
102     [..]
103 
104      The compilation flag USE_HAL_COMP_REGISTER_CALLBACKS, when set to 1,
105      allows the user to configure dynamically the driver callbacks.
106      Use Functions HAL_COMP_RegisterCallback()
107      to register an interrupt callback.
108     [..]
109 
110      Function HAL_COMP_RegisterCallback() allows to register following callbacks:
111        (+) TriggerCallback       : callback for COMP trigger.
112        (+) MspInitCallback       : callback for Msp Init.
113        (+) MspDeInitCallback     : callback for Msp DeInit.
114      This function takes as parameters the HAL peripheral handle, the Callback ID
115      and a pointer to the user callback function.
116     [..]
117 
118      Use function HAL_COMP_UnRegisterCallback to reset a callback to the default
119      weak function.
120     [..]
121 
122      HAL_COMP_UnRegisterCallback takes as parameters the HAL peripheral handle,
123      and the Callback ID.
124      This function allows to reset following callbacks:
125        (+) TriggerCallback       : callback for COMP trigger.
126        (+) MspInitCallback       : callback for Msp Init.
127        (+) MspDeInitCallback     : callback for Msp DeInit.
128      [..]
129 
130      By default, after the HAL_COMP_Init() and when the state is HAL_COMP_STATE_RESET
131      all callbacks are set to the corresponding weak functions:
132      example HAL_COMP_TriggerCallback().
133      Exception done for MspInit and MspDeInit functions that are
134      reset to the legacy weak functions in the HAL_COMP_Init()/ HAL_COMP_DeInit() only when
135      these callbacks are null (not registered beforehand).
136     [..]
137 
138      If MspInit or MspDeInit are not null, the HAL_COMP_Init()/ HAL_COMP_DeInit()
139      keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
140      [..]
141 
142      Callbacks can be registered/unregistered in HAL_COMP_STATE_READY state only.
143      Exception done MspInit/MspDeInit functions that can be registered/unregistered
144      in HAL_COMP_STATE_READY or HAL_COMP_STATE_RESET state,
145      thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
146     [..]
147 
148      Then, the user first registers the MspInit/MspDeInit user callbacks
149      using HAL_COMP_RegisterCallback() before calling HAL_COMP_DeInit()
150      or HAL_COMP_Init() function.
151      [..]
152 
153      When the compilation flag USE_HAL_COMP_REGISTER_CALLBACKS is set to 0 or
154      not defined, the callback registration feature is not available and all callbacks
155      are set to the corresponding weak functions.
156 
157   @endverbatim
158   ******************************************************************************
159   */
160 
161 /* Includes ------------------------------------------------------------------*/
162 #include "stm32wbxx_hal.h"
163 
164 /** @addtogroup STM32WBxx_HAL_Driver
165   * @{
166   */
167 
168 #ifdef HAL_COMP_MODULE_ENABLED
169 
170 #if defined (COMP1) || defined (COMP2)
171 
172 /** @defgroup COMP COMP
173   * @brief COMP HAL module driver
174   * @{
175   */
176 
177 /* Private typedef -----------------------------------------------------------*/
178 /* Private define ------------------------------------------------------------*/
179 /** @addtogroup COMP_Private_Constants
180   * @{
181   */
182 
183 /* Delay for COMP startup time.                                               */
184 /* Note: Delay required to reach propagation delay specification.             */
185 /* Literal set to maximum value (refer to device datasheet,                   */
186 /* parameter "tSTART").                                                       */
187 /* Unit: us                                                                   */
188 #define COMP_DELAY_STARTUP_US          (80UL)      /*!< Delay for COMP startup time */
189 
190 /* Delay for COMP voltage scaler stabilization time.                          */
191 /* Literal set to maximum value (refer to device datasheet,                   */
192 /* parameter "tSTART_SCALER").                                                */
193 /* Unit: us                                                                   */
194 #define COMP_DELAY_VOLTAGE_SCALER_STAB_US (200UL)  /*!< Delay for COMP voltage scaler stabilization time */
195 
196 #define COMP_OUTPUT_LEVEL_BITOFFSET_POS    (30UL)
197 
198 /**
199   * @}
200   */
201 
202 /* Private macro -------------------------------------------------------------*/
203 /* Private variables ---------------------------------------------------------*/
204 /* Private function prototypes -----------------------------------------------*/
205 /* Exported functions --------------------------------------------------------*/
206 
207 /** @defgroup COMP_Exported_Functions COMP Exported Functions
208   * @{
209   */
210 
211 /** @defgroup COMP_Exported_Functions_Group1 Initialization/de-initialization functions
212   *  @brief    Initialization and de-initialization functions.
213   *
214 @verbatim
215  ===============================================================================
216               ##### Initialization and de-initialization functions #####
217  ===============================================================================
218     [..]  This section provides functions to initialize and de-initialize comparators
219 
220 @endverbatim
221   * @{
222   */
223 
224 /**
225   * @brief  Initialize the COMP according to the specified
226   *         parameters in the COMP_InitTypeDef and initialize the associated handle.
227   * @note   If the selected comparator is locked, initialization can't be performed.
228   *         To unlock the configuration, perform a system reset.
229   * @param  hcomp  COMP handle
230   * @retval HAL status
231   */
HAL_COMP_Init(COMP_HandleTypeDef * hcomp)232 HAL_StatusTypeDef HAL_COMP_Init(COMP_HandleTypeDef *hcomp)
233 {
234   uint32_t tmp_csr;
235   uint32_t exti_line;
236   uint32_t comp_voltage_scaler_initialized; /* Value "0" if comparator voltage scaler is not initialized */
237   __IO uint32_t wait_loop_index = 0UL;
238   HAL_StatusTypeDef status = HAL_OK;
239 
240   /* Check the COMP handle allocation and lock status */
241   if (hcomp == NULL)
242   {
243     status = HAL_ERROR;
244   }
245   else if (__HAL_COMP_IS_LOCKED(hcomp))
246   {
247     status = HAL_ERROR;
248   }
249   else
250   {
251     /* Check the parameters */
252     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
253     assert_param(IS_COMP_INPUT_PLUS(hcomp->Instance, hcomp->Init.InputPlus));
254     assert_param(IS_COMP_INPUT_MINUS(hcomp->Instance, hcomp->Init.InputMinus));
255     assert_param(IS_COMP_OUTPUTPOL(hcomp->Init.OutputPol));
256     assert_param(IS_COMP_POWERMODE(hcomp->Init.Mode));
257     assert_param(IS_COMP_HYSTERESIS(hcomp->Init.Hysteresis));
258     assert_param(IS_COMP_BLANKINGSRC_INSTANCE(hcomp->Instance, hcomp->Init.BlankingSrce));
259     assert_param(IS_COMP_TRIGGERMODE(hcomp->Init.TriggerMode));
260 
261 #if defined(COMP2)
262     assert_param(IS_COMP_WINDOWMODE(hcomp->Init.WindowMode));
263 #endif
264 
265 
266     if (hcomp->State == HAL_COMP_STATE_RESET)
267     {
268       /* Allocate lock resource and initialize it */
269       hcomp->Lock = HAL_UNLOCKED;
270 
271       /* Set COMP error code to none */
272       COMP_CLEAR_ERRORCODE(hcomp);
273 
274 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
275       /* Init the COMP Callback settings */
276       hcomp->TriggerCallback = HAL_COMP_TriggerCallback; /* Legacy weak callback */
277 
278       if (hcomp->MspInitCallback == NULL)
279       {
280         hcomp->MspInitCallback = HAL_COMP_MspInit; /* Legacy weak MspInit  */
281       }
282 
283       /* Init the low level hardware */
284       /* Note: Internal control clock of the comparators must                 */
285       /*       be enabled in "HAL_COMP_MspInit()"                             */
286       /*       using "__HAL_RCC_SYSCFG_CLK_ENABLE()".                         */
287       hcomp->MspInitCallback(hcomp);
288 #else
289       /* Init the low level hardware */
290       /* Note: Internal control clock of the comparators must                 */
291       /*       be enabled in "HAL_COMP_MspInit()"                             */
292       /*       using "__HAL_RCC_SYSCFG_CLK_ENABLE()".                         */
293       HAL_COMP_MspInit(hcomp);
294 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
295     }
296 
297     /* Memorize voltage scaler state before initialization */
298     comp_voltage_scaler_initialized = READ_BIT(hcomp->Instance->CSR, COMP_CSR_SCALEN);
299 
300     /* Set COMP parameters */
301     tmp_csr = (hcomp->Init.InputMinus
302                | hcomp->Init.InputPlus
303                | hcomp->Init.BlankingSrce
304                | hcomp->Init.Hysteresis
305                | hcomp->Init.OutputPol
306                | hcomp->Init.Mode
307               );
308 
309     /* Set parameters in COMP register */
310     /* Note: Update all bits except read-only, lock and enable bits */
311 #if defined (COMP_CSR_WINMODE)
312     MODIFY_REG(hcomp->Instance->CSR,
313                COMP_CSR_PWRMODE  | COMP_CSR_INMSEL   | COMP_CSR_INPSEL  |
314                COMP_CSR_WINMODE  | COMP_CSR_POLARITY | COMP_CSR_HYST    |
315                COMP_CSR_BLANKING | COMP_CSR_BRGEN    | COMP_CSR_SCALEN  | COMP_CSR_INMESEL,
316                tmp_csr
317               );
318 #else
319     MODIFY_REG(hcomp->Instance->CSR,
320                COMP_CSR_PWRMODE  | COMP_CSR_INMSEL   | COMP_CSR_INPSEL  |
321                COMP_CSR_POLARITY | COMP_CSR_HYST    |
322                COMP_CSR_BLANKING | COMP_CSR_BRGEN    | COMP_CSR_SCALEN  | COMP_CSR_INMESEL,
323                tmp_csr
324               );
325 #endif /* COMP_CSR_WINMODE */
326 
327 
328 #if defined(COMP2)
329     /* Set window mode */
330     /* Note: Window mode bit is located into 1 out of the 2 pairs of COMP     */
331     /*       instances. Therefore, this function can update another COMP      */
332     /*       instance that the one currently selected.                        */
333     if (hcomp->Init.WindowMode == COMP_WINDOWMODE_COMP1_INPUT_PLUS_COMMON)
334     {
335       SET_BIT(COMP12_COMMON->CSR, COMP_CSR_WINMODE);
336     }
337     else
338     {
339       CLEAR_BIT(COMP12_COMMON->CSR, COMP_CSR_WINMODE);
340     }
341 #endif /* COMP2 */
342 
343 
344     /* Delay for COMP scaler bridge voltage stabilization */
345     /* Apply the delay if voltage scaler bridge is required and not already enabled */
346     if ((READ_BIT(hcomp->Instance->CSR, COMP_CSR_SCALEN) != 0UL) &&
347         (comp_voltage_scaler_initialized == 0UL))
348     {
349       /* Wait loop initialization and execution */
350       /* Note: Variable divided by 2 to compensate partially              */
351       /*       CPU processing cycles, scaling in us split to not          */
352       /*       exceed 32 bits register capacity and handle low frequency. */
353       wait_loop_index = ((COMP_DELAY_VOLTAGE_SCALER_STAB_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
354       while (wait_loop_index != 0UL)
355       {
356         wait_loop_index--;
357       }
358     }
359 
360     /* Get the EXTI line corresponding to the selected COMP instance */
361     exti_line = COMP_GET_EXTI_LINE(hcomp->Instance);
362 
363     /* Manage EXTI settings */
364     if ((hcomp->Init.TriggerMode & (COMP_EXTI_IT | COMP_EXTI_EVENT)) != 0UL)
365     {
366       /* Configure EXTI rising edge */
367       if ((hcomp->Init.TriggerMode & COMP_EXTI_RISING) != 0UL)
368       {
369         LL_EXTI_EnableRisingTrig_0_31(exti_line);
370       }
371       else
372       {
373         LL_EXTI_DisableRisingTrig_0_31(exti_line);
374       }
375 
376       /* Configure EXTI falling edge */
377       if ((hcomp->Init.TriggerMode & COMP_EXTI_FALLING) != 0UL)
378       {
379         LL_EXTI_EnableFallingTrig_0_31(exti_line);
380       }
381       else
382       {
383         LL_EXTI_DisableFallingTrig_0_31(exti_line);
384       }
385 
386       /* Clear COMP EXTI pending bit (if any) */
387       LL_EXTI_ClearFlag_0_31(exti_line);
388 
389       /* Configure EXTI event mode */
390       if ((hcomp->Init.TriggerMode & COMP_EXTI_EVENT) != 0UL)
391       {
392         LL_EXTI_EnableEvent_0_31(exti_line);
393       }
394       else
395       {
396         LL_EXTI_DisableEvent_0_31(exti_line);
397       }
398 
399       /* Configure EXTI interrupt mode */
400       if ((hcomp->Init.TriggerMode & COMP_EXTI_IT) != 0UL)
401       {
402         LL_EXTI_EnableIT_0_31(exti_line);
403       }
404       else
405       {
406         LL_EXTI_DisableIT_0_31(exti_line);
407       }
408     }
409     else
410     {
411       /* Disable EXTI event mode */
412       LL_EXTI_DisableEvent_0_31(exti_line);
413 
414       /* Disable EXTI interrupt mode */
415       LL_EXTI_DisableIT_0_31(exti_line);
416     }
417 
418     /* Set HAL COMP handle state */
419     /* Note: Transition from state reset to state ready,                      */
420     /*       otherwise (coming from state ready or busy) no state update.     */
421     if (hcomp->State == HAL_COMP_STATE_RESET)
422     {
423       hcomp->State = HAL_COMP_STATE_READY;
424     }
425   }
426 
427   return status;
428 }
429 
430 /**
431   * @brief  DeInitialize the COMP peripheral.
432   * @note   Deinitialization cannot be performed if the COMP configuration is locked.
433   *         To unlock the configuration, perform a system reset.
434   * @param  hcomp  COMP handle
435   * @retval HAL status
436   */
HAL_COMP_DeInit(COMP_HandleTypeDef * hcomp)437 HAL_StatusTypeDef HAL_COMP_DeInit(COMP_HandleTypeDef *hcomp)
438 {
439   HAL_StatusTypeDef status = HAL_OK;
440 
441   /* Check the COMP handle allocation and lock status */
442   if (hcomp == NULL)
443   {
444     status = HAL_ERROR;
445   }
446   else if (__HAL_COMP_IS_LOCKED(hcomp))
447   {
448     status = HAL_ERROR;
449   }
450   else
451   {
452     /* Check the parameter */
453     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
454 
455     /* Set COMP_CSR register to reset value */
456     WRITE_REG(hcomp->Instance->CSR, 0x00000000UL);
457 
458 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
459     if (hcomp->MspDeInitCallback == NULL)
460     {
461       hcomp->MspDeInitCallback = HAL_COMP_MspDeInit; /* Legacy weak MspDeInit  */
462     }
463 
464     /* DeInit the low level hardware: GPIO, RCC clock, NVIC */
465     hcomp->MspDeInitCallback(hcomp);
466 #else
467     /* DeInit the low level hardware: GPIO, RCC clock, NVIC */
468     HAL_COMP_MspDeInit(hcomp);
469 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
470 
471     /* Set HAL COMP handle state */
472     hcomp->State = HAL_COMP_STATE_RESET;
473 
474     /* Release Lock */
475     __HAL_UNLOCK(hcomp);
476   }
477 
478   return status;
479 }
480 
481 /**
482   * @brief  Initialize the COMP MSP.
483   * @param  hcomp  COMP handle
484   * @retval None
485   */
HAL_COMP_MspInit(COMP_HandleTypeDef * hcomp)486 __weak void HAL_COMP_MspInit(COMP_HandleTypeDef *hcomp)
487 {
488   /* Prevent unused argument(s) compilation warning */
489   UNUSED(hcomp);
490 
491   /* NOTE : This function should not be modified, when the callback is needed,
492             the HAL_COMP_MspInit could be implemented in the user file
493    */
494 }
495 
496 /**
497   * @brief  DeInitialize the COMP MSP.
498   * @param  hcomp  COMP handle
499   * @retval None
500   */
HAL_COMP_MspDeInit(COMP_HandleTypeDef * hcomp)501 __weak void HAL_COMP_MspDeInit(COMP_HandleTypeDef *hcomp)
502 {
503   /* Prevent unused argument(s) compilation warning */
504   UNUSED(hcomp);
505 
506   /* NOTE : This function should not be modified, when the callback is needed,
507             the HAL_COMP_MspDeInit could be implemented in the user file
508    */
509 }
510 
511 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
512 /**
513   * @brief  Register a User COMP Callback
514   *         To be used instead of the weak predefined callback
515   * @param  hcomp Pointer to a COMP_HandleTypeDef structure that contains
516   *                the configuration information for the specified COMP.
517   * @param  CallbackID ID of the callback to be registered
518   *         This parameter can be one of the following values:
519   *          @arg @ref HAL_COMP_TRIGGER_CB_ID Trigger callback ID
520   *          @arg @ref HAL_COMP_MSPINIT_CB_ID MspInit callback ID
521   *          @arg @ref HAL_COMP_MSPDEINIT_CB_ID MspDeInit callback ID
522   * @param  pCallback pointer to the Callback function
523   * @retval HAL status
524   */
HAL_COMP_RegisterCallback(COMP_HandleTypeDef * hcomp,HAL_COMP_CallbackIDTypeDef CallbackID,pCOMP_CallbackTypeDef pCallback)525 HAL_StatusTypeDef HAL_COMP_RegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID,
526                                             pCOMP_CallbackTypeDef pCallback)
527 {
528   HAL_StatusTypeDef status = HAL_OK;
529 
530   if (pCallback == NULL)
531   {
532     /* Update the error code */
533     hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
534 
535     return HAL_ERROR;
536   }
537 
538   if (HAL_COMP_STATE_READY == hcomp->State)
539   {
540     switch (CallbackID)
541     {
542       case HAL_COMP_TRIGGER_CB_ID :
543         hcomp->TriggerCallback = pCallback;
544         break;
545 
546       case HAL_COMP_MSPINIT_CB_ID :
547         hcomp->MspInitCallback = pCallback;
548         break;
549 
550       case HAL_COMP_MSPDEINIT_CB_ID :
551         hcomp->MspDeInitCallback = pCallback;
552         break;
553 
554       default :
555         /* Update the error code */
556         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
557 
558         /* Return error status */
559         status = HAL_ERROR;
560         break;
561     }
562   }
563   else if (HAL_COMP_STATE_RESET == hcomp->State)
564   {
565     switch (CallbackID)
566     {
567       case HAL_COMP_MSPINIT_CB_ID :
568         hcomp->MspInitCallback = pCallback;
569         break;
570 
571       case HAL_COMP_MSPDEINIT_CB_ID :
572         hcomp->MspDeInitCallback = pCallback;
573         break;
574 
575       default :
576         /* Update the error code */
577         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
578 
579         /* Return error status */
580         status = HAL_ERROR;
581         break;
582     }
583   }
584   else
585   {
586     /* Update the error code */
587     hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
588 
589     /* Return error status */
590     status =  HAL_ERROR;
591   }
592 
593   return status;
594 }
595 
596 /**
597   * @brief  Unregister a COMP Callback
598   *         COMP callback is redirected to the weak predefined callback
599   * @param  hcomp Pointer to a COMP_HandleTypeDef structure that contains
600   *                the configuration information for the specified COMP.
601   * @param  CallbackID ID of the callback to be unregistered
602   *         This parameter can be one of the following values:
603   *          @arg @ref HAL_COMP_TRIGGER_CB_ID Trigger callback ID
604   *          @arg @ref HAL_COMP_MSPINIT_CB_ID MspInit callback ID
605   *          @arg @ref HAL_COMP_MSPDEINIT_CB_ID MspDeInit callback ID
606   * @retval HAL status
607   */
HAL_COMP_UnRegisterCallback(COMP_HandleTypeDef * hcomp,HAL_COMP_CallbackIDTypeDef CallbackID)608 HAL_StatusTypeDef HAL_COMP_UnRegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID)
609 {
610   HAL_StatusTypeDef status = HAL_OK;
611 
612   if (HAL_COMP_STATE_READY == hcomp->State)
613   {
614     switch (CallbackID)
615     {
616       case HAL_COMP_TRIGGER_CB_ID :
617         hcomp->TriggerCallback = HAL_COMP_TriggerCallback;         /* Legacy weak callback */
618         break;
619 
620       case HAL_COMP_MSPINIT_CB_ID :
621         hcomp->MspInitCallback = HAL_COMP_MspInit;                 /* Legacy weak MspInit */
622         break;
623 
624       case HAL_COMP_MSPDEINIT_CB_ID :
625         hcomp->MspDeInitCallback = HAL_COMP_MspDeInit;             /* Legacy weak MspDeInit */
626         break;
627 
628       default :
629         /* Update the error code */
630         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
631 
632         /* Return error status */
633         status =  HAL_ERROR;
634         break;
635     }
636   }
637   else if (HAL_COMP_STATE_RESET == hcomp->State)
638   {
639     switch (CallbackID)
640     {
641       case HAL_COMP_MSPINIT_CB_ID :
642         hcomp->MspInitCallback = HAL_COMP_MspInit;                 /* Legacy weak MspInit */
643         break;
644 
645       case HAL_COMP_MSPDEINIT_CB_ID :
646         hcomp->MspDeInitCallback = HAL_COMP_MspDeInit;             /* Legacy weak MspDeInit */
647         break;
648 
649       default :
650         /* Update the error code */
651         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
652 
653         /* Return error status */
654         status =  HAL_ERROR;
655         break;
656     }
657   }
658   else
659   {
660     /* Update the error code */
661     hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
662 
663     /* Return error status */
664     status =  HAL_ERROR;
665   }
666 
667   return status;
668 }
669 
670 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
671 
672 /**
673   * @}
674   */
675 
676 /** @defgroup COMP_Exported_Functions_Group2 Start-Stop operation functions
677   *  @brief   Start-Stop operation functions.
678   *
679 @verbatim
680  ===============================================================================
681                       ##### IO operation functions #####
682  ===============================================================================
683     [..]  This section provides functions allowing to:
684       (+) Start a comparator instance.
685       (+) Stop a comparator instance.
686 
687 @endverbatim
688   * @{
689   */
690 
691 /**
692   * @brief  Start the comparator.
693   * @param  hcomp  COMP handle
694   * @retval HAL status
695   */
HAL_COMP_Start(COMP_HandleTypeDef * hcomp)696 HAL_StatusTypeDef HAL_COMP_Start(COMP_HandleTypeDef *hcomp)
697 {
698   __IO uint32_t wait_loop_index = 0UL;
699   HAL_StatusTypeDef status = HAL_OK;
700 
701   /* Check the COMP handle allocation and lock status */
702   if (hcomp == NULL)
703   {
704     status = HAL_ERROR;
705   }
706   else if (__HAL_COMP_IS_LOCKED(hcomp))
707   {
708     status = HAL_ERROR;
709   }
710   else
711   {
712     /* Check the parameter */
713     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
714 
715     if (hcomp->State == HAL_COMP_STATE_READY)
716     {
717       /* Enable the selected comparator */
718       SET_BIT(hcomp->Instance->CSR, COMP_CSR_EN);
719 
720       /* Set HAL COMP handle state */
721       hcomp->State = HAL_COMP_STATE_BUSY;
722 
723       /* Delay for COMP startup time */
724       /* Wait loop initialization and execution */
725       /* Note: Variable divided by 2 to compensate partially              */
726       /*       CPU processing cycles, scaling in us split to not          */
727       /*       exceed 32 bits register capacity and handle low frequency. */
728       wait_loop_index = ((COMP_DELAY_STARTUP_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
729       while (wait_loop_index != 0UL)
730       {
731         wait_loop_index--;
732       }
733     }
734     else
735     {
736       status = HAL_ERROR;
737     }
738   }
739 
740   return status;
741 }
742 
743 /**
744   * @brief  Stop the comparator.
745   * @param  hcomp  COMP handle
746   * @retval HAL status
747   */
HAL_COMP_Stop(COMP_HandleTypeDef * hcomp)748 HAL_StatusTypeDef HAL_COMP_Stop(COMP_HandleTypeDef *hcomp)
749 {
750   HAL_StatusTypeDef status = HAL_OK;
751 
752   /* Check the COMP handle allocation and lock status */
753   if (hcomp == NULL)
754   {
755     status = HAL_ERROR;
756   }
757   else if (__HAL_COMP_IS_LOCKED(hcomp))
758   {
759     status = HAL_ERROR;
760   }
761   else
762   {
763     /* Check the parameter */
764     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
765 
766     /* Check compliant states: HAL_COMP_STATE_READY or HAL_COMP_STATE_BUSY    */
767     /* (all states except HAL_COMP_STATE_RESET and except locked status.      */
768     if (hcomp->State != HAL_COMP_STATE_RESET)
769     {
770       /* Disable the selected comparator */
771       CLEAR_BIT(hcomp->Instance->CSR, COMP_CSR_EN);
772 
773       /* Set HAL COMP handle state */
774       hcomp->State = HAL_COMP_STATE_READY;
775     }
776     else
777     {
778       status = HAL_ERROR;
779     }
780   }
781 
782   return status;
783 }
784 
785 /**
786   * @brief  Comparator IRQ handler.
787   * @param  hcomp  COMP handle
788   * @retval None
789   */
HAL_COMP_IRQHandler(COMP_HandleTypeDef * hcomp)790 void HAL_COMP_IRQHandler(COMP_HandleTypeDef *hcomp)
791 {
792   /* Get the EXTI line corresponding to the selected COMP instance */
793   uint32_t exti_line = COMP_GET_EXTI_LINE(hcomp->Instance);
794 
795   /* Check COMP EXTI flag */
796   if (LL_EXTI_IsActiveFlag_0_31(exti_line) != 0UL)
797   {
798 #if defined(COMP2)
799     /* Check whether comparator is in independent or window mode */
800     if (READ_BIT(COMP12_COMMON->CSR, COMP_CSR_WINMODE) != 0UL)
801     {
802       /* Clear COMP EXTI line pending bit of the pair of comparators          */
803       /* in window mode.                                                      */
804       /* Note: Pair of comparators in window mode can both trig IRQ when      */
805       /*       input voltage is changing from "out of window" area            */
806       /*       (low or high ) to the other "out of window" area (high or low).*/
807       /*       Both flags must be cleared to call comparator trigger          */
808       /*       callback is called once.                                       */
809       LL_EXTI_ClearFlag_0_31((COMP_EXTI_LINE_COMP1 | COMP_EXTI_LINE_COMP2));
810     }
811     else
812 #endif /* COMP2 */
813     {
814       /* Clear COMP EXTI line pending bit */
815       LL_EXTI_ClearFlag_0_31(exti_line);
816     }
817 
818     /* COMP trigger user callback */
819 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
820     hcomp->TriggerCallback(hcomp);
821 #else
822     HAL_COMP_TriggerCallback(hcomp);
823 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
824   }
825 }
826 
827 /**
828   * @}
829   */
830 
831 /** @defgroup COMP_Exported_Functions_Group3 Peripheral Control functions
832   *  @brief   Management functions.
833   *
834 @verbatim
835  ===============================================================================
836                       ##### Peripheral Control functions #####
837  ===============================================================================
838     [..]
839     This subsection provides a set of functions allowing to control the comparators.
840 
841 @endverbatim
842   * @{
843   */
844 
845 /**
846   * @brief  Lock the selected comparator configuration.
847   * @note   A system reset is required to unlock the comparator configuration.
848   * @note   Locking the comparator from reset state is possible
849   *         if __HAL_RCC_SYSCFG_CLK_ENABLE() is being called before.
850   * @param  hcomp  COMP handle
851   * @retval HAL status
852   */
HAL_COMP_Lock(COMP_HandleTypeDef * hcomp)853 HAL_StatusTypeDef HAL_COMP_Lock(COMP_HandleTypeDef *hcomp)
854 {
855   HAL_StatusTypeDef status = HAL_OK;
856 
857   /* Check the COMP handle allocation and lock status */
858   if (hcomp == NULL)
859   {
860     status = HAL_ERROR;
861   }
862   else if (__HAL_COMP_IS_LOCKED(hcomp))
863   {
864     status = HAL_ERROR;
865   }
866   else
867   {
868     /* Check the parameter */
869     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
870 
871     /* Set HAL COMP handle state */
872     switch (hcomp->State)
873     {
874       case HAL_COMP_STATE_RESET:
875         hcomp->State = HAL_COMP_STATE_RESET_LOCKED;
876         break;
877       case HAL_COMP_STATE_READY:
878         hcomp->State = HAL_COMP_STATE_READY_LOCKED;
879         break;
880       default: /* HAL_COMP_STATE_BUSY */
881         hcomp->State = HAL_COMP_STATE_BUSY_LOCKED;
882         break;
883     }
884 
885     /* Set the lock bit corresponding to selected comparator */
886     __HAL_COMP_LOCK(hcomp);
887   }
888 
889   return status;
890 }
891 
892 /**
893   * @brief  Return the output level (high or low) of the selected comparator.
894   *         The output level depends on the selected polarity.
895   *         If the polarity is not inverted:
896   *           - Comparator output is low when the input plus is at a lower
897   *             voltage than the input minus
898   *           - Comparator output is high when the input plus is at a higher
899   *             voltage than the input minus
900   *         If the polarity is inverted:
901   *           - Comparator output is high when the input plus is at a lower
902   *             voltage than the input minus
903   *           - Comparator output is low when the input plus is at a higher
904   *             voltage than the input minus
905   * @param  hcomp  COMP handle
906   * @retval Returns the selected comparator output level:
907   *         @arg COMP_OUTPUT_LEVEL_LOW
908   *         @arg COMP_OUTPUT_LEVEL_HIGH
909   *
910   */
HAL_COMP_GetOutputLevel(const COMP_HandleTypeDef * hcomp)911 uint32_t HAL_COMP_GetOutputLevel(const COMP_HandleTypeDef *hcomp)
912 {
913   /* Check the parameter */
914   assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
915 
916   return (uint32_t)(READ_BIT(hcomp->Instance->CSR, COMP_CSR_VALUE)
917                     >> COMP_OUTPUT_LEVEL_BITOFFSET_POS);
918 }
919 
920 /**
921   * @brief  Comparator trigger callback.
922   * @param  hcomp  COMP handle
923   * @retval None
924   */
HAL_COMP_TriggerCallback(COMP_HandleTypeDef * hcomp)925 __weak void HAL_COMP_TriggerCallback(COMP_HandleTypeDef *hcomp)
926 {
927   /* Prevent unused argument(s) compilation warning */
928   UNUSED(hcomp);
929 
930   /* NOTE : This function should not be modified, when the callback is needed,
931             the HAL_COMP_TriggerCallback should be implemented in the user file
932    */
933 }
934 
935 
936 /**
937   * @}
938   */
939 
940 /** @defgroup COMP_Exported_Functions_Group4 Peripheral State functions
941   *  @brief   Peripheral State functions.
942   *
943 @verbatim
944  ===============================================================================
945                       ##### Peripheral State functions #####
946  ===============================================================================
947     [..]
948     This subsection permit to get in run-time the status of the peripheral.
949 
950 @endverbatim
951   * @{
952   */
953 
954 /**
955   * @brief  Return the COMP handle state.
956   * @param  hcomp  COMP handle
957   * @retval HAL state
958   */
HAL_COMP_GetState(const COMP_HandleTypeDef * hcomp)959 HAL_COMP_StateTypeDef HAL_COMP_GetState(const COMP_HandleTypeDef *hcomp)
960 {
961   /* Check the COMP handle allocation */
962   if (hcomp == NULL)
963   {
964     return HAL_COMP_STATE_RESET;
965   }
966 
967   /* Check the parameter */
968   assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
969 
970   /* Return HAL COMP handle state */
971   return hcomp->State;
972 }
973 
974 /**
975   * @brief  Return the COMP error code.
976   * @param hcomp COMP handle
977   * @retval COMP error code
978   */
HAL_COMP_GetError(const COMP_HandleTypeDef * hcomp)979 uint32_t HAL_COMP_GetError(const COMP_HandleTypeDef *hcomp)
980 {
981   /* Check the parameters */
982   assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
983 
984   return hcomp->ErrorCode;
985 }
986 
987 /**
988   * @}
989   */
990 
991 /**
992   * @}
993   */
994 
995 /**
996   * @}
997   */
998 
999 #endif /* COMP1 || COMP2 */
1000 
1001 #endif /* HAL_COMP_MODULE_ENABLED */
1002 
1003 /**
1004   * @}
1005   */
1006