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