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