1 /**
2 ******************************************************************************
3 * @file stm32g0xx_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) 2018 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 STM32G0xx 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 STM32G0xx 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
159 /* Includes ------------------------------------------------------------------*/
160 #include "stm32g0xx_hal.h"
161
162 /** @addtogroup STM32G0xx_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 #if defined(COMP3)
238 __IO uint32_t * comp_common_odd;
239 __IO uint32_t * comp_common_even;
240 #endif /* COMP3 */
241
242 /* Check the COMP handle allocation and lock status */
243 if(hcomp == NULL)
244 {
245 status = HAL_ERROR;
246 }
247 else if(__HAL_COMP_IS_LOCKED(hcomp))
248 {
249 status = HAL_ERROR;
250 }
251 else
252 {
253 /* Check the parameters */
254 assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
255 assert_param(IS_COMP_INPUT_PLUS(hcomp->Instance, hcomp->Init.InputPlus));
256 assert_param(IS_COMP_INPUT_MINUS(hcomp->Instance, hcomp->Init.InputMinus));
257 assert_param(IS_COMP_OUTPUTPOL(hcomp->Init.OutputPol));
258 assert_param(IS_COMP_POWERMODE(hcomp->Init.Mode));
259 assert_param(IS_COMP_HYSTERESIS(hcomp->Init.Hysteresis));
260 assert_param(IS_COMP_BLANKINGSRC_INSTANCE(hcomp->Instance, hcomp->Init.BlankingSrce));
261 assert_param(IS_COMP_TRIGGERMODE(hcomp->Init.TriggerMode));
262 assert_param(IS_COMP_WINDOWMODE(hcomp->Instance, hcomp->Init.WindowMode));
263 if(hcomp->Init.WindowMode != COMP_WINDOWMODE_DISABLE)
264 {
265 assert_param(IS_COMP_WINDOWOUTPUT(hcomp->Init.WindowOutput));
266 }
267
268 if(hcomp->State == HAL_COMP_STATE_RESET)
269 {
270 /* Allocate lock resource and initialize it */
271 hcomp->Lock = HAL_UNLOCKED;
272
273 /* Set COMP error code to none */
274 COMP_CLEAR_ERRORCODE(hcomp);
275
276
277 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
278 /* Init the COMP Callback settings */
279 hcomp->TriggerCallback = HAL_COMP_TriggerCallback; /* Legacy weak callback */
280
281 if (hcomp->MspInitCallback == NULL)
282 {
283 hcomp->MspInitCallback = HAL_COMP_MspInit; /* Legacy weak MspInit */
284 }
285
286 /* Init the low level hardware */
287 /* Note: Internal control clock of the comparators must */
288 /* be enabled in "HAL_COMP_MspInit()" */
289 /* using "__HAL_RCC_SYSCFG_CLK_ENABLE()". */
290 hcomp->MspInitCallback(hcomp);
291 #else
292 /* Init the low level hardware */
293 /* Note: Internal control clock of the comparators must */
294 /* be enabled in "HAL_COMP_MspInit()" */
295 /* using "__HAL_RCC_SYSCFG_CLK_ENABLE()". */
296 HAL_COMP_MspInit(hcomp);
297 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
298 }
299
300 /* Memorize voltage scaler state before initialization */
301 comp_voltage_scaler_initialized = READ_BIT(hcomp->Instance->CSR, (COMP_CSR_INMSEL_1 | COMP_CSR_INMSEL_0));
302
303 /* Set COMP parameters */
304 tmp_csr = ( hcomp->Init.InputMinus
305 | hcomp->Init.InputPlus
306 | hcomp->Init.BlankingSrce
307 | hcomp->Init.Hysteresis
308 | hcomp->Init.OutputPol
309 | hcomp->Init.Mode
310 );
311
312 /* Set parameters in COMP register */
313 /* Note: Update all bits except read-only, lock and enable bits */
314 MODIFY_REG(hcomp->Instance->CSR,
315 COMP_CSR_PWRMODE | COMP_CSR_INMSEL | COMP_CSR_INPSEL |
316 COMP_CSR_WINMODE | COMP_CSR_POLARITY | COMP_CSR_HYST |
317 COMP_CSR_BLANKING ,
318 tmp_csr
319 );
320
321 /* Set window mode */
322 /* Note: Window mode bit is located into 1 out of the 2 pairs of COMP */
323 /* instances. Therefore, this function can update another COMP */
324 /* instance that the one currently selected. */
325 #if defined(COMP3)
326 if(hcomp->Instance == COMP3)
327 {
328 /* Note: Exception for STM32G0 devices featuring ADC3 instance: in common */
329 /* group of COMP2 and COMP3, instances odd and even are inverted. */
330 /* Perform switch of parameter selected. */
331 comp_common_odd = &(COMP23_COMMON->CSR_EVEN);
332 comp_common_even = &(COMP23_COMMON->CSR_ODD);
333 }
334 else
335 {
336 comp_common_odd = &(COMP12_COMMON->CSR_ODD);
337 comp_common_even = &(COMP12_COMMON->CSR_EVEN);
338 }
339
340 if(hcomp->Init.WindowMode == COMP_WINDOWMODE_COMP1_INPUT_PLUS_COMMON)
341 {
342 CLEAR_BIT(*comp_common_odd, COMP_CSR_WINMODE);
343 SET_BIT(*comp_common_even, COMP_CSR_WINMODE);
344 }
345 else if(hcomp->Init.WindowMode == COMP_WINDOWMODE_COMP2_INPUT_PLUS_COMMON)
346 {
347 SET_BIT(*comp_common_odd, COMP_CSR_WINMODE);
348 CLEAR_BIT(*comp_common_even, COMP_CSR_WINMODE);
349 }
350 else
351 {
352 CLEAR_BIT(*comp_common_odd, COMP_CSR_WINMODE);
353 CLEAR_BIT(*comp_common_even, COMP_CSR_WINMODE);
354 }
355
356 /* Set window mode output */
357 /* Note: Window mode mode output can also be used when window mode */
358 /* is disabled, to use comparators in independent mode with their */
359 /* output connected through exclusive-or circuitry. */
360 switch (hcomp->Init.WindowOutput)
361 {
362 case COMP_WINDOWOUTPUT_COMP1: /* idem COMP_WINDOWOUTPUT_COMP3 (same literal value) */
363 SET_BIT(*comp_common_odd, COMP_CSR_WINOUT);
364 CLEAR_BIT(*comp_common_even, COMP_CSR_WINOUT);
365 break;
366
367 case COMP_WINDOWOUTPUT_COMP2:
368 CLEAR_BIT(*comp_common_odd, COMP_CSR_WINOUT);
369 SET_BIT(*comp_common_even, COMP_CSR_WINOUT);
370 break;
371
372 case COMP_WINDOWOUTPUT_BOTH:
373 SET_BIT(*comp_common_odd, COMP_CSR_WINOUT);
374 SET_BIT(*comp_common_even, COMP_CSR_WINOUT);
375 break;
376
377 default: /* COMP_WINDOWOUTPUT_EACH_COMP */
378 CLEAR_BIT(*comp_common_odd, COMP_CSR_WINOUT);
379 CLEAR_BIT(*comp_common_even, COMP_CSR_WINOUT);
380 break;
381 }
382 #else
383 if(hcomp->Init.WindowMode == COMP_WINDOWMODE_COMP1_INPUT_PLUS_COMMON)
384 {
385 CLEAR_BIT(COMP12_COMMON->CSR_ODD, COMP_CSR_WINMODE);
386 SET_BIT(COMP12_COMMON->CSR_EVEN, COMP_CSR_WINMODE);
387 }
388 else if(hcomp->Init.WindowMode == COMP_WINDOWMODE_COMP2_INPUT_PLUS_COMMON)
389 {
390 SET_BIT(COMP12_COMMON->CSR_ODD, COMP_CSR_WINMODE);
391 CLEAR_BIT(COMP12_COMMON->CSR_EVEN, COMP_CSR_WINMODE);
392 }
393 else
394 {
395 CLEAR_BIT(COMP12_COMMON->CSR_ODD, COMP_CSR_WINMODE);
396 CLEAR_BIT(COMP12_COMMON->CSR_EVEN, COMP_CSR_WINMODE);
397 }
398
399 /* Set window mode output */
400 /* Note: Window mode mode output can also be used when window mode */
401 /* is disabled, to use comparators in independent mode with their */
402 /* output connected through exclusive-or circuitry. */
403 switch (hcomp->Init.WindowOutput)
404 {
405 case COMP_WINDOWOUTPUT_COMP1:
406 SET_BIT(COMP12_COMMON->CSR_ODD, COMP_CSR_WINOUT);
407 CLEAR_BIT(COMP12_COMMON->CSR_EVEN, COMP_CSR_WINOUT);
408 break;
409
410 case COMP_WINDOWOUTPUT_COMP2:
411 CLEAR_BIT(COMP12_COMMON->CSR_ODD, COMP_CSR_WINOUT);
412 SET_BIT(COMP12_COMMON->CSR_EVEN, COMP_CSR_WINOUT);
413 break;
414
415 case COMP_WINDOWOUTPUT_BOTH:
416 SET_BIT(COMP12_COMMON->CSR_ODD, COMP_CSR_WINOUT);
417 SET_BIT(COMP12_COMMON->CSR_EVEN, COMP_CSR_WINOUT);
418 break;
419
420 default: /* COMP_WINDOWOUTPUT_EACH_COMP */
421 CLEAR_BIT(COMP12_COMMON->CSR_ODD, COMP_CSR_WINOUT);
422 CLEAR_BIT(COMP12_COMMON->CSR_EVEN, COMP_CSR_WINOUT);
423 break;
424 }
425 #endif /* COMP3 */
426
427 /* Delay for COMP scaler bridge voltage stabilization */
428 /* Apply the delay if voltage scaler bridge is required and not already enabled */
429 if ((READ_BIT(hcomp->Instance->CSR, (COMP_CSR_INMSEL_1 | COMP_CSR_INMSEL_0)) != 0UL) &&
430 (comp_voltage_scaler_initialized == 0UL) )
431 {
432 /* Wait loop initialization and execution */
433 /* Note: Variable divided by 2 to compensate partially */
434 /* CPU processing cycles, scaling in us split to not */
435 /* exceed 32 bits register capacity and handle low frequency. */
436 wait_loop_index = ((COMP_DELAY_VOLTAGE_SCALER_STAB_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
437 while(wait_loop_index != 0UL)
438 {
439 wait_loop_index--;
440 }
441 }
442
443 /* Get the EXTI line corresponding to the selected COMP instance */
444 exti_line = COMP_GET_EXTI_LINE(hcomp->Instance);
445
446 /* Manage EXTI settings */
447 if((hcomp->Init.TriggerMode & (COMP_EXTI_IT | COMP_EXTI_EVENT)) != 0UL)
448 {
449 /* Configure EXTI rising edge */
450 if((hcomp->Init.TriggerMode & COMP_EXTI_RISING) != 0UL)
451 {
452 LL_EXTI_EnableRisingTrig_0_31(exti_line);
453 }
454 else
455 {
456 LL_EXTI_DisableRisingTrig_0_31(exti_line);
457 }
458
459 /* Configure EXTI falling edge */
460 if((hcomp->Init.TriggerMode & COMP_EXTI_FALLING) != 0UL)
461 {
462 LL_EXTI_EnableFallingTrig_0_31(exti_line);
463 }
464 else
465 {
466 LL_EXTI_DisableFallingTrig_0_31(exti_line);
467 }
468
469 /* Clear COMP EXTI pending bit (if any) */
470 LL_EXTI_ClearRisingFlag_0_31(exti_line);
471 LL_EXTI_ClearFallingFlag_0_31(exti_line);
472
473 /* Configure EXTI event mode */
474 if((hcomp->Init.TriggerMode & COMP_EXTI_EVENT) != 0UL)
475 {
476 LL_EXTI_EnableEvent_0_31(exti_line);
477 }
478 else
479 {
480 LL_EXTI_DisableEvent_0_31(exti_line);
481 }
482
483 /* Configure EXTI interrupt mode */
484 if((hcomp->Init.TriggerMode & COMP_EXTI_IT) != 0UL)
485 {
486 LL_EXTI_EnableIT_0_31(exti_line);
487 }
488 else
489 {
490 LL_EXTI_DisableIT_0_31(exti_line);
491 }
492 }
493 else
494 {
495 /* Disable EXTI event mode */
496 LL_EXTI_DisableEvent_0_31(exti_line);
497
498 /* Disable EXTI interrupt mode */
499 LL_EXTI_DisableIT_0_31(exti_line);
500 }
501
502 /* Set HAL COMP handle state */
503 /* Note: Transition from state reset to state ready, */
504 /* otherwise (coming from state ready or busy) no state update. */
505 if (hcomp->State == HAL_COMP_STATE_RESET)
506 {
507 hcomp->State = HAL_COMP_STATE_READY;
508 }
509 }
510
511 return status;
512 }
513
514 /**
515 * @brief DeInitialize the COMP peripheral.
516 * @note Deinitialization cannot be performed if the COMP configuration is locked.
517 * To unlock the configuration, perform a system reset.
518 * @param hcomp COMP handle
519 * @retval HAL status
520 */
HAL_COMP_DeInit(COMP_HandleTypeDef * hcomp)521 HAL_StatusTypeDef HAL_COMP_DeInit(COMP_HandleTypeDef *hcomp)
522 {
523 HAL_StatusTypeDef status = HAL_OK;
524
525 /* Check the COMP handle allocation and lock status */
526 if(hcomp == NULL)
527 {
528 status = HAL_ERROR;
529 }
530 else if(__HAL_COMP_IS_LOCKED(hcomp))
531 {
532 status = HAL_ERROR;
533 }
534 else
535 {
536 /* Check the parameter */
537 assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
538
539 /* Set COMP_CSR register to reset value */
540 WRITE_REG(hcomp->Instance->CSR, 0x00000000UL);
541
542 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
543 if (hcomp->MspDeInitCallback == NULL)
544 {
545 hcomp->MspDeInitCallback = HAL_COMP_MspDeInit; /* Legacy weak MspDeInit */
546 }
547
548 /* DeInit the low level hardware: GPIO, RCC clock, NVIC */
549 hcomp->MspDeInitCallback(hcomp);
550 #else
551 /* DeInit the low level hardware: GPIO, RCC clock, NVIC */
552 HAL_COMP_MspDeInit(hcomp);
553 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
554
555 /* Set HAL COMP handle state */
556 hcomp->State = HAL_COMP_STATE_RESET;
557
558 /* Release Lock */
559 __HAL_UNLOCK(hcomp);
560 }
561
562 return status;
563 }
564
565 /**
566 * @brief Initialize the COMP MSP.
567 * @param hcomp COMP handle
568 * @retval None
569 */
HAL_COMP_MspInit(COMP_HandleTypeDef * hcomp)570 __weak void HAL_COMP_MspInit(COMP_HandleTypeDef *hcomp)
571 {
572 /* Prevent unused argument(s) compilation warning */
573 UNUSED(hcomp);
574
575 /* NOTE : This function should not be modified, when the callback is needed,
576 the HAL_COMP_MspInit could be implemented in the user file
577 */
578 }
579
580 /**
581 * @brief DeInitialize the COMP MSP.
582 * @param hcomp COMP handle
583 * @retval None
584 */
HAL_COMP_MspDeInit(COMP_HandleTypeDef * hcomp)585 __weak void HAL_COMP_MspDeInit(COMP_HandleTypeDef *hcomp)
586 {
587 /* Prevent unused argument(s) compilation warning */
588 UNUSED(hcomp);
589
590 /* NOTE : This function should not be modified, when the callback is needed,
591 the HAL_COMP_MspDeInit could be implemented in the user file
592 */
593 }
594
595 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
596 /**
597 * @brief Register a User COMP Callback
598 * To be used instead of the weak predefined callback
599 * @param hcomp Pointer to a COMP_HandleTypeDef structure that contains
600 * the configuration information for the specified COMP.
601 * @param CallbackID ID of the callback to be registered
602 * This parameter can be one of the following values:
603 * @arg @ref HAL_COMP_TRIGGER_CB_ID Trigger callback ID
604 * @arg @ref HAL_COMP_MSPINIT_CB_ID MspInit callback ID
605 * @arg @ref HAL_COMP_MSPDEINIT_CB_ID MspDeInit callback ID
606 * @param pCallback pointer to the Callback function
607 * @retval HAL status
608 */
HAL_COMP_RegisterCallback(COMP_HandleTypeDef * hcomp,HAL_COMP_CallbackIDTypeDef CallbackID,pCOMP_CallbackTypeDef pCallback)609 HAL_StatusTypeDef HAL_COMP_RegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID, pCOMP_CallbackTypeDef pCallback)
610 {
611 HAL_StatusTypeDef status = HAL_OK;
612
613 if (pCallback == NULL)
614 {
615 /* Update the error code */
616 hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
617
618 return HAL_ERROR;
619 }
620
621 if (HAL_COMP_STATE_READY == hcomp->State)
622 {
623 switch (CallbackID)
624 {
625 case HAL_COMP_TRIGGER_CB_ID :
626 hcomp->TriggerCallback = pCallback;
627 break;
628
629 case HAL_COMP_MSPINIT_CB_ID :
630 hcomp->MspInitCallback = pCallback;
631 break;
632
633 case HAL_COMP_MSPDEINIT_CB_ID :
634 hcomp->MspDeInitCallback = pCallback;
635 break;
636
637 default :
638 /* Update the error code */
639 hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
640
641 /* Return error status */
642 status = HAL_ERROR;
643 break;
644 }
645 }
646 else if (HAL_COMP_STATE_RESET == hcomp->State)
647 {
648 switch (CallbackID)
649 {
650 case HAL_COMP_MSPINIT_CB_ID :
651 hcomp->MspInitCallback = pCallback;
652 break;
653
654 case HAL_COMP_MSPDEINIT_CB_ID :
655 hcomp->MspDeInitCallback = pCallback;
656 break;
657
658 default :
659 /* Update the error code */
660 hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
661
662 /* Return error status */
663 status = HAL_ERROR;
664 break;
665 }
666 }
667 else
668 {
669 /* Update the error code */
670 hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
671
672 /* Return error status */
673 status = HAL_ERROR;
674 }
675
676 return status;
677 }
678
679 /**
680 * @brief Unregister a COMP Callback
681 * COMP callback is redirected to the weak predefined callback
682 * @param hcomp Pointer to a COMP_HandleTypeDef structure that contains
683 * the configuration information for the specified COMP.
684 * @param CallbackID ID of the callback to be unregistered
685 * This parameter can be one of the following values:
686 * @arg @ref HAL_COMP_TRIGGER_CB_ID Trigger callback ID
687 * @arg @ref HAL_COMP_MSPINIT_CB_ID MspInit callback ID
688 * @arg @ref HAL_COMP_MSPDEINIT_CB_ID MspDeInit callback ID
689 * @retval HAL status
690 */
HAL_COMP_UnRegisterCallback(COMP_HandleTypeDef * hcomp,HAL_COMP_CallbackIDTypeDef CallbackID)691 HAL_StatusTypeDef HAL_COMP_UnRegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID)
692 {
693 HAL_StatusTypeDef status = HAL_OK;
694
695 if (HAL_COMP_STATE_READY == hcomp->State)
696 {
697 switch (CallbackID)
698 {
699 case HAL_COMP_TRIGGER_CB_ID :
700 hcomp->TriggerCallback = HAL_COMP_TriggerCallback; /* Legacy weak callback */
701 break;
702
703 case HAL_COMP_MSPINIT_CB_ID :
704 hcomp->MspInitCallback = HAL_COMP_MspInit; /* Legacy weak MspInit */
705 break;
706
707 case HAL_COMP_MSPDEINIT_CB_ID :
708 hcomp->MspDeInitCallback = HAL_COMP_MspDeInit; /* Legacy weak MspDeInit */
709 break;
710
711 default :
712 /* Update the error code */
713 hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
714
715 /* Return error status */
716 status = HAL_ERROR;
717 break;
718 }
719 }
720 else if (HAL_COMP_STATE_RESET == hcomp->State)
721 {
722 switch (CallbackID)
723 {
724 case HAL_COMP_MSPINIT_CB_ID :
725 hcomp->MspInitCallback = HAL_COMP_MspInit; /* Legacy weak MspInit */
726 break;
727
728 case HAL_COMP_MSPDEINIT_CB_ID :
729 hcomp->MspDeInitCallback = HAL_COMP_MspDeInit; /* Legacy weak MspDeInit */
730 break;
731
732 default :
733 /* Update the error code */
734 hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
735
736 /* Return error status */
737 status = HAL_ERROR;
738 break;
739 }
740 }
741 else
742 {
743 /* Update the error code */
744 hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
745
746 /* Return error status */
747 status = HAL_ERROR;
748 }
749
750 return status;
751 }
752
753 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
754
755 /**
756 * @}
757 */
758
759 /** @defgroup COMP_Exported_Functions_Group2 Start-Stop operation functions
760 * @brief Start-Stop operation functions.
761 *
762 @verbatim
763 ===============================================================================
764 ##### IO operation functions #####
765 ===============================================================================
766 [..] This section provides functions allowing to:
767 (+) Start a comparator instance.
768 (+) Stop a comparator instance.
769
770 @endverbatim
771 * @{
772 */
773
774 /**
775 * @brief Start the comparator.
776 * @param hcomp COMP handle
777 * @retval HAL status
778 */
HAL_COMP_Start(COMP_HandleTypeDef * hcomp)779 HAL_StatusTypeDef HAL_COMP_Start(COMP_HandleTypeDef *hcomp)
780 {
781 __IO uint32_t wait_loop_index = 0UL;
782 HAL_StatusTypeDef status = HAL_OK;
783
784 /* Check the COMP handle allocation and lock status */
785 if(hcomp == NULL)
786 {
787 status = HAL_ERROR;
788 }
789 else if(__HAL_COMP_IS_LOCKED(hcomp))
790 {
791 status = HAL_ERROR;
792 }
793 else
794 {
795 /* Check the parameter */
796 assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
797
798 if(hcomp->State == HAL_COMP_STATE_READY)
799 {
800 /* Enable the selected comparator */
801 SET_BIT(hcomp->Instance->CSR, COMP_CSR_EN);
802
803 /* Set HAL COMP handle state */
804 hcomp->State = HAL_COMP_STATE_BUSY;
805
806 /* Delay for COMP startup time */
807 /* Wait loop initialization and execution */
808 /* Note: Variable divided by 2 to compensate partially */
809 /* CPU processing cycles, scaling in us split to not */
810 /* exceed 32 bits register capacity and handle low frequency. */
811 wait_loop_index = ((COMP_DELAY_STARTUP_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
812 while(wait_loop_index != 0UL)
813 {
814 wait_loop_index--;
815 }
816 }
817 else
818 {
819 status = HAL_ERROR;
820 }
821 }
822
823 return status;
824 }
825
826 /**
827 * @brief Stop the comparator.
828 * @param hcomp COMP handle
829 * @retval HAL status
830 */
HAL_COMP_Stop(COMP_HandleTypeDef * hcomp)831 HAL_StatusTypeDef HAL_COMP_Stop(COMP_HandleTypeDef *hcomp)
832 {
833 HAL_StatusTypeDef status = HAL_OK;
834
835 /* Check the COMP handle allocation and lock status */
836 if(hcomp == NULL)
837 {
838 status = HAL_ERROR;
839 }
840 else if(__HAL_COMP_IS_LOCKED(hcomp))
841 {
842 status = HAL_ERROR;
843 }
844 else
845 {
846 /* Check the parameter */
847 assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
848
849 /* Check compliant states: HAL_COMP_STATE_READY or HAL_COMP_STATE_BUSY */
850 /* (all states except HAL_COMP_STATE_RESET and except locked status. */
851 if(hcomp->State != HAL_COMP_STATE_RESET)
852 {
853 /* Disable the selected comparator */
854 CLEAR_BIT(hcomp->Instance->CSR, COMP_CSR_EN);
855
856 /* Set HAL COMP handle state */
857 hcomp->State = HAL_COMP_STATE_READY;
858 }
859 else
860 {
861 status = HAL_ERROR;
862 }
863 }
864
865 return status;
866 }
867
868 /**
869 * @brief Comparator IRQ handler.
870 * @param hcomp COMP handle
871 * @retval None
872 */
HAL_COMP_IRQHandler(COMP_HandleTypeDef * hcomp)873 void HAL_COMP_IRQHandler(COMP_HandleTypeDef *hcomp)
874 {
875 /* Get the EXTI line corresponding to the selected COMP instance */
876 uint32_t exti_line = COMP_GET_EXTI_LINE(hcomp->Instance);
877 uint32_t comparator_window_mode;
878 uint32_t comparator_window_exti_lines;
879
880 #if defined(COMP3)
881 if(hcomp->Instance == COMP3)
882 {
883 /* Case of window mode with COMP2 and COMP3 */
884 comparator_window_mode = READ_BIT(COMP23_COMMON->CSR_EVEN, COMP_CSR_WINMODE);
885 comparator_window_exti_lines = (COMP_EXTI_LINE_COMP2 | COMP_EXTI_LINE_COMP3);
886 }
887 else
888 {
889 comparator_window_mode = READ_BIT(COMP23_COMMON->CSR_EVEN, COMP_CSR_WINMODE);
890 if( (hcomp->Instance == COMP2) && (comparator_window_mode != 0UL))
891 {
892 /* Case of window mode with COMP2 and COMP3 */
893 comparator_window_exti_lines = (COMP_EXTI_LINE_COMP2 | COMP_EXTI_LINE_COMP3);
894 }
895 else
896 {
897 /* Case of window mode with COMP1 and COMP2 */
898 comparator_window_mode = READ_BIT(COMP12_COMMON->CSR_ODD, COMP_CSR_WINMODE);
899 comparator_window_mode |= READ_BIT(COMP12_COMMON->CSR_EVEN, COMP_CSR_WINMODE);
900 comparator_window_exti_lines = (COMP_EXTI_LINE_COMP1 | COMP_EXTI_LINE_COMP2);
901 }
902 }
903 #else
904 comparator_window_mode = READ_BIT(COMP12_COMMON->CSR_ODD, COMP_CSR_WINMODE);
905 comparator_window_mode |= READ_BIT(COMP12_COMMON->CSR_EVEN, COMP_CSR_WINMODE);
906 comparator_window_exti_lines = (COMP_EXTI_LINE_COMP1 | COMP_EXTI_LINE_COMP2);
907 #endif /* COMP3 */
908
909 /* Check COMP EXTI flag */
910 if(LL_EXTI_IsActiveRisingFlag_0_31(exti_line) != 0UL)
911 {
912 /* Check whether comparator is in independent or window mode */
913 if(comparator_window_mode != 0UL)
914 {
915 /* Clear COMP EXTI line pending bit of the pair of comparators */
916 /* in window mode. */
917 /* Note: Pair of comparators in window mode can both trig IRQ when */
918 /* input voltage is changing from "out of window" area */
919 /* (low or high ) to the other "out of window" area (high or low).*/
920 /* Both flags must be cleared to call comparator trigger */
921 /* callback is called once. */
922 LL_EXTI_ClearRisingFlag_0_31(comparator_window_exti_lines);
923 }
924 else
925 {
926 /* Clear COMP EXTI line pending bit */
927 LL_EXTI_ClearRisingFlag_0_31(exti_line);
928 }
929
930 /* COMP trigger user callback */
931 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
932 hcomp->TriggerCallback(hcomp);
933 #else
934 HAL_COMP_TriggerCallback(hcomp);
935 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
936 }
937 else if(LL_EXTI_IsActiveFallingFlag_0_31(exti_line) != 0UL)
938 {
939 /* Check whether comparator is in independent or window mode */
940 if(comparator_window_mode != 0UL)
941 {
942 /* Clear COMP EXTI line pending bit of the pair of comparators */
943 /* in window mode. */
944 /* Note: Pair of comparators in window mode can both trig IRQ when */
945 /* input voltage is changing from "out of window" area */
946 /* (low or high ) to the other "out of window" area (high or low).*/
947 /* Both flags must be cleared to call comparator trigger */
948 /* callback is called once. */
949 LL_EXTI_ClearFallingFlag_0_31(comparator_window_exti_lines);
950 }
951 else
952 {
953 /* Clear COMP EXTI line pending bit */
954 LL_EXTI_ClearFallingFlag_0_31(exti_line);
955 }
956
957 /* COMP trigger callback */
958 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
959 hcomp->TriggerCallback(hcomp);
960 #else
961 HAL_COMP_TriggerCallback(hcomp);
962 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
963 }
964 else
965 {
966 /* nothing to do */
967 }
968 }
969
970 /**
971 * @}
972 */
973
974 /** @defgroup COMP_Exported_Functions_Group3 Peripheral Control functions
975 * @brief Management functions.
976 *
977 @verbatim
978 ===============================================================================
979 ##### Peripheral Control functions #####
980 ===============================================================================
981 [..]
982 This subsection provides a set of functions allowing to control the comparators.
983
984 @endverbatim
985 * @{
986 */
987
988 /**
989 * @brief Lock the selected comparator configuration.
990 * @note A system reset is required to unlock the comparator configuration.
991 * @note Locking the comparator from reset state is possible
992 * if __HAL_RCC_SYSCFG_CLK_ENABLE() is being called before.
993 * @param hcomp COMP handle
994 * @retval HAL status
995 */
HAL_COMP_Lock(COMP_HandleTypeDef * hcomp)996 HAL_StatusTypeDef HAL_COMP_Lock(COMP_HandleTypeDef *hcomp)
997 {
998 HAL_StatusTypeDef status = HAL_OK;
999
1000 /* Check the COMP handle allocation and lock status */
1001 if(hcomp == NULL)
1002 {
1003 status = HAL_ERROR;
1004 }
1005 else if(__HAL_COMP_IS_LOCKED(hcomp))
1006 {
1007 status = HAL_ERROR;
1008 }
1009 else
1010 {
1011 /* Check the parameter */
1012 assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
1013
1014 /* Set HAL COMP handle state */
1015 switch(hcomp->State)
1016 {
1017 case HAL_COMP_STATE_RESET:
1018 hcomp->State = HAL_COMP_STATE_RESET_LOCKED;
1019 break;
1020 case HAL_COMP_STATE_READY:
1021 hcomp->State = HAL_COMP_STATE_READY_LOCKED;
1022 break;
1023 default: /* HAL_COMP_STATE_BUSY */
1024 hcomp->State = HAL_COMP_STATE_BUSY_LOCKED;
1025 break;
1026 }
1027 }
1028
1029 if(status == HAL_OK)
1030 {
1031 /* Set the lock bit corresponding to selected comparator */
1032 __HAL_COMP_LOCK(hcomp);
1033 }
1034
1035 return status;
1036 }
1037
1038 /**
1039 * @brief Return the output level (high or low) of the selected comparator.
1040 * The output level depends on the selected polarity.
1041 * If the polarity is not inverted:
1042 * - Comparator output is low when the input plus is at a lower
1043 * voltage than the input minus
1044 * - Comparator output is high when the input plus is at a higher
1045 * voltage than the input minus
1046 * If the polarity is inverted:
1047 * - Comparator output is high when the input plus is at a lower
1048 * voltage than the input minus
1049 * - Comparator output is low when the input plus is at a higher
1050 * voltage than the input minus
1051 * @param hcomp COMP handle
1052 * @retval Returns the selected comparator output level:
1053 * @arg COMP_OUTPUT_LEVEL_LOW
1054 * @arg COMP_OUTPUT_LEVEL_HIGH
1055 *
1056 */
HAL_COMP_GetOutputLevel(COMP_HandleTypeDef * hcomp)1057 uint32_t HAL_COMP_GetOutputLevel(COMP_HandleTypeDef *hcomp)
1058 {
1059 /* Check the parameter */
1060 assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
1061
1062 return (uint32_t)(READ_BIT(hcomp->Instance->CSR, COMP_CSR_VALUE)
1063 >> COMP_OUTPUT_LEVEL_BITOFFSET_POS);
1064 }
1065
1066 /**
1067 * @brief Comparator trigger callback.
1068 * @param hcomp COMP handle
1069 * @retval None
1070 */
HAL_COMP_TriggerCallback(COMP_HandleTypeDef * hcomp)1071 __weak void HAL_COMP_TriggerCallback(COMP_HandleTypeDef *hcomp)
1072 {
1073 /* Prevent unused argument(s) compilation warning */
1074 UNUSED(hcomp);
1075
1076 /* NOTE : This function should not be modified, when the callback is needed,
1077 the HAL_COMP_TriggerCallback should be implemented in the user file
1078 */
1079 }
1080
1081
1082 /**
1083 * @}
1084 */
1085
1086 /** @defgroup COMP_Exported_Functions_Group4 Peripheral State functions
1087 * @brief Peripheral State functions.
1088 *
1089 @verbatim
1090 ===============================================================================
1091 ##### Peripheral State functions #####
1092 ===============================================================================
1093 [..]
1094 This subsection permit to get in run-time the status of the peripheral.
1095
1096 @endverbatim
1097 * @{
1098 */
1099
1100 /**
1101 * @brief Return the COMP handle state.
1102 * @param hcomp COMP handle
1103 * @retval HAL state
1104 */
HAL_COMP_GetState(COMP_HandleTypeDef * hcomp)1105 HAL_COMP_StateTypeDef HAL_COMP_GetState(COMP_HandleTypeDef *hcomp)
1106 {
1107 /* Check the COMP handle allocation */
1108 if(hcomp == NULL)
1109 {
1110 return HAL_COMP_STATE_RESET;
1111 }
1112
1113 /* Check the parameter */
1114 assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
1115
1116 /* Return HAL COMP handle state */
1117 return hcomp->State;
1118 }
1119
1120 /**
1121 * @brief Return the COMP error code.
1122 * @param hcomp COMP handle
1123 * @retval COMP error code
1124 */
HAL_COMP_GetError(COMP_HandleTypeDef * hcomp)1125 uint32_t HAL_COMP_GetError(COMP_HandleTypeDef *hcomp)
1126 {
1127 /* Check the parameters */
1128 assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
1129
1130 return hcomp->ErrorCode;
1131 }
1132
1133 /**
1134 * @}
1135 */
1136
1137 /**
1138 * @}
1139 */
1140
1141 /**
1142 * @}
1143 */
1144
1145 #endif /* COMP1 || COMP2 */
1146
1147 #endif /* HAL_COMP_MODULE_ENABLED */
1148
1149 /**
1150 * @}
1151 */
1152