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