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