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