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