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