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