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