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