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