STM32L443xx HAL User Manual
stm32l4xx_hal_comp.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_hal_comp.c
00004   * @author  MCD Application Team
00005   * @brief   COMP HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the COMP peripheral:
00008   *           + Initialization and de-initialization functions
00009   *           + Peripheral control functions
00010   *           + Peripheral state functions
00011   *
00012   ******************************************************************************
00013   * @attention
00014   *
00015   * Copyright (c) 2017 STMicroelectronics.
00016   * All rights reserved.
00017   *
00018   * This software is licensed under terms that can be found in the LICENSE file
00019   * in the root directory of this software component.
00020   * If no LICENSE file comes with this software, it is provided AS-IS.
00021   *
00022   ******************************************************************************
00023   @verbatim
00024 ================================================================================
00025           ##### COMP Peripheral features #####
00026 ================================================================================
00027 
00028   [..]
00029       The STM32L4xx device family integrates two analog comparators instances:
00030       COMP1, COMP2 except for the STM32L412xx/STM32L422xx products featuring only
00031       one instance: COMP1.
00032       In the rest of the file, all comments related to a pair of comparators are not
00033       applicable to STM32L412xx/STM32L422xx.
00034       (#) Comparators input minus (inverting input) and input plus (non inverting input)
00035           can be set to internal references or to GPIO pins
00036           (refer to GPIO list in reference manual).
00037 
00038       (#) Comparators output level is available using HAL_COMP_GetOutputLevel()
00039           and can be redirected to other peripherals: GPIO pins (in mode
00040           alternate functions for comparator), timers.
00041           (refer to GPIO list in reference manual).
00042 
00043       (#) The comparators have interrupt capability through the EXTI controller
00044           with wake-up from sleep and stop modes.
00045 
00046       (#) Pairs of comparators instances can be combined in window mode
00047           (2 consecutive instances odd and even COMP<x> and COMP<x+1>).
00048 
00049           From the corresponding IRQ handler, the right interrupt source can be retrieved
00050           using macro __HAL_COMP_COMPx_EXTI_GET_FLAG().
00051 
00052             ##### How to use this driver #####
00053 ================================================================================
00054   [..]
00055       This driver provides functions to configure and program the comparator instances
00056       of STM32L4xx devices.
00057 
00058       To use the comparator, perform the following steps:
00059 
00060       (#)  Initialize the COMP low level resources by implementing the HAL_COMP_MspInit():
00061       (++) Configure the GPIO connected to comparator inputs plus and minus in analog mode
00062            using HAL_GPIO_Init().
00063       (++) If needed, configure the GPIO connected to comparator output in alternate function mode
00064            using HAL_GPIO_Init().
00065       (++) If required enable the COMP interrupt by configuring and enabling EXTI line in Interrupt mode and
00066            selecting the desired sensitivity level using HAL_GPIO_Init() function. After that enable the comparator
00067            interrupt vector using HAL_NVIC_EnableIRQ() function.
00068 
00069       (#) Configure the comparator using HAL_COMP_Init() function:
00070       (++) Select the input minus (inverting input)
00071       (++) Select the input plus (non-inverting input)
00072       (++) Select the hysteresis
00073       (++) Select the blanking source
00074       (++) Select the output polarity
00075       (++) Select the power mode
00076       (++) Select the window mode
00077 
00078       -@@- HAL_COMP_Init() calls internally __HAL_RCC_SYSCFG_CLK_ENABLE()
00079           to enable internal control clock of the comparators.
00080           However, this is a legacy strategy. In future STM32 families,
00081           COMP clock enable must be implemented by user in "HAL_COMP_MspInit()".
00082           Therefore, for compatibility anticipation, it is recommended to
00083           implement __HAL_RCC_SYSCFG_CLK_ENABLE() in "HAL_COMP_MspInit()".
00084 
00085       (#) Reconfiguration on-the-fly of comparator can be done by calling again
00086           function HAL_COMP_Init() with new input structure parameters values.
00087 
00088       (#) Enable the comparator using HAL_COMP_Start() function.
00089 
00090       (#) Use HAL_COMP_TriggerCallback() or HAL_COMP_GetOutputLevel() functions
00091           to manage comparator outputs (events and output level).
00092 
00093       (#) Disable the comparator using HAL_COMP_Stop() function.
00094 
00095       (#) De-initialize the comparator using HAL_COMP_DeInit() function.
00096 
00097       (#) For safety purpose, comparator configuration can be locked using HAL_COMP_Lock() function.
00098           The only way to unlock the comparator is a device hardware reset.
00099 
00100     *** Callback registration ***
00101     =============================================
00102     [..]
00103 
00104      The compilation flag USE_HAL_COMP_REGISTER_CALLBACKS, when set to 1,
00105      allows the user to configure dynamically the driver callbacks.
00106      Use Functions HAL_COMP_RegisterCallback()
00107      to register an interrupt callback.
00108     [..]
00109 
00110      Function HAL_COMP_RegisterCallback() allows to register following callbacks:
00111        (+) TriggerCallback       : callback for COMP trigger.
00112        (+) MspInitCallback       : callback for Msp Init.
00113        (+) MspDeInitCallback     : callback for Msp DeInit.
00114      This function takes as parameters the HAL peripheral handle, the Callback ID
00115      and a pointer to the user callback function.
00116     [..]
00117 
00118      Use function HAL_COMP_UnRegisterCallback to reset a callback to the default
00119      weak function.
00120     [..]
00121 
00122      HAL_COMP_UnRegisterCallback takes as parameters the HAL peripheral handle,
00123      and the Callback ID.
00124      This function allows to reset following callbacks:
00125        (+) TriggerCallback       : callback for COMP trigger.
00126        (+) MspInitCallback       : callback for Msp Init.
00127        (+) MspDeInitCallback     : callback for Msp DeInit.
00128      [..]
00129 
00130      By default, after the HAL_COMP_Init() and when the state is HAL_COMP_STATE_RESET
00131      all callbacks are set to the corresponding weak functions:
00132      example HAL_COMP_TriggerCallback().
00133      Exception done for MspInit and MspDeInit functions that are
00134      reset to the legacy weak functions in the HAL_COMP_Init()/ HAL_COMP_DeInit() only when
00135      these callbacks are null (not registered beforehand).
00136     [..]
00137 
00138      If MspInit or MspDeInit are not null, the HAL_COMP_Init()/ HAL_COMP_DeInit()
00139      keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
00140      [..]
00141 
00142      Callbacks can be registered/unregistered in HAL_COMP_STATE_READY state only.
00143      Exception done MspInit/MspDeInit functions that can be registered/unregistered
00144      in HAL_COMP_STATE_READY or HAL_COMP_STATE_RESET state,
00145      thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
00146     [..]
00147 
00148      Then, the user first registers the MspInit/MspDeInit user callbacks
00149      using HAL_COMP_RegisterCallback() before calling HAL_COMP_DeInit()
00150      or HAL_COMP_Init() function.
00151      [..]
00152 
00153      When the compilation flag USE_HAL_COMP_REGISTER_CALLBACKS is set to 0 or
00154      not defined, the callback registration feature is not available and all callbacks
00155      are set to the corresponding weak functions.
00156 
00157   @endverbatim
00158   ******************************************************************************
00159 
00160   Table 1. COMP inputs and output for STM32L4xx devices
00161   +-----------------------------------------------------------------+
00162   |                |                |     COMP1     |   COMP2 (4)   |
00163   |----------------|----------------|---------------|---------------+
00164   |                | IO1            |      PC5      |      PB4      |
00165   | Input plus     | IO2            |      PB2      |      PB6      |
00166   |                | IO3 (3)        |      PA1      |      PA3      |
00167   |----------------|----------------|---------------|---------------+
00168   |                | 1/4 VrefInt    |   Available   |   Available   |
00169   |                | 1/2 VrefInt    |   Available   |   Available   |
00170   |                | 3/4 VrefInt    |   Available   |   Available   |
00171   | Input minus    | VrefInt        |   Available   |   Available   |
00172   |                | DAC1 channel 1 |   Available   | Available (4) |
00173   |                | DAC1 channel 2 |   Available   | Available (4) |
00174   |                | IO1            |      PB1      |      PB3      |
00175   |                | IO2            |      PC4      |      PB7      |
00176   |                | IO3 (3)        |      PA0      |      PA2      |
00177   |                | IO4 (3)        |      PA4      |      PA4      |
00178   |                | IO5 (3)        |      PA5      |      PA5      |
00179   +----------------|----------------|---------------|---------------+
00180   | Output         |                |    PB0  (1)   |    PB5  (1)   |
00181   |                |                |    PB10 (1)   |    PB11 (1)   |
00182   |                |                |    TIM  (2)   |    TIM  (2)   |
00183   +-----------------------------------------------------------------+
00184   (1) GPIO must be set to alternate function for comparator
00185   (2) Comparators output to timers is set in timers instances.
00186   (3) Only STM32L43x/L44x
00187   (4) Not applicable to STM32L412x/L422x
00188 
00189   */
00190 
00191 /* Includes ------------------------------------------------------------------*/
00192 #include "stm32l4xx_hal.h"
00193 
00194 /** @addtogroup STM32L4xx_HAL_Driver
00195   * @{
00196   */
00197 
00198 #ifdef HAL_COMP_MODULE_ENABLED
00199 
00200 #if defined (COMP1) || defined (COMP2)
00201 
00202 /** @defgroup COMP COMP
00203   * @brief COMP HAL module driver
00204   * @{
00205   */
00206 
00207 /* Private typedef -----------------------------------------------------------*/
00208 /* Private define ------------------------------------------------------------*/
00209 /** @addtogroup COMP_Private_Constants
00210   * @{
00211   */
00212 
00213 /* Delay for COMP startup time.                                               */
00214 /* Note: Delay required to reach propagation delay specification.             */
00215 /* Literal set to maximum value (refer to device datasheet,                   */
00216 /* parameter "tSTART").                                                       */
00217 /* Unit: us                                                                   */
00218 #define COMP_DELAY_STARTUP_US          (80UL) /*!< Delay for COMP startup time */
00219 
00220 /* Delay for COMP voltage scaler stabilization time.                          */
00221 /* Literal set to maximum value (refer to device datasheet,                   */
00222 /* parameter "tSTART_SCALER").                                                */
00223 /* Unit: us                                                                   */
00224 #define COMP_DELAY_VOLTAGE_SCALER_STAB_US (200UL)  /*!< Delay for COMP voltage scaler stabilization time */
00225 
00226 #define COMP_OUTPUT_LEVEL_BITOFFSET_POS    (30UL)
00227 
00228 /**
00229   * @}
00230   */
00231 
00232 /* Private macro -------------------------------------------------------------*/
00233 /* Private variables ---------------------------------------------------------*/
00234 /* Private function prototypes -----------------------------------------------*/
00235 /* Exported functions --------------------------------------------------------*/
00236 
00237 /** @defgroup COMP_Exported_Functions COMP Exported Functions
00238   * @{
00239   */
00240 
00241 /** @defgroup COMP_Exported_Functions_Group1 Initialization/de-initialization functions
00242   *  @brief    Initialization and de-initialization functions.
00243   *
00244 @verbatim
00245  ===============================================================================
00246               ##### Initialization and de-initialization functions #####
00247  ===============================================================================
00248     [..]  This section provides functions to initialize and de-initialize comparators
00249 
00250 @endverbatim
00251   * @{
00252   */
00253 
00254 /**
00255   * @brief  Initialize the COMP according to the specified
00256   *         parameters in the COMP_InitTypeDef and initialize the associated handle.
00257   * @note   If the selected comparator is locked, initialization can't be performed.
00258   *         To unlock the configuration, perform a system reset.
00259   * @param  hcomp  COMP handle
00260   * @retval HAL status
00261   */
00262 HAL_StatusTypeDef HAL_COMP_Init(COMP_HandleTypeDef *hcomp)
00263 {
00264   uint32_t tmp_csr;
00265   uint32_t exti_line;
00266   uint32_t comp_voltage_scaler_initialized; /* Value "0" if comparator voltage scaler is not initialized */
00267   __IO uint32_t wait_loop_index = 0UL;
00268   HAL_StatusTypeDef status = HAL_OK;
00269 
00270   /* Check the COMP handle allocation and lock status */
00271   if(hcomp == NULL)
00272   {
00273     status = HAL_ERROR;
00274   }
00275   else if(__HAL_COMP_IS_LOCKED(hcomp))
00276   {
00277     status = HAL_ERROR;
00278   }
00279   else
00280   {
00281     /* Check the parameters */
00282     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
00283     assert_param(IS_COMP_INPUT_PLUS(hcomp->Instance, hcomp->Init.NonInvertingInput));
00284     assert_param(IS_COMP_INPUT_MINUS(hcomp->Instance, hcomp->Init.InvertingInput));
00285     assert_param(IS_COMP_OUTPUTPOL(hcomp->Init.OutputPol));
00286     assert_param(IS_COMP_POWERMODE(hcomp->Init.Mode));
00287     assert_param(IS_COMP_HYSTERESIS(hcomp->Init.Hysteresis));
00288     assert_param(IS_COMP_BLANKINGSRC_INSTANCE(hcomp->Instance, hcomp->Init.BlankingSrce));
00289     assert_param(IS_COMP_TRIGGERMODE(hcomp->Init.TriggerMode));
00290 #if defined(COMP2)
00291     assert_param(IS_COMP_WINDOWMODE(hcomp->Init.WindowMode));
00292 #endif
00293 
00294     if(hcomp->State == HAL_COMP_STATE_RESET)
00295     {
00296       /* Allocate lock resource and initialize it */
00297       hcomp->Lock = HAL_UNLOCKED;
00298 
00299       /* Set COMP error code to none */
00300       COMP_CLEAR_ERRORCODE(hcomp);
00301 
00302       /* Init SYSCFG and the low level hardware to access comparators */
00303       /* Note: HAL_COMP_Init() calls __HAL_RCC_SYSCFG_CLK_ENABLE()            */
00304       /*       to enable internal control clock of the comparators.           */
00305       /*       However, this is a legacy strategy. In future STM32 families,  */
00306       /*       COMP clock enable must be implemented by user                  */
00307       /*       in "HAL_COMP_MspInit()".                                       */
00308       /*       Therefore, for compatibility anticipation, it is recommended   */
00309       /*       to implement __HAL_RCC_SYSCFG_CLK_ENABLE()                     */
00310       /*       in "HAL_COMP_MspInit()".                                       */
00311       __HAL_RCC_SYSCFG_CLK_ENABLE();
00312 
00313 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
00314       /* Init the COMP Callback settings */
00315       hcomp->TriggerCallback = HAL_COMP_TriggerCallback; /* Legacy weak callback */
00316 
00317       if (hcomp->MspInitCallback == NULL)
00318       {
00319         hcomp->MspInitCallback = HAL_COMP_MspInit; /* Legacy weak MspInit  */
00320       }
00321 
00322       /* Init the low level hardware */
00323       hcomp->MspInitCallback(hcomp);
00324 #else
00325       /* Init the low level hardware */
00326       HAL_COMP_MspInit(hcomp);
00327 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
00328     }
00329 
00330     /* Memorize voltage scaler state before initialization */
00331     comp_voltage_scaler_initialized = READ_BIT(hcomp->Instance->CSR, COMP_CSR_SCALEN);
00332 
00333     /* Set COMP parameters */
00334     tmp_csr = (  hcomp->Init.NonInvertingInput
00335                | hcomp->Init.InvertingInput
00336                | hcomp->Init.BlankingSrce
00337                | hcomp->Init.Hysteresis
00338                | hcomp->Init.OutputPol
00339                | hcomp->Init.Mode
00340               );
00341 
00342     /* Set parameters in COMP register */
00343     /* Note: Update all bits except read-only, lock and enable bits */
00344 #if defined (COMP_CSR_INMESEL)
00345 #if defined (COMP_CSR_WINMODE)
00346     MODIFY_REG(hcomp->Instance->CSR,
00347                COMP_CSR_PWRMODE  | COMP_CSR_INMSEL   | COMP_CSR_INPSEL  |
00348                COMP_CSR_WINMODE  | COMP_CSR_POLARITY | COMP_CSR_HYST    |
00349                COMP_CSR_BLANKING | COMP_CSR_BRGEN    | COMP_CSR_SCALEN  | COMP_CSR_INMESEL,
00350                tmp_csr
00351               );
00352 #else
00353     MODIFY_REG(hcomp->Instance->CSR,
00354                COMP_CSR_PWRMODE  | COMP_CSR_INMSEL   | COMP_CSR_INPSEL  |
00355                                    COMP_CSR_POLARITY | COMP_CSR_HYST    |
00356                COMP_CSR_BLANKING | COMP_CSR_BRGEN    | COMP_CSR_SCALEN  | COMP_CSR_INMESEL,
00357                tmp_csr
00358               );
00359 #endif /* COMP_CSR_WINMODE */
00360 #else
00361     MODIFY_REG(hcomp->Instance->CSR,
00362                COMP_CSR_PWRMODE  | COMP_CSR_INMSEL   | COMP_CSR_INPSEL  |
00363                COMP_CSR_WINMODE  | COMP_CSR_POLARITY | COMP_CSR_HYST    |
00364                COMP_CSR_BLANKING | COMP_CSR_BRGEN    | COMP_CSR_SCALEN,
00365                tmp_csr
00366               );
00367 #endif /* COMP_CSR_INMESEL */
00368 
00369 #if defined(COMP2)
00370     /* Set window mode */
00371     /* Note: Window mode bit is located into 1 out of the 2 pairs of COMP     */
00372     /*       instances. Therefore, this function can update another COMP      */
00373     /*       instance that the one currently selected.                        */
00374     if(hcomp->Init.WindowMode == COMP_WINDOWMODE_COMP1_INPUT_PLUS_COMMON)
00375     {
00376       SET_BIT(COMP12_COMMON->CSR, COMP_CSR_WINMODE);
00377     }
00378     else
00379     {
00380       CLEAR_BIT(COMP12_COMMON->CSR, COMP_CSR_WINMODE);
00381     }
00382 #endif /* COMP2 */
00383 
00384     /* Delay for COMP scaler bridge voltage stabilization */
00385     /* Apply the delay if voltage scaler bridge is required and not already enabled */
00386     if ((READ_BIT(hcomp->Instance->CSR, COMP_CSR_SCALEN) != 0UL) &&
00387         (comp_voltage_scaler_initialized == 0UL)               )
00388     {
00389       /* Wait loop initialization and execution */
00390       /* Note: Variable divided by 2 to compensate partially              */
00391       /*       CPU processing cycles, scaling in us split to not          */
00392       /*       exceed 32 bits register capacity and handle low frequency. */
00393       wait_loop_index = ((COMP_DELAY_VOLTAGE_SCALER_STAB_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
00394       while(wait_loop_index != 0UL)
00395       {
00396         wait_loop_index--;
00397       }
00398     }
00399 
00400     /* Get the EXTI line corresponding to the selected COMP instance */
00401     exti_line = COMP_GET_EXTI_LINE(hcomp->Instance);
00402 
00403     /* Manage EXTI settings */
00404     if((hcomp->Init.TriggerMode & (COMP_EXTI_IT | COMP_EXTI_EVENT)) != 0UL)
00405     {
00406       /* Configure EXTI rising edge */
00407       if((hcomp->Init.TriggerMode & COMP_EXTI_RISING) != 0UL)
00408       {
00409         LL_EXTI_EnableRisingTrig_0_31(exti_line);
00410       }
00411       else
00412       {
00413         LL_EXTI_DisableRisingTrig_0_31(exti_line);
00414       }
00415 
00416       /* Configure EXTI falling edge */
00417       if((hcomp->Init.TriggerMode & COMP_EXTI_FALLING) != 0UL)
00418       {
00419         LL_EXTI_EnableFallingTrig_0_31(exti_line);
00420       }
00421       else
00422       {
00423         LL_EXTI_DisableFallingTrig_0_31(exti_line);
00424       }
00425 
00426       /* Clear COMP EXTI pending bit (if any) */
00427       LL_EXTI_ClearFlag_0_31(exti_line);
00428 
00429       /* Configure EXTI event mode */
00430       if((hcomp->Init.TriggerMode & COMP_EXTI_EVENT) != 0UL)
00431       {
00432         LL_EXTI_EnableEvent_0_31(exti_line);
00433       }
00434       else
00435       {
00436         LL_EXTI_DisableEvent_0_31(exti_line);
00437       }
00438 
00439       /* Configure EXTI interrupt mode */
00440       if((hcomp->Init.TriggerMode & COMP_EXTI_IT) != 0UL)
00441       {
00442         LL_EXTI_EnableIT_0_31(exti_line);
00443       }
00444       else
00445       {
00446         LL_EXTI_DisableIT_0_31(exti_line);
00447       }
00448     }
00449     else
00450     {
00451       /* Disable EXTI event mode */
00452       LL_EXTI_DisableEvent_0_31(exti_line);
00453 
00454       /* Disable EXTI interrupt mode */
00455       LL_EXTI_DisableIT_0_31(exti_line);
00456     }
00457 
00458     /* Set HAL COMP handle state */
00459     /* Note: Transition from state reset to state ready,                      */
00460     /*       otherwise (coming from state ready or busy) no state update.     */
00461     if (hcomp->State == HAL_COMP_STATE_RESET)
00462     {
00463       hcomp->State = HAL_COMP_STATE_READY;
00464     }
00465   }
00466 
00467   return status;
00468 }
00469 
00470 /**
00471   * @brief  DeInitialize the COMP peripheral.
00472   * @note   Deinitialization cannot be performed if the COMP configuration is locked.
00473   *         To unlock the configuration, perform a system reset.
00474   * @param  hcomp  COMP handle
00475   * @retval HAL status
00476   */
00477 HAL_StatusTypeDef HAL_COMP_DeInit(COMP_HandleTypeDef *hcomp)
00478 {
00479   HAL_StatusTypeDef status = HAL_OK;
00480 
00481   /* Check the COMP handle allocation and lock status */
00482   if(hcomp == NULL)
00483   {
00484     status = HAL_ERROR;
00485   }
00486   else if(__HAL_COMP_IS_LOCKED(hcomp))
00487   {
00488     status = HAL_ERROR;
00489   }
00490   else
00491   {
00492     /* Check the parameter */
00493     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
00494 
00495     /* Set COMP_CSR register to reset value */
00496     WRITE_REG(hcomp->Instance->CSR, 0x00000000UL);
00497 
00498 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
00499     if (hcomp->MspDeInitCallback == NULL)
00500     {
00501       hcomp->MspDeInitCallback = HAL_COMP_MspDeInit; /* Legacy weak MspDeInit  */
00502     }
00503 
00504     /* DeInit the low level hardware: GPIO, RCC clock, NVIC */
00505     hcomp->MspDeInitCallback(hcomp);
00506 #else
00507     /* DeInit the low level hardware: GPIO, RCC clock, NVIC */
00508     HAL_COMP_MspDeInit(hcomp);
00509 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
00510 
00511     /* Set HAL COMP handle state */
00512     hcomp->State = HAL_COMP_STATE_RESET;
00513 
00514     /* Release Lock */
00515     __HAL_UNLOCK(hcomp);
00516   }
00517 
00518   return status;
00519 }
00520 
00521 /**
00522   * @brief  Initialize the COMP MSP.
00523   * @param  hcomp  COMP handle
00524   * @retval None
00525   */
00526 __weak void HAL_COMP_MspInit(COMP_HandleTypeDef *hcomp)
00527 {
00528   /* Prevent unused argument(s) compilation warning */
00529   UNUSED(hcomp);
00530 
00531   /* NOTE : This function should not be modified, when the callback is needed,
00532             the HAL_COMP_MspInit could be implemented in the user file
00533    */
00534 }
00535 
00536 /**
00537   * @brief  DeInitialize the COMP MSP.
00538   * @param  hcomp  COMP handle
00539   * @retval None
00540   */
00541 __weak void HAL_COMP_MspDeInit(COMP_HandleTypeDef *hcomp)
00542 {
00543   /* Prevent unused argument(s) compilation warning */
00544   UNUSED(hcomp);
00545 
00546   /* NOTE : This function should not be modified, when the callback is needed,
00547             the HAL_COMP_MspDeInit could be implemented in the user file
00548    */
00549 }
00550 
00551 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
00552 /**
00553   * @brief  Register a User COMP Callback
00554   *         To be used instead of the weak predefined callback
00555   * @param  hcomp Pointer to a COMP_HandleTypeDef structure that contains
00556   *                the configuration information for the specified COMP.
00557   * @param  CallbackID ID of the callback to be registered
00558   *         This parameter can be one of the following values:
00559   *          @arg @ref HAL_COMP_TRIGGER_CB_ID Trigger callback ID
00560   *          @arg @ref HAL_COMP_MSPINIT_CB_ID MspInit callback ID
00561   *          @arg @ref HAL_COMP_MSPDEINIT_CB_ID MspDeInit callback ID
00562   * @param  pCallback pointer to the Callback function
00563   * @retval HAL status
00564   */
00565 HAL_StatusTypeDef HAL_COMP_RegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID, pCOMP_CallbackTypeDef pCallback)
00566 {
00567   HAL_StatusTypeDef status = HAL_OK;
00568 
00569   if (pCallback == NULL)
00570   {
00571     /* Update the error code */
00572     hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
00573 
00574     return HAL_ERROR;
00575   }
00576 
00577   if (HAL_COMP_STATE_READY == hcomp->State)
00578   {
00579     switch (CallbackID)
00580     {
00581       case HAL_COMP_TRIGGER_CB_ID :
00582         hcomp->TriggerCallback = pCallback;
00583         break;
00584 
00585       case HAL_COMP_MSPINIT_CB_ID :
00586         hcomp->MspInitCallback = pCallback;
00587         break;
00588 
00589       case HAL_COMP_MSPDEINIT_CB_ID :
00590         hcomp->MspDeInitCallback = pCallback;
00591         break;
00592 
00593       default :
00594         /* Update the error code */
00595         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
00596 
00597         /* Return error status */
00598         status = HAL_ERROR;
00599         break;
00600     }
00601   }
00602   else if (HAL_COMP_STATE_RESET == hcomp->State)
00603   {
00604     switch (CallbackID)
00605     {
00606       case HAL_COMP_MSPINIT_CB_ID :
00607         hcomp->MspInitCallback = pCallback;
00608         break;
00609 
00610       case HAL_COMP_MSPDEINIT_CB_ID :
00611         hcomp->MspDeInitCallback = pCallback;
00612         break;
00613 
00614       default :
00615         /* Update the error code */
00616         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
00617 
00618         /* Return error status */
00619         status = HAL_ERROR;
00620         break;
00621     }
00622   }
00623   else
00624   {
00625     /* Update the error code */
00626     hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
00627 
00628     /* Return error status */
00629     status =  HAL_ERROR;
00630   }
00631 
00632   return status;
00633 }
00634 
00635 /**
00636   * @brief  Unregister a COMP Callback
00637   *         COMP callback is redirected to the weak predefined callback
00638   * @param  hcomp Pointer to a COMP_HandleTypeDef structure that contains
00639   *                the configuration information for the specified COMP.
00640   * @param  CallbackID ID of the callback to be unregistered
00641   *         This parameter can be one of the following values:
00642   *          @arg @ref HAL_COMP_TRIGGER_CB_ID Trigger callback ID
00643   *          @arg @ref HAL_COMP_MSPINIT_CB_ID MspInit callback ID
00644   *          @arg @ref HAL_COMP_MSPDEINIT_CB_ID MspDeInit callback ID
00645   * @retval HAL status
00646   */
00647 HAL_StatusTypeDef HAL_COMP_UnRegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID)
00648 {
00649   HAL_StatusTypeDef status = HAL_OK;
00650 
00651   if (HAL_COMP_STATE_READY == hcomp->State)
00652   {
00653     switch (CallbackID)
00654     {
00655       case HAL_COMP_TRIGGER_CB_ID :
00656         hcomp->TriggerCallback = HAL_COMP_TriggerCallback;         /* Legacy weak callback */
00657         break;
00658 
00659       case HAL_COMP_MSPINIT_CB_ID :
00660         hcomp->MspInitCallback = HAL_COMP_MspInit;                 /* Legacy weak MspInit */
00661         break;
00662 
00663       case HAL_COMP_MSPDEINIT_CB_ID :
00664         hcomp->MspDeInitCallback = HAL_COMP_MspDeInit;             /* Legacy weak MspDeInit */
00665         break;
00666 
00667       default :
00668         /* Update the error code */
00669         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
00670 
00671         /* Return error status */
00672         status =  HAL_ERROR;
00673         break;
00674     }
00675   }
00676   else if (HAL_COMP_STATE_RESET == hcomp->State)
00677   {
00678     switch (CallbackID)
00679     {
00680       case HAL_COMP_MSPINIT_CB_ID :
00681         hcomp->MspInitCallback = HAL_COMP_MspInit;                 /* Legacy weak MspInit */
00682         break;
00683 
00684       case HAL_COMP_MSPDEINIT_CB_ID :
00685         hcomp->MspDeInitCallback = HAL_COMP_MspDeInit;             /* Legacy weak MspDeInit */
00686         break;
00687 
00688       default :
00689         /* Update the error code */
00690         hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
00691 
00692         /* Return error status */
00693         status =  HAL_ERROR;
00694         break;
00695     }
00696   }
00697   else
00698   {
00699     /* Update the error code */
00700     hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
00701 
00702     /* Return error status */
00703     status =  HAL_ERROR;
00704   }
00705 
00706   return status;
00707 }
00708 
00709 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
00710 
00711 /**
00712   * @}
00713   */
00714 
00715 /** @defgroup COMP_Exported_Functions_Group2 Start-Stop operation functions
00716   *  @brief   Start-Stop operation functions.
00717   *
00718 @verbatim
00719  ===============================================================================
00720                       ##### IO operation functions #####
00721  ===============================================================================
00722     [..]  This section provides functions allowing to:
00723       (+) Start a comparator instance.
00724       (+) Stop a comparator instance.
00725 
00726 @endverbatim
00727   * @{
00728   */
00729 
00730 /**
00731   * @brief  Start the comparator.
00732   * @param  hcomp  COMP handle
00733   * @retval HAL status
00734   */
00735 HAL_StatusTypeDef HAL_COMP_Start(COMP_HandleTypeDef *hcomp)
00736 {
00737   __IO uint32_t wait_loop_index = 0UL;
00738   HAL_StatusTypeDef status = HAL_OK;
00739 
00740   /* Check the COMP handle allocation and lock status */
00741   if(hcomp == NULL)
00742   {
00743     status = HAL_ERROR;
00744   }
00745   else if(__HAL_COMP_IS_LOCKED(hcomp))
00746   {
00747     status = HAL_ERROR;
00748   }
00749   else
00750   {
00751     /* Check the parameter */
00752     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
00753 
00754     if(hcomp->State == HAL_COMP_STATE_READY)
00755     {
00756       /* Enable the selected comparator */
00757       SET_BIT(hcomp->Instance->CSR, COMP_CSR_EN);
00758 
00759       /* Set HAL COMP handle state */
00760       hcomp->State = HAL_COMP_STATE_BUSY;
00761 
00762       /* Delay for COMP startup time */
00763       /* Wait loop initialization and execution */
00764       /* Note: Variable divided by 2 to compensate partially              */
00765       /*       CPU processing cycles, scaling in us split to not          */
00766       /*       exceed 32 bits register capacity and handle low frequency. */
00767       wait_loop_index = ((COMP_DELAY_STARTUP_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
00768       while(wait_loop_index != 0UL)
00769       {
00770         wait_loop_index--;
00771       }
00772     }
00773     else
00774     {
00775       status = HAL_ERROR;
00776     }
00777   }
00778 
00779   return status;
00780 }
00781 
00782 /**
00783   * @brief  Stop the comparator.
00784   * @param  hcomp  COMP handle
00785   * @retval HAL status
00786   */
00787 HAL_StatusTypeDef HAL_COMP_Stop(COMP_HandleTypeDef *hcomp)
00788 {
00789   HAL_StatusTypeDef status = HAL_OK;
00790 
00791   /* Check the COMP handle allocation and lock status */
00792   if(hcomp == NULL)
00793   {
00794     status = HAL_ERROR;
00795   }
00796   else if(__HAL_COMP_IS_LOCKED(hcomp))
00797   {
00798     status = HAL_ERROR;
00799   }
00800   else
00801   {
00802     /* Check the parameter */
00803     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
00804 
00805     /* Check compliant states: HAL_COMP_STATE_READY or HAL_COMP_STATE_BUSY    */
00806     /* (all states except HAL_COMP_STATE_RESET and except locked status.      */
00807     if(hcomp->State != HAL_COMP_STATE_RESET)
00808     {
00809       /* Disable the selected comparator */
00810       CLEAR_BIT(hcomp->Instance->CSR, COMP_CSR_EN);
00811 
00812       /* Set HAL COMP handle state */
00813       hcomp->State = HAL_COMP_STATE_READY;
00814     }
00815     else
00816     {
00817       status = HAL_ERROR;
00818     }
00819   }
00820 
00821   return status;
00822 }
00823 
00824 /**
00825   * @brief  Comparator IRQ handler.
00826   * @param  hcomp  COMP handle
00827   * @retval None
00828   */
00829 void HAL_COMP_IRQHandler(COMP_HandleTypeDef *hcomp)
00830 {
00831   /* Get the EXTI line corresponding to the selected COMP instance */
00832   uint32_t exti_line = COMP_GET_EXTI_LINE(hcomp->Instance);
00833 
00834   /* Check COMP EXTI flag */
00835   if(LL_EXTI_IsActiveFlag_0_31(exti_line) != 0UL)
00836   {
00837 #if defined(COMP2)
00838     /* Check whether comparator is in independent or window mode */
00839     if(READ_BIT(COMP12_COMMON->CSR, COMP_CSR_WINMODE) != 0UL)
00840     {
00841       /* Clear COMP EXTI line pending bit of the pair of comparators          */
00842       /* in window mode.                                                      */
00843       /* Note: Pair of comparators in window mode can both trig IRQ when      */
00844       /*       input voltage is changing from "out of window" area            */
00845       /*       (low or high ) to the other "out of window" area (high or low).*/
00846       /*       Both flags must be cleared to call comparator trigger          */
00847       /*       callback is called once.                                       */
00848       LL_EXTI_ClearFlag_0_31((COMP_EXTI_LINE_COMP1 | COMP_EXTI_LINE_COMP2));
00849     }
00850     else
00851 #endif /* COMP2 */
00852     {
00853       /* Clear COMP EXTI line pending bit */
00854       LL_EXTI_ClearFlag_0_31(exti_line);
00855     }
00856 
00857     /* COMP trigger user callback */
00858 #if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
00859     hcomp->TriggerCallback(hcomp);
00860 #else
00861     HAL_COMP_TriggerCallback(hcomp);
00862 #endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
00863   }
00864 }
00865 
00866 /**
00867   * @}
00868   */
00869 
00870 /** @defgroup COMP_Exported_Functions_Group3 Peripheral Control functions
00871   *  @brief   Management functions.
00872   *
00873 @verbatim
00874  ===============================================================================
00875                       ##### Peripheral Control functions #####
00876  ===============================================================================
00877     [..]
00878     This subsection provides a set of functions allowing to control the comparators.
00879 
00880 @endverbatim
00881   * @{
00882   */
00883 
00884 /**
00885   * @brief  Lock the selected comparator configuration.
00886   * @note   A system reset is required to unlock the comparator configuration.
00887   * @note   Locking the comparator from reset state is possible
00888   *         if __HAL_RCC_SYSCFG_CLK_ENABLE() is being called before.
00889   * @param  hcomp  COMP handle
00890   * @retval HAL status
00891   */
00892 HAL_StatusTypeDef HAL_COMP_Lock(COMP_HandleTypeDef *hcomp)
00893 {
00894   HAL_StatusTypeDef status = HAL_OK;
00895 
00896   /* Check the COMP handle allocation and lock status */
00897   if(hcomp == NULL)
00898   {
00899     status = HAL_ERROR;
00900   }
00901   else if(__HAL_COMP_IS_LOCKED(hcomp))
00902   {
00903     status = HAL_ERROR;
00904   }
00905   else
00906   {
00907     /* Check the parameter */
00908     assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
00909 
00910     /* Set HAL COMP handle state */
00911     switch(hcomp->State)
00912     {
00913       case HAL_COMP_STATE_RESET:
00914         hcomp->State = HAL_COMP_STATE_RESET_LOCKED;
00915         break;
00916       case HAL_COMP_STATE_READY:
00917         hcomp->State = HAL_COMP_STATE_READY_LOCKED;
00918         break;
00919       default: /* HAL_COMP_STATE_BUSY */
00920         hcomp->State = HAL_COMP_STATE_BUSY_LOCKED;
00921         break;
00922     }
00923   }
00924 
00925   if(status == HAL_OK)
00926   {
00927     /* Set the lock bit corresponding to selected comparator */
00928     __HAL_COMP_LOCK(hcomp);
00929   }
00930 
00931   return status;
00932 }
00933 
00934 /**
00935   * @brief  Return the output level (high or low) of the selected comparator.
00936   *         The output level depends on the selected polarity.
00937   *         If the polarity is not inverted:
00938   *           - Comparator output is low when the input plus is at a lower
00939   *             voltage than the input minus
00940   *           - Comparator output is high when the input plus is at a higher
00941   *             voltage than the input minus
00942   *         If the polarity is inverted:
00943   *           - Comparator output is high when the input plus is at a lower
00944   *             voltage than the input minus
00945   *           - Comparator output is low when the input plus is at a higher
00946   *             voltage than the input minus
00947   * @param  hcomp  COMP handle
00948   * @retval Returns the selected comparator output level:
00949   *         @arg COMP_OUTPUT_LEVEL_LOW
00950   *         @arg COMP_OUTPUT_LEVEL_HIGH
00951   *
00952   */
00953 uint32_t HAL_COMP_GetOutputLevel(COMP_HandleTypeDef *hcomp)
00954 {
00955   /* Check the parameter */
00956   assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
00957 
00958   return (uint32_t)(READ_BIT(hcomp->Instance->CSR, COMP_CSR_VALUE)
00959                     >> COMP_OUTPUT_LEVEL_BITOFFSET_POS);
00960 }
00961 
00962 /**
00963   * @brief  Comparator trigger callback.
00964   * @param  hcomp  COMP handle
00965   * @retval None
00966   */
00967 __weak void HAL_COMP_TriggerCallback(COMP_HandleTypeDef *hcomp)
00968 {
00969   /* Prevent unused argument(s) compilation warning */
00970   UNUSED(hcomp);
00971 
00972   /* NOTE : This function should not be modified, when the callback is needed,
00973             the HAL_COMP_TriggerCallback should be implemented in the user file
00974    */
00975 }
00976 
00977 
00978 /**
00979   * @}
00980   */
00981 
00982 /** @defgroup COMP_Exported_Functions_Group4 Peripheral State functions
00983   *  @brief   Peripheral State functions.
00984   *
00985 @verbatim
00986  ===============================================================================
00987                       ##### Peripheral State functions #####
00988  ===============================================================================
00989     [..]
00990     This subsection permit to get in run-time the status of the peripheral.
00991 
00992 @endverbatim
00993   * @{
00994   */
00995 
00996 /**
00997   * @brief  Return the COMP handle state.
00998   * @param  hcomp  COMP handle
00999   * @retval HAL state
01000   */
01001 HAL_COMP_StateTypeDef HAL_COMP_GetState(COMP_HandleTypeDef *hcomp)
01002 {
01003   /* Check the COMP handle allocation */
01004   if(hcomp == NULL)
01005   {
01006     return HAL_COMP_STATE_RESET;
01007   }
01008 
01009   /* Check the parameter */
01010   assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
01011 
01012   /* Return HAL COMP handle state */
01013   return hcomp->State;
01014 }
01015 
01016 /**
01017   * @brief  Return the COMP error code.
01018   * @param hcomp COMP handle
01019   * @retval COMP error code
01020   */
01021 uint32_t HAL_COMP_GetError(COMP_HandleTypeDef *hcomp)
01022 {
01023   /* Check the parameters */
01024   assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
01025 
01026   return hcomp->ErrorCode;
01027 }
01028 
01029 /**
01030   * @}
01031   */
01032 
01033 /**
01034   * @}
01035   */
01036 
01037 /**
01038   * @}
01039   */
01040 
01041 #endif /* COMP1 || COMP2 */
01042 
01043 #endif /* HAL_COMP_MODULE_ENABLED */
01044 
01045 /**
01046   * @}
01047   */