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>© 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