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