1 /**
2   ******************************************************************************
3   * @file    stm32l1xx_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) 2017 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       The STM32L1xx device family integrates 2 analog comparators COMP1 and
29       COMP2:
30       (#) The non inverting input and inverting input can be set to GPIO pins.
31           HAL COMP driver configures the Routing Interface (RI) to connect the
32           selected I/O pins to comparator input.
33           Caution: Comparator COMP1 and ADC cannot be used at the same time as
34           ADC since they share the ADC switch matrix: COMP1 non-inverting
35           input is routed through ADC switch matrix. Except if ADC is intended
36           to measure voltage on COMP1 non-inverting input: it can be performed
37           on ADC channel VCOMP.
38 
39       (#) The COMP output is available using HAL_COMP_GetOutputLevel().
40 
41       (#) The COMP output can be redirected to embedded timers (TIM2, TIM3,
42           TIM4, TIM10).
43           COMP output cannot be redirected to any I/O pin.
44 
45       (#) The comparators COMP1 and COMP2 can be combined in window mode.
46           In this mode, COMP2 non inverting input is used as common
47           non-inverting input.
48 
49       (#) The 2 comparators have interrupt capability with wake-up
50           from Sleep and Stop modes (through the EXTI controller):
51           (++) COMP1 is internally connected to EXTI Line 21
52           (++) COMP2 is internally connected to EXTI Line 22
53 
54           From the corresponding IRQ handler, the right interrupt source can be retrieved with the
55           macros __HAL_COMP_COMP1_EXTI_GET_FLAG() and __HAL_COMP_COMP2_EXTI_GET_FLAG().
56 
57       (#) The comparators also offer the possibility to output the voltage
58           reference (VrefInt), used on inverting inputs, on I/O pin through
59           a buffer. To use it, refer to macro "__HAL_SYSCFG_VREFINT_OUT_ENABLE()".
60 
61             ##### How to use this driver #####
62 ================================================================================
63   [..]
64       This driver provides functions to configure and program the Comparators of all STM32L1xx devices.
65 
66       To use the comparator, perform the following steps:
67 
68       (#)  Initialize the COMP low level resources by implementing the HAL_COMP_MspInit().
69       (++) Configure the comparator input I/O pin using HAL_GPIO_Init():
70            - For all inputs: I/O pin in analog mode (Schmitt trigger disabled)
71            - Possible alternate configuration, for non-inverting inputs of comparator 2: I/O pin in floating mode (Schmitt trigger enabled).
72            It is recommended to use analog configuration to avoid any overconsumption around VDD/2.
73       (++) Enable COMP Peripheral clock using macro __HAL_RCC_COMP_CLK_ENABLE()
74       (++) If required enable the COMP interrupt (EXTI line Interrupt): enable
75            the comparator interrupt vector using HAL_NVIC_EnableIRQ(COMP_IRQn)
76            and HAL_NVIC_SetPriority(COMP_IRQn, xxx, xxx) functions.
77 
78       (#) Configure the comparator using HAL_COMP_Init() function:
79       (++) Select the inverting input (COMP2 only)
80       (++) Select the non-inverting input
81       (++) Select the output redirection to timers (COMP2 only)
82       (++) Select the speed mode (COMP2 only)
83       (++) Select the window mode (related to COMP1 and COMP2, but selected
84            by COMP2 only)
85       (++) Select the pull-up/down resistors on non-inverting input (COMP1 only)
86 
87       (#) Enable the comparator using HAL_COMP_Start() or HAL_COMP_Start_IT()
88           function
89 
90       (#) If needed, use HAL_COMP_GetOutputLevel() or HAL_COMP_TriggerCallback()
91           functions to manage comparator actions (output level or events)
92 
93       (#) Disable the comparator using HAL_COMP_Stop() or HAL_COMP_Stop_IT()
94           function
95 
96       (#) De-initialize the comparator using HAL_COMP_DeInit() function
97 
98     *** Callback registration ***
99     =============================================
100     [..]
101 
102      The compilation flag USE_HAL_COMP_REGISTER_CALLBACKS, when set to 1,
103      allows the user to configure dynamically the driver callbacks.
104      Use Functions HAL_COMP_RegisterCallback()
105      to register an interrupt callback.
106     [..]
107 
108      Function HAL_COMP_RegisterCallback() allows to register following callbacks:
109        (+) TriggerCallback       : callback for COMP trigger.
110        (+) MspInitCallback       : callback for Msp Init.
111        (+) MspDeInitCallback     : callback for Msp DeInit.
112      This function takes as parameters the HAL peripheral handle, the Callback ID
113      and a pointer to the user callback function.
114     [..]
115 
116      Use function HAL_COMP_UnRegisterCallback to reset a callback to the default
117      weak function.
118     [..]
119 
120      HAL_COMP_UnRegisterCallback takes as parameters the HAL peripheral handle,
121      and the Callback ID.
122      This function allows to reset following callbacks:
123        (+) TriggerCallback       : callback for COMP trigger.
124        (+) MspInitCallback       : callback for Msp Init.
125        (+) MspDeInitCallback     : callback for Msp DeInit.
126      [..]
127 
128      By default, after the HAL_COMP_Init() and when the state is HAL_COMP_STATE_RESET
129      all callbacks are set to the corresponding weak functions:
130      example HAL_COMP_TriggerCallback().
131      Exception done for MspInit and MspDeInit functions that are
132      reset to the legacy weak functions in the HAL_COMP_Init()/ HAL_COMP_DeInit() only when
133      these callbacks are null (not registered beforehand).
134     [..]
135 
136      If MspInit or MspDeInit are not null, the HAL_COMP_Init()/ HAL_COMP_DeInit()
137      keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
138      [..]
139 
140      Callbacks can be registered/unregistered in HAL_COMP_STATE_READY state only.
141      Exception done MspInit/MspDeInit functions that can be registered/unregistered
142      in HAL_COMP_STATE_READY or HAL_COMP_STATE_RESET state,
143      thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
144     [..]
145 
146      Then, the user first registers the MspInit/MspDeInit user callbacks
147      using HAL_COMP_RegisterCallback() before calling HAL_COMP_DeInit()
148      or HAL_COMP_Init() function.
149      [..]
150 
151      When the compilation flag USE_HAL_COMP_REGISTER_CALLBACKS is set to 0 or
152      not defined, the callback registration feature is not available and all callbacks
153      are set to the corresponding weak functions.
154 
155   @endverbatim
156   ******************************************************************************
157   */
158 
159 /*
160   Additional remark:
161     Table 1. COMP Inputs for the STM32L1xx devices
162     +----------------------------------------------------------------------+
163     |                 |                                |  COMP1  |  COMP2  |
164     |-----------------|--------------------------------|---------|---------|
165     |                 | 1/4 VREFINT                    |   --    |   OK    |
166     |                 | 1/2 VREFINT                    |   --    |   OK    |
167     |                 | 3/4 VREFINT                    |   --    |   OK    |
168     | Inverting       | VREFINT                        |   OK    |   OK    |
169     | input           | DAC Ch1 OUT (PA4)              |   --    |   OK    |
170     |                 | DAC Ch2 OUT (PA5)              |   --    |   OK    |
171     |                 | IO: PB3                        |   --    |   OK    |
172     |-----------------|--------------------------------|---------|---------|
173     |                 | IO:                            |         |         |
174     |                 |   PB4, 5, 6*, 7*               |   ---   |   OK    |
175     | Non-inverting   |   PA0*, 1*, 2*, 3*, 4, 5, 6, 7 |   OK    |   ---   |
176     | input           |   PB0, 1, 12, 13, 14, 15       |   OK    |   ---   |
177     |                 |   PC0, 1, 2, 3, 4, 5           |   OK    |   ---   |
178     |                 |   PE7, 8, 9, 10                |   OK    |   ---   |
179     |                 |   PF6, 7, 8, 9, 10             |   OK    |   ---   |
180     |                 | OPAMP1 output                  |   OK    |   ---   |
181     |                 | OPAMP2 output                  |   OK    |   ---   |
182     |                 | OPAMP3 output**                |   OK    |   ---   |
183     +----------------------------------------------------------------------+
184     *: Available on devices category Cat.3, Cat.4, Cat.5 only.
185     **: Available on devices category Cat.4 only.
186 
187     [..] Table 2. COMP Outputs redirection to embedded timers
188     +-----------------------------------+
189     |      COMP1      |      COMP2      |
190     |-----------------|-----------------|
191     |                 |  TIM2 IC4       |
192     |                 |  TIM2 OCREF CLR |
193     | (no redirection |  TIM3 IC4       |
194     |   to timers)    |  TIM3 OCREF CLR |
195     |                 |  TIM4 IC4       |
196     |                 |  TIM4 OCREF CLR |
197     |                 |  TIM10 IC1      |
198     +-----------------------------------+
199 */
200 
201 /* Includes ------------------------------------------------------------------*/
202 #include "stm32l1xx_hal.h"
203 
204 /** @addtogroup STM32L1xx_HAL_Driver
205   * @{
206   */
207 
208 /** @defgroup COMP COMP
209   * @brief COMP HAL module driver
210   * @{
211   */
212 
213 #ifdef HAL_COMP_MODULE_ENABLED
214 
215 /* Private typedef -----------------------------------------------------------*/
216 /* Private define ------------------------------------------------------------*/
217 
218 /** @defgroup COMP_Private_Constants COMP Private Constants
219   * @{
220   */
221   /* Delay for COMP start-up time.                                            */
222   /* Maximum delay is 10us for comparator 1 and 25us for comparator 2 in slow */
223   /* mode (refer to device datasheet, parameter tSTART).                      */
224   /* Delay in CPU cycles, fixed to worst case: maximum CPU frequency 32MHz to */
225   /* have the minimum number of CPU cycles to fulfill this delay.             */
226   /*  - Comparator 1: delay minimum of 320 CPU cycles. Wait loop takes 3 CPU  */
227   /*                 cycles per iteration, therefore total wait iterations    */
228   /*                 number must be initialized at 106 iterations.            */
229   /*  - Comparator 2: delay minimum of 800 CPU cycles. Wait loop takes 3 CPU  */
230   /*                 cycles per iteration, therefore total wait iterations    */
231   /*                 number must be initialized at 266 iterations.            */
232 #define COMP1_START_DELAY_CPU_CYCLES       (106U)
233 #define COMP2_START_DELAY_CPU_CYCLES       (266U)
234 
235   /* Comparator status "locked": to update COMP handle state (software lock   */
236   /* only on COMP of STM32L1xx devices) by bitfield:                          */
237   /* states HAL_COMP_STATE_READY_LOCKED, HAL_COMP_STATE_BUSY_LOCKED.          */
238 #define COMP_STATE_BIT_LOCK     (0x00000010U)
239 
240 /**
241   * @}
242   */
243 
244 
245 /* Private macro -------------------------------------------------------------*/
246 /* Private variables ---------------------------------------------------------*/
247 /* Private function prototypes -----------------------------------------------*/
248 /* Private functions ---------------------------------------------------------*/
249 
250 /** @defgroup COMP_Exported_Functions COMP Exported Functions
251   * @{
252   */
253 
254 /** @defgroup COMP_Exported_Functions_Group1 Initialization and de-initialization functions
255  *  @brief    Initialization and Configuration functions
256  *
257 @verbatim
258  ===============================================================================
259               ##### Initialization and de-initialization functions #####
260  ===============================================================================
261     [..]  This section provides functions to initialize and de-initialize comparators
262 
263 @endverbatim
264   * @{
265   */
266 
267 /**
268   * @brief  Initializes the COMP according to the specified
269   *         parameters in the COMP_InitTypeDef and create the associated handle.
270   * @note   If the selected comparator is locked, initialization can't be performed.
271   *         To unlock the configuration, perform a system reset.
272   * @param  hcomp COMP handle
273   * @retval HAL status
274   */
HAL_COMP_Init(COMP_HandleTypeDef * hcomp)275 HAL_StatusTypeDef HAL_COMP_Init(COMP_HandleTypeDef *hcomp)
276 {
277   HAL_StatusTypeDef status = HAL_OK;
278 
279   /* Check the COMP handle allocation and lock status */
280   if((hcomp == NULL) || ((hcomp->State & COMP_STATE_BIT_LOCK) != RESET))
281   {
282     status = HAL_ERROR;
283   }
284   else
285   {
286     /* Check the parameter */
287     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
288 
289     if (hcomp->Instance == COMP1)
290     {
291       assert_param(IS_COMP_NONINVERTINGINPUTPULL(hcomp->Init.NonInvertingInputPull));
292     }
293     else /* if (hcomp->Instance == COMP2) */
294     {
295       assert_param(IS_COMP_INVERTINGINPUT(hcomp->Init.InvertingInput));
296       assert_param(IS_COMP_OUTPUT(hcomp->Init.Output));
297       assert_param(IS_COMP_MODE(hcomp->Init.Mode));
298       assert_param(IS_COMP_WINDOWMODE(hcomp->Init.WindowMode));
299     }
300 
301     /* In window mode, non-inverting inputs of the 2 comparators are          */
302     /* connected together and are using inputs of COMP2 only. If COMP1 is     */
303     /* selected, this parameter is discarded.                                 */
304     if ((hcomp->Init.WindowMode == COMP_WINDOWMODE_DISABLE) ||
305         (hcomp->Instance == COMP2)                            )
306     {
307       assert_param(IS_COMP_NONINVERTINGINPUT(hcomp->Init.NonInvertingInput));
308     }
309 
310 
311     /* Enable SYSCFG clock and the low level hardware to access comparators */
312     if(hcomp->State == HAL_COMP_STATE_RESET)
313     {
314       /* Allocate lock resource and initialize it */
315       hcomp->Lock = HAL_UNLOCKED;
316 
317       /* Enable SYSCFG clock to control the routing Interface (RI) */
318       __HAL_RCC_SYSCFG_CLK_ENABLE();
319 
320 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
321       /* Init the COMP Callback settings */
322       hcomp->TriggerCallback = HAL_COMP_TriggerCallback; /* Legacy weak callback */
323 
324       if (hcomp->MspInitCallback == NULL)
325       {
326         hcomp->MspInitCallback = HAL_COMP_MspInit; /* Legacy weak MspInit  */
327       }
328 
329       /* Init the low level hardware */
330       hcomp->MspInitCallback(hcomp);
331 #else
332       /* Init the low level hardware */
333       HAL_COMP_MspInit(hcomp);
334 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
335     }
336 
337     /* Configuration of comparator:                                           */
338     /*  - Output selection                                                    */
339     /*  - Inverting input selection                                           */
340     /*  - Window mode                                                         */
341     /*  - Mode fast/slow speed                                                */
342     /*  - Inverting input pull-up/down resistors                              */
343 
344     /* Configuration depending on comparator instance */
345     if (hcomp->Instance == COMP1)
346     {
347       MODIFY_REG(COMP->CSR, COMP_CSR_400KPD | COMP_CSR_10KPD | COMP_CSR_400KPU | COMP_CSR_10KPU,
348                             hcomp->Init.NonInvertingInputPull                                   );
349     }
350     else /* if (hcomp->Instance == COMP2) */
351     {
352       /* Note: If comparator 2 is not enabled, inverting input (parameter     */
353       /*       "hcomp->Init.InvertingInput") is configured into function      */
354       /*       "HAL_COMP_Start()" since inverting  input selection also       */
355       /*       enables the comparator 2.                                      */
356       /*       If comparator 2 is already enabled, inverting input is         */
357       /*       reconfigured on the fly.                                       */
358       if (__COMP_IS_ENABLED(hcomp) == RESET)
359       {
360         MODIFY_REG(COMP->CSR, COMP_CSR_OUTSEL  |
361                               COMP_CSR_WNDWE   |
362                               COMP_CSR_SPEED          ,
363                               hcomp->Init.Output     |
364                               hcomp->Init.WindowMode |
365                               hcomp->Init.Mode        );
366       }
367       else
368       {
369         MODIFY_REG(COMP->CSR, COMP_CSR_OUTSEL  |
370                               COMP_CSR_INSEL   |
371                               COMP_CSR_WNDWE   |
372                               COMP_CSR_SPEED              ,
373                               hcomp->Init.Output         |
374                               hcomp->Init.InvertingInput |
375                               hcomp->Init.WindowMode     |
376                               hcomp->Init.Mode            );
377       }
378     }
379 
380     /* Configure Routing Interface (RI) switches for comparator non-inverting */
381     /* input.                                                                 */
382     /* Except in 2 cases:                                                     */
383     /* - if non-inverting input has no selection: it can be the case for      */
384     /*   COMP1 in window mode.                                                */
385     /* - particular case for PC3: if switch COMP1_SW1 is closed               */
386     /*   (by macro "__HAL_OPAMP_OPAMP3OUT_CONNECT_ADC_COMP1()" or             */
387     /*   "__HAL_RI_SWITCH_COMP1_SW1_CLOSE()"), connection between pin PC3     */
388     /*    (or OPAMP3, if available) and COMP1 is done directly, without going */
389     /*    through ADC switch matrix.                                          */
390 #if defined(COMP_CSR_SW1)
391     if(READ_BIT(COMP->CSR, COMP_CSR_SW1) != RESET)
392     {
393       if(hcomp->Init.NonInvertingInput != COMP_NONINVERTINGINPUT_PC3)
394       {
395         /* Case of switch COMP1_SW1 closed and non-inverting input different of PC3:
396            setting of another input is not possible (issue of pin shorted with PC3) */
397         status = HAL_ERROR;
398       }
399     }
400     else
401 #endif
402     {
403       if (__COMP_ROUTING_INTERFACE_TOBECONFIGURED(hcomp))
404       {
405         if (hcomp->Instance == COMP1)
406         {
407           /* Enable the switch control mode */
408           __HAL_RI_SWITCHCONTROLMODE_ENABLE();
409 
410           /* Close the analog switch of ADC switch matrix to COMP1 (ADC         */
411           /* channel 26: Vcomp)                                                 */
412           __HAL_RI_IOSWITCH_CLOSE(RI_IOSWITCH_VCOMP);
413         }
414 
415         /* Close the I/O analog switch corresponding to comparator              */
416         /* non-inverting input selected.                                        */
417         __HAL_RI_IOSWITCH_CLOSE(hcomp->Init.NonInvertingInput);
418       }
419     }
420 
421 
422     /* Initialize the COMP state*/
423     if(hcomp->State == HAL_COMP_STATE_RESET)
424     {
425       hcomp->State = HAL_COMP_STATE_READY;
426     }
427   }
428 
429   return status;
430 }
431 
432 
433 /**
434   * @brief  DeInitializes the COMP peripheral
435   * @note   Deinitialization can't be performed if the COMP configuration is locked.
436   *         To unlock the configuration, perform a system reset.
437   * @param  hcomp COMP handle
438   * @retval HAL status
439   */
HAL_COMP_DeInit(COMP_HandleTypeDef * hcomp)440 HAL_StatusTypeDef HAL_COMP_DeInit(COMP_HandleTypeDef *hcomp)
441 {
442   HAL_StatusTypeDef status = HAL_OK;
443 
444   /* Check the COMP handle allocation and lock status */
445   if((hcomp == NULL) || ((hcomp->State & COMP_STATE_BIT_LOCK) != RESET))
446   {
447     status = HAL_ERROR;
448   }
449   else
450   {
451     /* Check the parameter */
452     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
453 
454     /* Reset configuration depending on comparator instance */
455     if (hcomp->Instance == COMP1)
456     {
457       CLEAR_BIT(COMP->CSR , COMP_CSR_400KPD | COMP_CSR_10KPD | COMP_CSR_400KPU | COMP_CSR_10KPU);
458     }
459     else /* if (hcomp->Instance == COMP2) */
460     {
461       CLEAR_BIT(COMP->CSR , COMP_CSR_OUTSEL |
462                             COMP_CSR_WNDWE  |
463                             COMP_CSR_INSEL  |
464                             COMP_CSR_SPEED   );
465     }
466 
467 
468     /* Restore default state of Routing Interface (RI) switches for           */
469     /* comparator non-inverting input.                                        */
470     if (hcomp->Init.NonInvertingInput != COMP_NONINVERTINGINPUT_NONE)
471     {
472       /* Open the I/O analog switch corresponding to comparator               */
473       /* non-inverting input selected.                                        */
474       __HAL_RI_IOSWITCH_OPEN(hcomp->Init.NonInvertingInput);
475     }
476     if (hcomp->Instance == COMP1)
477     {
478       /* Open the analog switch of ADC switch matrix to COMP1 (ADC            */
479       /* channel 26: Vcomp)                                                   */
480       __HAL_RI_IOSWITCH_OPEN(RI_IOSWITCH_VCOMP);
481 
482       /* Disable the switch control mode */
483       __HAL_RI_SWITCHCONTROLMODE_DISABLE();
484     }
485 
486 
487 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
488     if (hcomp->MspDeInitCallback == NULL)
489     {
490       hcomp->MspDeInitCallback = HAL_COMP_MspDeInit; /* Legacy weak MspDeInit  */
491     }
492 
493     /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
494     hcomp->MspDeInitCallback(hcomp);
495 #else
496     /* DeInit the low level hardware: SYSCFG, GPIO, CLOCK, NVIC */
497     HAL_COMP_MspDeInit(hcomp);
498 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
499 
500     hcomp->State = HAL_COMP_STATE_RESET;
501 
502     /* Process unlocked */
503     __HAL_UNLOCK(hcomp);
504   }
505 
506   return status;
507 }
508 
509 /**
510   * @brief  Initializes the COMP MSP.
511   * @param  hcomp COMP handle
512   * @retval None
513   */
HAL_COMP_MspInit(COMP_HandleTypeDef * hcomp)514 __weak void HAL_COMP_MspInit(COMP_HandleTypeDef *hcomp)
515 {
516   /* Prevent unused argument(s) compilation warning */
517   UNUSED(hcomp);
518 
519   /* NOTE : This function Should not be modified, when the callback is needed,
520             the HAL_COMP_MspInit could be implenetd in the user file
521    */
522 }
523 
524 /**
525   * @brief  DeInitializes COMP MSP.
526   * @param  hcomp COMP handle
527   * @retval None
528   */
HAL_COMP_MspDeInit(COMP_HandleTypeDef * hcomp)529 __weak void HAL_COMP_MspDeInit(COMP_HandleTypeDef *hcomp)
530 {
531   /* Prevent unused argument(s) compilation warning */
532   UNUSED(hcomp);
533 
534   /* NOTE : This function Should not be modified, when the callback is needed,
535             the HAL_COMP_MspDeInit could be implenetd in the user file
536    */
537 }
538 
539 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
540 /**
541   * @brief  Register a User COMP Callback
542   *         To be used instead of the weak predefined callback
543   * @param  hcomp Pointer to a COMP_HandleTypeDef structure that contains
544   *                the configuration information for the specified COMP.
545   * @param  CallbackID ID of the callback to be registered
546   *         This parameter can be one of the following values:
547   *          @arg @ref HAL_COMP_TRIGGER_CB_ID Trigger callback ID
548   *          @arg @ref HAL_COMP_MSPINIT_CB_ID MspInit callback ID
549   *          @arg @ref HAL_COMP_MSPDEINIT_CB_ID MspDeInit callback ID
550   * @param  pCallback pointer to the Callback function
551   * @retval HAL status
552   */
HAL_COMP_RegisterCallback(COMP_HandleTypeDef * hcomp,HAL_COMP_CallbackIDTypeDef CallbackID,pCOMP_CallbackTypeDef pCallback)553 HAL_StatusTypeDef HAL_COMP_RegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID, pCOMP_CallbackTypeDef pCallback)
554 {
555   HAL_StatusTypeDef status = HAL_OK;
556 
557   if (pCallback == NULL)
558   {
559     /* Update the error code */
560     hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
561 
562     return HAL_ERROR;
563   }
564 
565   if (HAL_COMP_STATE_READY == hcomp->State)
566   {
567     switch (CallbackID)
568     {
569       case HAL_COMP_TRIGGER_CB_ID :
570         hcomp->TriggerCallback = pCallback;
571         break;
572 
573       case HAL_COMP_MSPINIT_CB_ID :
574         hcomp->MspInitCallback = pCallback;
575         break;
576 
577       case HAL_COMP_MSPDEINIT_CB_ID :
578         hcomp->MspDeInitCallback = pCallback;
579         break;
580 
581       default :
582         /* Update the error code */
583         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
584 
585         /* Return error status */
586         status = HAL_ERROR;
587         break;
588     }
589   }
590   else if (HAL_COMP_STATE_RESET == hcomp->State)
591   {
592     switch (CallbackID)
593     {
594       case HAL_COMP_MSPINIT_CB_ID :
595         hcomp->MspInitCallback = pCallback;
596         break;
597 
598       case HAL_COMP_MSPDEINIT_CB_ID :
599         hcomp->MspDeInitCallback = pCallback;
600         break;
601 
602       default :
603         /* Update the error code */
604         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
605 
606         /* Return error status */
607         status = HAL_ERROR;
608         break;
609     }
610   }
611   else
612   {
613     /* Update the error code */
614     hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
615 
616     /* Return error status */
617     status =  HAL_ERROR;
618   }
619 
620   return status;
621 }
622 
623 /**
624   * @brief  Unregister a COMP Callback
625   *         COMP callback is redirected to the weak predefined callback
626   * @param  hcomp Pointer to a COMP_HandleTypeDef structure that contains
627   *                the configuration information for the specified COMP.
628   * @param  CallbackID ID of the callback to be unregistered
629   *         This parameter can be one of the following values:
630   *          @arg @ref HAL_COMP_TRIGGER_CB_ID Trigger callback ID
631   *          @arg @ref HAL_COMP_MSPINIT_CB_ID MspInit callback ID
632   *          @arg @ref HAL_COMP_MSPDEINIT_CB_ID MspDeInit callback ID
633   * @retval HAL status
634   */
HAL_COMP_UnRegisterCallback(COMP_HandleTypeDef * hcomp,HAL_COMP_CallbackIDTypeDef CallbackID)635 HAL_StatusTypeDef HAL_COMP_UnRegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID)
636 {
637   HAL_StatusTypeDef status = HAL_OK;
638 
639   if (HAL_COMP_STATE_READY == hcomp->State)
640   {
641     switch (CallbackID)
642     {
643       case HAL_COMP_TRIGGER_CB_ID :
644         hcomp->TriggerCallback = HAL_COMP_TriggerCallback;         /* Legacy weak callback */
645         break;
646 
647       case HAL_COMP_MSPINIT_CB_ID :
648         hcomp->MspInitCallback = HAL_COMP_MspInit;                 /* Legacy weak MspInit */
649         break;
650 
651       case HAL_COMP_MSPDEINIT_CB_ID :
652         hcomp->MspDeInitCallback = HAL_COMP_MspDeInit;             /* Legacy weak MspDeInit */
653         break;
654 
655       default :
656         /* Update the error code */
657         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
658 
659         /* Return error status */
660         status =  HAL_ERROR;
661         break;
662     }
663   }
664   else if (HAL_COMP_STATE_RESET == hcomp->State)
665   {
666     switch (CallbackID)
667     {
668       case HAL_COMP_MSPINIT_CB_ID :
669         hcomp->MspInitCallback = HAL_COMP_MspInit;                 /* Legacy weak MspInit */
670         break;
671 
672       case HAL_COMP_MSPDEINIT_CB_ID :
673         hcomp->MspDeInitCallback = HAL_COMP_MspDeInit;             /* Legacy weak MspDeInit */
674         break;
675 
676       default :
677         /* Update the error code */
678         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
679 
680         /* Return error status */
681         status =  HAL_ERROR;
682         break;
683     }
684   }
685   else
686   {
687     /* Update the error code */
688     hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
689 
690     /* Return error status */
691     status =  HAL_ERROR;
692   }
693 
694   return status;
695 }
696 
697 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
698 
699 /**
700   * @}
701   */
702 
703 /** @defgroup COMP_Exported_Functions_Group2 I/O operation functions
704  *  @brief   I/O operation functions
705  *
706 @verbatim
707  ===============================================================================
708                       ##### IO operation functions #####
709  ===============================================================================
710     [..]
711     This subsection provides a set of functions allowing to manage the COMP
712     start and stop actions with or without interruption on ExtI line.
713 
714 @endverbatim
715   * @{
716   */
717 
718 /**
719   * @brief  Start the comparator
720   * @param  hcomp COMP handle
721   * @retval HAL status
722   */
HAL_COMP_Start(COMP_HandleTypeDef * hcomp)723 HAL_StatusTypeDef HAL_COMP_Start(COMP_HandleTypeDef *hcomp)
724 {
725   HAL_StatusTypeDef status = HAL_OK;
726   uint32_t wait_loop_cycles = 0;
727   __IO uint32_t wait_loop_index = 0;
728 
729   /* Check the COMP handle allocation and lock status */
730   if((hcomp == NULL) || ((hcomp->State & COMP_STATE_BIT_LOCK) != RESET))
731   {
732     status = HAL_ERROR;
733   }
734   else
735   {
736     /* Check the parameter */
737     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
738 
739     if(hcomp->State == HAL_COMP_STATE_READY)
740     {
741 
742       /* Note: For comparator 2, inverting input (parameter                   */
743       /*       "hcomp->Init.InvertingInput") is configured into this          */
744       /*       function instead of function "HAL_COMP_Init()" since           */
745       /*       inverting input selection also enables the comparator 2.       */
746       __HAL_COMP_ENABLE(hcomp);
747 
748       /* Set delay for COMP start-up time */
749       if (hcomp->Instance == COMP1)
750       {
751         wait_loop_cycles = COMP1_START_DELAY_CPU_CYCLES;
752       }
753       else /* if (hcomp->Instance == COMP2) */
754       {
755         wait_loop_cycles = COMP2_START_DELAY_CPU_CYCLES;
756       }
757 
758       /* Delay for COMP start-up time.                                         */
759       /* Delay fixed to worst case: maximum CPU frequency                     */
760       while(wait_loop_index < wait_loop_cycles)
761       {
762         wait_loop_index++;
763       }
764 
765       /* Update COMP state */
766       hcomp->State = HAL_COMP_STATE_BUSY;
767 
768     }
769     else
770     {
771       status = HAL_ERROR;
772     }
773   }
774 
775   return status;
776 }
777 
778 /**
779   * @brief  Stop the comparator
780   * @param  hcomp COMP handle
781   * @retval HAL status
782   */
HAL_COMP_Stop(COMP_HandleTypeDef * hcomp)783 HAL_StatusTypeDef HAL_COMP_Stop(COMP_HandleTypeDef *hcomp)
784 {
785   HAL_StatusTypeDef status = HAL_OK;
786 
787   /* Check the COMP handle allocation and lock status */
788   if((hcomp == NULL) || ((hcomp->State & COMP_STATE_BIT_LOCK) != RESET))
789   {
790     status = HAL_ERROR;
791   }
792   else
793   {
794     /* Check the parameter */
795     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
796 
797     if(hcomp->State == HAL_COMP_STATE_BUSY)
798     {
799       /* Disable the selected comparator */
800       __HAL_COMP_DISABLE(hcomp);
801 
802       /* Update COMP state */
803       hcomp->State = HAL_COMP_STATE_READY;
804     }
805     else
806     {
807       status = HAL_ERROR;
808     }
809   }
810 
811   return status;
812 }
813 
814 /**
815   * @brief  Enables the interrupt and starts the comparator
816   * @param  hcomp COMP handle
817   * @retval HAL status.
818   */
HAL_COMP_Start_IT(COMP_HandleTypeDef * hcomp)819 HAL_StatusTypeDef HAL_COMP_Start_IT(COMP_HandleTypeDef *hcomp)
820 {
821   HAL_StatusTypeDef status = HAL_OK;
822   uint32_t extiline = 0;
823 
824   status = HAL_COMP_Start(hcomp);
825   if(status == HAL_OK)
826   {
827     /* Check the parameter */
828     assert_param(IS_COMP_TRIGGERMODE(hcomp->Init.TriggerMode));
829 
830     /* Get the Exti Line output configuration */
831     extiline = COMP_GET_EXTI_LINE(hcomp->Instance);
832 
833     /* Configure the trigger rising edge */
834     if((hcomp->Init.TriggerMode & COMP_TRIGGERMODE_IT_RISING) != RESET)
835     {
836       SET_BIT(EXTI->RTSR, extiline);
837     }
838     else
839     {
840       CLEAR_BIT(EXTI->RTSR, extiline);
841     }
842 
843     /* Configure the trigger falling edge */
844     if((hcomp->Init.TriggerMode & COMP_TRIGGERMODE_IT_FALLING) != RESET)
845     {
846       SET_BIT(EXTI->FTSR, extiline);
847     }
848     else
849     {
850       CLEAR_BIT(EXTI->FTSR, extiline);
851     }
852 
853     /* Clear COMP EXTI pending bit */
854     WRITE_REG(EXTI->PR, extiline);
855 
856     /* Enable EXTI interrupt mode */
857     SET_BIT(EXTI->IMR, extiline);
858 
859   }
860 
861   return status;
862 }
863 
864 /**
865   * @brief  Disable the interrupt and Stop the comparator
866   * @param  hcomp COMP handle
867   * @retval HAL status
868   */
HAL_COMP_Stop_IT(COMP_HandleTypeDef * hcomp)869 HAL_StatusTypeDef HAL_COMP_Stop_IT(COMP_HandleTypeDef *hcomp)
870 {
871   HAL_StatusTypeDef status = HAL_OK;
872 
873   /* Disable the EXTI Line interrupt mode */
874   CLEAR_BIT(EXTI->IMR, COMP_GET_EXTI_LINE(hcomp->Instance));
875 
876   status = HAL_COMP_Stop(hcomp);
877 
878   return status;
879 }
880 
881 /**
882   * @brief  Comparator IRQ Handler
883   * @param  hcomp COMP handle
884   * @retval HAL status
885   */
HAL_COMP_IRQHandler(COMP_HandleTypeDef * hcomp)886 void HAL_COMP_IRQHandler(COMP_HandleTypeDef *hcomp)
887 {
888   uint32_t extiline = COMP_GET_EXTI_LINE(hcomp->Instance);
889 
890   /* Check COMP Exti flag */
891   if(READ_BIT(EXTI->PR, extiline) != RESET)
892   {
893     /* Clear COMP EXTI pending bit */
894     WRITE_REG(EXTI->PR, extiline);
895 
896     /* COMP trigger callback */
897 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
898     hcomp->TriggerCallback(hcomp);
899 #else
900     HAL_COMP_TriggerCallback(hcomp);
901 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
902   }
903 }
904 
905 /**
906   * @}
907   */
908 
909 /** @defgroup COMP_Exported_Functions_Group3 Peripheral Control functions
910  *  @brief   Peripheral Control functions
911  *
912 @verbatim
913  ===============================================================================
914                       ##### Peripheral Control functions #####
915  ===============================================================================
916     [..]
917     This subsection provides a set of functions allowing to control the COMP
918     management functions: Lock status, comparator output level check, IRQ
919     callback (in case of usage of comparator with interruption on ExtI line).
920 
921 @endverbatim
922   * @{
923   */
924 
925 /**
926   * @brief  Lock the selected comparator configuration.
927   *         Caution: On STM32L1, HAL COMP lock is software lock only (not
928   *         hardware lock as on some other STM32 devices)
929   * @param  hcomp COMP handle
930   * @retval HAL status
931   */
HAL_COMP_Lock(COMP_HandleTypeDef * hcomp)932 HAL_StatusTypeDef HAL_COMP_Lock(COMP_HandleTypeDef *hcomp)
933 {
934   HAL_StatusTypeDef status = HAL_OK;
935 
936   /* Check the COMP handle allocation and lock status */
937   if((hcomp == NULL) || ((hcomp->State & COMP_STATE_BIT_LOCK) != RESET))
938   {
939     status = HAL_ERROR;
940   }
941   else
942   {
943     /* Check the parameter */
944     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
945 
946     /* Set lock flag on state */
947     switch(hcomp->State)
948     {
949     case HAL_COMP_STATE_BUSY:
950       hcomp->State = HAL_COMP_STATE_BUSY_LOCKED;
951       break;
952     case HAL_COMP_STATE_READY:
953       hcomp->State = HAL_COMP_STATE_READY_LOCKED;
954       break;
955     default:
956       /* unexpected state */
957       status = HAL_ERROR;
958       break;
959     }
960   }
961 
962   return status;
963 }
964 
965 /**
966   * @brief  Return the output level (high or low) of the selected comparator.
967   *         The output level depends on the selected polarity.
968   *           - Comparator output is low when the non-inverting input is at a lower
969   *             voltage than the inverting input
970   *           - Comparator output is high when the non-inverting input is at a higher
971   *             voltage than the inverting input
972   * @param  hcomp COMP handle
973   * @retval Returns the selected comparator output level: COMP_OUTPUTLEVEL_LOW or COMP_OUTPUTLEVEL_HIGH.
974   *
975   */
HAL_COMP_GetOutputLevel(COMP_HandleTypeDef * hcomp)976 uint32_t HAL_COMP_GetOutputLevel(COMP_HandleTypeDef *hcomp)
977 {
978   uint32_t level = 0;
979 
980   /* Check the parameter */
981   assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
982 
983   /* Read output level of the selected comparator */
984   if(READ_BIT(COMP->CSR, __COMP_CSR_CMPXOUT(hcomp)) == RESET)
985   {
986     level = COMP_OUTPUTLEVEL_LOW;
987   }
988   else
989   {
990     level = COMP_OUTPUTLEVEL_HIGH;
991   }
992 
993   return(level);
994 }
995 
996 /**
997   * @brief  Comparator trigger callback.
998   * @param  hcomp COMP handle
999   * @retval None
1000   */
HAL_COMP_TriggerCallback(COMP_HandleTypeDef * hcomp)1001 __weak void HAL_COMP_TriggerCallback(COMP_HandleTypeDef *hcomp)
1002 {
1003   /* Prevent unused argument(s) compilation warning */
1004   UNUSED(hcomp);
1005 
1006   /* NOTE : This function should not be modified, when the callback is needed,
1007             the HAL_COMP_TriggerCallback should be implemented in the user file
1008    */
1009 }
1010 
1011 
1012 /**
1013   * @}
1014   */
1015 
1016 /** @defgroup COMP_Exported_Functions_Group4 Peripheral State functions
1017  *  @brief   Peripheral State functions
1018  *
1019 @verbatim
1020  ===============================================================================
1021                       ##### Peripheral State functions #####
1022  ===============================================================================
1023     [..]
1024     This subsection permit to get in run-time the status of the peripheral.
1025 
1026 @endverbatim
1027   * @{
1028   */
1029 
1030 /**
1031   * @brief  Return the COMP state
1032   * @param  hcomp  COMP handle
1033   * @retval HAL state
1034   */
HAL_COMP_GetState(COMP_HandleTypeDef * hcomp)1035 HAL_COMP_StateTypeDef HAL_COMP_GetState(COMP_HandleTypeDef *hcomp)
1036 {
1037   /* Check the COMP handle allocation */
1038   if(hcomp == NULL)
1039   {
1040     return HAL_COMP_STATE_RESET;
1041   }
1042 
1043   /* Check the parameter */
1044   assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
1045 
1046   return hcomp->State;
1047 }
1048 
1049 /**
1050   * @brief  Return the COMP error code.
1051   * @param hcomp COMP handle
1052   * @retval COMP error code
1053   */
HAL_COMP_GetError(COMP_HandleTypeDef * hcomp)1054 uint32_t HAL_COMP_GetError(COMP_HandleTypeDef *hcomp)
1055 {
1056   /* Check the parameters */
1057   assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
1058 
1059   return hcomp->ErrorCode;
1060 }
1061 
1062 /**
1063   * @}
1064   */
1065 
1066 /**
1067   * @}
1068   */
1069 
1070 #endif /* HAL_COMP_MODULE_ENABLED */
1071 /**
1072   * @}
1073   */
1074 
1075 /**
1076   * @}
1077   */
1078 
1079