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