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