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