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