1 /**
2   ******************************************************************************
3   * @file    stm32l0xx_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) 2016 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 STM32L0xx device family integrates two analog comparators instances
30       COMP1 and COMP2:
31       (#) The COMP 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       (#) The COMP 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       (#) Pairs of comparators instances can be combined in window mode
41           (2 consecutive instances odd and even COMP<x> and COMP<x+1>).
42 
43       (#) The comparators have interrupt capability through the EXTI controller
44           with wake-up from sleep and stop modes:
45           (++) COMP1 is internally connected to EXTI Line 21
46           (++) COMP2 is internally connected to EXTI Line 22
47 
48           From the corresponding IRQ handler, the right interrupt source can be retrieved
49           using macro __HAL_COMP_COMP1_EXTI_GET_FLAG() and __HAL_COMP_COMP2_EXTI_GET_FLAG().
50 
51             ##### How to use this driver #####
52 ================================================================================
53   [..]
54       This driver provides functions to configure and program the comparator instances
55       of STM32L0xx devices.
56 
57       To use the comparator, perform the following steps:
58 
59       (#)  Initialize the COMP low level resources by implementing the HAL_COMP_MspInit():
60       (++) Configure the GPIO connected to comparator inputs plus and minus in analog mode
61            using HAL_GPIO_Init().
62       (++) If needed, configure the GPIO connected to comparator output in alternate function mode
63            using HAL_GPIO_Init().
64       (++) If required enable the COMP interrupt by configuring and enabling EXTI line in Interrupt mode and
65            selecting the desired sensitivity level using HAL_GPIO_Init() function. After that enable the comparator
66            interrupt vector using HAL_NVIC_EnableIRQ() function.
67 
68       (#) Configure the comparator using HAL_COMP_Init() function:
69       (++) Select the input minus (inverting input)
70       (++) Select the input plus (non-inverting input)
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   Table 1. COMP inputs and output for STM32L0xx devices
158   +---------------------------------------------------------+
159   |                |                |   COMP1   |   COMP2   |
160   |----------------|----------------|-----------|-----------|
161   |                | IO1            |    PA1    |    PA3    |
162   | Input plus     | IO2            |    ---    |    PA4    |
163   |                | IO3            |    ---    |    PB5    |
164   |                | IO4            |    ---    |    PB6    |
165   |                | IO5            |    ---    |    PB7    |
166   |----------------|----------------|-----------------------|
167   |                | 1/4 VrefInt    |    ---    | Available |
168   |                | 1/2 VrefInt    |    ---    | Available |
169   |                | 3/4 VrefInt    |    ---    | Available |
170   | Input minus    | VrefInt        | Available | Available |
171   |                | DAC1 channel 1 | Available | Available |
172   |                | DAC1 channel 2 | Available | Available |
173   |                | IO1            |    PA0    |    PA2    |
174   |                | IO2            |    PA5    |    PA5    |
175   |                | IO3            |    ---    |    PB3    |
176   +---------------------------------------------------------+
177   | Output         |                |  PA0  (1) |  PA2  (1) |
178   |                |                |  PA6  (1) |  PA7  (1) |
179   |                |                |  PA11 (1) |  PA12 (1) |
180   |                |                |  LPTIM    |  LPTIM    |
181   |                |                |  TIM  (2) |  TIM  (2) |
182   +-----------------------------------------------------------+
183   (1) GPIO must be set to alternate function for comparator
184   (2) Comparators output to timers is set in timers instances.
185 
186   ******************************************************************************
187   */
188 
189 #if !defined (STM32L010xB) && !defined (STM32L010x8) && !defined (STM32L010x6) && !defined (STM32L010x4)
190 /* Includes ------------------------------------------------------------------*/
191 #include "stm32l0xx_hal.h"
192 
193 /** @addtogroup STM32L0xx_HAL_Driver
194   * @{
195   */
196 
197 /** @defgroup COMP COMP
198   * @brief COMP HAL module driver
199   * @{
200   */
201 
202 #ifdef HAL_COMP_MODULE_ENABLED
203 
204 /* Private typedef -----------------------------------------------------------*/
205 /* Private define ------------------------------------------------------------*/
206 /** @addtogroup COMP_Private_Constants
207   * @{
208   */
209 
210 /* Delay for COMP startup time.                                               */
211 /* Note: Delay required to reach propagation delay specification.             */
212 /* Literal set to maximum value (refer to device datasheet,                   */
213 /* parameter "tSTART").                                                       */
214 /* Unit: us                                                                   */
215 #define COMP_DELAY_STARTUP_US             (25U)  /*!< Delay for COMP startup time */
216 
217 /* Delay for COMP voltage scaler stabilization time (voltage from VrefInt,    */
218 /* delay based on VrefInt startup time).                                      */
219 /* Literal set to maximum value (refer to device datasheet,                   */
220 /* parameter "TVREFINT").                                                     */
221 /* Unit: us                                                                   */
222 #define COMP_DELAY_VOLTAGE_SCALER_STAB_US (3000U)  /*!< Delay for COMP voltage scaler stabilization time */
223 
224 #define COMP_OUTPUT_LEVEL_BITOFFSET_POS  (30U)
225 
226 #define C_REV_ID_A              0x1000U /* Cut1.0 */
227 #define C_REV_ID_Z              0x1008U /* Cut1.1 */
228 #define C_REV_ID_Y              0x1003U /* Cut1.2 */
229 
230 #define C_DEV_ID_L073           0x447U
231 #define C_DEV_ID_L053           0x417U
232 
233 /**
234   * @}
235   */
236 
237 /* Private macro -------------------------------------------------------------*/
238 /* Private variables ---------------------------------------------------------*/
239 /* Private function prototypes -----------------------------------------------*/
240 /* Exported functions --------------------------------------------------------*/
241 
242 /** @defgroup COMP_Exported_Functions COMP Exported Functions
243   * @{
244   */
245 
246 /** @defgroup COMP_Exported_Functions_Group1 Initialization/de-initialization functions
247  *  @brief    Initialization and de-initialization functions.
248  *
249 @verbatim
250  ===============================================================================
251               ##### Initialization and de-initialization functions #####
252  ===============================================================================
253     [..]  This section provides functions to initialize and de-initialize comparators
254 
255 @endverbatim
256   * @{
257   */
258 
259 /**
260   * @brief  Initialize the COMP according to the specified
261   *         parameters in the COMP_InitTypeDef and initialize the associated handle.
262   * @note   If the selected comparator is locked, initialization can't be performed.
263   *         To unlock the configuration, perform a system reset.
264   * @note   When the LPTIM connection is enabled, the following pins LPTIM_IN1(PB5, PC0)
265             and LPTIM_IN2(PB7, PC2) should not be configured in alternate function.
266   * @param  hcomp  COMP handle
267   * @retval HAL status
268   */
HAL_COMP_Init(COMP_HandleTypeDef * hcomp)269 HAL_StatusTypeDef HAL_COMP_Init(COMP_HandleTypeDef *hcomp)
270 {
271   uint32_t tmp_csr = 0U;
272   uint32_t exti_line = 0U;
273   uint32_t comp_voltage_scaler_not_initialized = 0U;
274   __IO uint32_t wait_loop_index = 0U;
275   HAL_StatusTypeDef status = HAL_OK;
276 
277   /* Check the COMP handle allocation and lock status */
278   if((hcomp == NULL) || (__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_TRIGGERMODE(hcomp->Init.TriggerMode));
291     assert_param(IS_COMP_WINDOWMODE(hcomp->Init.WindowMode));
292 
293     if(hcomp->State == HAL_COMP_STATE_RESET)
294     {
295       /* Allocate lock resource and initialize it */
296       hcomp->Lock = HAL_UNLOCKED;
297 
298       /* Init SYSCFG and the low level hardware to access comparators */
299       /* Note: HAL_COMP_Init() calls __HAL_RCC_SYSCFG_CLK_ENABLE()            */
300       /*       to enable internal control clock of the comparators.           */
301       /*       However, this is a legacy strategy. In future STM32 families,  */
302       /*       COMP clock enable must be implemented by user                  */
303       /*       in "HAL_COMP_MspInit()".                                       */
304       /*       Therefore, for compatibility anticipation, it is recommended   */
305       /*       to implement __HAL_RCC_SYSCFG_CLK_ENABLE()                     */
306       /*       in "HAL_COMP_MspInit()".                                       */
307       __HAL_RCC_SYSCFG_CLK_ENABLE();
308 
309 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
310       /* Init the COMP Callback settings */
311       hcomp->TriggerCallback = HAL_COMP_TriggerCallback; /* Legacy weak callback */
312 
313       if (hcomp->MspInitCallback == NULL)
314       {
315         hcomp->MspInitCallback = HAL_COMP_MspInit; /* Legacy weak MspInit  */
316       }
317 
318       /* Init the low level hardware */
319       hcomp->MspInitCallback(hcomp);
320 #else
321       /* Init the low level hardware */
322       HAL_COMP_MspInit(hcomp);
323 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
324     }
325 
326     /* Set COMP parameters */
327     tmp_csr = (hcomp->Init.InvertingInput   |
328                hcomp->Init.OutputPol         );
329 
330     /* Configuration specific to comparator instance: COMP2 */
331     if ((hcomp->Instance) == COMP2)
332     {
333       /* Comparator input plus configuration is available on COMP2 only */
334       /* Comparator power mode configuration is available on COMP2 only */
335       tmp_csr |= (hcomp->Init.NonInvertingInput |
336                   hcomp->Init.Mode               );
337 
338       /* COMP2 specificity: when using VrefInt or subdivision of VrefInt,     */
339       /* specific path must be enabled.                                       */
340       if((hcomp->Init.InvertingInput == COMP_INPUT_MINUS_VREFINT)    ||
341          (hcomp->Init.InvertingInput == COMP_INPUT_MINUS_1_4VREFINT) ||
342          (hcomp->Init.InvertingInput == COMP_INPUT_MINUS_1_2VREFINT) ||
343          (hcomp->Init.InvertingInput == COMP_INPUT_MINUS_3_4VREFINT)   )
344       {
345         /* Memorize voltage scaler state before initialization */
346         comp_voltage_scaler_not_initialized = (READ_BIT(SYSCFG->CFGR3, SYSCFG_CFGR3_ENBUFLP_VREFINT_COMP) == 0U);
347 
348         SET_BIT(SYSCFG->CFGR3, SYSCFG_CFGR3_EN_VREFINT           |
349                                SYSCFG_CFGR3_ENBUFLP_VREFINT_COMP  );
350 
351         /* Delay for COMP scaler bridge voltage stabilization */
352         /* Apply the delay if voltage scaler bridge is enabled for the first time */
353         if (comp_voltage_scaler_not_initialized != 0U)
354         {
355           /* Wait loop initialization and execution */
356           /* Note: Variable divided by 2 to compensate partially              */
357           /*       CPU processing cycles.                                     */
358           wait_loop_index = (COMP_DELAY_VOLTAGE_SCALER_STAB_US * (SystemCoreClock / (1000000U * 2U)));
359           while(wait_loop_index != 0U)
360           {
361             wait_loop_index--;
362           }
363         }
364       }
365     }
366 
367     /* Set comparator output connection to LPTIM */
368     if (hcomp->Init.LPTIMConnection != COMP_LPTIMCONNECTION_DISABLED)
369     {
370       /* LPTIM connection requested on COMP1 */
371       if ((hcomp->Instance) == COMP1)
372       {
373         /* Note : COMP1 can be connected to the input 1 of LPTIM if requested */
374         assert_param(IS_COMP1_LPTIMCONNECTION(hcomp->Init.LPTIMConnection));
375 
376         /* Note: Compatibility with previous driver version using             */
377         /* generic literal COMP_LPTIMCONNECTION_ENABLED corresponding         */
378         /* to LPTIM input 1 for COMP1.                                        */
379           tmp_csr |= (COMP_CSR_COMP1LPTIM1IN1);
380         }
381       else
382       {
383         /* Note : COMP2 can be connected to input 1 or input 2 of LPTIM if requested */
384         assert_param(IS_COMP2_LPTIMCONNECTION(hcomp->Init.LPTIMConnection));
385 
386         switch (hcomp->Init.LPTIMConnection)
387         {
388         case  COMP_LPTIMCONNECTION_IN1_ENABLED :
389           tmp_csr |= (COMP_CSR_COMP2LPTIM1IN1);
390           break;
391         case  COMP_LPTIMCONNECTION_IN2_ENABLED :
392         default :
393           /* Note: Default case for compatibility with previous driver version*/
394           /* using generic literal COMP_LPTIMCONNECTION_ENABLED corresponding */
395           /* to LPTIM input 2 for COMP2.                                      */
396 
397           /* Check the MCU_ID in order to allow or not the COMP2 connection to LPTIM input 2 */
398           if (((HAL_GetDEVID() == C_DEV_ID_L073) && (HAL_GetREVID() == C_REV_ID_A))
399                             ||
400               ((HAL_GetDEVID() == C_DEV_ID_L053) && (HAL_GetREVID() == C_REV_ID_A))
401                             ||
402               ((HAL_GetDEVID() == C_DEV_ID_L053) && (HAL_GetREVID() == C_REV_ID_Z)))
403           {
404             assert_param(IS_COMP2_LPTIMCONNECTION_RESTRICTED(hcomp->Init.LPTIMConnection));
405 
406             /* Error: On the selected device, COMP2 cannot be connected to LPTIM input 2 */
407             status = HAL_ERROR;
408           }
409           else
410           {
411             tmp_csr |= (COMP_CSR_COMP2LPTIM1IN2);
412           }
413           break;
414         }
415       }
416     }
417 
418     /* Update comparator register */
419     if ((hcomp->Instance) == COMP1)
420     {
421       MODIFY_REG(hcomp->Instance->CSR,
422                  COMP_CSR_COMP1INNSEL     | COMP_CSR_COMP1WM       |
423                  COMP_CSR_COMP1LPTIM1IN1  | COMP_CSR_COMP1POLARITY  ,
424                  tmp_csr
425                 );
426     }
427     else /* Instance == COMP2 */
428     {
429       MODIFY_REG(hcomp->Instance->CSR,
430                  COMP_CSR_COMP2SPEED     | COMP_CSR_COMP2INNSEL    |
431                  COMP_CSR_COMP2INPSEL    | COMP_CSR_COMP2POLARITY  |
432                  COMP_CSR_COMP2LPTIM1IN2 | COMP_CSR_COMP2LPTIM1IN1  ,
433                  tmp_csr
434                 );
435     }
436 
437     /* Set window mode */
438     /* Note: Window mode bit is located into 1 out of the 2 pairs of COMP     */
439     /*       instances. Therefore, this function can update another COMP      */
440     /*       instance that the one currently selected.                        */
441     if(hcomp->Init.WindowMode == COMP_WINDOWMODE_COMP1_INPUT_PLUS_COMMON)
442     {
443       SET_BIT(COMP12_COMMON->CSR, COMP_CSR_WINMODE);
444     }
445     else
446     {
447       CLEAR_BIT(COMP12_COMMON->CSR, COMP_CSR_WINMODE);
448     }
449 
450     /* Get the EXTI line corresponding to the selected COMP instance */
451     exti_line = COMP_GET_EXTI_LINE(hcomp->Instance);
452 
453     /* Manage EXTI settings */
454     if((hcomp->Init.TriggerMode & (COMP_EXTI_IT | COMP_EXTI_EVENT)) != RESET)
455     {
456       /* Configure EXTI rising edge */
457       if((hcomp->Init.TriggerMode & COMP_EXTI_RISING) != RESET)
458       {
459         SET_BIT(EXTI->RTSR, exti_line);
460       }
461       else
462       {
463         CLEAR_BIT(EXTI->RTSR, exti_line);
464       }
465 
466       /* Configure EXTI falling edge */
467       if((hcomp->Init.TriggerMode & COMP_EXTI_FALLING) != RESET)
468       {
469         SET_BIT(EXTI->FTSR, exti_line);
470       }
471       else
472       {
473         CLEAR_BIT(EXTI->FTSR, exti_line);
474       }
475 
476       /* Clear COMP EXTI pending bit (if any) */
477       WRITE_REG(EXTI->PR, exti_line);
478 
479       /* Configure EXTI event mode */
480       if((hcomp->Init.TriggerMode & COMP_EXTI_EVENT) != RESET)
481       {
482         SET_BIT(EXTI->EMR, exti_line);
483       }
484       else
485       {
486         CLEAR_BIT(EXTI->EMR, exti_line);
487       }
488 
489       /* Configure EXTI interrupt mode */
490       if((hcomp->Init.TriggerMode & COMP_EXTI_IT) != RESET)
491       {
492         SET_BIT(EXTI->IMR, exti_line);
493       }
494       else
495       {
496         CLEAR_BIT(EXTI->IMR, exti_line);
497       }
498     }
499     else
500     {
501       /* Disable EXTI event mode */
502       CLEAR_BIT(EXTI->EMR, exti_line);
503 
504       /* Disable EXTI interrupt mode */
505       CLEAR_BIT(EXTI->IMR, exti_line);
506     }
507 
508     /* Set HAL COMP handle state */
509     /* Note: Transition from state reset to state ready,                      */
510     /*       otherwise (coming from state ready or busy) no state update.     */
511     if (hcomp->State == HAL_COMP_STATE_RESET)
512     {
513       hcomp->State = HAL_COMP_STATE_READY;
514     }
515   }
516 
517   return status;
518 }
519 
520 /**
521   * @brief  DeInitialize the COMP peripheral.
522   * @note   Deinitialization cannot be performed if the COMP configuration is locked.
523   *         To unlock the configuration, perform a system reset.
524   * @param  hcomp  COMP handle
525   * @retval HAL status
526   */
HAL_COMP_DeInit(COMP_HandleTypeDef * hcomp)527 HAL_StatusTypeDef HAL_COMP_DeInit(COMP_HandleTypeDef *hcomp)
528 {
529   HAL_StatusTypeDef status = HAL_OK;
530 
531   /* Check the COMP handle allocation and lock status */
532   if((hcomp == NULL) || (__HAL_COMP_IS_LOCKED(hcomp)))
533   {
534     status = HAL_ERROR;
535   }
536   else
537   {
538     /* Check the parameter */
539     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
540 
541     /* Set COMP_CSR register to reset value */
542     WRITE_REG(hcomp->Instance->CSR, 0x00000000U);
543 
544 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
545     if (hcomp->MspDeInitCallback == NULL)
546     {
547       hcomp->MspDeInitCallback = HAL_COMP_MspDeInit; /* Legacy weak MspDeInit  */
548     }
549 
550     /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
551     hcomp->MspDeInitCallback(hcomp);
552 #else
553     /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
554     HAL_COMP_MspDeInit(hcomp);
555 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
556 
557     /* Set HAL COMP handle state */
558     hcomp->State = HAL_COMP_STATE_RESET;
559 
560     /* Release Lock */
561     __HAL_UNLOCK(hcomp);
562   }
563 
564   return status;
565 }
566 
567 /**
568   * @brief  Initialize the COMP MSP.
569   * @param  hcomp  COMP handle
570   * @retval None
571   */
HAL_COMP_MspInit(COMP_HandleTypeDef * hcomp)572 __weak void HAL_COMP_MspInit(COMP_HandleTypeDef *hcomp)
573 {
574   /* Prevent unused argument(s) compilation warning */
575   UNUSED(hcomp);
576 
577   /* NOTE : This function should not be modified, when the callback is needed,
578             the HAL_COMP_MspInit could be implemented in the user file
579    */
580 }
581 
582 /**
583   * @brief  DeInitialize the COMP MSP.
584   * @param  hcomp  COMP handle
585   * @retval None
586   */
HAL_COMP_MspDeInit(COMP_HandleTypeDef * hcomp)587 __weak void HAL_COMP_MspDeInit(COMP_HandleTypeDef *hcomp)
588 {
589   /* Prevent unused argument(s) compilation warning */
590   UNUSED(hcomp);
591 
592   /* NOTE : This function should not be modified, when the callback is needed,
593             the HAL_COMP_MspDeInit could be implemented in the user file
594    */
595 }
596 
597 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
598 /**
599   * @brief  Register a User COMP Callback
600   *         To be used instead of the weak predefined callback
601   * @param  hcomp Pointer to a COMP_HandleTypeDef structure that contains
602   *                the configuration information for the specified COMP.
603   * @param  CallbackID ID of the callback to be registered
604   *         This parameter can be one of the following values:
605   *          @arg @ref HAL_COMP_TRIGGER_CB_ID Trigger callback ID
606   *          @arg @ref HAL_COMP_MSPINIT_CB_ID MspInit callback ID
607   *          @arg @ref HAL_COMP_MSPDEINIT_CB_ID MspDeInit callback ID
608   * @param  pCallback pointer to the Callback function
609   * @retval HAL status
610   */
HAL_COMP_RegisterCallback(COMP_HandleTypeDef * hcomp,HAL_COMP_CallbackIDTypeDef CallbackID,pCOMP_CallbackTypeDef pCallback)611 HAL_StatusTypeDef HAL_COMP_RegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID, pCOMP_CallbackTypeDef pCallback)
612 {
613   HAL_StatusTypeDef status = HAL_OK;
614 
615   if (pCallback == NULL)
616   {
617     /* Update the error code */
618     hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
619 
620     return HAL_ERROR;
621   }
622 
623   if (HAL_COMP_STATE_READY == hcomp->State)
624   {
625     switch (CallbackID)
626     {
627       case HAL_COMP_TRIGGER_CB_ID :
628         hcomp->TriggerCallback = pCallback;
629         break;
630 
631       case HAL_COMP_MSPINIT_CB_ID :
632         hcomp->MspInitCallback = pCallback;
633         break;
634 
635       case HAL_COMP_MSPDEINIT_CB_ID :
636         hcomp->MspDeInitCallback = pCallback;
637         break;
638 
639       default :
640         /* Update the error code */
641         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
642 
643         /* Return error status */
644         status = HAL_ERROR;
645         break;
646     }
647   }
648   else if (HAL_COMP_STATE_RESET == hcomp->State)
649   {
650     switch (CallbackID)
651     {
652       case HAL_COMP_MSPINIT_CB_ID :
653         hcomp->MspInitCallback = pCallback;
654         break;
655 
656       case HAL_COMP_MSPDEINIT_CB_ID :
657         hcomp->MspDeInitCallback = pCallback;
658         break;
659 
660       default :
661         /* Update the error code */
662         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
663 
664         /* Return error status */
665         status = HAL_ERROR;
666         break;
667     }
668   }
669   else
670   {
671     /* Update the error code */
672     hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
673 
674     /* Return error status */
675     status =  HAL_ERROR;
676   }
677 
678   return status;
679 }
680 
681 /**
682   * @brief  Unregister a COMP Callback
683   *         COMP callback is redirected to the weak predefined callback
684   * @param  hcomp Pointer to a COMP_HandleTypeDef structure that contains
685   *                the configuration information for the specified COMP.
686   * @param  CallbackID ID of the callback to be unregistered
687   *         This parameter can be one of the following values:
688   *          @arg @ref HAL_COMP_TRIGGER_CB_ID Trigger callback ID
689   *          @arg @ref HAL_COMP_MSPINIT_CB_ID MspInit callback ID
690   *          @arg @ref HAL_COMP_MSPDEINIT_CB_ID MspDeInit callback ID
691   * @retval HAL status
692   */
HAL_COMP_UnRegisterCallback(COMP_HandleTypeDef * hcomp,HAL_COMP_CallbackIDTypeDef CallbackID)693 HAL_StatusTypeDef HAL_COMP_UnRegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID)
694 {
695   HAL_StatusTypeDef status = HAL_OK;
696 
697   if (HAL_COMP_STATE_READY == hcomp->State)
698   {
699     switch (CallbackID)
700     {
701       case HAL_COMP_TRIGGER_CB_ID :
702         hcomp->TriggerCallback = HAL_COMP_TriggerCallback;         /* Legacy weak callback */
703         break;
704 
705       case HAL_COMP_MSPINIT_CB_ID :
706         hcomp->MspInitCallback = HAL_COMP_MspInit;                 /* Legacy weak MspInit */
707         break;
708 
709       case HAL_COMP_MSPDEINIT_CB_ID :
710         hcomp->MspDeInitCallback = HAL_COMP_MspDeInit;             /* Legacy weak MspDeInit */
711         break;
712 
713       default :
714         /* Update the error code */
715         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
716 
717         /* Return error status */
718         status =  HAL_ERROR;
719         break;
720     }
721   }
722   else if (HAL_COMP_STATE_RESET == hcomp->State)
723   {
724     switch (CallbackID)
725     {
726       case HAL_COMP_MSPINIT_CB_ID :
727         hcomp->MspInitCallback = HAL_COMP_MspInit;                 /* Legacy weak MspInit */
728         break;
729 
730       case HAL_COMP_MSPDEINIT_CB_ID :
731         hcomp->MspDeInitCallback = HAL_COMP_MspDeInit;             /* Legacy weak MspDeInit */
732         break;
733 
734       default :
735         /* Update the error code */
736         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
737 
738         /* Return error status */
739         status =  HAL_ERROR;
740         break;
741     }
742   }
743   else
744   {
745     /* Update the error code */
746     hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
747 
748     /* Return error status */
749     status =  HAL_ERROR;
750   }
751 
752   return status;
753 }
754 
755 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
756 
757 /**
758   * @}
759   */
760 
761 /** @defgroup COMP_Exported_Functions_Group2 Start-Stop operation functions
762  *  @brief   Start-Stop operation functions.
763  *
764 @verbatim
765  ===============================================================================
766                       ##### IO operation functions #####
767  ===============================================================================
768     [..]  This section provides functions allowing to:
769       (+) Start a comparator instance.
770       (+) Stop a comparator instance.
771 
772 @endverbatim
773   * @{
774   */
775 
776 /**
777   * @brief  Start the comparator.
778   * @param  hcomp  COMP handle
779   * @retval HAL status
780   */
HAL_COMP_Start(COMP_HandleTypeDef * hcomp)781 HAL_StatusTypeDef HAL_COMP_Start(COMP_HandleTypeDef *hcomp)
782 {
783   __IO uint32_t wait_loop_index = 0U;
784   HAL_StatusTypeDef status = HAL_OK;
785 
786   /* Check the COMP handle allocation and lock status */
787   if((hcomp == NULL) || (__HAL_COMP_IS_LOCKED(hcomp)))
788   {
789     status = HAL_ERROR;
790   }
791   else
792   {
793     /* Check the parameter */
794     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
795 
796     if(hcomp->State == HAL_COMP_STATE_READY)
797     {
798       /* Enable the selected comparator */
799       SET_BIT(hcomp->Instance->CSR, COMP_CSR_COMPxEN);
800 
801       /* Set HAL COMP handle state */
802       hcomp->State = HAL_COMP_STATE_BUSY;
803 
804       /* Delay for COMP startup time */
805       /* Wait loop initialization and execution */
806       /* Note: Variable divided by 2 to compensate partially                  */
807       /*       CPU processing cycles.                                         */
808       wait_loop_index = (COMP_DELAY_STARTUP_US * (SystemCoreClock / (1000000U * 2U)));
809       while(wait_loop_index != 0U)
810       {
811         wait_loop_index--;
812       }
813     }
814     else
815     {
816       status = HAL_ERROR;
817     }
818   }
819 
820   return status;
821 }
822 
823 /**
824   * @brief  Stop the comparator.
825   * @param  hcomp  COMP handle
826   * @retval HAL status
827   */
HAL_COMP_Stop(COMP_HandleTypeDef * hcomp)828 HAL_StatusTypeDef HAL_COMP_Stop(COMP_HandleTypeDef *hcomp)
829 {
830   HAL_StatusTypeDef status = HAL_OK;
831 
832   /* Check the COMP handle allocation and lock status */
833   if((hcomp == NULL) || (__HAL_COMP_IS_LOCKED(hcomp)))
834   {
835     status = HAL_ERROR;
836   }
837   else
838   {
839     /* Check the parameter */
840     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
841 
842     if((hcomp->State == HAL_COMP_STATE_BUSY)  ||
843        (hcomp->State == HAL_COMP_STATE_READY)   )
844     {
845       /* Disable the selected comparator */
846       CLEAR_BIT(hcomp->Instance->CSR, COMP_CSR_COMPxEN);
847 
848       /* Set HAL COMP handle state */
849       hcomp->State = HAL_COMP_STATE_READY;
850     }
851     else
852     {
853       status = HAL_ERROR;
854     }
855   }
856 
857   return status;
858 }
859 
860 /**
861   * @brief  Comparator IRQ handler.
862   * @param  hcomp  COMP handle
863   * @retval None
864   */
HAL_COMP_IRQHandler(COMP_HandleTypeDef * hcomp)865 void HAL_COMP_IRQHandler(COMP_HandleTypeDef *hcomp)
866 {
867   /* Get the EXTI line corresponding to the selected COMP instance */
868   uint32_t exti_line = COMP_GET_EXTI_LINE(hcomp->Instance);
869 
870   /* Check COMP EXTI flag */
871   if(READ_BIT(EXTI->PR, exti_line) != RESET)
872   {
873     /* Check whether comparator is in independent or window mode */
874     if(READ_BIT(COMP12_COMMON->CSR, COMP_CSR_WINMODE) != 0)
875     {
876       /* Clear COMP EXTI line pending bit of the pair of comparators          */
877       /* in window mode.                                                      */
878       /* Note: Pair of comparators in window mode can both trig IRQ when      */
879       /*       input voltage is changing from "out of window" area            */
880       /*       (low or high ) to the other "out of window" area (high or low).*/
881       /*       Both flags must be cleared to call comparator trigger          */
882       /*       callback is called once.                                       */
883       WRITE_REG(EXTI->PR, (COMP_EXTI_LINE_COMP1 | COMP_EXTI_LINE_COMP2));
884     }
885     else
886     {
887       /* Clear COMP EXTI line pending bit */
888       WRITE_REG(EXTI->PR, exti_line);
889     }
890 
891     /* COMP trigger callback */
892 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
893     hcomp->TriggerCallback(hcomp);
894 #else
895     HAL_COMP_TriggerCallback(hcomp);
896 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
897   }
898 }
899 
900 /**
901   * @}
902   */
903 
904 /** @defgroup COMP_Exported_Functions_Group3 Peripheral Control functions
905  *  @brief   Management functions.
906  *
907 @verbatim
908  ===============================================================================
909                       ##### Peripheral Control functions #####
910  ===============================================================================
911     [..]
912     This subsection provides a set of functions allowing to control the comparators.
913 
914 @endverbatim
915   * @{
916   */
917 
918 /**
919   * @brief  Lock the selected comparator configuration.
920   * @note   A system reset is required to unlock the comparator configuration.
921   * @note   Locking the comparator from reset state is possible
922   *         if __HAL_RCC_SYSCFG_CLK_ENABLE() is being called before.
923   * @param  hcomp  COMP handle
924   * @retval HAL status
925   */
HAL_COMP_Lock(COMP_HandleTypeDef * hcomp)926 HAL_StatusTypeDef HAL_COMP_Lock(COMP_HandleTypeDef *hcomp)
927 {
928   HAL_StatusTypeDef status = HAL_OK;
929 
930   /* Check the COMP handle allocation and lock status */
931   if((hcomp == NULL) || (__HAL_COMP_IS_LOCKED(hcomp)))
932   {
933     status = HAL_ERROR;
934   }
935   else
936   {
937     /* Check the parameter */
938     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
939 
940     /* Set HAL COMP handle state */
941     hcomp->State = ((HAL_COMP_StateTypeDef)(hcomp->State | COMP_STATE_BITFIELD_LOCK));
942   }
943 
944   if(status == HAL_OK)
945   {
946     /* Set the lock bit corresponding to selected comparator */
947     __HAL_COMP_LOCK(hcomp);
948   }
949 
950   return status;
951 }
952 
953 /**
954   * @brief  Return the output level (high or low) of the selected comparator.
955   *         The output level depends on the selected polarity.
956   *         If the polarity is not inverted:
957   *           - Comparator output is low when the input plus is at a lower
958   *             voltage than the input minus
959   *           - Comparator output is high when the input plus is at a higher
960   *             voltage than the input minus
961   *         If the polarity is inverted:
962   *           - Comparator output is high when the input plus is at a lower
963   *             voltage than the input minus
964   *           - Comparator output is low when the input plus is at a higher
965   *             voltage than the input minus
966   * @param  hcomp  COMP handle
967   * @retval Returns the selected comparator output level:
968   *         @arg @ref COMP_OUTPUT_LEVEL_LOW
969   *         @arg @ref COMP_OUTPUT_LEVEL_HIGH
970   *
971   */
HAL_COMP_GetOutputLevel(COMP_HandleTypeDef * hcomp)972 uint32_t HAL_COMP_GetOutputLevel(COMP_HandleTypeDef *hcomp)
973 {
974   /* Check the parameter */
975   assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
976 
977   return (uint32_t)(READ_BIT(hcomp->Instance->CSR, COMP_CSR_COMPxOUTVALUE)
978                     >> COMP_OUTPUT_LEVEL_BITOFFSET_POS);
979 }
980 
981 /**
982   * @brief  Comparator trigger callback.
983   * @param  hcomp  COMP handle
984   * @retval None
985   */
HAL_COMP_TriggerCallback(COMP_HandleTypeDef * hcomp)986 __weak void HAL_COMP_TriggerCallback(COMP_HandleTypeDef *hcomp)
987 {
988   /* Prevent unused argument(s) compilation warning */
989   UNUSED(hcomp);
990 
991   /* NOTE : This function should not be modified, when the callback is needed,
992             the HAL_COMP_TriggerCallback should be implemented in the user file
993    */
994 }
995 
996 
997 /**
998   * @}
999   */
1000 
1001 /** @defgroup COMP_Exported_Functions_Group4 Peripheral State functions
1002  *  @brief   Peripheral State functions.
1003  *
1004 @verbatim
1005  ===============================================================================
1006                       ##### Peripheral State functions #####
1007  ===============================================================================
1008     [..]
1009     This subsection permit to get in run-time the status of the peripheral.
1010 
1011 @endverbatim
1012   * @{
1013   */
1014 
1015 /**
1016   * @brief  Return the COMP handle state.
1017   * @param  hcomp  COMP handle
1018   * @retval HAL state
1019   */
HAL_COMP_GetState(COMP_HandleTypeDef * hcomp)1020 HAL_COMP_StateTypeDef HAL_COMP_GetState(COMP_HandleTypeDef *hcomp)
1021 {
1022   /* Check the COMP handle allocation */
1023   if(hcomp == NULL)
1024   {
1025     return HAL_COMP_STATE_RESET;
1026   }
1027 
1028   /* Check the parameter */
1029   assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
1030 
1031   /* Return HAL COMP handle state */
1032   return hcomp->State;
1033 }
1034 
1035 /**
1036   * @brief  Return the COMP error code.
1037   * @param hcomp COMP handle
1038   * @retval COMP error code
1039   */
HAL_COMP_GetError(COMP_HandleTypeDef * hcomp)1040 uint32_t HAL_COMP_GetError(COMP_HandleTypeDef *hcomp)
1041 {
1042   /* Check the parameters */
1043   assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
1044 
1045   return hcomp->ErrorCode;
1046 }
1047 
1048 /**
1049   * @}
1050   */
1051 
1052 /**
1053   * @}
1054   */
1055 
1056 #endif /* HAL_COMP_MODULE_ENABLED */
1057 /**
1058   * @}
1059   */
1060 
1061 /**
1062   * @}
1063   */
1064 
1065 #endif /* !defined (STM32L010xB) && !defined (STM32L010x8) && !defined (STM32L010x6) && !defined (STM32L010x4) */
1066