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