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