1 /**
2   ******************************************************************************
3   * @file    stm32l5xx_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 STM32L5xx 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 STM32L5xx 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 /* Includes ------------------------------------------------------------------*/
159 #include "stm32l5xx_hal.h"
160 
161 /** @addtogroup STM32L5xx_HAL_Driver
162   * @{
163   */
164 
165 #ifdef HAL_COMP_MODULE_ENABLED
166 
167 #if defined (COMP1) || defined (COMP2)
168 
169 /** @defgroup COMP COMP
170   * @brief COMP HAL module driver
171   * @{
172   */
173 
174 /* Private typedef -----------------------------------------------------------*/
175 /* Private define ------------------------------------------------------------*/
176 /** @addtogroup COMP_Private_Constants
177   * @{
178   */
179 
180 /* Delay for COMP startup time.                                               */
181 /* Note: Delay required to reach propagation delay specification.             */
182 /* Literal set to maximum value (refer to device datasheet,                   */
183 /* parameter "tSTART").                                                       */
184 /* Unit: us                                                                   */
185 #define COMP_DELAY_STARTUP_US          (80UL)      /*!< Delay for COMP startup time */
186 
187 /* Delay for COMP voltage scaler stabilization time.                          */
188 /* Literal set to maximum value (refer to device datasheet,                   */
189 /* parameter "tSTART_SCALER").                                                */
190 /* Unit: us                                                                   */
191 #define COMP_DELAY_VOLTAGE_SCALER_STAB_US (200UL)  /*!< Delay for COMP voltage scaler stabilization time */
192 
193 #define COMP_OUTPUT_LEVEL_BITOFFSET_POS    (30UL)
194 
195 /**
196   * @}
197   */
198 
199 /* Private macro -------------------------------------------------------------*/
200 /* Private variables ---------------------------------------------------------*/
201 /* Private function prototypes -----------------------------------------------*/
202 /* Exported functions --------------------------------------------------------*/
203 
204 /** @defgroup COMP_Exported_Functions COMP Exported Functions
205   * @{
206   */
207 
208 /** @defgroup COMP_Exported_Functions_Group1 Initialization/de-initialization functions
209   *  @brief    Initialization and de-initialization functions.
210   *
211 @verbatim
212  ===============================================================================
213               ##### Initialization and de-initialization functions #####
214  ===============================================================================
215     [..]  This section provides functions to initialize and de-initialize comparators
216 
217 @endverbatim
218   * @{
219   */
220 
221 /**
222   * @brief  Initialize the COMP according to the specified
223   *         parameters in the COMP_InitTypeDef and initialize the associated handle.
224   * @note   If the selected comparator is locked, initialization can't be performed.
225   *         To unlock the configuration, perform a system reset.
226   * @param  hcomp  COMP handle
227   * @retval HAL status
228   */
HAL_COMP_Init(COMP_HandleTypeDef * hcomp)229 HAL_StatusTypeDef HAL_COMP_Init(COMP_HandleTypeDef *hcomp)
230 {
231   uint32_t tmp_csr;
232   uint32_t exti_line;
233   uint32_t comp_voltage_scaler_initialized; /* Value "0" if comparator voltage scaler is not initialized */
234   __IO uint32_t wait_loop_index = 0UL;
235   HAL_StatusTypeDef status = HAL_OK;
236 
237   /* Check the COMP handle allocation and lock status */
238   if (hcomp == NULL)
239   {
240     status = HAL_ERROR;
241   }
242   else if (__HAL_COMP_IS_LOCKED(hcomp))
243   {
244     status = HAL_ERROR;
245   }
246   else
247   {
248     /* Check the parameters */
249     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
250     assert_param(IS_COMP_INPUT_PLUS(hcomp->Instance, hcomp->Init.InputPlus));
251     assert_param(IS_COMP_INPUT_MINUS(hcomp->Instance, hcomp->Init.InputMinus));
252     assert_param(IS_COMP_OUTPUTPOL(hcomp->Init.OutputPol));
253     assert_param(IS_COMP_POWERMODE(hcomp->Init.Mode));
254     assert_param(IS_COMP_HYSTERESIS(hcomp->Init.Hysteresis));
255     assert_param(IS_COMP_BLANKINGSRC_INSTANCE(hcomp->Instance, hcomp->Init.BlankingSrce));
256     assert_param(IS_COMP_TRIGGERMODE(hcomp->Init.TriggerMode));
257 
258     assert_param(IS_COMP_WINDOWMODE(hcomp->Init.WindowMode));
259 
260 
261     if (hcomp->State == HAL_COMP_STATE_RESET)
262     {
263       /* Allocate lock resource and initialize it */
264       hcomp->Lock = HAL_UNLOCKED;
265 
266       /* Set COMP error code to none */
267       COMP_CLEAR_ERRORCODE(hcomp);
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,
310                tmp_csr
311               );
312 
313 
314     /* Set window mode */
315     /* Note: Window mode bit is located into 1 out of the 2 pairs of COMP     */
316     /*       instances. Therefore, this function can update another COMP      */
317     /*       instance that the one currently selected.                        */
318     if (hcomp->Init.WindowMode == COMP_WINDOWMODE_COMP1_INPUT_PLUS_COMMON)
319     {
320       SET_BIT(COMP12_COMMON->CSR, COMP_CSR_WINMODE);
321     }
322     else
323     {
324       CLEAR_BIT(COMP12_COMMON->CSR, COMP_CSR_WINMODE);
325     }
326 
327 
328     /* Delay for COMP scaler bridge voltage stabilization */
329     /* Apply the delay if voltage scaler bridge is required and not already enabled */
330     if ((READ_BIT(hcomp->Instance->CSR, COMP_CSR_SCALEN) != 0UL) &&
331         (comp_voltage_scaler_initialized == 0UL))
332     {
333       /* Wait loop initialization and execution */
334       /* Note: Variable divided by 2 to compensate partially              */
335       /*       CPU processing cycles, scaling in us split to not          */
336       /*       exceed 32 bits register capacity and handle low frequency. */
337       wait_loop_index = ((COMP_DELAY_VOLTAGE_SCALER_STAB_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
338       while (wait_loop_index != 0UL)
339       {
340         wait_loop_index--;
341       }
342     }
343 
344     /* Get the EXTI line corresponding to the selected COMP instance */
345     exti_line = COMP_GET_EXTI_LINE(hcomp->Instance);
346 
347     /* Manage EXTI settings */
348     if ((hcomp->Init.TriggerMode & (COMP_EXTI_IT | COMP_EXTI_EVENT)) != 0UL)
349     {
350       /* Configure EXTI rising edge */
351       if ((hcomp->Init.TriggerMode & COMP_EXTI_RISING) != 0UL)
352       {
353         LL_EXTI_EnableRisingTrig_0_31(exti_line);
354       }
355       else
356       {
357         LL_EXTI_DisableRisingTrig_0_31(exti_line);
358       }
359 
360       /* Configure EXTI falling edge */
361       if ((hcomp->Init.TriggerMode & COMP_EXTI_FALLING) != 0UL)
362       {
363         LL_EXTI_EnableFallingTrig_0_31(exti_line);
364       }
365       else
366       {
367         LL_EXTI_DisableFallingTrig_0_31(exti_line);
368       }
369 
370       /* Clear COMP EXTI pending bit (if any) */
371       LL_EXTI_ClearRisingFlag_0_31(exti_line);
372       LL_EXTI_ClearFallingFlag_0_31(exti_line);
373 
374       /* Configure EXTI event mode */
375       if ((hcomp->Init.TriggerMode & COMP_EXTI_EVENT) != 0UL)
376       {
377         LL_EXTI_EnableEvent_0_31(exti_line);
378       }
379       else
380       {
381         LL_EXTI_DisableEvent_0_31(exti_line);
382       }
383 
384       /* Configure EXTI interrupt mode */
385       if ((hcomp->Init.TriggerMode & COMP_EXTI_IT) != 0UL)
386       {
387         LL_EXTI_EnableIT_0_31(exti_line);
388       }
389       else
390       {
391         LL_EXTI_DisableIT_0_31(exti_line);
392       }
393     }
394     else
395     {
396       /* Disable EXTI event mode */
397       LL_EXTI_DisableEvent_0_31(exti_line);
398 
399       /* Disable EXTI interrupt mode */
400       LL_EXTI_DisableIT_0_31(exti_line);
401     }
402 
403     /* Set HAL COMP handle state */
404     /* Note: Transition from state reset to state ready,                      */
405     /*       otherwise (coming from state ready or busy) no state update.     */
406     if (hcomp->State == HAL_COMP_STATE_RESET)
407     {
408       hcomp->State = HAL_COMP_STATE_READY;
409     }
410   }
411 
412   return status;
413 }
414 
415 /**
416   * @brief  DeInitialize the COMP peripheral.
417   * @note   Deinitialization cannot be performed if the COMP configuration is locked.
418   *         To unlock the configuration, perform a system reset.
419   * @param  hcomp  COMP handle
420   * @retval HAL status
421   */
HAL_COMP_DeInit(COMP_HandleTypeDef * hcomp)422 HAL_StatusTypeDef HAL_COMP_DeInit(COMP_HandleTypeDef *hcomp)
423 {
424   HAL_StatusTypeDef status = HAL_OK;
425 
426   /* Check the COMP handle allocation and lock status */
427   if (hcomp == NULL)
428   {
429     status = HAL_ERROR;
430   }
431   else if (__HAL_COMP_IS_LOCKED(hcomp))
432   {
433     status = HAL_ERROR;
434   }
435   else
436   {
437     /* Check the parameter */
438     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
439 
440     /* Set COMP_CSR register to reset value */
441     WRITE_REG(hcomp->Instance->CSR, 0x00000000UL);
442 
443 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
444     if (hcomp->MspDeInitCallback == NULL)
445     {
446       hcomp->MspDeInitCallback = HAL_COMP_MspDeInit; /* Legacy weak MspDeInit  */
447     }
448 
449     /* DeInit the low level hardware: GPIO, RCC clock, NVIC */
450     hcomp->MspDeInitCallback(hcomp);
451 #else
452     /* DeInit the low level hardware: GPIO, RCC clock, NVIC */
453     HAL_COMP_MspDeInit(hcomp);
454 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
455 
456     /* Set HAL COMP handle state */
457     hcomp->State = HAL_COMP_STATE_RESET;
458 
459     /* Release Lock */
460     __HAL_UNLOCK(hcomp);
461   }
462 
463   return status;
464 }
465 
466 /**
467   * @brief  Initialize the COMP MSP.
468   * @param  hcomp  COMP handle
469   * @retval None
470   */
HAL_COMP_MspInit(COMP_HandleTypeDef * hcomp)471 __weak void HAL_COMP_MspInit(COMP_HandleTypeDef *hcomp)
472 {
473   /* Prevent unused argument(s) compilation warning */
474   UNUSED(hcomp);
475 
476   /* NOTE : This function should not be modified, when the callback is needed,
477             the HAL_COMP_MspInit could be implemented in the user file
478    */
479 }
480 
481 /**
482   * @brief  DeInitialize the COMP MSP.
483   * @param  hcomp  COMP handle
484   * @retval None
485   */
HAL_COMP_MspDeInit(COMP_HandleTypeDef * hcomp)486 __weak void HAL_COMP_MspDeInit(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_MspDeInit could be implemented in the user file
493    */
494 }
495 
496 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
497 /**
498   * @brief  Register a User COMP Callback
499   *         To be used instead of the weak predefined callback
500   * @param  hcomp Pointer to a COMP_HandleTypeDef structure that contains
501   *                the configuration information for the specified COMP.
502   * @param  CallbackID ID of the callback to be registered
503   *         This parameter can be one of the following values:
504   *          @arg @ref HAL_COMP_TRIGGER_CB_ID Trigger callback ID
505   *          @arg @ref HAL_COMP_MSPINIT_CB_ID MspInit callback ID
506   *          @arg @ref HAL_COMP_MSPDEINIT_CB_ID MspDeInit callback ID
507   * @param  pCallback pointer to the Callback function
508   * @retval HAL status
509   */
HAL_COMP_RegisterCallback(COMP_HandleTypeDef * hcomp,HAL_COMP_CallbackIDTypeDef CallbackID,pCOMP_CallbackTypeDef pCallback)510 HAL_StatusTypeDef HAL_COMP_RegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID,
511                                             pCOMP_CallbackTypeDef pCallback)
512 {
513   HAL_StatusTypeDef status = HAL_OK;
514 
515   if (pCallback == NULL)
516   {
517     /* Update the error code */
518     hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
519 
520     return HAL_ERROR;
521   }
522 
523   if (HAL_COMP_STATE_READY == hcomp->State)
524   {
525     switch (CallbackID)
526     {
527       case HAL_COMP_TRIGGER_CB_ID :
528         hcomp->TriggerCallback = pCallback;
529         break;
530 
531       case HAL_COMP_MSPINIT_CB_ID :
532         hcomp->MspInitCallback = pCallback;
533         break;
534 
535       case HAL_COMP_MSPDEINIT_CB_ID :
536         hcomp->MspDeInitCallback = pCallback;
537         break;
538 
539       default :
540         /* Update the error code */
541         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
542 
543         /* Return error status */
544         status = HAL_ERROR;
545         break;
546     }
547   }
548   else if (HAL_COMP_STATE_RESET == hcomp->State)
549   {
550     switch (CallbackID)
551     {
552       case HAL_COMP_MSPINIT_CB_ID :
553         hcomp->MspInitCallback = pCallback;
554         break;
555 
556       case HAL_COMP_MSPDEINIT_CB_ID :
557         hcomp->MspDeInitCallback = pCallback;
558         break;
559 
560       default :
561         /* Update the error code */
562         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
563 
564         /* Return error status */
565         status = HAL_ERROR;
566         break;
567     }
568   }
569   else
570   {
571     /* Update the error code */
572     hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
573 
574     /* Return error status */
575     status =  HAL_ERROR;
576   }
577 
578   return status;
579 }
580 
581 /**
582   * @brief  Unregister a COMP Callback
583   *         COMP callback is redirected to the weak predefined callback
584   * @param  hcomp Pointer to a COMP_HandleTypeDef structure that contains
585   *                the configuration information for the specified COMP.
586   * @param  CallbackID ID of the callback to be unregistered
587   *         This parameter can be one of the following values:
588   *          @arg @ref HAL_COMP_TRIGGER_CB_ID Trigger callback ID
589   *          @arg @ref HAL_COMP_MSPINIT_CB_ID MspInit callback ID
590   *          @arg @ref HAL_COMP_MSPDEINIT_CB_ID MspDeInit callback ID
591   * @retval HAL status
592   */
HAL_COMP_UnRegisterCallback(COMP_HandleTypeDef * hcomp,HAL_COMP_CallbackIDTypeDef CallbackID)593 HAL_StatusTypeDef HAL_COMP_UnRegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID)
594 {
595   HAL_StatusTypeDef status = HAL_OK;
596 
597   if (HAL_COMP_STATE_READY == hcomp->State)
598   {
599     switch (CallbackID)
600     {
601       case HAL_COMP_TRIGGER_CB_ID :
602         hcomp->TriggerCallback = HAL_COMP_TriggerCallback;         /* Legacy weak callback */
603         break;
604 
605       case HAL_COMP_MSPINIT_CB_ID :
606         hcomp->MspInitCallback = HAL_COMP_MspInit;                 /* Legacy weak MspInit */
607         break;
608 
609       case HAL_COMP_MSPDEINIT_CB_ID :
610         hcomp->MspDeInitCallback = HAL_COMP_MspDeInit;             /* Legacy weak MspDeInit */
611         break;
612 
613       default :
614         /* Update the error code */
615         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
616 
617         /* Return error status */
618         status =  HAL_ERROR;
619         break;
620     }
621   }
622   else if (HAL_COMP_STATE_RESET == hcomp->State)
623   {
624     switch (CallbackID)
625     {
626       case HAL_COMP_MSPINIT_CB_ID :
627         hcomp->MspInitCallback = HAL_COMP_MspInit;                 /* Legacy weak MspInit */
628         break;
629 
630       case HAL_COMP_MSPDEINIT_CB_ID :
631         hcomp->MspDeInitCallback = HAL_COMP_MspDeInit;             /* Legacy weak MspDeInit */
632         break;
633 
634       default :
635         /* Update the error code */
636         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
637 
638         /* Return error status */
639         status =  HAL_ERROR;
640         break;
641     }
642   }
643   else
644   {
645     /* Update the error code */
646     hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
647 
648     /* Return error status */
649     status =  HAL_ERROR;
650   }
651 
652   return status;
653 }
654 
655 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
656 
657 /**
658   * @}
659   */
660 
661 /** @defgroup COMP_Exported_Functions_Group2 Start-Stop operation functions
662   *  @brief   Start-Stop operation functions.
663   *
664 @verbatim
665  ===============================================================================
666                       ##### IO operation functions #####
667  ===============================================================================
668     [..]  This section provides functions allowing to:
669       (+) Start a comparator instance.
670       (+) Stop a comparator instance.
671 
672 @endverbatim
673   * @{
674   */
675 
676 /**
677   * @brief  Start the comparator.
678   * @param  hcomp  COMP handle
679   * @retval HAL status
680   */
HAL_COMP_Start(COMP_HandleTypeDef * hcomp)681 HAL_StatusTypeDef HAL_COMP_Start(COMP_HandleTypeDef *hcomp)
682 {
683   __IO uint32_t wait_loop_index = 0UL;
684   HAL_StatusTypeDef status = HAL_OK;
685 
686   /* Check the COMP handle allocation and lock status */
687   if (hcomp == NULL)
688   {
689     status = HAL_ERROR;
690   }
691   else if (__HAL_COMP_IS_LOCKED(hcomp))
692   {
693     status = HAL_ERROR;
694   }
695   else
696   {
697     /* Check the parameter */
698     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
699 
700     if (hcomp->State == HAL_COMP_STATE_READY)
701     {
702       /* Enable the selected comparator */
703       SET_BIT(hcomp->Instance->CSR, COMP_CSR_EN);
704 
705       /* Set HAL COMP handle state */
706       hcomp->State = HAL_COMP_STATE_BUSY;
707 
708       /* Delay for COMP startup time */
709       /* Wait loop initialization and execution */
710       /* Note: Variable divided by 2 to compensate partially              */
711       /*       CPU processing cycles, scaling in us split to not          */
712       /*       exceed 32 bits register capacity and handle low frequency. */
713       wait_loop_index = ((COMP_DELAY_STARTUP_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
714       while (wait_loop_index != 0UL)
715       {
716         wait_loop_index--;
717       }
718     }
719     else
720     {
721       status = HAL_ERROR;
722     }
723   }
724 
725   return status;
726 }
727 
728 /**
729   * @brief  Stop the comparator.
730   * @param  hcomp  COMP handle
731   * @retval HAL status
732   */
HAL_COMP_Stop(COMP_HandleTypeDef * hcomp)733 HAL_StatusTypeDef HAL_COMP_Stop(COMP_HandleTypeDef *hcomp)
734 {
735   HAL_StatusTypeDef status = HAL_OK;
736 
737   /* Check the COMP handle allocation and lock status */
738   if (hcomp == NULL)
739   {
740     status = HAL_ERROR;
741   }
742   else if (__HAL_COMP_IS_LOCKED(hcomp))
743   {
744     status = HAL_ERROR;
745   }
746   else
747   {
748     /* Check the parameter */
749     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
750 
751     /* Check compliant states: HAL_COMP_STATE_READY or HAL_COMP_STATE_BUSY    */
752     /* (all states except HAL_COMP_STATE_RESET and except locked status.      */
753     if (hcomp->State != HAL_COMP_STATE_RESET)
754     {
755       /* Disable the selected comparator */
756       CLEAR_BIT(hcomp->Instance->CSR, COMP_CSR_EN);
757 
758       /* Set HAL COMP handle state */
759       hcomp->State = HAL_COMP_STATE_READY;
760     }
761     else
762     {
763       status = HAL_ERROR;
764     }
765   }
766 
767   return status;
768 }
769 
770 /**
771   * @brief  Comparator IRQ handler.
772   * @param  hcomp  COMP handle
773   * @retval None
774   */
HAL_COMP_IRQHandler(COMP_HandleTypeDef * hcomp)775 void HAL_COMP_IRQHandler(COMP_HandleTypeDef *hcomp)
776 {
777   /* Get the EXTI line corresponding to the selected COMP instance */
778   uint32_t exti_line = COMP_GET_EXTI_LINE(hcomp->Instance);
779 
780   /* Check COMP EXTI flag */
781   if (LL_EXTI_IsActiveRisingFlag_0_31(exti_line) != 0UL)
782   {
783     /* Check whether comparator is in independent or window mode */
784     if (READ_BIT(COMP12_COMMON->CSR, COMP_CSR_WINMODE) != 0UL)
785     {
786       /* Clear COMP EXTI line pending bit of the pair of comparators          */
787       /* in window mode.                                                      */
788       /* Note: Pair of comparators in window mode can both trig IRQ when      */
789       /*       input voltage is changing from "out of window" area            */
790       /*       (low or high ) to the other "out of window" area (high or low).*/
791       /*       Both flags must be cleared to call comparator trigger          */
792       /*       callback is called once.                                       */
793       LL_EXTI_ClearRisingFlag_0_31((COMP_EXTI_LINE_COMP1 | COMP_EXTI_LINE_COMP2));
794     }
795     else
796     {
797       /* Clear COMP EXTI line pending bit */
798       LL_EXTI_ClearRisingFlag_0_31(exti_line);
799     }
800 
801     /* COMP trigger user callback */
802 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
803     hcomp->TriggerCallback(hcomp);
804 #else
805     HAL_COMP_TriggerCallback(hcomp);
806 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
807   }
808   else if (LL_EXTI_IsActiveFallingFlag_0_31(exti_line) != 0UL)
809   {
810     /* Check whether comparator is in independent or window mode */
811     if (READ_BIT(COMP12_COMMON->CSR, COMP_CSR_WINMODE) != 0UL)
812     {
813       /* Clear COMP EXTI line pending bit of the pair of comparators          */
814       /* in window mode.                                                      */
815       /* Note: Pair of comparators in window mode can both trig IRQ when      */
816       /*       input voltage is changing from "out of window" area            */
817       /*       (low or high ) to the other "out of window" area (high or low).*/
818       /*       Both flags must be cleared to call comparator trigger          */
819       /*       callback is called once.                                       */
820       LL_EXTI_ClearFallingFlag_0_31((COMP_EXTI_LINE_COMP1 | COMP_EXTI_LINE_COMP2));
821     }
822     else
823     {
824       /* Clear COMP EXTI line pending bit */
825       LL_EXTI_ClearFallingFlag_0_31(exti_line);
826     }
827 
828     /* COMP trigger callback */
829 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
830     hcomp->TriggerCallback(hcomp);
831 #else
832     HAL_COMP_TriggerCallback(hcomp);
833 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
834   }
835   else
836   {
837     /* nothing to do */
838   }
839 }
840 
841 /**
842   * @}
843   */
844 
845 /** @defgroup COMP_Exported_Functions_Group3 Peripheral Control functions
846   *  @brief   Management functions.
847   *
848 @verbatim
849  ===============================================================================
850                       ##### Peripheral Control functions #####
851  ===============================================================================
852     [..]
853     This subsection provides a set of functions allowing to control the comparators.
854 
855 @endverbatim
856   * @{
857   */
858 
859 /**
860   * @brief  Lock the selected comparator configuration.
861   * @note   A system reset is required to unlock the comparator configuration.
862   * @note   Locking the comparator from reset state is possible
863   *         if __HAL_RCC_SYSCFG_CLK_ENABLE() is being called before.
864   * @param  hcomp  COMP handle
865   * @retval HAL status
866   */
HAL_COMP_Lock(COMP_HandleTypeDef * hcomp)867 HAL_StatusTypeDef HAL_COMP_Lock(COMP_HandleTypeDef *hcomp)
868 {
869   HAL_StatusTypeDef status = HAL_OK;
870 
871   /* Check the COMP handle allocation and lock status */
872   if (hcomp == NULL)
873   {
874     status = HAL_ERROR;
875   }
876   else if (__HAL_COMP_IS_LOCKED(hcomp))
877   {
878     status = HAL_ERROR;
879   }
880   else
881   {
882     /* Check the parameter */
883     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
884 
885     /* Set HAL COMP handle state */
886     switch (hcomp->State)
887     {
888       case HAL_COMP_STATE_RESET:
889         hcomp->State = HAL_COMP_STATE_RESET_LOCKED;
890         break;
891       case HAL_COMP_STATE_READY:
892         hcomp->State = HAL_COMP_STATE_READY_LOCKED;
893         break;
894       default: /* HAL_COMP_STATE_BUSY */
895         hcomp->State = HAL_COMP_STATE_BUSY_LOCKED;
896         break;
897     }
898 
899     /* Set the lock bit corresponding to selected comparator */
900     __HAL_COMP_LOCK(hcomp);
901   }
902 
903   return status;
904 }
905 
906 /**
907   * @brief  Return the output level (high or low) of the selected comparator.
908   *         The output level depends on the selected polarity.
909   *         If the polarity is not inverted:
910   *           - Comparator output is low when the input plus is at a lower
911   *             voltage than the input minus
912   *           - Comparator output is high when the input plus is at a higher
913   *             voltage than the input minus
914   *         If the polarity is inverted:
915   *           - Comparator output is high when the input plus is at a lower
916   *             voltage than the input minus
917   *           - Comparator output is low when the input plus is at a higher
918   *             voltage than the input minus
919   * @param  hcomp  COMP handle
920   * @retval Returns the selected comparator output level:
921   *         @arg COMP_OUTPUT_LEVEL_LOW
922   *         @arg COMP_OUTPUT_LEVEL_HIGH
923   *
924   */
HAL_COMP_GetOutputLevel(const COMP_HandleTypeDef * hcomp)925 uint32_t HAL_COMP_GetOutputLevel(const COMP_HandleTypeDef *hcomp)
926 {
927   /* Check the parameter */
928   assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
929 
930   return (uint32_t)(READ_BIT(hcomp->Instance->CSR, COMP_CSR_VALUE)
931                     >> COMP_OUTPUT_LEVEL_BITOFFSET_POS);
932 }
933 
934 /**
935   * @brief  Comparator trigger callback.
936   * @param  hcomp  COMP handle
937   * @retval None
938   */
HAL_COMP_TriggerCallback(COMP_HandleTypeDef * hcomp)939 __weak void HAL_COMP_TriggerCallback(COMP_HandleTypeDef *hcomp)
940 {
941   /* Prevent unused argument(s) compilation warning */
942   UNUSED(hcomp);
943 
944   /* NOTE : This function should not be modified, when the callback is needed,
945             the HAL_COMP_TriggerCallback should be implemented in the user file
946    */
947 }
948 
949 
950 /**
951   * @}
952   */
953 
954 /** @defgroup COMP_Exported_Functions_Group4 Peripheral State functions
955   *  @brief   Peripheral State functions.
956   *
957 @verbatim
958  ===============================================================================
959                       ##### Peripheral State functions #####
960  ===============================================================================
961     [..]
962     This subsection permit to get in run-time the status of the peripheral.
963 
964 @endverbatim
965   * @{
966   */
967 
968 /**
969   * @brief  Return the COMP handle state.
970   * @param  hcomp  COMP handle
971   * @retval HAL state
972   */
HAL_COMP_GetState(const COMP_HandleTypeDef * hcomp)973 HAL_COMP_StateTypeDef HAL_COMP_GetState(const COMP_HandleTypeDef *hcomp)
974 {
975   /* Check the COMP handle allocation */
976   if (hcomp == NULL)
977   {
978     return HAL_COMP_STATE_RESET;
979   }
980 
981   /* Check the parameter */
982   assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
983 
984   /* Return HAL COMP handle state */
985   return hcomp->State;
986 }
987 
988 /**
989   * @brief  Return the COMP error code.
990   * @param hcomp COMP handle
991   * @retval COMP error code
992   */
HAL_COMP_GetError(const COMP_HandleTypeDef * hcomp)993 uint32_t HAL_COMP_GetError(const COMP_HandleTypeDef *hcomp)
994 {
995   /* Check the parameters */
996   assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
997 
998   return hcomp->ErrorCode;
999 }
1000 
1001 /**
1002   * @}
1003   */
1004 
1005 /**
1006   * @}
1007   */
1008 
1009 /**
1010   * @}
1011   */
1012 
1013 #endif /* COMP1 || COMP2 */
1014 
1015 #endif /* HAL_COMP_MODULE_ENABLED */
1016 
1017 /**
1018   * @}
1019   */
1020