Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:08

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_opamp.c
0004   * @author  MCD Application Team
0005   * @brief   OPAMP HAL module driver.
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the operational amplifier(s) peripheral:
0008   *           + Initialization and de-initialization functions
0009   *           + IO operation functions
0010   *           + Peripheral Control functions
0011   *           + Peripheral State functions
0012   *
0013   ******************************************************************************
0014   * @attention
0015   *
0016   * Copyright (c) 2017 STMicroelectronics.
0017   * All rights reserved.
0018   *
0019   * This software is licensed under terms that can be found in the LICENSE file
0020   * in the root directory of this software component.
0021   * If no LICENSE file comes with this software, it is provided AS-IS.
0022   *
0023   ******************************************************************************
0024   @verbatim
0025 ================================================================================
0026           ##### OPAMP Peripheral Features #####
0027 ================================================================================
0028 
0029   [..] The device integrates 2 operational amplifiers OPAMP1 & OPAMP2
0030 
0031        (#) The OPAMP(s) provides several exclusive running modes.
0032        (++) Standalone mode
0033        (++) Programmable Gain Amplifier (PGA) modes
0034        (++) Follower mode
0035 
0036        (#) Each OPAMP(s) can be configured in normal and high speed mode.
0037 
0038        (#) The OPAMP(s) provide(s) calibration capabilities.
0039        (++) Calibration aims at correcting some offset for running mode.
0040        (++) The OPAMP uses either factory calibration settings OR user defined
0041            calibration (trimming) settings (i.e. trimming mode).
0042        (++) The user defined settings can be figured out using self calibration
0043            handled by HAL_OPAMP_SelfCalibrate, HAL_OPAMPEx_SelfCalibrateAll
0044        (++) HAL_OPAMP_SelfCalibrate:
0045        (+++) Runs automatically the calibration in 2 steps.
0046             (90% of VDDA for NMOS transistors, 10% of VDDA for PMOS transistors).
0047             (As OPAMP is Rail-to-rail input/output, these 2 steps calibration is
0048              appropriate and enough in most cases).
0049        (+++) Runs automatically the calibration.
0050        (+++) Enables the user trimming mode
0051        (+++) Updates the init structure with trimming values with fresh calibration
0052             results.
0053             The user may store the calibration results for larger
0054             (ex monitoring the trimming as a function of temperature
0055             for instance)
0056        (+++) HAL_OPAMPEx_SelfCalibrateAll
0057             runs calibration of all OPAMPs in parallel to save search time.
0058 
0059        (#) Running mode: Standalone mode
0060        (++) Gain is set externally (gain depends on external loads).
0061        (++) Follower mode also possible externally by connecting the inverting input to
0062            the output.
0063 
0064        (#) Running mode: Follower mode
0065        (++) No Inverting Input is connected.
0066 
0067        (#) Running mode: Programmable Gain Amplifier (PGA) mode
0068            (Resistor feedback output)
0069        (#) The OPAMP(s) output(s) can be internally connected to resistor feedback
0070            output.
0071        (#) OPAMP gain can be selected as :
0072 
0073       (##) Gain of x2, x4, x8 or x16 for non inverting mode with:
0074       (+++) VREF- referenced.
0075       (+++) Filtering on VINM0, VREF- referenced.
0076       (+++) VINM0 node for bias voltage and VINP0 for input signal.
0077       (+++) VINM0 node for bias voltage and VINP0 for input signal, VINM1 node for filtering.
0078 
0079       (##) Gain of x-1, x-3, x-7 or x-15 for inverting mode with:
0080       (+++) VINM0 node for input signal and VINP0 for bias.
0081       (+++) VINM0 node for input signal and VINP0 for bias voltage, VINM1 node for filtering.
0082 
0083        (#) The OPAMPs inverting input can be selected according to the Reference Manual
0084            "OPAMP functional description" chapter.
0085 
0086        (#) The OPAMPs non inverting input can be selected according to the Reference Manual
0087            "OPAMP functional description" chapter.
0088 
0089 
0090             ##### How to use this driver #####
0091 ================================================================================
0092   [..]
0093 
0094     *** High speed / normal power mode ***
0095     ============================================
0096     [..]  To run in high speed mode:
0097 
0098       (#) Configure the OPAMP using HAL_OPAMP_Init() function:
0099       (++) Select OPAMP_POWERMODE_HIGHSPEED
0100       (++) Otherwise select OPAMP_POWERMODE_NORMAL
0101 
0102     *** Calibration ***
0103     ============================================
0104     [..]  To run the OPAMP calibration self calibration:
0105 
0106       (#) Start calibration using HAL_OPAMP_SelfCalibrate.
0107            Store the calibration results.
0108 
0109     *** Running mode ***
0110     ============================================
0111 
0112     [..]  To use the OPAMP, perform the following steps:
0113 
0114       (#) Fill in the HAL_OPAMP_MspInit() to
0115       (++) Enable the OPAMP Peripheral clock using macro __HAL_RCC_OPAMP_CLK_ENABLE()
0116       (++) Configure the OPAMP input AND output in analog mode using
0117            HAL_GPIO_Init() to map the OPAMP output to the GPIO pin.
0118 
0119       (#) Registrate Callbacks
0120       (++) The compilation define  USE_HAL_OPAMP_REGISTER_CALLBACKS when set to 1
0121            allows the user to configure dynamically the driver callbacks.
0122 
0123       (++) Use Functions HAL_OPAMP_RegisterCallback() to register a user callback,
0124            it allows to register following callbacks:
0125       (+++) MspInitCallback         : OPAMP MspInit.
0126       (+++) MspDeInitCallback       : OPAMP MspDeInit.
0127            This function takes as parameters the HAL peripheral handle, the Callback ID
0128            and a pointer to the user callback function.
0129 
0130       (++) Use function HAL_OPAMP_UnRegisterCallback() to reset a callback to the default
0131            weak (overridden) function. It allows to reset following callbacks:
0132       (+++) MspInitCallback         : OPAMP MspInit.
0133       (+++) MspDeInitCallback       : OPAMP MspDeInit.
0134       (+++) All Callbacks
0135       (#) Configure the OPAMP using HAL_OPAMP_Init() function:
0136       (++) Select the mode
0137       (++) Select the inverting input
0138       (++) Select the non-inverting input
0139       (++) If PGA mode is enabled, Select if inverting input is connected.
0140       (++) Select either factory or user defined trimming mode.
0141       (++) If the user-defined trimming mode is enabled, select PMOS & NMOS trimming values
0142           (typically values set by HAL_OPAMP_SelfCalibrate function).
0143 
0144       (#) Enable the OPAMP using HAL_OPAMP_Start() function.
0145 
0146       (#) Disable the OPAMP using HAL_OPAMP_Stop() function.
0147 
0148       (#) Lock the OPAMP in running mode using HAL_OPAMP_Lock() function.
0149           Caution: On STM32H7, HAL OPAMP lock is software lock only (not
0150           hardware lock as on some other STM32 devices)
0151 
0152       (#) If needed, unlock the OPAMP using HAL_OPAMPEx_Unlock() function.
0153 
0154     *** Running mode: change of configuration while OPAMP ON  ***
0155     ============================================
0156     [..] To Re-configure OPAMP when OPAMP is ON (change on the fly)
0157       (#) If needed, fill in the HAL_OPAMP_MspInit()
0158       (++) This is the case for instance if you wish to use new OPAMP I/O
0159 
0160       (#) Configure the OPAMP using HAL_OPAMP_Init() function:
0161       (++) As in configure case, select first the parameters you wish to modify.
0162 
0163       (#) Change from high speed mode to normal power mode (& vice versa) requires
0164           first HAL_OPAMP_DeInit() (force OPAMP OFF) and then HAL_OPAMP_Init().
0165           In other words, of OPAMP is ON, HAL_OPAMP_Init can NOT change power mode
0166           alone.
0167 
0168   @endverbatim
0169   ******************************************************************************
0170     Table 1.  OPAMPs inverting/non-inverting inputs for the STM32H7 devices:
0171 
0172     +------------------------------------------------------------------------|
0173     |                 |         | OPAMP1               | OPAMP2              |
0174     |-----------------|---------|----------------------|---------------------|
0175     | Inverting Input | VM_SEL  |   VINM0-> PC5        |    VINM0-> PE8      |
0176     |                 |         |   VINM1-> PA7        |    VINM1-> PG1      |
0177     |                 |         |   Internal:          |    Internal:        |
0178     |                 |         |     ADC1_IN9         |      OPAMP2_OUT     |
0179     |                 |         |     ADC2_IN9         |     PGA mode        |
0180     |                 |         |     OPAMP1_OUT       |                     |
0181     |                 |         |     PGA mode         |                     |
0182     |-----------------|---------|----------------------|---------------------|
0183     |  Non Inverting  | VP_SEL  |                      |                     |
0184     |                 |         |  VP0 -> PB0 (GPIO)   |  VP0 -> PE9 (GPIO)  |
0185     |                 |         |  Internal:           |  Internal:          |
0186     |    Input        |         |    DAC1_CH1_int      |   DAC1_CH2_int      |
0187     |                 |         |    ADC1_IN8          |   DAC2_CH1_int      |
0188     |                 |         |    ADC2_IN8          |   COMP2_INP         |
0189     |                 |         |    COMP1_INP         |                     |
0190     +------------------------------------------------------------------------|
0191 
0192 
0193    [..] Table 2.  OPAMPs outputs for the STM32H7 devices:
0194 
0195     +-------------------------------------------------------------------------
0196     |                 |        | OPAMP1                | OPAMP2              |
0197     |-----------------|--------|-----------------------|---------------------|
0198     | Output          |  VOUT  |  PC4                  |  PE7                |
0199     |                 |        |  & ADC1_IN4|          | & COMP2_INN7 if     |
0200     |                 |        |    ADC2_IN4           |connected internally |
0201     |                 |        |   COMP1_INN7 if       |                     |
0202     |                 |        |  connected internally |                     |
0203     |-----------------|--------|-----------------------|---------------------|
0204   */
0205 
0206 /* Includes ------------------------------------------------------------------*/
0207 #include "stm32h7xx_hal.h"
0208 
0209 /** @addtogroup STM32H7xx_HAL_Driver
0210   * @{
0211   */
0212 
0213 /** @defgroup OPAMP OPAMP
0214   * @ingroup RTEMSBSPsARMSTM32H7
0215   * @brief OPAMP module driver
0216   * @{
0217   */
0218 
0219 #ifdef HAL_OPAMP_MODULE_ENABLED
0220 
0221 /* Private types -------------------------------------------------------------*/
0222 /* Private variables ---------------------------------------------------------*/
0223 /* Private constants ---------------------------------------------------------*/
0224 /** @addtogroup OPAMP_Private_Constants
0225   * @{
0226   */
0227 
0228 /* CSR register reset value */
0229 #define OPAMP_CSR_RESET_VALUE             0x00000000U
0230 
0231 /* CSR Init masks */
0232 
0233 #define OPAMP_CSR_INIT_MASK_PGA (OPAMP_CSR_OPAHSM | OPAMP_CSR_VMSEL | OPAMP_CSR_PGGAIN | OPAMP_CSR_PGGAIN  \
0234                                 | OPAMP_CSR_VPSEL | OPAMP_CSR_USERTRIM)
0235 
0236 
0237 #define OPAMP_CSR_INIT_MASK_FOLLOWER (OPAMP_CSR_OPAHSM | OPAMP_CSR_VMSEL| OPAMP_CSR_VPSEL \
0238                                     | OPAMP_CSR_USERTRIM)
0239 
0240 
0241 #define OPAMP_CSR_INIT_MASK_STANDALONE (OPAMP_CSR_OPAHSM | OPAMP_CSR_VMSEL | OPAMP_CSR_VPSEL  \
0242                                        | OPAMP_CSR_VMSEL | OPAMP_CSR_USERTRIM)
0243 /**
0244   * @}
0245   */
0246 
0247 /* Private macros ------------------------------------------------------------*/
0248 /* Private functions ---------------------------------------------------------*/
0249 /* Exported functions --------------------------------------------------------*/
0250 
0251 /** @defgroup OPAMP_Exported_Functions OPAMP Exported Functions
0252   * @ingroup RTEMSBSPsARMSTM32H7
0253   * @{
0254   */
0255 
0256 /** @defgroup OPAMP_Exported_Functions_Group1 Initialization and de-initialization functions
0257   * @ingroup RTEMSBSPsARMSTM32H7
0258  *  @brief    Initialization and Configuration functions
0259  *
0260 @verbatim
0261   ==============================================================================
0262               ##### Initialization and de-initialization functions #####
0263   ==============================================================================
0264 
0265 @endverbatim
0266   * @{
0267   */
0268 
0269 /**
0270   * @brief  Initialize the OPAMP according to the specified
0271   *         parameters in the OPAMP_InitTypeDef and initialize the associated handle.
0272   * @note   If the selected opamp is locked, initialization can't be performed.
0273   *         To unlock the configuration, perform a system reset.
0274   * @param  hopamp OPAMP handle
0275   * @retval HAL status
0276   */
0277 HAL_StatusTypeDef HAL_OPAMP_Init(OPAMP_HandleTypeDef *hopamp)
0278 {
0279   HAL_StatusTypeDef status = HAL_OK;
0280   uint32_t updateotrlpotr;
0281 
0282   /* Check the OPAMP handle allocation and lock status */
0283   /* Init not allowed if calibration is ongoing */
0284   if(hopamp == NULL)
0285   {
0286     return HAL_ERROR;
0287   }
0288   else if(hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED)
0289   {
0290     return HAL_ERROR;
0291   }
0292   else if(hopamp->State == HAL_OPAMP_STATE_CALIBBUSY)
0293   {
0294     return HAL_ERROR;
0295   }
0296   else
0297   {
0298     /* Check the parameter */
0299     assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
0300 
0301     /* Set OPAMP parameters */
0302     assert_param(IS_OPAMP_POWERMODE(hopamp->Init.PowerMode));
0303     assert_param(IS_OPAMP_FUNCTIONAL_NORMALMODE(hopamp->Init.Mode));
0304     assert_param(IS_OPAMP_NONINVERTING_INPUT(hopamp->Init.NonInvertingInput));
0305 
0306 #if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1)
0307     if(hopamp->State == HAL_OPAMP_STATE_RESET)
0308     {
0309       if(hopamp->MspInitCallback == NULL)
0310       {
0311         hopamp->MspInitCallback               = HAL_OPAMP_MspInit;
0312       }
0313     }
0314 #endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */
0315     if ((hopamp->Init.Mode) == OPAMP_STANDALONE_MODE)
0316     {
0317       assert_param(IS_OPAMP_INVERTING_INPUT_STANDALONE(hopamp->Init.InvertingInput));
0318     }
0319 
0320     if ((hopamp->Init.Mode) == OPAMP_PGA_MODE)
0321     {
0322       assert_param(IS_OPAMP_PGA_GAIN(hopamp->Init.PgaGain));
0323       assert_param(IS_OPAMP_PGACONNECT(hopamp->Init.PgaConnect));
0324     }
0325 
0326 
0327     assert_param(IS_OPAMP_TRIMMING(hopamp->Init.UserTrimming));
0328 
0329     if ((hopamp->Init.UserTrimming) == OPAMP_TRIMMING_USER)
0330     {
0331       if (hopamp->Init.PowerMode == OPAMP_POWERMODE_NORMAL)
0332       {
0333         assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueP));
0334         assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueN));
0335       }
0336     else
0337       {
0338         assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValuePHighSpeed));
0339         assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueNHighSpeed));
0340       }
0341     }
0342 
0343     if(hopamp->State == HAL_OPAMP_STATE_RESET)
0344     {
0345       /* Allocate lock resource and initialize it */
0346       hopamp->Lock = HAL_UNLOCKED;
0347     }
0348 
0349 #if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1)
0350     hopamp->MspInitCallback(hopamp);
0351 #else
0352     /* Call MSP init function */
0353     HAL_OPAMP_MspInit(hopamp);
0354 #endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */
0355 
0356     /* Set operating mode */
0357     CLEAR_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALON);
0358     /* In PGA mode InvertingInput is Not Applicable  */
0359     if (hopamp->Init.Mode == OPAMP_PGA_MODE)
0360     {
0361       MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_INIT_MASK_PGA, \
0362                                         hopamp->Init.PowerMode | \
0363                                         hopamp->Init.Mode | \
0364                                         hopamp->Init.PgaGain | \
0365                                         hopamp->Init.PgaConnect | \
0366                                         hopamp->Init.NonInvertingInput | \
0367                                         hopamp->Init.UserTrimming);
0368     }
0369 
0370     if (hopamp->Init.Mode == OPAMP_FOLLOWER_MODE)
0371     {
0372   /* In Follower mode InvertingInput is Not Applicable  */
0373     MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_INIT_MASK_FOLLOWER, \
0374                                               hopamp->Init.PowerMode | \
0375                                               hopamp->Init.Mode | \
0376                                               hopamp->Init.NonInvertingInput | \
0377                                               hopamp->Init.UserTrimming);
0378     }
0379 
0380     if (hopamp->Init.Mode == OPAMP_STANDALONE_MODE)
0381     {
0382       MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_INIT_MASK_STANDALONE, \
0383                                         hopamp->Init.PowerMode | \
0384                                         hopamp->Init.Mode | \
0385                                         hopamp->Init.InvertingInput    | \
0386                                         hopamp->Init.NonInvertingInput | \
0387                                         hopamp->Init.UserTrimming);
0388     }
0389 
0390     if (hopamp->Init.UserTrimming == OPAMP_TRIMMING_USER)
0391     {
0392       /* Set power mode and associated calibration parameters */
0393       if (hopamp->Init.PowerMode != OPAMP_POWERMODE_HIGHSPEED)
0394       {
0395         /* OPAMP_POWERMODE_NORMAL */
0396         /* Set calibration mode (factory or user) and values for            */
0397         /* transistors differential pair high (PMOS) and low (NMOS) for     */
0398         /* normal mode.                                                     */
0399         updateotrlpotr = (((hopamp->Init.TrimmingValueP) << (OPAMP_INPUT_NONINVERTING)) \
0400                          | (hopamp->Init.TrimmingValueN));
0401         MODIFY_REG(hopamp->Instance->OTR, OPAMP_OTR_TRIMOFFSETN | OPAMP_OTR_TRIMOFFSETP, updateotrlpotr);
0402       }
0403       else
0404       {
0405         /* OPAMP_POWERMODE_HIGHSPEED*/
0406         /* transistors differential pair high (PMOS) and low (NMOS) for     */
0407         /* high speed mode.                                                     */
0408         updateotrlpotr = (((hopamp->Init.TrimmingValuePHighSpeed) << (OPAMP_INPUT_NONINVERTING)) \
0409                          | (hopamp->Init.TrimmingValueNHighSpeed));
0410         MODIFY_REG(hopamp->Instance->HSOTR, OPAMP_OTR_TRIMOFFSETN | OPAMP_OTR_TRIMOFFSETP, updateotrlpotr);
0411       }
0412     }
0413 
0414     /* Update the OPAMP state*/
0415     if (hopamp->State == HAL_OPAMP_STATE_RESET)
0416     {
0417       /* From RESET state to READY State */
0418       hopamp->State = HAL_OPAMP_STATE_READY;
0419     }
0420     /* else: remain in READY or BUSY state (no update) */
0421     return status;
0422   }
0423 }
0424 
0425 /**
0426   * @brief  DeInitialize the OPAMP peripheral
0427   * @note   Deinitialization can be performed if the OPAMP configuration is locked.
0428   *         (the lock is SW in H7)
0429   * @param  hopamp OPAMP handle
0430   * @retval HAL status
0431   */
0432 HAL_StatusTypeDef HAL_OPAMP_DeInit(OPAMP_HandleTypeDef *hopamp)
0433 {
0434   HAL_StatusTypeDef status = HAL_OK;
0435 
0436   /* Check the OPAMP handle allocation */
0437   /* DeInit not allowed if calibration is on going */
0438   if(hopamp == NULL)
0439   {
0440     status = HAL_ERROR;
0441   }
0442   else if(hopamp->State == HAL_OPAMP_STATE_CALIBBUSY)
0443   {
0444     status = HAL_ERROR;
0445   }
0446   else
0447   {
0448     /* Check the parameter */
0449     assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
0450 
0451     /* Set OPAMP_CSR register to reset value */
0452     WRITE_REG(hopamp->Instance->CSR, OPAMP_CSR_RESET_VALUE);
0453 
0454     /* DeInit the low level hardware */
0455 #if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1)
0456     if(hopamp->MspDeInitCallback == NULL)
0457     {
0458       hopamp->MspDeInitCallback = HAL_OPAMP_MspDeInit;
0459     }
0460     /* DeInit the low level hardware */
0461     hopamp->MspDeInitCallback(hopamp);
0462 #else
0463     HAL_OPAMP_MspDeInit(hopamp);
0464 #endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */
0465 
0466     /* Update the OPAMP state*/
0467     hopamp->State = HAL_OPAMP_STATE_RESET;
0468     /* Process unlocked */
0469     __HAL_UNLOCK(hopamp);
0470 
0471   }
0472 
0473   return status;
0474 }
0475 
0476 
0477 /**
0478   * @brief  Initialize the OPAMP MSP.
0479   * @param  hopamp OPAMP handle
0480   * @retval None
0481   */
0482 __weak void HAL_OPAMP_MspInit(OPAMP_HandleTypeDef *hopamp)
0483 {
0484   /* Prevent unused argument(s) compilation warning */
0485   UNUSED(hopamp);
0486 
0487   /* NOTE : This function should not be modified, when the callback is needed,
0488             the function "HAL_OPAMP_MspInit()" must be implemented in the user file.
0489    */
0490 }
0491 
0492 /**
0493   * @brief  DeInitialize OPAMP MSP.
0494   * @param  hopamp OPAMP handle
0495   * @retval None
0496   */
0497 __weak void HAL_OPAMP_MspDeInit(OPAMP_HandleTypeDef *hopamp)
0498 {
0499   /* Prevent unused argument(s) compilation warning */
0500   UNUSED(hopamp);
0501   /* NOTE : This function should not be modified, when the callback is needed,
0502             the function "HAL_OPAMP_MspDeInit()" must be implemented in the user file.
0503    */
0504 }
0505 
0506 /**
0507   * @}
0508   */
0509 
0510 
0511 /** @defgroup OPAMP_Exported_Functions_Group2 IO operation functions
0512   * @ingroup RTEMSBSPsARMSTM32H7
0513  *  @brief   IO operation functions
0514  *
0515 @verbatim
0516  ===============================================================================
0517                         ##### IO operation functions #####
0518  ===============================================================================
0519     [..]
0520     This subsection provides a set of functions allowing to manage the OPAMP
0521     start, stop and calibration actions.
0522 
0523 @endverbatim
0524   * @{
0525   */
0526 
0527 /**
0528   * @brief  Start the OPAMP.
0529   * @param  hopamp OPAMP handle
0530   * @retval HAL status
0531   */
0532 HAL_StatusTypeDef HAL_OPAMP_Start(OPAMP_HandleTypeDef *hopamp)
0533 {
0534   HAL_StatusTypeDef status = HAL_OK;
0535 
0536   /* Check the OPAMP handle allocation */
0537   /* Check if OPAMP locked */
0538   if(hopamp == NULL)
0539   {
0540     status = HAL_ERROR;
0541   }
0542   else if(hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED)
0543   {
0544     status = HAL_ERROR;
0545   }
0546   else
0547   {
0548     /* Check the parameter */
0549     assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
0550 
0551     if(hopamp->State == HAL_OPAMP_STATE_READY)
0552     {
0553       /* Enable the selected opamp */
0554       SET_BIT (hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN);
0555 
0556       /* Update the OPAMP state*/
0557       /* From HAL_OPAMP_STATE_READY to HAL_OPAMP_STATE_BUSY */
0558       hopamp->State = HAL_OPAMP_STATE_BUSY;
0559     }
0560     else
0561     {
0562       status = HAL_ERROR;
0563     }
0564 
0565    }
0566   return status;
0567 }
0568 
0569 /**
0570   * @brief  Stop the OPAMP.
0571   * @param  hopamp OPAMP handle
0572   * @retval HAL status
0573   */
0574 HAL_StatusTypeDef HAL_OPAMP_Stop(OPAMP_HandleTypeDef *hopamp)
0575 {
0576   HAL_StatusTypeDef status = HAL_OK;
0577 
0578   /* Check the OPAMP handle allocation */
0579   /* Check if OPAMP locked */
0580   /* Check if OPAMP calibration ongoing */
0581   if(hopamp == NULL)
0582   {
0583     status = HAL_ERROR;
0584   }
0585   else if(hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED)
0586   {
0587     status = HAL_ERROR;
0588   }
0589   else if(hopamp->State == HAL_OPAMP_STATE_CALIBBUSY)
0590   {
0591     status = HAL_ERROR;
0592   }
0593   else
0594   {
0595     /* Check the parameter */
0596     assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
0597 
0598     if(hopamp->State == HAL_OPAMP_STATE_BUSY)
0599     {
0600       /* Disable the selected opamp */
0601       CLEAR_BIT (hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN);
0602 
0603       /* Update the OPAMP state*/
0604       /* From  HAL_OPAMP_STATE_BUSY to HAL_OPAMP_STATE_READY*/
0605       hopamp->State = HAL_OPAMP_STATE_READY;
0606     }
0607     else
0608     {
0609       status = HAL_ERROR;
0610     }
0611   }
0612   return status;
0613 }
0614 
0615 /**
0616   * @brief  Run the self calibration of one OPAMP.
0617   * @note   Calibration is performed in the mode specified in OPAMP init
0618   *         structure (mode normal or high-speed). To perform calibration for
0619   *         both modes, repeat this function twice after OPAMP init structure
0620   *         accordingly updated.
0621   * @param  hopamp handle
0622   * @retval Updated offset trimming values (PMOS & NMOS), user trimming is enabled
0623   * @retval HAL status
0624   */
0625 HAL_StatusTypeDef HAL_OPAMP_SelfCalibrate(OPAMP_HandleTypeDef *hopamp)
0626 {
0627 
0628   HAL_StatusTypeDef status = HAL_OK;
0629 
0630   uint32_t trimmingvaluen;
0631   uint32_t trimmingvaluep;
0632   uint32_t delta;
0633   uint32_t opampmode;
0634 
0635   __IO uint32_t* tmp_opamp_reg_trimming;   /* Selection of register of trimming depending on power mode: OTR or HSOTR */
0636 
0637   /* Check the OPAMP handle allocation */
0638   /* Check if OPAMP locked */
0639   if(hopamp == NULL)
0640   {
0641     status = HAL_ERROR;
0642   }
0643   else if(hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED)
0644   {
0645     status = HAL_ERROR;
0646   }
0647   else
0648   {
0649 
0650     /* Check if OPAMP in calibration mode and calibration not yet enable */
0651     if(hopamp->State ==  HAL_OPAMP_STATE_READY)
0652     {
0653       /* Check the parameter */
0654       assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
0655       assert_param(IS_OPAMP_POWERMODE(hopamp->Init.PowerMode));
0656 
0657       opampmode = READ_BIT(hopamp->Instance->CSR,OPAMP_CSR_VMSEL);
0658 
0659       /* Use of standalone mode */
0660       MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_VMSEL, OPAMP_STANDALONE_MODE);
0661       /*  user trimming values are used for offset calibration */
0662       SET_BIT(hopamp->Instance->CSR, OPAMP_CSR_USERTRIM);
0663 
0664       /* Select trimming settings depending on power mode */
0665       if (hopamp->Init.PowerMode == OPAMP_POWERMODE_NORMAL)
0666       {
0667         tmp_opamp_reg_trimming = &hopamp->Instance->OTR;
0668 
0669       }
0670       else
0671       {
0672         /* high speed Mode */
0673         tmp_opamp_reg_trimming = &hopamp->Instance->HSOTR;
0674       }
0675 
0676 
0677       /* Enable calibration */
0678       SET_BIT (hopamp->Instance->CSR, OPAMP_CSR_CALON);
0679 
0680       /* Force internal reference on VP */
0681       SET_BIT (hopamp->Instance->CSR, OPAMP_CSR_FORCEVP);
0682 
0683       /* 1st calibration - N */
0684       MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_CALSEL, OPAMP_VREF_90VDDA);
0685 
0686       /* Enable the selected opamp */
0687       SET_BIT (hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN);
0688 
0689       /* Init trimming counter */
0690       /* Medium value */
0691       trimmingvaluen = 16U;
0692       delta = 8U;
0693 
0694       while (delta != 0U)
0695       {
0696         /* Set candidate trimming */
0697         /* OPAMP_POWERMODE_NORMAL */
0698         MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETN, trimmingvaluen);
0699 
0700         /* OFFTRIMmax delay 2 ms as per datasheet (electrical characteristics */
0701         /* Offset trim time: during calibration, minimum time needed between */
0702         /* two steps to have 1 mV accuracy */
0703         HAL_Delay(OPAMP_TRIMMING_DELAY);
0704 
0705         if (READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT) != 0U)
0706         {
0707           /* OPAMP_CSR_CALOUT is HIGH try higher trimming */
0708           trimmingvaluen += delta;
0709         }
0710         else
0711         {
0712           /* OPAMP_CSR_CALOUT is LOW try lower trimming */
0713           trimmingvaluen -= delta;
0714         }
0715         /* Divide range by 2 to continue dichotomy sweep */
0716         delta >>= 1;
0717       }
0718 
0719       /* Still need to check if right calibration is current value or one step below */
0720       /* Indeed the first value that causes the OUTCAL bit to change from 1  to 0  */
0721 
0722       MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETN, trimmingvaluen);
0723 
0724       /* OFFTRIMmax delay 2 ms as per datasheet (electrical characteristics */
0725       /* Offset trim time: during calibration, minimum time needed between */
0726       /* two steps to have 1 mV accuracy */
0727       HAL_Delay(OPAMP_TRIMMING_DELAY);
0728 
0729       if ((READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT)) != 0U)
0730       {
0731         /* Trimming value is actually one value more */
0732         trimmingvaluen++;
0733         /* Set right trimming */
0734         MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETN, trimmingvaluen);
0735       }
0736 
0737       /* 2nd calibration - P */
0738       MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_CALSEL, OPAMP_VREF_10VDDA);
0739 
0740       /* Init trimming counter */
0741       /* Medium value */
0742       trimmingvaluep = 16U;
0743       delta = 8U;
0744 
0745       while (delta != 0U)
0746       {
0747         /* Set candidate trimming */
0748         /* OPAMP_POWERMODE_NORMAL */
0749         MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETP, (trimmingvaluep<<OPAMP_INPUT_NONINVERTING));
0750 
0751         /* OFFTRIMmax delay 2 ms as per datasheet (electrical characteristics */
0752         /* Offset trim time: during calibration, minimum time needed between */
0753         /* two steps to have 1 mV accuracy */
0754         HAL_Delay(OPAMP_TRIMMING_DELAY);
0755 
0756         if (READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT)!= 0U)
0757         {
0758           /* OPAMP_CSR_CALOUT is HIGH try higher trimming */
0759           trimmingvaluep += delta;
0760         }
0761         else
0762         {
0763           /* OPAMP_CSR_CALOUT  is LOW try lower trimming */
0764           trimmingvaluep -= delta;
0765         }
0766 
0767         /* Divide range by 2 to continue dichotomy sweep */
0768         delta >>= 1U;
0769       }
0770 
0771       /* Still need to check if right calibration is current value or one step below */
0772       /* Indeed the first value that causes the OUTCAL bit to change from 1 to 0  */
0773       /* Set candidate trimming */
0774       MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETP, (trimmingvaluep<<OPAMP_INPUT_NONINVERTING));
0775 
0776       /* OFFTRIMmax delay 2 ms as per datasheet (electrical characteristics */
0777       /* Offset trim time: during calibration, minimum time needed between */
0778       /* two steps to have 1 mV accuracy */
0779       HAL_Delay(OPAMP_TRIMMING_DELAY);
0780 
0781       if (READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT) != 0U)
0782       {
0783         /* Trimming value is actually one value more */
0784         trimmingvaluep++;
0785         MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETP, (trimmingvaluep<<OPAMP_INPUT_NONINVERTING));
0786       }
0787 
0788       /* Disable calibration & set normal mode (operating mode) */
0789       CLEAR_BIT (hopamp->Instance->CSR, OPAMP_CSR_CALON);
0790 
0791       /* Disable the OPAMP */
0792       CLEAR_BIT (hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN);
0793 
0794       /* Set operating mode back */
0795       CLEAR_BIT(hopamp->Instance->CSR, OPAMP_CSR_FORCEVP);
0796 
0797       /* Self calibration is successful  */
0798       /* Store calibration(user trimming) results in init structure. */
0799 
0800       /* Set user trimming mode */
0801       hopamp->Init.UserTrimming = OPAMP_TRIMMING_USER;
0802 
0803       /* Affect calibration parameters depending on mode normal/high speed */
0804       if (hopamp->Init.PowerMode != OPAMP_POWERMODE_HIGHSPEED)
0805       {
0806         /* Write calibration result N */
0807         hopamp->Init.TrimmingValueN = trimmingvaluen;
0808         /* Write calibration result P */
0809         hopamp->Init.TrimmingValueP = trimmingvaluep;
0810       }
0811       else
0812       {
0813         /* Write calibration result N */
0814         hopamp->Init.TrimmingValueNHighSpeed = trimmingvaluen;
0815         /* Write calibration result P */
0816         hopamp->Init.TrimmingValuePHighSpeed = trimmingvaluep;
0817       }
0818     /* Restore OPAMP mode after calibration */
0819     MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_VMSEL, opampmode);
0820     }
0821 
0822     else
0823     {
0824       /* OPAMP can not be calibrated from this mode */
0825       status = HAL_ERROR;
0826     }
0827   }
0828   return status;
0829 }
0830 
0831 /**
0832   * @}
0833   */
0834 
0835 /** @defgroup OPAMP_Exported_Functions_Group3 Peripheral Control functions
0836   * @ingroup RTEMSBSPsARMSTM32H7
0837  *  @brief   Peripheral Control functions
0838  *
0839 @verbatim
0840  ===============================================================================
0841                       ##### Peripheral Control functions #####
0842  ===============================================================================
0843     [..]
0844     This subsection provides a set of functions allowing to control the OPAMP data
0845     transfers.
0846 
0847 
0848 
0849 @endverbatim
0850   * @{
0851   */
0852 
0853 /**
0854   * @brief  Lock the selected OPAMP configuration.
0855   * @note   On STM32H7, HAL OPAMP lock is software lock only (in
0856   *         contrast of hardware lock available on some other STM32
0857   *         devices)
0858   * @param  hopamp OPAMP handle
0859   * @retval HAL status
0860   */
0861 HAL_StatusTypeDef HAL_OPAMP_Lock(OPAMP_HandleTypeDef *hopamp)
0862 {
0863   HAL_StatusTypeDef status = HAL_OK;
0864 
0865   /* Check the OPAMP handle allocation */
0866   /* Check if OPAMP locked */
0867   /* OPAMP can be locked when enabled and running in normal mode */
0868   /*   It is meaningless otherwise */
0869   if(hopamp == NULL)
0870   {
0871     status = HAL_ERROR;
0872   }
0873 
0874   else if(hopamp->State != HAL_OPAMP_STATE_BUSY)
0875   {
0876     status = HAL_ERROR;
0877   }
0878   else
0879   {
0880     /* Check the parameter */
0881     assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
0882 
0883    /* OPAMP state changed to locked */
0884     hopamp->State = HAL_OPAMP_STATE_BUSYLOCKED;
0885   }
0886   return status;
0887 }
0888 
0889 /**
0890   * @brief  Return the OPAMP factory trimming value.
0891   * @note            On STM32H7 OPAMP, user can retrieve factory trimming if
0892   *                  OPAMP has never been set to user trimming before.
0893   *                  Therefore, this function must be called when OPAMP init
0894   *                  parameter "UserTrimming" is set to trimming factory,
0895   *                  and before OPAMP  calibration (function
0896   *                  "HAL_OPAMP_SelfCalibrate()").
0897   *                  Otherwise, factory trimming value cannot be retrieved and
0898   *                  error status is returned.
0899   * @param  hopamp  OPAMP handle
0900   * @param  trimmingoffset  Trimming offset (P or N)
0901   *         This parameter must be a value of @ref OPAMP_FactoryTrimming
0902   * @note   Calibration parameter retrieved is corresponding to the mode
0903   *         specified in OPAMP init structure (mode normal or high-speed).
0904   *         To retrieve calibration parameters for both modes, repeat this
0905   *         function after OPAMP init structure accordingly updated.
0906   * @retval Trimming value (P or N): range: 0->31
0907   *         or OPAMP_FACTORYTRIMMING_DUMMY if trimming value is not available
0908   *
0909   */
0910 HAL_OPAMP_TrimmingValueTypeDef HAL_OPAMP_GetTrimOffset (OPAMP_HandleTypeDef *hopamp, uint32_t trimmingoffset)
0911 {
0912   HAL_OPAMP_TrimmingValueTypeDef trimmingvalue;
0913   __IO uint32_t* tmp_opamp_reg_trimming;  /* Selection of register of trimming depending on power mode: OTR or LPOTR */
0914 
0915   /* Check the OPAMP handle allocation */
0916   /* Value can be retrieved in HAL_OPAMP_STATE_READY state */
0917   if(hopamp == NULL)
0918   {
0919     return OPAMP_FACTORYTRIMMING_DUMMY;
0920   }
0921 
0922   if(hopamp->State == HAL_OPAMP_STATE_READY)
0923   {
0924     /* Check the parameter */
0925     assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
0926     assert_param(IS_OPAMP_FACTORYTRIMMING(trimmingoffset));
0927     assert_param(IS_OPAMP_POWERMODE(hopamp->Init.PowerMode));
0928 
0929     /* Check the trimming mode */
0930     if (READ_BIT(hopamp->Instance->CSR,OPAMP_CSR_USERTRIM)!= 0U)
0931     {
0932       /* This function must called when OPAMP init parameter "UserTrimming"   */
0933       /* is set to trimming factory, and before OPAMP calibration (function   */
0934       /* "HAL_OPAMP_SelfCalibrate()").                                        */
0935       /* Otherwise, factory trimming value cannot be retrieved and error       */
0936       /* status is returned.                                                  */
0937       trimmingvalue = OPAMP_FACTORYTRIMMING_DUMMY;
0938     }
0939     else
0940     {
0941       /* Select trimming settings depending on power mode */
0942       if (hopamp->Init.PowerMode == OPAMP_POWERMODE_NORMAL)
0943       {
0944         tmp_opamp_reg_trimming = &hopamp->Instance->OTR;
0945       }
0946       else
0947       {
0948         tmp_opamp_reg_trimming = &hopamp->Instance->HSOTR;
0949       }
0950 
0951       /* Get factory trimming  */
0952       if (trimmingoffset == OPAMP_FACTORYTRIMMING_P)
0953       {
0954         /* OPAMP_FACTORYTRIMMING_P */
0955         trimmingvalue = ((*tmp_opamp_reg_trimming) & OPAMP_OTR_TRIMOFFSETP) >> OPAMP_INPUT_NONINVERTING;
0956       }
0957       else
0958       {
0959         /* OPAMP_FACTORYTRIMMING_N */
0960         trimmingvalue = (*tmp_opamp_reg_trimming) & OPAMP_OTR_TRIMOFFSETN;
0961       }
0962     }
0963   }
0964   else
0965   {
0966     return OPAMP_FACTORYTRIMMING_DUMMY;
0967   }
0968 
0969   return trimmingvalue;
0970 }
0971 
0972 #if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1)
0973 /**
0974   * @brief  Register a User OPAMP Callback
0975   *         To be used instead of the weak (overridden) predefined callback
0976   * @param hopamp  OPAMP handle
0977   * @param CallbackId  ID of the callback to be registered
0978   *        This parameter can be one of the following values:
0979   *          @arg @ref HAL_OPAMP_MSPINIT_CB_ID       OPAMP MspInit callback ID
0980   *          @arg @ref HAL_OPAMP_MSPDEINIT_CB_ID     OPAMP MspDeInit callback ID
0981   * @param pCallback  pointer to the Callback function
0982   * @retval status
0983   */
0984 HAL_StatusTypeDef HAL_OPAMP_RegisterCallback (OPAMP_HandleTypeDef *hopamp, HAL_OPAMP_CallbackIDTypeDef CallbackId, pOPAMP_CallbackTypeDef pCallback)
0985 {
0986   HAL_StatusTypeDef status = HAL_OK;
0987 
0988   if(pCallback == NULL)
0989   {
0990     return HAL_ERROR;
0991   }
0992 
0993   /* Process locked */
0994   __HAL_LOCK(hopamp);
0995 
0996   if(hopamp->State == HAL_OPAMP_STATE_READY)
0997   {
0998     switch (CallbackId)
0999     {
1000     case HAL_OPAMP_MSPINIT_CB_ID :
1001       hopamp->MspInitCallback = pCallback;
1002       break;
1003     case HAL_OPAMP_MSPDEINIT_CB_ID :
1004       hopamp->MspDeInitCallback = pCallback;
1005       break;
1006     default :
1007       /* update return status */
1008       status =  HAL_ERROR;
1009       break;
1010     }
1011   }
1012   else if (hopamp->State == HAL_OPAMP_STATE_RESET)
1013   {
1014     switch (CallbackId)
1015     {
1016     case HAL_OPAMP_MSPINIT_CB_ID :
1017       hopamp->MspInitCallback = pCallback;
1018       break;
1019     case HAL_OPAMP_MSPDEINIT_CB_ID :
1020       hopamp->MspDeInitCallback = pCallback;
1021       break;
1022     default :
1023       /* update return status */
1024       status =  HAL_ERROR;
1025       break;
1026     }
1027   }
1028   else
1029   {
1030     /* update return status */
1031     status =  HAL_ERROR;
1032   }
1033 
1034   /* Release Lock */
1035   __HAL_UNLOCK(hopamp);
1036   return status;
1037 }
1038 
1039 /**
1040   * @brief  Unregister a User OPAMP Callback
1041   *         OPAMP Callback is redirected to the weak (overridden) predefined callback
1042   * @param hopamp  OPAMP handle
1043   * @param CallbackId  ID of the callback to be unregistered
1044   *        This parameter can be one of the following values:
1045   *          @arg @ref HAL_OPAMP_MSPINIT_CB_ID    OPAMP MSP Init Callback ID
1046   *          @arg @ref HAL_OPAMP_MSPDEINIT_CB_ID  OPAMP MSP DeInit Callback ID
1047   *          @arg @ref HAL_OPAMP_ALL_CB_ID        OPAMP All Callbacks
1048   * @retval status
1049   */
1050 HAL_StatusTypeDef HAL_OPAMP_UnRegisterCallback (OPAMP_HandleTypeDef *hopamp, HAL_OPAMP_CallbackIDTypeDef CallbackId)
1051 {
1052   HAL_StatusTypeDef status = HAL_OK;
1053 
1054   /* Process locked */
1055   __HAL_LOCK(hopamp);
1056 
1057   if(hopamp->State == HAL_OPAMP_STATE_READY)
1058   {
1059     switch (CallbackId)
1060     {
1061     case HAL_OPAMP_MSPINIT_CB_ID :
1062       hopamp->MspInitCallback = HAL_OPAMP_MspInit;
1063       break;
1064     case HAL_OPAMP_MSPDEINIT_CB_ID :
1065       hopamp->MspDeInitCallback = HAL_OPAMP_MspDeInit;
1066       break;
1067     case HAL_OPAMP_ALL_CB_ID :
1068       hopamp->MspInitCallback = HAL_OPAMP_MspInit;
1069       hopamp->MspDeInitCallback = HAL_OPAMP_MspDeInit;
1070       break;
1071     default :
1072       /* update return status */
1073       status =  HAL_ERROR;
1074       break;
1075     }
1076   }
1077   else if (hopamp->State == HAL_OPAMP_STATE_RESET)
1078   {
1079     switch (CallbackId)
1080     {
1081     case HAL_OPAMP_MSPINIT_CB_ID :
1082       hopamp->MspInitCallback = HAL_OPAMP_MspInit;
1083       break;
1084     case HAL_OPAMP_MSPDEINIT_CB_ID :
1085       hopamp->MspDeInitCallback = HAL_OPAMP_MspDeInit;
1086       break;
1087     default :
1088       /* update return status */
1089       status =  HAL_ERROR;
1090       break;
1091     }
1092   }
1093   else
1094   {
1095     /* update return status */
1096     status =  HAL_ERROR;
1097   }
1098 
1099   /* Release Lock */
1100   __HAL_UNLOCK(hopamp);
1101   return status;
1102 }
1103 
1104 #endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */
1105 
1106 /**
1107   * @}
1108   */
1109 
1110 
1111 /** @defgroup OPAMP_Exported_Functions_Group4 Peripheral State functions
1112   * @ingroup RTEMSBSPsARMSTM32H7
1113   *  @brief   Peripheral State functions
1114   *
1115 @verbatim
1116  ===============================================================================
1117                       ##### Peripheral State functions #####
1118  ===============================================================================
1119     [..]
1120     This subsection permits to get in run-time the status of the peripheral.
1121 
1122 @endverbatim
1123   * @{
1124   */
1125 
1126 /**
1127   * @brief  Return the OPAMP handle state.
1128   * @param  hopamp  OPAMP handle
1129   * @retval HAL state
1130   */
1131 HAL_OPAMP_StateTypeDef HAL_OPAMP_GetState(OPAMP_HandleTypeDef *hopamp)
1132 {
1133   /* Check the OPAMP handle allocation */
1134   if(hopamp == NULL)
1135   {
1136     return HAL_OPAMP_STATE_RESET;
1137   }
1138 
1139   /* Check the parameter */
1140   assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
1141 
1142   /* Return OPAMP handle state */
1143   return hopamp->State;
1144 }
1145 
1146 /**
1147   * @}
1148   */
1149 
1150 /**
1151   * @}
1152   */
1153 #endif /* HAL_OPAMP_MODULE_ENABLED */
1154 /**
1155   * @}
1156   */
1157 
1158 /**
1159   * @}
1160   */
1161