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