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