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