1 /**
2   **********************************************************************************************************************
3   * @file    stm32h5xx_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   * @attention
13   *
14   * Copyright (c) 2022 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file
18   * in the root directory of this software component.
19   * If no LICENSE file comes with this software, it is provided AS-IS.
20   *
21   **********************************************************************************************************************
22   @verbatim
23   ======================================================================================================================
24                                      ##### COMP Peripheral features #####
25   ======================================================================================================================
26 
27   [..]
28       The STM32H5xx device family integrates one analog comparator instance: COMP1.
29       (#) Comparators input minus (inverting input) and input plus (non inverting input)
30           can be set to internal references or to GPIO pins
31           (refer to GPIO list in reference manual).
32 
33       (#) Comparators output level is available using HAL_COMP_GetOutputLevel()
34           and can be redirected to other peripherals: GPIO pins (in mode
35           alternate functions for comparator), timers.
36           (refer to GPIO list in reference manual).
37 
38       (#) The comparators have interrupt capability through direct line to NVIC (featuring
39           low latency interrupt).
40           Caution: Specific behavior for comparator of this STM32 series: comparator output triggers interruption
41                    on high level
42           - triggering on level (instead of edge) implies to disable interrupt in comparator IRQ handler.
43             In case of further operation needed in interrupt mode, comparator interruption must be rearmed.
44           - triggering on high level implies that comparator output initial state must at low level.
45             Then, comparator can trig signal on rising edge.
46             Trigger a signal on falling edge is possible by inverting comparator polarity.
47 
48   ======================================================================================================================
49                                        ##### How to use this driver #####
50   ======================================================================================================================
51   [..]
52       This driver provides functions to configure and program the comparator instances of
53       STM32H5xx 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       -@@- HAL_COMP_Init() calls "HAL_COMP_MspInit()", COMP clock enable using system RCC
74            must be implemented in this function.
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(), HAL_COMP_Start_IT_OneShot() or HAL_COMP_Start_IT_AutoRearm()
80           Note: Using HAL_COMP_Start_IT_OneShot() or HAL_COMP_Start_IT_AutoRearm(), these functions can change
81                 comparator output polarity to match initial comparator output level constraint.
82           Note: Using HAL_COMP_Start_IT_OneShot(), after each interruption triggered the interruption
83                 is disabled in IRQ handler. If needed, comparartor interruption can be rearmed by calling again
84                 start function.
85           Note: In case of comparator and interruption used to exit from low power mode, user most ensure of stable
86                 comparator input voltage (risk would be that comparator trigs early and IT disabled in IRQ handler
87                 before device entering in low power mode, inducing no further system wake up possible).
88                 Most appropriate function is HAL_COMP_Start_IT_AutoRearm() because comparartor triggers remains enable,
89                 ensuring system wake up capability.
90 
91       (#) Use HAL_COMP_TriggerCallback() or HAL_COMP_GetOutputLevel() functions
92           to manage comparator outputs (events and output level).
93 
94       (#) Disable the comparator using HAL_COMP_Stop() or HAL_COMP_Stop_IT() functions.
95 
96       (#) De-initialize the comparator using HAL_COMP_DeInit() function.
97 
98       (#) For safety purpose, comparator configuration can be locked using HAL_COMP_Lock() function.
99           The only way to unlock the comparator is a device hardware reset.
100 
101     *** Callback registration ***
102     =============================================
103     [..]
104 
105      The compilation flag USE_HAL_COMP_REGISTER_CALLBACKS, when set to 1,
106      allows the user to configure dynamically the driver callbacks.
107      Use Functions HAL_COMP_RegisterCallback()
108      to register an interrupt callback.
109     [..]
110 
111      Function HAL_COMP_RegisterCallback() allows to register following callbacks:
112        (+) TriggerCallback       : callback for COMP trigger.
113        (+) MspInitCallback       : callback for Msp Init.
114        (+) MspDeInitCallback     : callback for Msp DeInit.
115      This function takes as parameters the HAL peripheral handle, the Callback ID
116      and a pointer to the user callback function.
117     [..]
118 
119      Use function HAL_COMP_UnRegisterCallback to reset a callback to the default
120      weak function.
121     [..]
122 
123      HAL_COMP_UnRegisterCallback takes as parameters the HAL peripheral handle,
124      and the Callback ID.
125      This function allows to reset following callbacks:
126        (+) TriggerCallback       : callback for COMP trigger.
127        (+) MspInitCallback       : callback for Msp Init.
128        (+) MspDeInitCallback     : callback for Msp DeInit.
129      [..]
130 
131      By default, after the HAL_COMP_Init() and when the state is HAL_COMP_STATE_RESET
132      all callbacks are set to the corresponding weak functions:
133      example HAL_COMP_TriggerCallback().
134      Exception done for MspInit and MspDeInit functions that are
135      reset to the legacy weak functions in the HAL_COMP_Init() / HAL_COMP_DeInit() only when
136      these callbacks are null (not registered beforehand).
137     [..]
138 
139      If MspInit or MspDeInit are not null, the HAL_COMP_Init() / HAL_COMP_DeInit()
140      keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
141      [..]
142 
143      Callbacks can be registered/unregistered in HAL_COMP_STATE_READY state only.
144      Exception done MspInit/MspDeInit functions that can be registered/unregistered
145      in HAL_COMP_STATE_READY or HAL_COMP_STATE_RESET state,
146      thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
147     [..]
148 
149      Then, the user first registers the MspInit/MspDeInit user callbacks
150      using HAL_COMP_RegisterCallback() before calling HAL_COMP_DeInit()
151      or HAL_COMP_Init() function.
152      [..]
153 
154      When the compilation flag USE_HAL_COMP_REGISTER_CALLBACKS is set to 0 or
155      not defined, the callback registration feature is not available and all callbacks
156      are set to the corresponding weak functions.
157 
158   @endverbatim
159   **********************************************************************************************************************
160   */
161 
162 /* Includes ----------------------------------------------------------------------------------------------------------*/
163 #include "stm32h5xx_hal.h"
164 
165 /** @addtogroup STM32H5xx_HAL_Driver
166   * @{
167   */
168 
169 #ifdef HAL_COMP_MODULE_ENABLED
170 
171 #if defined (COMP1)
172 
173 /** @defgroup COMP COMP
174   * @brief COMP HAL module driver
175   * @{
176   */
177 
178 /* Private typedef ---------------------------------------------------------------------------------------------------*/
179 /* Private define ----------------------------------------------------------------------------------------------------*/
180 /** @addtogroup COMP_Private_Constants
181   * @{
182   */
183 
184 /* Delay for COMP startup time.                                               */
185 /* Note: Delay required to reach propagation delay specification.             */
186 /* Literal set to maximum value (refer to device datasheet,                   */
187 /* parameter "tSTART").                                                       */
188 /* Unit: us                                                                   */
189 #define COMP_DELAY_STARTUP_US          (80UL) /*!< Delay for COMP startup time */
190 
191 /* Delay for COMP voltage scaler stabilization time.                          */
192 /* Literal set to maximum value (refer to device datasheet,                   */
193 /* parameter "tSTART_SCALER").                                                */
194 /* Unit: us                                                                   */
195 #define COMP_DELAY_VOLTAGE_SCALER_STAB_US (200UL)  /*!< Delay for COMP voltage scaler stabilization time */
196 
197 
198 /**
199   * @}
200   */
201 
202 /* Private macro -----------------------------------------------------------------------------------------------------*/
203 /* Private variables -------------------------------------------------------------------------------------------------*/
204 /* Private function prototypes ---------------------------------------------------------------------------------------*/
205 /* Exported functions ------------------------------------------------------------------------------------------------*/
206 
207 /** @defgroup COMP_Exported_Functions COMP Exported Functions
208   * @{
209   */
210 
211 /** @defgroup COMP_Exported_Functions_Group1 Initialization/de-initialization functions
212   *  @brief    Initialization and de-initialization functions.
213   *
214 @verbatim
215  =======================================================================================================================
216                            ##### Initialization and de-initialization functions #####
217  =======================================================================================================================
218     [..]  This section provides functions to initialize and de-initialize comparators
219 
220 @endverbatim
221   * @{
222   */
223 
224 /**
225   * @brief  Initialize the COMP according to the specified
226   *         parameters in the COMP_InitTypeDef and initialize the associated handle.
227   * @note   If the selected comparator is locked, initialization can't be performed.
228   *         To unlock the configuration, perform a system reset.
229   * @param  hcomp COMP handle
230   * @retval HAL status
231   */
HAL_COMP_Init(COMP_HandleTypeDef * hcomp)232 HAL_StatusTypeDef HAL_COMP_Init(COMP_HandleTypeDef *hcomp)
233 {
234   uint32_t tmp_csr;
235   uint32_t exti_line;
236   uint32_t comp_voltage_scaler_initialized; /* Value "0" if comparator voltage scaler is not initialized */
237   __IO uint32_t wait_loop_index = 0UL;
238   HAL_StatusTypeDef status = HAL_OK;
239 
240   /* Check the COMP handle allocation and lock status */
241   if (hcomp == NULL)
242   {
243     status = HAL_ERROR;
244   }
245   else if (__HAL_COMP_IS_LOCKED(hcomp))
246   {
247     status = HAL_ERROR;
248   }
249   else
250   {
251     /* Check the parameters */
252     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
253     assert_param(IS_COMP_INPUT_PLUS(hcomp->Instance, hcomp->Init.InputPlus));
254     assert_param(IS_COMP_INPUT_MINUS(hcomp->Instance, hcomp->Init.InputMinus));
255     assert_param(IS_COMP_OUTPUTPOL(hcomp->Init.OutputPol));
256     assert_param(IS_COMP_POWERMODE(hcomp->Init.Mode));
257     assert_param(IS_COMP_HYSTERESIS(hcomp->Init.Hysteresis));
258     assert_param(IS_COMP_BLANKINGSRCE(hcomp->Init.BlankingSrce));
259     assert_param(IS_COMP_TRIGGERMODE(hcomp->Init.TriggerMode));
260 
261     if (hcomp->State == HAL_COMP_STATE_RESET)
262     {
263       /* Allocate lock resource and initialize it */
264       hcomp->Lock = HAL_UNLOCKED;
265 
266       /* Set COMP error code to none */
267       COMP_CLEAR_ERRORCODE(hcomp);
268 
269       hcomp->InterruptAutoRearm = 0;
270 
271 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1U)
272       /* Init the COMP Callback settings */
273       hcomp->TriggerCallback = HAL_COMP_TriggerCallback; /* Legacy weak callback */
274 
275       if (hcomp->MspInitCallback == NULL)
276       {
277         hcomp->MspInitCallback = HAL_COMP_MspInit; /* Legacy weak MspInit  */
278       }
279 
280       /* Init the low level hardware */
281       hcomp->MspInitCallback(hcomp);
282 #else
283       /* Init the low level hardware */
284       HAL_COMP_MspInit(hcomp);
285 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
286     }
287 
288     /* Memorize voltage scaler state before initialization */
289     comp_voltage_scaler_initialized = READ_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_SCALEN);
290 
291     /* Set COMP parameters */
292     tmp_csr = (hcomp->Init.InputMinus
293                | hcomp->Init.InputPlus
294                | hcomp->Init.BlankingSrce
295                | hcomp->Init.Hysteresis
296                | hcomp->Init.OutputPol
297                | hcomp->Init.Mode);
298 
299     /* Set parameters in COMP register */
300     /* Note: Update all bits except read-only, lock and enable bits */
301     MODIFY_REG(hcomp->Instance->CFGR1,
302                COMP_CFGR1_PWRMODE | COMP_CFGR1_INMSEL | COMP_CFGR1_INPSEL1
303                | COMP_CFGR1_INPSEL2 | COMP_CFGR1_POLARITY | COMP_CFGR1_HYST
304                | COMP_CFGR1_BLANKING | COMP_CFGR1_BRGEN | COMP_CFGR1_SCALEN,
305                tmp_csr
306               );
307 
308     if (hcomp->Init.InputPlus == COMP_INPUT_PLUS_IO2)
309     {
310       MODIFY_REG(hcomp->Instance->CFGR2, COMP_CFGR2_INPSEL0, COMP_CFGR2_INPSEL0);
311     }
312 
313     /* Delay for COMP scaler bridge voltage stabilization */
314     /* Apply the delay if voltage scaler bridge is enabled for the first time */
315     if ((READ_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_SCALEN) != 0UL) &&
316         (comp_voltage_scaler_initialized != 0UL))
317     {
318       /* Wait loop initialization and execution */
319       /* Note: Variable divided by 2 to compensate partially              */
320       /*       CPU processing cycles, scaling in us split to not          */
321       /*       exceed 32 bits register capacity and handle low frequency. */
322       wait_loop_index = ((COMP_DELAY_VOLTAGE_SCALER_STAB_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
323       while (wait_loop_index != 0UL)
324       {
325         wait_loop_index--;
326       }
327     }
328 
329     /* Get the EXTI line corresponding to the selected COMP instance */
330     exti_line = COMP_GET_EXTI_LINE(hcomp->Instance);
331 
332     /* Manage EXTI settings */
333     if ((hcomp->Init.TriggerMode & COMP_EXTI_IT) != 0UL)
334     {
335       LL_EXTI_EnableIT_0_31(exti_line);
336     }
337     else
338     {
339       /* Disable EXTI interrupt mode */
340       LL_EXTI_DisableIT_0_31(exti_line);
341     }
342 
343     /* Set HAL COMP handle state */
344     /* Note: Transition from state reset to state ready,                      */
345     /*       otherwise (coming from state ready or busy) no state update.     */
346     if (hcomp->State == HAL_COMP_STATE_RESET)
347     {
348       hcomp->State = HAL_COMP_STATE_READY;
349     }
350   }
351 
352   return status;
353 }
354 
355 /**
356   * @brief  DeInitialize the COMP peripheral.
357   * @note   Deinitialization cannot be performed if the COMP configuration is locked.
358   *         To unlock the configuration, perform a system reset.
359   * @param  hcomp  COMP handle
360   * @retval HAL status
361   */
HAL_COMP_DeInit(COMP_HandleTypeDef * hcomp)362 HAL_StatusTypeDef HAL_COMP_DeInit(COMP_HandleTypeDef *hcomp)
363 {
364   HAL_StatusTypeDef status = HAL_OK;
365 
366   /* Check the COMP handle allocation and lock status */
367   if (hcomp == NULL)
368   {
369     status = HAL_ERROR;
370   }
371   else if (__HAL_COMP_IS_LOCKED(hcomp))
372   {
373     status = HAL_ERROR;
374   }
375   else
376   {
377     /* Check the parameter */
378     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
379 
380     /* Set configuration register to reset value */
381     WRITE_REG(hcomp->Instance->CFGR1, 0x00000000UL);
382 
383 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1U)
384     if (hcomp->MspDeInitCallback == NULL)
385     {
386       hcomp->MspDeInitCallback = HAL_COMP_MspDeInit; /* Legacy weak MspDeInit  */
387     }
388 
389     /* DeInit the low level hardware */
390     hcomp->MspDeInitCallback(hcomp);
391 #else
392     /* DeInit the low level hardware */
393     HAL_COMP_MspDeInit(hcomp);
394 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
395 
396     /* Set HAL COMP handle state */
397     hcomp->State = HAL_COMP_STATE_RESET;
398 
399     /* Release Lock */
400     __HAL_UNLOCK(hcomp);
401   }
402 
403   return status;
404 }
405 
406 /**
407   * @brief  Initialize the COMP MSP.
408   * @param  hcomp COMP handle
409   * @retval None
410   */
HAL_COMP_MspInit(COMP_HandleTypeDef * hcomp)411 __weak void HAL_COMP_MspInit(COMP_HandleTypeDef *hcomp)
412 {
413   /* Prevent unused argument(s) compilation warning */
414   UNUSED(hcomp);
415 
416   /* NOTE : This function should not be modified, when the callback is needed,
417             the HAL_COMP_MspInit could be implemented in the user file
418    */
419 }
420 
421 /**
422   * @brief  DeInitialize the COMP MSP.
423   * @param  hcomp COMP handle
424   * @retval None
425   */
HAL_COMP_MspDeInit(COMP_HandleTypeDef * hcomp)426 __weak void HAL_COMP_MspDeInit(COMP_HandleTypeDef *hcomp)
427 {
428   /* Prevent unused argument(s) compilation warning */
429   UNUSED(hcomp);
430 
431   /* NOTE : This function should not be modified, when the callback is needed,
432             the HAL_COMP_MspDeInit could be implemented in the user file
433    */
434 }
435 
436 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1U)
437 /**
438   * @brief  Register a User COMP Callback
439   *         To be used instead of the weak predefined callback
440   * @param  hcomp Pointer to a COMP_HandleTypeDef structure that contains
441   *                the configuration information for the specified COMP.
442   * @param  CallbackID ID of the callback to be registered
443   *         This parameter can be one of the following values:
444   *          @arg @ref HAL_COMP_TRIGGER_CB_ID Trigger callback ID
445   *          @arg @ref HAL_COMP_MSPINIT_CB_ID MspInit callback ID
446   *          @arg @ref HAL_COMP_MSPDEINIT_CB_ID MspDeInit callback ID
447   * @param  pCallback pointer to the Callback function
448   * @retval HAL status
449   */
HAL_COMP_RegisterCallback(COMP_HandleTypeDef * hcomp,HAL_COMP_CallbackIDTypeDef CallbackID,pCOMP_CallbackTypeDef pCallback)450 HAL_StatusTypeDef HAL_COMP_RegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID,
451                                             pCOMP_CallbackTypeDef pCallback)
452 {
453   HAL_StatusTypeDef status = HAL_OK;
454 
455   if (pCallback == NULL)
456   {
457     /* Update the error code */
458     hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
459 
460     return HAL_ERROR;
461   }
462 
463   if (HAL_COMP_STATE_READY == hcomp->State)
464   {
465     switch (CallbackID)
466     {
467       case HAL_COMP_TRIGGER_CB_ID :
468         hcomp->TriggerCallback = pCallback;
469         break;
470 
471       case HAL_COMP_MSPINIT_CB_ID :
472         hcomp->MspInitCallback = pCallback;
473         break;
474 
475       case HAL_COMP_MSPDEINIT_CB_ID :
476         hcomp->MspDeInitCallback = pCallback;
477         break;
478 
479       default :
480         /* Update the error code */
481         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
482 
483         /* Return error status */
484         status = HAL_ERROR;
485         break;
486     }
487   }
488   else if (HAL_COMP_STATE_RESET == hcomp->State)
489   {
490     switch (CallbackID)
491     {
492       case HAL_COMP_MSPINIT_CB_ID :
493         hcomp->MspInitCallback = pCallback;
494         break;
495 
496       case HAL_COMP_MSPDEINIT_CB_ID :
497         hcomp->MspDeInitCallback = pCallback;
498         break;
499 
500       default :
501         /* Update the error code */
502         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
503 
504         /* Return error status */
505         status = HAL_ERROR;
506         break;
507     }
508   }
509   else
510   {
511     /* Update the error code */
512     hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
513 
514     /* Return error status */
515     status =  HAL_ERROR;
516   }
517 
518   return status;
519 }
520 
521 /**
522   * @brief  Unregister a COMP Callback
523   *         COMP callback is redirected to the weak predefined callback
524   * @param  hcomp Pointer to a COMP_HandleTypeDef structure that contains
525   *                the configuration information for the specified COMP.
526   * @param  CallbackID ID of the callback to be unregistered
527   *         This parameter can be one of the following values:
528   *          @arg @ref HAL_COMP_TRIGGER_CB_ID Trigger callback ID
529   *          @arg @ref HAL_COMP_MSPINIT_CB_ID MspInit callback ID
530   *          @arg @ref HAL_COMP_MSPDEINIT_CB_ID MspDeInit callback ID
531   * @retval HAL status
532   */
HAL_COMP_UnRegisterCallback(COMP_HandleTypeDef * hcomp,HAL_COMP_CallbackIDTypeDef CallbackID)533 HAL_StatusTypeDef HAL_COMP_UnRegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID)
534 {
535   HAL_StatusTypeDef status = HAL_OK;
536 
537   if (HAL_COMP_STATE_READY == hcomp->State)
538   {
539     switch (CallbackID)
540     {
541       case HAL_COMP_TRIGGER_CB_ID :
542         hcomp->TriggerCallback = HAL_COMP_TriggerCallback;         /* Legacy weak callback */
543         break;
544 
545       case HAL_COMP_MSPINIT_CB_ID :
546         hcomp->MspInitCallback = HAL_COMP_MspInit;                 /* Legacy weak MspInit */
547         break;
548 
549       case HAL_COMP_MSPDEINIT_CB_ID :
550         hcomp->MspDeInitCallback = HAL_COMP_MspDeInit;             /* Legacy weak MspDeInit */
551         break;
552 
553       default :
554         /* Update the error code */
555         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
556 
557         /* Return error status */
558         status =  HAL_ERROR;
559         break;
560     }
561   }
562   else if (HAL_COMP_STATE_RESET == hcomp->State)
563   {
564     switch (CallbackID)
565     {
566       case HAL_COMP_MSPINIT_CB_ID :
567         hcomp->MspInitCallback = HAL_COMP_MspInit;                 /* Legacy weak MspInit */
568         break;
569 
570       case HAL_COMP_MSPDEINIT_CB_ID :
571         hcomp->MspDeInitCallback = HAL_COMP_MspDeInit;             /* Legacy weak MspDeInit */
572         break;
573 
574       default :
575         /* Update the error code */
576         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
577 
578         /* Return error status */
579         status =  HAL_ERROR;
580         break;
581     }
582   }
583   else
584   {
585     /* Update the error code */
586     hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
587 
588     /* Return error status */
589     status =  HAL_ERROR;
590   }
591 
592   return status;
593 }
594 
595 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
596 
597 /**
598   * @}
599   */
600 
601 /** @defgroup COMP_Exported_Functions_Group2 Start-Stop operation functions
602   *  @brief   Start-Stop operation functions.
603   *
604 @verbatim
605  =======================================================================================================================
606                                       ##### IO operation functions #####
607  =======================================================================================================================
608     [..]  This section provides functions allowing to:
609       (+) Start a comparator instance.
610       (+) Stop a comparator instance.
611 
612 @endverbatim
613   * @{
614   */
615 
616 /**
617   * @brief  Start the comparator.
618   * @param  hcomp COMP handle
619   * @retval HAL status
620   */
HAL_COMP_Start(COMP_HandleTypeDef * hcomp)621 HAL_StatusTypeDef HAL_COMP_Start(COMP_HandleTypeDef *hcomp)
622 {
623   __IO uint32_t wait_loop_index = 0UL;
624 
625   HAL_StatusTypeDef status = HAL_OK;
626 
627   /* Check the COMP handle allocation and lock status */
628   if (hcomp == NULL)
629   {
630     status = HAL_ERROR;
631   }
632   else if (__HAL_COMP_IS_LOCKED(hcomp))
633   {
634     status = HAL_ERROR;
635   }
636   else
637   {
638     /* Check the parameter */
639     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
640 
641     if ((hcomp->Init.TriggerMode & COMP_EXTI_IT) != 0UL)
642     {
643       /* Case of operation with interruption */
644       /* Note: Specific to comparator of this STM32 series featuring IT with direct line only (low latency) */
645       status = HAL_COMP_Start_IT_AutoRearm(hcomp);
646     }
647     else
648     {
649       if (hcomp->State == HAL_COMP_STATE_READY)
650       {
651         /* Enable the selected comparator */
652         SET_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_EN);
653 
654         /* Set HAL COMP handle state */
655         hcomp->State = HAL_COMP_STATE_BUSY;
656 
657         /* Delay for COMP startup time */
658         /* Wait loop initialization and execution */
659         /* Note: Variable divided by 2 to compensate partially              */
660         /*       CPU processing cycles, scaling in us split to not          */
661         /*       exceed 32 bits register capacity and handle low frequency. */
662         wait_loop_index = ((COMP_DELAY_STARTUP_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
663         while (wait_loop_index != 0UL)
664         {
665           wait_loop_index--;
666         }
667       }
668       else
669       {
670         status = HAL_ERROR;
671       }
672     }
673   }
674 
675   return status;
676 }
677 
678 /**
679   * @brief  Stop the comparator.
680   * @param  hcomp COMP handle
681   * @retval HAL status
682   */
HAL_COMP_Stop(COMP_HandleTypeDef * hcomp)683 HAL_StatusTypeDef HAL_COMP_Stop(COMP_HandleTypeDef *hcomp)
684 {
685   HAL_StatusTypeDef status = HAL_OK;
686 
687   /* Check the COMP handle allocation and lock status */
688   if (hcomp == NULL)
689   {
690     status = HAL_ERROR;
691   }
692   else if (__HAL_COMP_IS_LOCKED(hcomp))
693   {
694     status = HAL_ERROR;
695   }
696   else
697   {
698     /* Check the parameter */
699     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
700 
701     /* Check compliant states: HAL_COMP_STATE_READY or HAL_COMP_STATE_BUSY    */
702     /* (all states except HAL_COMP_STATE_RESET and except locked status.      */
703     if (hcomp->State != HAL_COMP_STATE_RESET)
704     {
705       /* Disable the selected comparator */
706       CLEAR_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_EN);
707 
708       /* Set HAL COMP handle state */
709       hcomp->State = HAL_COMP_STATE_READY;
710     }
711     else
712     {
713       status = HAL_ERROR;
714     }
715   }
716 
717   return status;
718 }
719 
720 /**
721   * @brief  Start the comparator with interruption low latency, interruption disabled at first trigger occurrence.
722   * @note   Interruption low latency is achieved through direct line to NVIC (instead of going through EXTI).
723   * @note   If needed, comparartor interruption can be rearmed by calling again this function.
724   * @note   Specific to comparator of this STM32 series: comparator output triggers interruption on high level.
725             This function can change output polarity depending on initial output level.
726   * @param  hcomp COMP handle
727   * @retval HAL status
728   */
HAL_COMP_Start_IT_OneShot(COMP_HandleTypeDef * hcomp)729 HAL_StatusTypeDef HAL_COMP_Start_IT_OneShot(COMP_HandleTypeDef *hcomp)
730 {
731   __IO uint32_t wait_loop_index = 0UL;
732   uint32_t polarity_toggle = 0U;
733   HAL_StatusTypeDef status = HAL_OK;
734 
735   /* Check the COMP handle allocation and lock status */
736   if (hcomp == NULL)
737   {
738     status = HAL_ERROR;
739   }
740   else if (__HAL_COMP_IS_LOCKED(hcomp))
741   {
742     status = HAL_ERROR;
743   }
744   else
745   {
746     /* Check the parameter */
747     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
748 
749     if (hcomp->State == HAL_COMP_STATE_READY)
750     {
751       /* Enable the selected comparator */
752       SET_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_EN);
753 
754       /* Set HAL COMP handle state */
755       hcomp->State = HAL_COMP_STATE_BUSY;
756 
757       /* Delay for COMP startup time */
758       /* Wait loop initialization and execution */
759       /* Note: Variable divided by 2 to compensate partially              */
760       /*       CPU processing cycles, scaling in us split to not          */
761       /*       exceed 32 bits register capacity and handle low frequency. */
762       wait_loop_index = ((COMP_DELAY_STARTUP_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
763       while (wait_loop_index != 0UL)
764       {
765         wait_loop_index--;
766       }
767 
768       /* Check whether initial comparator output level is compliant with interruption mode */
769       if (hcomp->Init.TriggerMode == COMP_EXTI_FALLING)
770       {
771         if (HAL_COMP_GetOutputLevel(hcomp) != COMP_OUTPUT_LEVEL_HIGH)
772         {
773           polarity_toggle = 1U;
774         }
775       }
776       else /* COMP_EXTI_RISING */
777       {
778         if (HAL_COMP_GetOutputLevel(hcomp) != COMP_OUTPUT_LEVEL_LOW)
779         {
780           polarity_toggle = 1U;
781         }
782       }
783 
784       if (polarity_toggle == 1U)
785       {
786         /* Toggle poarity */
787         if (READ_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_POLARITY) == 0UL)
788         {
789           SET_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_POLARITY);
790         }
791         else
792         {
793           CLEAR_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_POLARITY);
794         }
795       }
796 
797       /* Enable comparator interruption */
798       hcomp->InterruptAutoRearm = 0U;
799       __HAL_COMP_CLEAR_FLAG( COMP_CLEAR_C1IF);
800       SET_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_ITEN);
801     }
802     else
803     {
804       status = HAL_ERROR;
805     }
806   }
807 
808   return status;
809 }
810 
811 /**
812   * @brief  Start the comparator with interruption low latency, interruption rearmed at each trigger occurrence.
813   * @note   Interruption low latency is achieved through direct line to NVIC (instead of going through EXTI).
814   * @note   If needed, comparartor interruption can be rearmed by calling again this function.
815   * @note   Specific to comparator of this STM32 series: comparator output triggers interruption on high level.
816             This function can change output polarity depending on initial output level.
817   * @param  hcomp COMP handle
818   * @retval HAL status
819   */
HAL_COMP_Start_IT_AutoRearm(COMP_HandleTypeDef * hcomp)820 HAL_StatusTypeDef HAL_COMP_Start_IT_AutoRearm(COMP_HandleTypeDef *hcomp)
821 {
822   __IO uint32_t wait_loop_index = 0UL;
823   uint32_t polarity_toggle = 0U;
824   HAL_StatusTypeDef status = HAL_OK;
825 
826   /* Check the COMP handle allocation and lock status */
827   if (hcomp == NULL)
828   {
829     status = HAL_ERROR;
830   }
831   else if (__HAL_COMP_IS_LOCKED(hcomp))
832   {
833     status = HAL_ERROR;
834   }
835   else
836   {
837     /* Check the parameter */
838     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
839 
840     if (hcomp->State == HAL_COMP_STATE_READY)
841     {
842       /* Enable the selected comparator */
843       SET_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_EN);
844 
845       /* Set HAL COMP handle state */
846       hcomp->State = HAL_COMP_STATE_BUSY;
847 
848       /* Delay for COMP startup time */
849       /* Wait loop initialization and execution */
850       /* Note: Variable divided by 2 to compensate partially              */
851       /*       CPU processing cycles, scaling in us split to not          */
852       /*       exceed 32 bits register capacity and handle low frequency. */
853       wait_loop_index = ((COMP_DELAY_STARTUP_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
854       while (wait_loop_index != 0UL)
855       {
856         wait_loop_index--;
857       }
858 
859       /* Check whether initial comparator output level is compliant with interruption mode */
860       if (hcomp->Init.TriggerMode == COMP_EXTI_FALLING)
861       {
862         if (HAL_COMP_GetOutputLevel(hcomp) != COMP_OUTPUT_LEVEL_HIGH)
863         {
864           polarity_toggle = 1U;
865         }
866       }
867       else /* COMP_EXTI_RISING */
868       {
869         if (HAL_COMP_GetOutputLevel(hcomp) != COMP_OUTPUT_LEVEL_LOW)
870         {
871           polarity_toggle = 1U;
872         }
873       }
874 
875       if (polarity_toggle == 1U)
876       {
877         /* Toggle poarity */
878         if (READ_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_POLARITY) == 0UL)
879         {
880           SET_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_POLARITY);
881         }
882         else
883         {
884           CLEAR_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_POLARITY);
885         }
886       }
887 
888       /* Enable comparator interruption */
889       hcomp->InterruptAutoRearm = 1U;
890       __HAL_COMP_CLEAR_FLAG( COMP_CLEAR_C1IF);
891       SET_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_ITEN);
892     }
893     else
894     {
895       status = HAL_ERROR;
896     }
897   }
898 
899   return status;
900 }
901 
902 /**
903   * @brief  Disable the interrupt and Stop the comparator.
904   * @param  hcomp COMP handle
905   * @retval HAL status
906   */
HAL_COMP_Stop_IT(COMP_HandleTypeDef * hcomp)907 HAL_StatusTypeDef HAL_COMP_Stop_IT(COMP_HandleTypeDef *hcomp)
908 {
909   HAL_StatusTypeDef status = HAL_OK;
910 
911   /* Check the COMP handle allocation and lock status */
912   if (hcomp == NULL)
913   {
914     status = HAL_ERROR;
915   }
916   else if (__HAL_COMP_IS_LOCKED(hcomp))
917   {
918     status = HAL_ERROR;
919   }
920   else
921   {
922     /* Check the parameter */
923     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
924 
925     /* Check compliant states: HAL_COMP_STATE_READY or HAL_COMP_STATE_BUSY    */
926     /* (all states except HAL_COMP_STATE_RESET and except locked status.      */
927     if (hcomp->State != HAL_COMP_STATE_RESET)
928     {
929       /* Disable the selected comparator */
930       CLEAR_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_EN);
931 
932       /* Disable the EXTI Line interrupt mode */
933       CLEAR_BIT(EXTI->IMR1, COMP_GET_EXTI_LINE(hcomp->Instance));
934 
935       /* Disable the Interrupt comparator */
936       CLEAR_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_ITEN);
937 
938       /* Set HAL COMP handle state */
939       hcomp->State = HAL_COMP_STATE_READY;
940     }
941     else
942     {
943       status = HAL_ERROR;
944     }
945   }
946 
947   return status;
948 }
949 
950 /**
951   * @brief  Comparator IRQ handler.
952   * @param  hcomp COMP handle
953   * @retval None
954   */
HAL_COMP_IRQHandler(COMP_HandleTypeDef * hcomp)955 void HAL_COMP_IRQHandler(COMP_HandleTypeDef *hcomp)
956 {
957   uint32_t polarity_toggle = 0U;
958 
959   /* Disable COMP interrupt */
960   /* Note: Specific to comparator of this STM32 series: comparator output triggers interruption on high level. */
961   __HAL_COMP_DISABLE_IT(hcomp, COMP_IT_EN);
962 
963   /* Clear COMP1 interrupt flag */
964   __HAL_COMP_CLEAR_C1IFLAG();
965   NVIC_ClearPendingIRQ(COMP1_IRQn);
966 
967   /* COMP trigger callback */
968 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1U)
969   hcomp->TriggerCallback(hcomp);
970 #else
971   HAL_COMP_TriggerCallback(hcomp);
972 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
973 
974   if (hcomp->InterruptAutoRearm == 1U)
975   {
976     /* Check whether initial comparator output level is compliant with interruption mode */
977     if (hcomp->Init.TriggerMode == COMP_EXTI_FALLING)
978     {
979       if (HAL_COMP_GetOutputLevel(hcomp) != COMP_OUTPUT_LEVEL_HIGH)
980       {
981         polarity_toggle = 1U;
982       }
983     }
984     else /* COMP_EXTI_RISING */
985     {
986       if (HAL_COMP_GetOutputLevel(hcomp) != COMP_OUTPUT_LEVEL_LOW)
987       {
988         polarity_toggle = 1U;
989       }
990     }
991 
992     if (polarity_toggle == 1U)
993     {
994       /* Toggle poarity */
995       if (READ_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_POLARITY) == 0UL)
996       {
997         SET_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_POLARITY);
998       }
999       else
1000       {
1001         CLEAR_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_POLARITY);
1002       }
1003     }
1004 
1005     /* Enable COMP interrupt */
1006     __HAL_COMP_ENABLE_IT(hcomp, COMP_IT_EN);
1007   }
1008   else
1009   {
1010     /* Change COMP state */
1011     hcomp->State = HAL_COMP_STATE_READY;
1012   }
1013 }
1014 
1015 /**
1016   * @}
1017   */
1018 
1019 /** @defgroup COMP_Exported_Functions_Group3 Peripheral Control functions
1020   *  @brief   Management functions.
1021   *
1022 @verbatim
1023  =======================================================================================================================
1024                                    ##### Peripheral Control functions #####
1025  =======================================================================================================================
1026     [..]
1027     This subsection provides a set of functions allowing to control the comparators.
1028 
1029 @endverbatim
1030   * @{
1031   */
1032 
1033 /**
1034   * @brief  Lock the selected comparator configuration.
1035   * @note   A system reset is required to unlock the comparator configuration.
1036   * @param  hcomp COMP handle
1037   * @retval HAL status
1038   */
HAL_COMP_Lock(COMP_HandleTypeDef * hcomp)1039 HAL_StatusTypeDef HAL_COMP_Lock(COMP_HandleTypeDef *hcomp)
1040 {
1041   HAL_StatusTypeDef status = HAL_OK;
1042 
1043   /* Check the COMP handle allocation and lock status */
1044   if (hcomp == NULL)
1045   {
1046     status = HAL_ERROR;
1047   }
1048   else if (__HAL_COMP_IS_LOCKED(hcomp))
1049   {
1050     status = HAL_ERROR;
1051   }
1052   else
1053   {
1054     /* Check the parameter */
1055     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
1056 
1057     /* Set HAL COMP handle state */
1058     switch (hcomp->State)
1059     {
1060       case HAL_COMP_STATE_RESET:
1061         hcomp->State = HAL_COMP_STATE_RESET_LOCKED;
1062         break;
1063       case HAL_COMP_STATE_READY:
1064         hcomp->State = HAL_COMP_STATE_READY_LOCKED;
1065         break;
1066       default: /* HAL_COMP_STATE_BUSY */
1067         hcomp->State = HAL_COMP_STATE_BUSY_LOCKED;
1068         break;
1069     }
1070 
1071     /* Set the lock bit corresponding to selected comparator */
1072     __HAL_COMP_LOCK(hcomp);
1073   }
1074   return status;
1075 }
1076 
1077 /**
1078   * @brief  Return the output level (high or low) of the selected comparator.
1079   * @note   The output level depends on the selected polarity.
1080   *         If the polarity is not inverted:
1081   *           - Comparator output is low when the input plus is at a lower
1082   *             voltage than the input minus
1083   *           - Comparator output is high when the input plus is at a higher
1084   *             voltage than the input minus
1085   *         If the polarity is inverted:
1086   *           - Comparator output is high when the input plus is at a lower
1087   *             voltage than the input minus
1088   *           - Comparator output is low when the input plus is at a higher
1089   *             voltage than the input minus
1090   * @note   Specific to comparator of this STM32 series: comparator output
1091   *         triggers interruption on high level. HAL_COMP_Start_x functions
1092   *         can change output polarity depending on initial output level.
1093   * @param  hcomp  COMP handle
1094   * @retval Returns the selected comparator output level:
1095   *         @arg @ref COMP_OUTPUT_LEVEL_LOW
1096   *         @arg @ref COMP_OUTPUT_LEVEL_HIGH
1097   *
1098   */
HAL_COMP_GetOutputLevel(const COMP_HandleTypeDef * hcomp)1099 uint32_t HAL_COMP_GetOutputLevel(const COMP_HandleTypeDef *hcomp)
1100 {
1101   /* Check the parameter */
1102   assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
1103 
1104   return (uint32_t)(READ_BIT(COMP1->SR, COMP_SR_C1VAL));
1105 }
1106 
1107 /**
1108   * @brief  Comparator trigger callback.
1109   * @param  hcomp COMP handle
1110   * @retval None
1111   */
HAL_COMP_TriggerCallback(COMP_HandleTypeDef * hcomp)1112 __weak void HAL_COMP_TriggerCallback(COMP_HandleTypeDef *hcomp)
1113 {
1114   /* Prevent unused argument(s) compilation warning */
1115   UNUSED(hcomp);
1116 
1117   /* NOTE : This function should not be modified, when the callback is needed,
1118             the HAL_COMP_TriggerCallback should be implemented in the user file
1119    */
1120 }
1121 
1122 
1123 /**
1124   * @}
1125   */
1126 
1127 /** @defgroup COMP_Exported_Functions_Group4 Peripheral State functions
1128   *  @brief   Peripheral State functions.
1129   *
1130 @verbatim
1131  =======================================================================================================================
1132                                       ##### Peripheral State functions #####
1133  =======================================================================================================================
1134     [..]
1135     This subsection permit to get in run-time the status of the peripheral.
1136 
1137 @endverbatim
1138   * @{
1139   */
1140 
1141 /**
1142   * @brief  Return the COMP handle state.
1143   * @param  hcomp  COMP handle
1144   * @retval HAL state
1145   */
HAL_COMP_GetState(const COMP_HandleTypeDef * hcomp)1146 HAL_COMP_StateTypeDef HAL_COMP_GetState(const COMP_HandleTypeDef *hcomp)
1147 {
1148   /* Check the COMP handle allocation */
1149   if (hcomp == NULL)
1150   {
1151     return HAL_COMP_STATE_RESET;
1152   }
1153 
1154   /* Check the parameter */
1155   assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
1156 
1157   /* Return HAL COMP handle state */
1158   return hcomp->State;
1159 }
1160 
1161 /**
1162   * @brief  Return the COMP error code.
1163   * @param hcomp COMP handle
1164   * @retval COMP error code
1165   */
HAL_COMP_GetError(const COMP_HandleTypeDef * hcomp)1166 uint32_t HAL_COMP_GetError(const COMP_HandleTypeDef *hcomp)
1167 {
1168   /* Check the parameters */
1169   assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
1170 
1171   return hcomp->ErrorCode;
1172 }
1173 
1174 /**
1175   * @}
1176   */
1177 
1178 /**
1179   * @}
1180   */
1181 
1182 /**
1183   * @}
1184   */
1185 
1186 #endif /* COMP1 */
1187 
1188 #endif /* HAL_COMP_MODULE_ENABLED */
1189 
1190 /**
1191   * @}
1192   */
1193