STM32L486xx HAL User Manual
stm32l4xx_hal_opamp.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_hal_opamp.c
00004   * @author  MCD Application Team
00005   * @brief   OPAMP HAL module driver.
00006   *          This file provides firmware functions to manage the following 
00007   *          functionalities of the operational amplifier(s) peripheral: 
00008   *           + OPAMP configuration
00009   *           + OPAMP calibration
00010   *          Thanks to
00011   *           + Initialization and de-initialization functions
00012   *           + IO operation functions
00013   *           + Peripheral Control functions
00014   *           + Peripheral State functions
00015   *         
00016   @verbatim
00017 ================================================================================
00018           ##### OPAMP Peripheral Features #####
00019 ================================================================================
00020            
00021   [..] The device integrates 1 or 2 operational amplifiers OPAMP1 & OPAMP2
00022        
00023        (#) The OPAMP(s) provide(s) several exclusive running modes.       
00024        (++) 1 OPAMP: STM32L431xx STM32L432xx STM32L433xx STM32L442xx STM32L443xx
00025        (++) 2 OPAMP: STM32L471xx STM32L475xx STM32L476xx STM32L485xx STM32L486xx
00026 
00027        (#) The OPAMP(s) provide(s) several exclusive running modes.
00028        (++) Standalone mode
00029        (++) Programmable Gain Amplifier (PGA) mode (Resistor feedback output)
00030        (++) Follower mode
00031 
00032        (#) All OPAMP (same for all OPAMPs) can operate in
00033        (++) Either Low range (VDDA < 2.4V) power supply
00034        (++) Or High range (VDDA > 2.4V) power supply
00035 
00036        (#) Each OPAMP(s) can be configured in normal and low power mode.
00037 
00038        (#) The OPAMP(s) provide(s) calibration capabilities.  
00039        (++) Calibration aims at correcting some offset for running mode.
00040        (++) The OPAMP uses either factory calibration settings OR user defined 
00041            calibration (trimming) settings (i.e. trimming mode).
00042        (++) The user defined settings can be figured out using self calibration 
00043            handled by HAL_OPAMP_SelfCalibrate, HAL_OPAMPEx_SelfCalibrateAll
00044        (++) HAL_OPAMP_SelfCalibrate:
00045        (+++) Runs automatically the calibration.
00046        (+++) Enables the user trimming mode
00047        (+++) Updates the init structure with trimming values with fresh calibration 
00048             results. 
00049             The user may store the calibration results for larger 
00050             (ex monitoring the trimming as a function of temperature 
00051             for instance)
00052        (+++) HAL_OPAMPEx_SelfCalibrateAll
00053             runs calibration of all OPAMPs in parallel to save search time.
00054                     
00055        (#) Running mode: Standalone mode 
00056        (++) Gain is set externally (gain depends on external loads).
00057        (++) Follower mode also possible externally by connecting the inverting input to
00058            the output.
00059        
00060        (#) Running mode: Follower mode
00061        (++) No Inverting Input is connected.
00062        
00063        (#) Running mode: Programmable Gain Amplifier (PGA) mode 
00064            (Resistor feedback output)
00065        (++) The OPAMP(s) output(s) can be internally connected to resistor feedback
00066            output.
00067        (++) OPAMP gain is either 2, 4, 8 or 16.
00068         
00069        (#) The OPAMPs inverting input can be selected according to the Reference Manual 
00070            "OPAMP function description" chapter.
00071        
00072        (#) The OPAMPs non inverting input can be selected according to the Reference Manual 
00073            "OPAMP function description" chapter.
00074        
00075       
00076             ##### How to use this driver #####
00077 ================================================================================
00078   [..] 
00079 
00080     *** Power supply range ***
00081     ============================================
00082     [..] To run in low power mode:
00083 
00084       (#) Configure the OPAMP using HAL_OPAMP_Init() function:
00085       (++) Select OPAMP_POWERSUPPLY_LOW (VDDA lower than 2.4V)
00086       (++) Otherwise select OPAMP_POWERSUPPLY_HIGH (VDDA higher than 2.4V)
00087 
00088     *** Low / normal power mode ***
00089     ============================================
00090     [..] To run in low power mode:
00091 
00092       (#) Configure the OPAMP using HAL_OPAMP_Init() function:
00093       (++) Select OPAMP_POWERMODE_LOWPOWER
00094       (++) Otherwise select OPAMP_POWERMODE_NORMAL
00095 
00096     *** Calibration ***
00097     ============================================
00098     [..] To run the OPAMP calibration self calibration:
00099 
00100       (#) Start calibration using HAL_OPAMP_SelfCalibrate. 
00101            Store the calibration results.
00102 
00103     *** Running mode ***
00104     ============================================
00105       
00106     [..] To use the OPAMP, perform the following steps:
00107             
00108       (#) Fill in the HAL_OPAMP_MspInit() to
00109       (++) Enable the OPAMP Peripheral clock using macro __HAL_RCC_OPAMP_CLK_ENABLE()
00110       (++) Configure the OPAMP input AND output in analog mode using 
00111            HAL_GPIO_Init() to map the OPAMP output to the GPIO pin.
00112   
00113       (#) Registrate Callbacks
00114       (++) The compilation define  USE_HAL_OPAMP_REGISTER_CALLBACKS when set to 1
00115            allows the user to configure dynamically the driver callbacks.
00116 
00117       (++) Use Functions @ref HAL_OPAMP_RegisterCallback() to register a user callback,
00118            it allows to register following callbacks:
00119       (+++) MspInitCallback         : OPAMP MspInit.  
00120       (+++) MspDeInitCallback       : OPAMP MspFeInit.
00121            This function takes as parameters the HAL peripheral handle, the Callback ID
00122            and a pointer to the user callback function.
00123 
00124       (++) Use function @ref HAL_OPAMP_UnRegisterCallback() to reset a callback to the default
00125            weak (surcharged) function. It allows to reset following callbacks:
00126       (+++) MspInitCallback         : OPAMP MspInit.  
00127       (+++) MspDeInitCallback       : OPAMP MspdeInit.
00128       (+++) All Callbacks
00129 
00130       (#) Configure the OPAMP using HAL_OPAMP_Init() function:
00131       (++) Select the mode
00132       (++) Select the inverting input
00133       (++) Select the non-inverting input 
00134       (++) If PGA mode is enabled, Select if inverting input is connected.
00135       (++) Select either factory or user defined trimming mode.
00136       (++) If the user-defined trimming mode is enabled, select PMOS & NMOS trimming values
00137           (typically values set by HAL_OPAMP_SelfCalibrate function).
00138       
00139       (#) Enable the OPAMP using HAL_OPAMP_Start() function.
00140            
00141       (#) Disable the OPAMP using HAL_OPAMP_Stop() function.
00142       
00143       (#) Lock the OPAMP in running mode using HAL_OPAMP_Lock() function.
00144           Caution: On STM32L4, HAL OPAMP lock is software lock only (not 
00145           hardware lock as on some other STM32 devices)
00146 
00147       (#) If needed, unlock the OPAMP using HAL_OPAMPEx_Unlock() function.
00148 
00149     *** Running mode: change of configuration while OPAMP ON  ***
00150     ============================================
00151     [..] To Re-configure OPAMP when OPAMP is ON (change on the fly)
00152       (#) If needed, fill in the HAL_OPAMP_MspInit()
00153       (++) This is the case for instance if you wish to use new OPAMP I/O
00154 
00155       (#) Configure the OPAMP using HAL_OPAMP_Init() function:
00156       (++) As in configure case, select first the parameters you wish to modify.
00157       
00158       (#) Change from low power mode to normal power mode (& vice versa) requires  
00159           first HAL_OPAMP_DeInit() (force OPAMP OFF) and then HAL_OPAMP_Init(). 
00160           In other words, of OPAMP is ON, HAL_OPAMP_Init can NOT change power mode
00161           alone.
00162 
00163   @endverbatim
00164   ******************************************************************************
00165 
00166       Table 1.  OPAMPs inverting/non-inverting inputs for the STM32L4 devices:
00167       +------------------------------------------------------------------------|     
00168       |                 |         | OPAMP1               | OPAMP2              |
00169       |-----------------|---------|----------------------|---------------------|
00170       | Inverting Input | VM_SEL  |                      |                     |
00171       |                 |         |  IO0-> PA1           | IO0-> PA7           |
00172       |                 |         |  LOW LEAKAGE IO (2)  | LOW LEAKAGE IO (2)  |
00173       |                 |         |  Not connected       | Not connected       |
00174       | (1)             |         |    PGA mode only     |   PGA mode only     |
00175       |-----------------|---------|----------------------|---------------------|
00176       |  Non Inverting  | VP_SEL  |                      |                     |
00177       |                 |         |  IO0-> PA0 (GPIO)    | IO0-> PA6  (GPIO)   |
00178       |    Input        |         |  DAC1_OUT1 internal  | DAC1_OUT2 internal  |
00179       +------------------------------------------------------------------------|
00180        (1): NA in follower mode.
00181        (2): Available on some package only (ex. BGA132).
00182            
00183            
00184       Table 2.  OPAMPs outputs for the STM32L4 devices:
00185 
00186       +-------------------------------------------------------------------------     
00187       |                 |        | OPAMP1                | OPAMP2              |
00188       |-----------------|--------|-----------------------|---------------------|
00189       | Output          |  VOUT  |  PA3                  |  PB0                |
00190       |                 |        |  & (1) ADC12_IN if    | & (1) ADC12_IN if   |
00191       |                 |        |  connected internally | connected internally|
00192       |-----------------|--------|-----------------------|---------------------|
00193        (1): ADC1 or ADC2 shall select IN15.
00194 
00195   ******************************************************************************
00196   * @attention
00197   *
00198   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
00199   *
00200   * Redistribution and use in source and binary forms, with or without modification,
00201   * are permitted provided that the following conditions are met:
00202   *   1. Redistributions of source code must retain the above copyright notice,
00203   *      this list of conditions and the following disclaimer.
00204   *   2. Redistributions in binary form must reproduce the above copyright notice,
00205   *      this list of conditions and the following disclaimer in the documentation
00206   *      and/or other materials provided with the distribution.
00207   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00208   *      may be used to endorse or promote products derived from this software
00209   *      without specific prior written permission.
00210   *
00211   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00212   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00213   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00214   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00215   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00216   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00217   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00218   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00219   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00220   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00221   *
00222   ******************************************************************************  
00223   */
00224 
00225 /* Includes ------------------------------------------------------------------*/
00226 #include "stm32l4xx_hal.h"
00227     
00228 /** @addtogroup STM32L4xx_HAL_Driver
00229   * @{
00230   */
00231 
00232 /** @defgroup OPAMP OPAMP
00233   * @brief OPAMP module driver
00234   * @{
00235   */
00236 
00237 #ifdef HAL_OPAMP_MODULE_ENABLED
00238 
00239 /* Private types -------------------------------------------------------------*/
00240 /* Private variables ---------------------------------------------------------*/
00241 /* Private constants ---------------------------------------------------------*/
00242 /** @addtogroup OPAMP_Private_Constants
00243   * @{
00244   */
00245 
00246 /* CSR register reset value */ 
00247 #define OPAMP_CSR_RESET_VALUE             ((uint32_t)0x00000000)
00248 
00249 #define OPAMP_CSR_RESET_BITS    (OPAMP_CSR_OPAMPxEN | OPAMP_CSR_OPALPM | OPAMP_CSR_OPAMODE \
00250                                | OPAMP_CSR_PGGAIN | OPAMP_CSR_VMSEL | OPAMP_CSR_VPSEL \
00251                                | OPAMP_CSR_CALON | OPAMP_CSR_USERTRIM)
00252 
00253 /* CSR Init masks */
00254 #define OPAMP_CSR_INIT_MASK_PGA (OPAMP_CSR_OPALPM | OPAMP_CSR_OPAMODE| OPAMP_CSR_PGGAIN \
00255                                | OPAMP_CSR_VMSEL | OPAMP_CSR_VPSEL | OPAMP_CSR_USERTRIM)
00256 
00257 #define OPAMP_CSR_INIT_MASK_FOLLOWER (OPAMP_CSR_OPALPM | OPAMP_CSR_OPAMODE| OPAMP_CSR_VPSEL \
00258                                     | OPAMP_CSR_USERTRIM)
00259 
00260 #define OPAMP_CSR_INIT_MASK_STANDALONE (OPAMP_CSR_OPALPM | OPAMP_CSR_OPAMODE| OPAMP_CSR_VPSEL \
00261                                       | OPAMP_CSR_VMSEL | OPAMP_CSR_USERTRIM)
00262 
00263 
00264 /**
00265   * @}
00266   */ 
00267 
00268 /* Private macros ------------------------------------------------------------*/
00269 /* Private functions ---------------------------------------------------------*/
00270 /* Exported functions --------------------------------------------------------*/
00271 
00272 /** @defgroup OPAMP_Exported_Functions OPAMP Exported Functions
00273   * @{
00274   */
00275 
00276 /** @defgroup OPAMP_Exported_Functions_Group1 Initialization and de-initialization functions 
00277  *  @brief    Initialization and Configuration functions 
00278  *
00279 @verbatim    
00280   ==============================================================================
00281               ##### Initialization and de-initialization functions #####
00282   ==============================================================================
00283  
00284 @endverbatim
00285   * @{
00286   */
00287 
00288 /**
00289   * @brief  Initializes the OPAMP according to the specified
00290   *         parameters in the OPAMP_InitTypeDef and initialize the associated handle.
00291   * @note   If the selected opamp is locked, initialization can't be performed.
00292   *         To unlock the configuration, perform a system reset.
00293   * @param  hopamp: OPAMP handle
00294   * @retval HAL status
00295   */
00296 HAL_StatusTypeDef HAL_OPAMP_Init(OPAMP_HandleTypeDef *hopamp)
00297 { 
00298   HAL_StatusTypeDef status = HAL_OK;
00299   uint32_t updateotrlpotr = 0;
00300 
00301   /* Check the OPAMP handle allocation and lock status */
00302   /* Init not allowed if calibration is ongoing */
00303   if((hopamp == NULL) || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED)
00304                       || (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY))
00305   {
00306     return HAL_ERROR;
00307   }
00308   else
00309   {
00310     /* Check the parameter */
00311     assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
00312        
00313     /* Set OPAMP parameters */
00314     assert_param(IS_OPAMP_POWER_SUPPLY_RANGE(hopamp->Init.PowerSupplyRange));
00315     assert_param(IS_OPAMP_POWERMODE(hopamp->Init.PowerMode));
00316     assert_param(IS_OPAMP_FUNCTIONAL_NORMALMODE(hopamp->Init.Mode));
00317     assert_param(IS_OPAMP_NONINVERTING_INPUT(hopamp->Init.NonInvertingInput));
00318     
00319     if(hopamp->State == HAL_OPAMP_STATE_RESET)
00320     {  
00321 #if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1)
00322     if(hopamp->MspInitCallback == NULL)
00323     {
00324       hopamp->MspInitCallback               = HAL_OPAMP_MspInit;
00325     } 
00326 #endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */
00327     }
00328     
00329     if ((hopamp->Init.Mode) == OPAMP_STANDALONE_MODE)
00330     {
00331       assert_param(IS_OPAMP_INVERTING_INPUT_STANDALONE(hopamp->Init.InvertingInput));
00332     }
00333 
00334     if ((hopamp->Init.Mode) == OPAMP_PGA_MODE)      
00335     {
00336       assert_param(IS_OPAMP_INVERTING_INPUT_PGA(hopamp->Init.InvertingInput));
00337     }
00338     
00339     if ((hopamp->Init.Mode) == OPAMP_PGA_MODE)
00340     {
00341       assert_param(IS_OPAMP_PGA_GAIN(hopamp->Init.PgaGain));
00342     }
00343     
00344     assert_param(IS_OPAMP_TRIMMING(hopamp->Init.UserTrimming)); 
00345     if ((hopamp->Init.UserTrimming) == OPAMP_TRIMMING_USER)
00346     {
00347       if (hopamp->Init.PowerMode == OPAMP_POWERMODE_NORMAL)
00348       {
00349         assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueP));
00350         assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueN));
00351       }
00352     else
00353       {
00354         assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValuePLowPower));
00355         assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueNLowPower));
00356       }
00357     }
00358      
00359     if(hopamp->State == HAL_OPAMP_STATE_RESET)
00360     {
00361       /* Allocate lock resource and initialize it */
00362       hopamp->Lock = HAL_UNLOCKED;
00363     }
00364 
00365 #if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1)
00366     hopamp->MspInitCallback(hopamp);    
00367 #else    
00368     /* Call MSP init function */
00369     HAL_OPAMP_MspInit(hopamp);
00370 #endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */
00371 
00372     /* Set operating mode */
00373     CLEAR_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALON);
00374                                               
00375     if (hopamp->Init.Mode == OPAMP_PGA_MODE)
00376     {
00377       MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_INIT_MASK_PGA, \
00378                                         hopamp->Init.PowerMode | \
00379                                         hopamp->Init.Mode | \
00380                                         hopamp->Init.PgaGain | \
00381                                         hopamp->Init.InvertingInput    | \
00382                                         hopamp->Init.NonInvertingInput | \
00383                                         hopamp->Init.UserTrimming);
00384     }
00385     
00386     if (hopamp->Init.Mode == OPAMP_FOLLOWER_MODE)
00387     {
00388     /* In Follower mode InvertingInput is Not Applicable  */
00389     MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_INIT_MASK_FOLLOWER, \
00390                                         hopamp->Init.PowerMode | \
00391                                         hopamp->Init.Mode | \
00392                                         hopamp->Init.NonInvertingInput | \
00393                                         hopamp->Init.UserTrimming);     
00394     }     
00395     
00396     if (hopamp->Init.Mode == OPAMP_STANDALONE_MODE)
00397     {
00398       MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_INIT_MASK_STANDALONE, \
00399                                         hopamp->Init.PowerMode | \
00400                                         hopamp->Init.Mode | \
00401                                         hopamp->Init.InvertingInput    | \
00402                                         hopamp->Init.NonInvertingInput | \
00403                                         hopamp->Init.UserTrimming);
00404     } 
00405     
00406     if (hopamp->Init.UserTrimming == OPAMP_TRIMMING_USER)
00407     {
00408       /* Set power mode and associated calibration parameters */
00409       if (hopamp->Init.PowerMode != OPAMP_POWERMODE_LOWPOWER)
00410       {
00411         /* OPAMP_POWERMODE_NORMAL */
00412         /* Set calibration mode (factory or user) and values for            */
00413         /* transistors differential pair high (PMOS) and low (NMOS) for     */
00414         /* normal mode.                                                     */
00415         updateotrlpotr = (((hopamp->Init.TrimmingValueP) << (OPAMP_INPUT_NONINVERTING)) \
00416                          | (hopamp->Init.TrimmingValueN)); 
00417         MODIFY_REG(hopamp->Instance->OTR, OPAMP_OTR_TRIMOFFSETN | OPAMP_OTR_TRIMOFFSETP, updateotrlpotr);
00418       }
00419       else
00420       {
00421         /* OPAMP_POWERMODE_LOWPOWER */
00422         /* transistors differential pair high (PMOS) and low (NMOS) for     */
00423         /* low power mode.                                                     */
00424         updateotrlpotr = (((hopamp->Init.TrimmingValuePLowPower) << (OPAMP_INPUT_NONINVERTING)) \
00425                          | (hopamp->Init.TrimmingValueNLowPower)); 
00426         MODIFY_REG(hopamp->Instance->LPOTR, OPAMP_OTR_TRIMOFFSETN | OPAMP_OTR_TRIMOFFSETP, updateotrlpotr);     
00427       }
00428     } 
00429 
00430     /* Configure the power supply range */
00431     /* The OPAMP_CSR_OPARANGE is common configuration for all OPAMPs */
00432     /* bit OPAMP1_CSR_OPARANGE is used for both OPAMPs */
00433     MODIFY_REG(OPAMP1->CSR, OPAMP1_CSR_OPARANGE, hopamp->Init.PowerSupplyRange);
00434     
00435     /* Update the OPAMP state*/
00436     if (hopamp->State == HAL_OPAMP_STATE_RESET)
00437     {
00438       /* From RESET state to READY State */
00439       hopamp->State = HAL_OPAMP_STATE_READY;
00440     }
00441     /* else: remain in READY or BUSY state (no update) */
00442     return status;
00443   }
00444 }
00445 
00446 /**
00447   * @brief  DeInitialize the OPAMP peripheral.
00448   * @note   Deinitialization can be performed if the OPAMP configuration is locked.
00449   *         (the lock is SW in L4)
00450   * @param  hopamp: OPAMP handle
00451   * @retval HAL status
00452   */
00453 HAL_StatusTypeDef HAL_OPAMP_DeInit(OPAMP_HandleTypeDef *hopamp)
00454 {
00455   HAL_StatusTypeDef status = HAL_OK;
00456   
00457   /* Check the OPAMP handle allocation */
00458   /* DeInit not allowed if calibration is ongoing */
00459   if((hopamp == NULL) || (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY))
00460   {
00461     status = HAL_ERROR;
00462   }
00463   else
00464   {
00465     /* Check the parameter */
00466     assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
00467 
00468     /* Set OPAMP_CSR register to reset value */
00469     /* Mind that OPAMP1_CSR_OPARANGE of CSR of OPAMP1 remains unchanged (applies to both OPAMPs) */ 
00470     /* OPAMP shall be disabled first separately */     
00471     CLEAR_BIT(hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN);
00472     MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_RESET_BITS, OPAMP_CSR_RESET_VALUE);
00473     
00474 #if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1)
00475   if(hopamp->MspDeInitCallback == NULL)
00476   {
00477     hopamp->MspDeInitCallback = HAL_OPAMP_MspDeInit;
00478   }
00479   /* DeInit the low level hardware */
00480   hopamp->MspDeInitCallback(hopamp);
00481 #else
00482     /* DeInit the low level hardware: GPIO, CLOCK and NVIC */
00483     HAL_OPAMP_MspDeInit(hopamp);
00484 #endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */
00485     /* Update the OPAMP state*/
00486     hopamp->State = HAL_OPAMP_STATE_RESET;   
00487     
00488     /* Process unlocked */
00489     __HAL_UNLOCK(hopamp);
00490   }
00491   return status;
00492 }
00493 
00494 /**
00495   * @brief  Initialize the OPAMP MSP.
00496   * @param  hopamp: OPAMP handle
00497   * @retval None
00498   */
00499 __weak void HAL_OPAMP_MspInit(OPAMP_HandleTypeDef *hopamp)
00500 {
00501   /* Prevent unused argument(s) compilation warning */
00502   UNUSED(hopamp);
00503 
00504   /* NOTE : This function should not be modified, when the callback is needed,
00505             the function "HAL_OPAMP_MspInit()" must be implemented in the user file.
00506    */
00507 }
00508 
00509 /**
00510   * @brief  DeInitialize OPAMP MSP.
00511   * @param  hopamp: OPAMP handle
00512   * @retval None
00513   */
00514 __weak void HAL_OPAMP_MspDeInit(OPAMP_HandleTypeDef *hopamp)
00515 {
00516   /* Prevent unused argument(s) compilation warning */
00517   UNUSED(hopamp);
00518 
00519   /* NOTE : This function should not be modified, when the callback is needed,
00520             the function "HAL_OPAMP_MspDeInit()" must be implemented in the user file.
00521    */
00522 }
00523 
00524 /**
00525   * @}
00526   */
00527 
00528 
00529 /** @defgroup OPAMP_Exported_Functions_Group2 IO operation functions 
00530  *  @brief   IO operation functions 
00531  *
00532 @verbatim   
00533  ===============================================================================
00534                         ##### IO operation functions #####
00535  =============================================================================== 
00536     [..]
00537     This subsection provides a set of functions allowing to manage the OPAMP
00538     start, stop and calibration actions.
00539 
00540 @endverbatim
00541   * @{
00542   */
00543 
00544 /**
00545   * @brief  Start the OPAMP.
00546   * @param  hopamp: OPAMP handle
00547   * @retval HAL status
00548   */
00549 
00550 HAL_StatusTypeDef HAL_OPAMP_Start(OPAMP_HandleTypeDef *hopamp)
00551 { 
00552   HAL_StatusTypeDef status = HAL_OK;
00553   
00554   /* Check the OPAMP handle allocation */
00555   /* Check if OPAMP locked */
00556   if((hopamp == NULL) || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED))
00557   {
00558     status = HAL_ERROR;
00559   }
00560   else
00561   {
00562     /* Check the parameter */
00563     assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
00564     
00565     if(hopamp->State == HAL_OPAMP_STATE_READY)
00566     {
00567       /* Enable the selected opamp */
00568       SET_BIT (hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN);
00569 
00570       /* Update the OPAMP state*/     
00571       /* From HAL_OPAMP_STATE_READY to HAL_OPAMP_STATE_BUSY */
00572       hopamp->State = HAL_OPAMP_STATE_BUSY;   
00573     }
00574     else
00575     {
00576       status = HAL_ERROR;
00577     }
00578     
00579    }
00580   return status;
00581 }
00582 
00583 /**
00584   * @brief  Stop the OPAMP.
00585   * @param  hopamp: OPAMP handle
00586   * @retval HAL status
00587   */
00588 HAL_StatusTypeDef HAL_OPAMP_Stop(OPAMP_HandleTypeDef *hopamp)
00589 { 
00590   HAL_StatusTypeDef status = HAL_OK;
00591     
00592   /* Check the OPAMP handle allocation */
00593   /* Check if OPAMP locked */
00594   /* Check if OPAMP calibration ongoing */
00595   if((hopamp == NULL) || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED) \
00596                       || (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY))  
00597   {
00598     status = HAL_ERROR;
00599   }
00600   else
00601   {
00602     /* Check the parameter */
00603     assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
00604 
00605     if(hopamp->State == HAL_OPAMP_STATE_BUSY)
00606     {
00607       /* Disable the selected opamp */
00608       CLEAR_BIT (hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN); 
00609     
00610       /* Update the OPAMP state*/     
00611       /* From  HAL_OPAMP_STATE_BUSY to HAL_OPAMP_STATE_READY*/
00612       hopamp->State = HAL_OPAMP_STATE_READY;
00613     }
00614     else
00615     {
00616       status = HAL_ERROR;
00617     }
00618   }
00619   return status;
00620 }
00621 
00622 /**
00623   * @brief  Run the self calibration of one OPAMP.
00624   * @note   Calibration is performed in the mode specified in OPAMP init
00625   *         structure (mode normal or low-power). To perform calibration for
00626   *         both modes, repeat this function twice after OPAMP init structure
00627   *         accordingly updated.
00628   * @note   Calibration runs about 10 ms.
00629   * @param  hopamp handle
00630   * @retval Updated offset trimming values (PMOS & NMOS), user trimming is enabled
00631   * @retval HAL status
00632 
00633   */
00634 
00635 HAL_StatusTypeDef HAL_OPAMP_SelfCalibrate(OPAMP_HandleTypeDef *hopamp)
00636 { 
00637 
00638   HAL_StatusTypeDef status = HAL_OK;
00639   
00640   uint32_t trimmingvaluen = 0;
00641   uint32_t trimmingvaluep = 0;
00642   uint32_t delta;
00643   uint32_t opampmode;
00644   
00645   __IO uint32_t* tmp_opamp_reg_trimming;   /* Selection of register of trimming depending on power mode: OTR or LPOTR */
00646     
00647   /* Check the OPAMP handle allocation */
00648   /* Check if OPAMP locked */
00649   if((hopamp == NULL) || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED))
00650   {
00651     status = HAL_ERROR;
00652   }
00653   else
00654   {
00655     /* Check if OPAMP in calibration mode and calibration not yet enable */
00656     if(hopamp->State ==  HAL_OPAMP_STATE_READY)
00657     {
00658       /* Check the parameter */
00659       assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
00660       assert_param(IS_OPAMP_POWERMODE(hopamp->Init.PowerMode));
00661 
00662       /* Save OPAMP mode as in                                       */
00663       /* STM32L471xx STM32L475xx STM32L476xx STM32L485xx STM32L486xx */
00664       /* the calibration is not working in PGA mode                  */
00665       opampmode = READ_BIT(hopamp->Instance->CSR,OPAMP_CSR_OPAMODE);
00666       
00667       /* Use of standalone mode */ 
00668       MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_OPAMODE, OPAMP_STANDALONE_MODE); 
00669 
00670       /*  user trimming values are used for offset calibration */
00671       SET_BIT(hopamp->Instance->CSR, OPAMP_CSR_USERTRIM);
00672       
00673       /* Select trimming settings depending on power mode */
00674       if (hopamp->Init.PowerMode == OPAMP_POWERMODE_NORMAL)
00675       {
00676         tmp_opamp_reg_trimming = &hopamp->Instance->OTR;
00677       }
00678       else
00679       {
00680         tmp_opamp_reg_trimming = &hopamp->Instance->LPOTR;
00681       }
00682       
00683       /* Enable calibration */
00684       SET_BIT (hopamp->Instance->CSR, OPAMP_CSR_CALON);
00685   
00686       /* 1st calibration - N */
00687       CLEAR_BIT (hopamp->Instance->CSR, OPAMP_CSR_CALSEL);
00688       
00689       /* Enable the selected opamp */
00690       SET_BIT (hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN);
00691       
00692       /* Init trimming counter */    
00693       /* Medium value */
00694       trimmingvaluen = 16; 
00695       delta = 8;
00696            
00697       while (delta != 0)
00698       {
00699         /* Set candidate trimming */
00700         /* OPAMP_POWERMODE_NORMAL */
00701         MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETN, trimmingvaluen);
00702         
00703         /* OFFTRIMmax delay 1 ms as per datasheet (electrical characteristics */ 
00704         /* Offset trim time: during calibration, minimum time needed between */
00705         /* two steps to have 1 mV accuracy */
00706         HAL_Delay(OPAMP_TRIMMING_DELAY);
00707 
00708         if (READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT) != RESET)
00709         { 
00710           /* OPAMP_CSR_CALOUT is HIGH try higher trimming */
00711           trimmingvaluen -= delta;
00712         }
00713         else
00714         {
00715           /* OPAMP_CSR_CALOUT is LOW try lower trimming */
00716           trimmingvaluen += delta;
00717         }
00718         /* Divide range by 2 to continue dichotomy sweep */       
00719         delta >>= 1;
00720       }
00721 
00722       /* Still need to check if right calibration is current value or one step below */
00723       /* Indeed the first value that causes the OUTCAL bit to change from 0 to 1  */
00724       /* Set candidate trimming */
00725       MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETN, trimmingvaluen);
00726            
00727       /* OFFTRIMmax delay 1 ms as per datasheet (electrical characteristics */ 
00728       /* Offset trim time: during calibration, minimum time needed between */
00729       /* two steps to have 1 mV accuracy */
00730       HAL_Delay(OPAMP_TRIMMING_DELAY);
00731       
00732       if ((READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT)) == 0)
00733       { 
00734         /* Trimming value is actually one value more */
00735         trimmingvaluen++;
00736         /* Set right trimming */
00737         MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETN, trimmingvaluen);
00738       }
00739 
00740       /* 2nd calibration - P */
00741       SET_BIT (hopamp->Instance->CSR, OPAMP_CSR_CALSEL);
00742       
00743       /* Init trimming counter */    
00744       /* Medium value */
00745       trimmingvaluep = 16; 
00746       delta = 8;
00747       
00748       while (delta != 0)
00749       {
00750         /* Set candidate trimming */
00751         /* OPAMP_POWERMODE_NORMAL */
00752         MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETP, (trimmingvaluep<<OPAMP_INPUT_NONINVERTING));
00753 
00754         /* OFFTRIMmax delay 1 ms as per datasheet (electrical characteristics */ 
00755         /* Offset trim time: during calibration, minimum time needed between */
00756         /* two steps to have 1 mV accuracy */
00757         HAL_Delay(OPAMP_TRIMMING_DELAY);
00758 
00759         if (READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT) != RESET)
00760         { 
00761           /* OPAMP_CSR_CALOUT is HIGH try higher trimming */
00762           trimmingvaluep += delta;
00763         }
00764         else
00765         {
00766           /* OPAMP_CSR_CALOUT  is LOW try lower trimming */
00767           trimmingvaluep -= delta;
00768         }
00769         
00770         /* Divide range by 2 to continue dichotomy sweep */
00771         delta >>= 1;
00772       }
00773       
00774       /* Still need to check if right calibration is current value or one step below */
00775       /* Indeed the first value that causes the OUTCAL bit to change from 1 to 0  */
00776       /* Set candidate trimming */
00777       MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETP, (trimmingvaluep<<OPAMP_INPUT_NONINVERTING));
00778 
00779       /* OFFTRIMmax delay 1 ms as per datasheet (electrical characteristics */ 
00780       /* Offset trim time: during calibration, minimum time needed between */
00781       /* two steps to have 1 mV accuracy */
00782       HAL_Delay(OPAMP_TRIMMING_DELAY);
00783       
00784       if (READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT) != RESET)
00785       {
00786         /* Trimming value is actually one value more */
00787         trimmingvaluep++;
00788         MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETP, (trimmingvaluep<<OPAMP_INPUT_NONINVERTING));
00789       }
00790       
00791       /* Disable the OPAMP */
00792       CLEAR_BIT (hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN);
00793       
00794       /* Disable calibration & set normal mode (operating mode) */
00795       CLEAR_BIT (hopamp->Instance->CSR, OPAMP_CSR_CALON);
00796                  
00797       /* Self calibration is successful  */
00798       /* Store calibration(user trimming) results in init structure. */
00799 
00800       /* Set user trimming mode */  
00801       hopamp->Init.UserTrimming = OPAMP_TRIMMING_USER;
00802 
00803       /* Affect calibration parameters depending on mode normal/low power */
00804       if (hopamp->Init.PowerMode != OPAMP_POWERMODE_LOWPOWER)
00805       {
00806         /* Write calibration result N */
00807         hopamp->Init.TrimmingValueN = trimmingvaluen;
00808         /* Write calibration result P */
00809         hopamp->Init.TrimmingValueP = trimmingvaluep;
00810       }
00811       else
00812       {
00813         /* Write calibration result N */
00814         hopamp->Init.TrimmingValueNLowPower = trimmingvaluen;
00815         /* Write calibration result P */
00816         hopamp->Init.TrimmingValuePLowPower = trimmingvaluep;
00817       }
00818     
00819     /* Restore OPAMP mode after calibration */
00820     MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_OPAMODE, opampmode);
00821     }
00822     else
00823     {
00824       /* OPAMP can not be calibrated from this mode */ 
00825       status = HAL_ERROR;
00826     }   
00827   }
00828   return status;
00829 }
00830 
00831 /**
00832   * @}
00833   */
00834 
00835 /** @defgroup OPAMP_Exported_Functions_Group3 Peripheral Control functions 
00836  *  @brief   Peripheral Control functions 
00837  *
00838 @verbatim   
00839  ===============================================================================
00840                       ##### Peripheral Control functions #####
00841  =============================================================================== 
00842     [..]
00843     This subsection provides a set of functions allowing to control the OPAMP data 
00844     transfers.
00845 
00846 
00847 
00848 @endverbatim
00849   * @{
00850   */
00851 
00852 /**
00853   * @brief  Lock the selected OPAMP configuration.
00854   * @note   On STM32L4, HAL OPAMP lock is software lock only (in 
00855   *         contrast of hardware lock available on some other STM32 
00856   *         devices).
00857   * @param  hopamp: OPAMP handle
00858   * @retval HAL status
00859   */
00860 HAL_StatusTypeDef HAL_OPAMP_Lock(OPAMP_HandleTypeDef *hopamp)
00861 {
00862   HAL_StatusTypeDef status = HAL_OK;
00863 
00864   /* Check the OPAMP handle allocation */
00865   /* Check if OPAMP locked */
00866   /* OPAMP can be locked when enabled and running in normal mode */ 
00867   /*   It is meaningless otherwise */
00868   if((hopamp == NULL) || (hopamp->State == HAL_OPAMP_STATE_RESET) \
00869                       || (hopamp->State == HAL_OPAMP_STATE_READY) \
00870                       || (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY)\
00871                       || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED))
00872   
00873   {
00874     status = HAL_ERROR;
00875   }
00876   
00877   else
00878   {
00879     /* Check the parameter */
00880     assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
00881     
00882    /* OPAMP state changed to locked */
00883     hopamp->State = HAL_OPAMP_STATE_BUSYLOCKED;
00884   }
00885   return status; 
00886 }
00887 
00888 /**
00889   * @brief  Return the OPAMP factory trimming value.
00890   * @note            On STM32L4 OPAMP, user can retrieve factory trimming if 
00891   *                  OPAMP has never been set to user trimming before.
00892   *                  Therefore, this function must be called when OPAMP init  
00893   *                  parameter "UserTrimming" is set to trimming factory, 
00894   *                  and before OPAMP  calibration (function 
00895   *                  "HAL_OPAMP_SelfCalibrate()").
00896   *                  Otherwise, factory trimming value cannot be retrieved and 
00897   *                  error status is returned.
00898   * @param  hopamp : OPAMP handle
00899   * @param  trimmingoffset : Trimming offset (P or N)
00900   *         This parameter must be a value of @ref OPAMP_FactoryTrimming
00901   * @note   Calibration parameter retrieved is corresponding to the mode 
00902   *         specified in OPAMP init structure (mode normal or low-power). 
00903   *         To retrieve calibration parameters for both modes, repeat this 
00904   *         function after OPAMP init structure accordingly updated.
00905   * @retval Trimming value (P or N): range: 0->31
00906   *         or OPAMP_FACTORYTRIMMING_DUMMY if trimming value is not available
00907   *
00908   */
00909 
00910 HAL_OPAMP_TrimmingValueTypeDef HAL_OPAMP_GetTrimOffset (OPAMP_HandleTypeDef *hopamp, uint32_t trimmingoffset)
00911 {
00912   HAL_OPAMP_TrimmingValueTypeDef trimmingvalue;
00913   __IO uint32_t* tmp_opamp_reg_trimming;  /* Selection of register of trimming depending on power mode: OTR or LPOTR */
00914   
00915   /* Check the OPAMP handle allocation */
00916   /* Value can be retrieved in HAL_OPAMP_STATE_READY state */
00917   if((hopamp == NULL) || (hopamp->State == HAL_OPAMP_STATE_RESET) \
00918                       || (hopamp->State == HAL_OPAMP_STATE_BUSY) \
00919                       || (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY)\
00920                       || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED))
00921   {
00922     return OPAMP_FACTORYTRIMMING_DUMMY;
00923   }
00924   else
00925   {
00926     /* Check the parameter */
00927     assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
00928     assert_param(IS_OPAMP_FACTORYTRIMMING(trimmingoffset));
00929     assert_param(IS_OPAMP_POWERMODE(hopamp->Init.PowerMode));
00930     
00931     /* Check the trimming mode */
00932     if (READ_BIT(hopamp->Instance->CSR,OPAMP_CSR_USERTRIM) != RESET)
00933     {
00934       /* This function must called when OPAMP init parameter "UserTrimming"   */
00935       /* is set to trimming factory, and before OPAMP calibration (function   */
00936       /* "HAL_OPAMP_SelfCalibrate()").                                        */
00937       /* Otherwise, factory trimming value cannot be retrieved and error       */
00938       /* status is returned.                                                  */
00939       trimmingvalue = OPAMP_FACTORYTRIMMING_DUMMY;
00940     }
00941     else
00942     {
00943       /* Select trimming settings depending on power mode */
00944       if (hopamp->Init.PowerMode == OPAMP_POWERMODE_NORMAL)
00945       {
00946         tmp_opamp_reg_trimming = &OPAMP->OTR;
00947       }
00948       else
00949       {
00950         tmp_opamp_reg_trimming = &OPAMP->LPOTR;
00951       }      
00952     
00953       /* Get factory trimming  */
00954       if (trimmingoffset == OPAMP_FACTORYTRIMMING_P)
00955       {
00956         /* OPAMP_FACTORYTRIMMING_P */
00957         trimmingvalue = ((*tmp_opamp_reg_trimming) & OPAMP_OTR_TRIMOFFSETP) >> OPAMP_INPUT_NONINVERTING;
00958       }
00959       else
00960       {
00961         /* OPAMP_FACTORYTRIMMING_N */
00962         trimmingvalue = (*tmp_opamp_reg_trimming) & OPAMP_OTR_TRIMOFFSETN;
00963       }
00964     }
00965   }  
00966   return trimmingvalue;
00967 }
00968 
00969 /**
00970   * @}
00971   */
00972 
00973 
00974 /** @defgroup OPAMP_Exported_Functions_Group4 Peripheral State functions 
00975  *  @brief   Peripheral State functions 
00976  *
00977 @verbatim   
00978  ===============================================================================
00979                       ##### Peripheral State functions #####
00980  =============================================================================== 
00981     [..]
00982     This subsection permits to get in run-time the status of the peripheral.
00983 
00984 @endverbatim
00985   * @{
00986   */
00987 
00988 /**
00989   * @brief  Return the OPAMP handle state.
00990   * @param  hopamp : OPAMP handle
00991   * @retval HAL state
00992   */
00993 HAL_OPAMP_StateTypeDef HAL_OPAMP_GetState(OPAMP_HandleTypeDef *hopamp)
00994 {
00995   /* Check the OPAMP handle allocation */
00996   if(hopamp == NULL)
00997   {
00998     return HAL_OPAMP_STATE_RESET;
00999   }
01000 
01001   /* Check the parameter */
01002   assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
01003 
01004   /* Return OPAMP handle state */
01005   return hopamp->State;
01006 }
01007 
01008 /**
01009   * @}
01010   */
01011 
01012 #if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1)
01013 /**
01014   * @brief  Register a User OPAMP Callback
01015   *         To be used instead of the weak (surcharged) predefined callback 
01016   * @param hopamp : OPAMP handle
01017   * @param CallbackID : ID of the callback to be registered
01018   *        This parameter can be one of the following values:
01019   *          @arg @ref HAL_OPAMP_MSP_INIT_CB_ID       OPAMP MspInit callback ID 
01020   *          @arg @ref HAL_OPAMP_MSP_DEINIT_CB_ID     OPAMP MspDeInit callback ID  
01021   * @param pCallback : pointer to the Callback function
01022   * @retval status
01023   */
01024 HAL_StatusTypeDef HAL_OPAMP_RegisterCallback (OPAMP_HandleTypeDef *hopamp, HAL_OPAMP_CallbackIDTypeDef CallbackID, pOPAMP_CallbackTypeDef pCallback)
01025 {
01026   HAL_StatusTypeDef status = HAL_OK;
01027 
01028   if(pCallback == NULL)
01029   {
01030     return HAL_ERROR;
01031   }
01032 
01033   /* Process locked */
01034   __HAL_LOCK(hopamp);
01035   
01036   if(hopamp->State == HAL_OPAMP_STATE_READY)
01037   {
01038     switch (CallbackID)
01039     {
01040     case HAL_OPAMP_MSP_INIT_CB_ID :
01041       hopamp->MspInitCallback = pCallback;
01042       break;
01043     case HAL_OPAMP_MSP_DEINIT_CB_ID :
01044       hopamp->MspDeInitCallback = pCallback;
01045       break;
01046     default :
01047       /* update return status */
01048       status =  HAL_ERROR;
01049       break;
01050     }
01051   }
01052   else if (hopamp->State == HAL_OPAMP_STATE_RESET)
01053   {
01054     switch (CallbackID)
01055     {
01056     case HAL_OPAMP_MSP_INIT_CB_ID :
01057       hopamp->MspInitCallback = pCallback;
01058       break;
01059     case HAL_OPAMP_MSP_DEINIT_CB_ID :
01060       hopamp->MspDeInitCallback = pCallback;
01061       break;
01062     default :
01063       /* update return status */
01064       status =  HAL_ERROR;
01065       break;
01066     }
01067   }
01068   else
01069   {
01070     /* update return status */
01071     status =  HAL_ERROR;
01072   }
01073 
01074   /* Release Lock */
01075   __HAL_UNLOCK(hopamp);
01076   return status;
01077 }
01078 
01079 /**
01080   * @brief  Unregister a User OPAMP Callback
01081   *         OPAMP Callback is redirected to the weak (surcharged) predefined callback 
01082   * @param hopamp : OPAMP handle
01083   * @param CallbackID : ID of the callback to be unregistered
01084   *        This parameter can be one of the following values:
01085   *          @arg @ref HAL_OPAMP_MSP_INIT_CB_ID              OPAMP MSP Init Callback ID
01086   *          @arg @ref HAL_OPAMP_MSP_DEINIT_CB_ID            OPAMP MSP DeInit Callback ID
01087   *          @arg @ref HAL_OPAMP_ALL_CB_ID                   OPAMP All Callbacks
01088   * @retval status
01089   */
01090 
01091 HAL_StatusTypeDef HAL_OPAMP_UnRegisterCallback (OPAMP_HandleTypeDef *hopamp, HAL_OPAMP_CallbackIDTypeDef CallbackID)
01092 {
01093   HAL_StatusTypeDef status = HAL_OK;
01094 
01095   /* Process locked */
01096   __HAL_LOCK(hopamp);
01097   
01098   if(hopamp->State == HAL_OPAMP_STATE_READY)
01099   {
01100     switch (CallbackID)
01101     {     
01102       case HAL_OPAMP_MSP_INIT_CB_ID :
01103       hopamp->MspInitCallback = HAL_OPAMP_MspInit;
01104       break;
01105     case HAL_OPAMP_MSP_DEINIT_CB_ID :
01106       hopamp->MspDeInitCallback = HAL_OPAMP_MspDeInit;
01107       break;
01108     case HAL_OPAMP_ALL_CB_ID :
01109       hopamp->MspInitCallback = HAL_OPAMP_MspInit;
01110       hopamp->MspDeInitCallback = HAL_OPAMP_MspDeInit;
01111       break;
01112     default :
01113       /* update return status */
01114       status =  HAL_ERROR;
01115       break;
01116     }
01117   }
01118   else if (hopamp->State == HAL_OPAMP_STATE_RESET)
01119   {
01120     switch (CallbackID)
01121     {
01122     case HAL_OPAMP_MSP_INIT_CB_ID :
01123       hopamp->MspInitCallback = HAL_OPAMP_MspInit;
01124       break;
01125     case HAL_OPAMP_MSP_DEINIT_CB_ID :
01126       hopamp->MspDeInitCallback = HAL_OPAMP_MspDeInit;
01127       break;
01128     default :
01129       /* update return status */
01130       status =  HAL_ERROR;
01131       break;
01132     }
01133   }
01134   else
01135   {
01136     /* update return status */
01137     status =  HAL_ERROR;
01138   }
01139 
01140   /* Release Lock */
01141   __HAL_UNLOCK(hopamp);
01142   return status;
01143 }
01144 
01145 #endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */
01146 
01147 
01148 /**
01149   * @}
01150   */
01151   
01152   /**
01153   * @}
01154   */ 
01155   
01156 #endif /* HAL_OPAMP_MODULE_ENABLED */
01157 /**
01158   * @}
01159   */
01160 
01161 /**
01162   * @}
01163   */
01164 
01165 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/