| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922 |
- /**
- ******************************************************************************
- * @file stm32f3xx_hal_opamp.c
- * @author MCD Application Team
- * @brief OPAMP HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the operational amplifiers (OPAMP1,...OPAMP4)
- * peripheral:
- * + OPAMP Configuration
- * + OPAMP calibration
- * Thanks to
- * + Initialization/de-initialization functions
- * + I/O operation functions
- * + Peripheral Control functions
- * + Peripheral State functions
- *
- @verbatim
- ================================================================================
- ##### OPAMP Peripheral Features #####
- ================================================================================
-
- [..] The device integrates up to 4 operational amplifiers OPAMP1, OPAMP2,
- OPAMP3 and OPAMP4:
-
- (#) The OPAMP(s) provides several exclusive running modes.
- (++) Standalone mode
- (++) Programmable Gain Amplifier (PGA) mode (Resistor feedback output)
- (++) Follower mode
- (#) The OPAMP(s) provide(s) calibration capabilities.
- (++) Calibration aims at correcting some offset for running mode.
- (++) The OPAMP uses either factory calibration settings OR user defined
- calibration (trimming) settings (i.e. trimming mode).
- (++) The user defined settings can be figured out using self calibration
- handled by HAL_OPAMP_SelfCalibrate, HAL_OPAMPEx_SelfCalibrateAll
- (++) HAL_OPAMP_SelfCalibrate:
- (++) Runs automatically the calibration in 2 steps.
- (90U% of VDDA for NMOS transistors, 10U% of VDDA for PMOS transistors).
- (As OPAMP is Rail-to-rail input/output, these 2 steps calibration is
- appropriate and enough in most cases).
- (++) Enables the user trimming mode
- (++) Updates the init structure with trimming values with fresh calibration
- results.
- The user may store the calibration results for larger
- (ex monitoring the trimming as a function of temperature
- for instance)
- (++) for STM32F3 devices having 2 or 4 OPAMPs
- HAL_OPAMPEx_SelfCalibrateAll
- runs calibration of 2 or 4 OPAMPs in parallel.
-
- (#) For any running mode, an additional Timer-controlled Mux (multiplexer)
- mode can be set on top.
- (++) Timer-controlled Mux mode allows Automatic switching between inverting
- and non-inverting input.
- (++) Hence on top of defaults (primary) inverting and non-inverting inputs,
- the user shall select secondary inverting and non inverting inputs.
- (++) TIM1 CC6 provides the alternate switching tempo between defaults
- (primary) and secondary inputs.
-
- (#) Running mode: Standalone mode
- (++) Gain is set externally (gain depends on external loads).
- (++) Follower mode also possible externally by connecting the inverting input to
- the output.
-
- (#) Running mode: Follower mode
- (++) No Inverting Input is connected.
-
- (#) Running mode: Programmable Gain Amplifier (PGA) mode
- (Resistor feedback output)
- (++) The OPAMP(s) output(s) can be internally connected to resistor feedback
- output.
- (++) OPAMP gain is either 2U, 4U, 8 or 16.
-
-
- ##### How to use this driver #####
- ================================================================================
- [..]
- *** Calibration ***
- ============================================
- [..]
- To run the opamp calibration self calibration:
- (#) Start calibration using HAL_OPAMP_SelfCalibrate.
- Store the calibration results.
- *** Running mode ***
- ============================================
- [..]
- To use the opamp, perform the following steps:
-
- (#) Fill in the HAL_OPAMP_MspInit() to
- (++) Configure the opamp input AND output in analog mode using
- HAL_GPIO_Init() to map the opamp output to the GPIO pin.
-
- (#) Configure the opamp using HAL_OPAMP_Init() function:
- (++) Select the mode
- (++) Select the inverting input
- (++) Select the non-inverting input
- (++) Select if the Timer controlled Mux mode is enabled/disabled
- (++) If the Timer controlled Mux mode is enabled, select the secondary inverting input
- (++) If the Timer controlled Mux mode is enabled, Select the secondary non-inverting input
- (++) If PGA mode is enabled, Select if inverting input is connected.
- (++) Select either factory or user defined trimming mode.
- (++) If the user defined trimming mode is enabled, select PMOS & NMOS trimming values
- (typ. settings returned by HAL_OPAMP_SelfCalibrate function).
-
- (#) Enable the opamp using HAL_OPAMP_Start() function.
-
- (#) Disable the opamp using HAL_OPAMP_Stop() function.
-
- (#) Lock the opamp in running mode using HAL_OPAMP_Lock() function. From then The configuration
- can be modified
- (++) After HW reset
- (++) OR thanks to HAL_OPAMP_MspDeInit called (user defined) from HAL_OPAMP_DeInit.
- *** Running mode: change of configuration while OPAMP ON ***
- ============================================
- [..]
- To Re-configure OPAMP when OPAMP is ON (change on the fly)
- (#) If needed, Fill in the HAL_OPAMP_MspInit()
- (++) This is the case for instance if you wish to use new OPAMP I/O
- (#) Configure the opamp using HAL_OPAMP_Init() function:
- (++) As in configure case, selects first the parameters you wish to modify.
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of STMicroelectronics nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************
- */
- /*
- Additional Tables:
- The OPAMPs non inverting input (both default and secondary) can be
- selected among the list shown by table below.
-
- The OPAMPs non inverting input (both default and secondary) can be
- selected among the list shown by table below.
-
- Table 1. OPAMPs inverting/non-inverting inputs for the STM32F3 devices:
- +--------------------------------------------------------------+
- | | | OPAMP1 | OPAMP2 | OPAMP3 | OPAMP4 |
- |-----------------|--------|--------|--------|--------|--------|
- | | No conn| X | X | X | X |
- | Inverting Input | VM0 | PC5 | PC5 | PB10 | PB10 |
- | (1) | VM1 | PA3 | PA5 | PB2 | PD8 |
- |-----------------|--------|--------|--------|--------|--------|
- | | VP0 | PA1 | PA7 | PB0 | PB13 |
- | Non Inverting | VP1 | PA7 | PD14 | PB13 | PD11 |
- | Input | VP2 | PA3 | PB0 | PA1 | PA4 |
- | | VP3 | PA5 | PB14 | PA5 | PB11 |
- +--------------------------------------------------------------+
- (1): NA in follower mode.
-
- Table 2. OPAMPs outputs for the STM32F3 devices:
- +--------------------------------------------------------------+
- | | | OPAMP1 | OPAMP2 | OPAMP3 | OPAMP4 |
- |-----------------|--------|--------|--------|--------|--------|
- | Output | | PA2 | PA6 | PB1 | PB12 |
- |-----------------|--------|--------|--------|--------|--------|
- */
- /* Includes ------------------------------------------------------------------*/
- #include "stm32f3xx_hal.h"
-
- /** @addtogroup STM32F3xx_HAL_Driver
- * @{
- */
- #ifdef HAL_OPAMP_MODULE_ENABLED
- #if defined(STM32F302xE) || defined(STM32F303xE) || defined(STM32F398xx) || \
- defined(STM32F302xC) || defined(STM32F303xC) || defined(STM32F358xx) || \
- defined(STM32F303x8) || defined(STM32F334x8) || defined(STM32F328xx) || \
- defined(STM32F301x8) || defined(STM32F302x8) || defined(STM32F318xx)
- /** @defgroup OPAMP OPAMP
- * @brief OPAMP HAL module driver
- * @{
- */
- /* Private typedef -----------------------------------------------------------*/
- /* Private define ------------------------------------------------------------*/
- /** @defgroup OPAMP_Private_Define OPAMP Private Define
- * @{
- */
- /* CSR register reset value */
- #define OPAMP_CSR_RESET_VALUE (0x00000000U)
- /**
- * @}
- */
- /* Private macro -------------------------------------------------------------*/
- /* Private variables ---------------------------------------------------------*/
- /* Private function prototypes -----------------------------------------------*/
- /* Exported functions ---------------------------------------------------------*/
- /** @defgroup OPAMP_Exported_Functions OPAMP Exported Functions
- * @{
- */
- /** @defgroup OPAMP_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
- @verbatim
- ===============================================================================
- ##### Initialization and de-initialization functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
-
- @endverbatim
- * @{
- */
- /**
- * @brief Initializes the OPAMP according to the specified
- * parameters in the OPAMP_InitTypeDef and create the associated handle.
- * @note If the selected opamp is locked, initialization can't be performed.
- * To unlock the configuration, perform a system reset.
- * @param hopamp OPAMP handle
- * @retval HAL status
- */
- HAL_StatusTypeDef HAL_OPAMP_Init(OPAMP_HandleTypeDef *hopamp)
- {
- HAL_StatusTypeDef status = HAL_OK;
- /* Check the OPAMP handle allocation and lock status */
- /* Init not allowed if calibration is ongoing */
- if((hopamp == NULL) || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED) \
- || (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY))
- {
- return HAL_ERROR;
- }
- else
- {
-
- /* Check the parameter */
- assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
-
- /* Set OPAMP parameters */
- assert_param(IS_OPAMP_FUNCTIONAL_NORMALMODE(hopamp->Init.Mode));
- assert_param(IS_OPAMP_NONINVERTING_INPUT(hopamp->Init.NonInvertingInput));
- if ((hopamp->Init.Mode) == OPAMP_STANDALONE_MODE)
- {
- assert_param(IS_OPAMP_INVERTING_INPUT(hopamp->Init.InvertingInput));
- }
-
- assert_param(IS_OPAMP_TIMERCONTROLLED_MUXMODE(hopamp->Init.TimerControlledMuxmode));
- if ((hopamp->Init.TimerControlledMuxmode) == OPAMP_TIMERCONTROLLEDMUXMODE_ENABLE)
- {
- assert_param(IS_OPAMP_SEC_NONINVERTINGINPUT(hopamp->Init.NonInvertingInputSecondary));
- if ((hopamp->Init.Mode) == OPAMP_STANDALONE_MODE)
- {
- assert_param(IS_OPAMP_SEC_INVERTINGINPUT(hopamp->Init.InvertingInputSecondary));
- }
- }
-
- if ((hopamp->Init.Mode) == OPAMP_PGA_MODE)
- {
- assert_param(IS_OPAMP_PGACONNECT(hopamp->Init.PgaConnect));
- assert_param(IS_OPAMP_PGA_GAIN(hopamp->Init.PgaGain));
- }
-
- assert_param(IS_OPAMP_TRIMMING(hopamp->Init.UserTrimming));
- if ((hopamp->Init.UserTrimming) == OPAMP_TRIMMING_USER)
- {
- assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueP));
- assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueN));
- }
-
- /* Init SYSCFG and the low level hardware to access opamp */
- __HAL_RCC_SYSCFG_CLK_ENABLE();
-
- if(hopamp->State == HAL_OPAMP_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- hopamp->Lock = HAL_UNLOCKED;
- }
- /* Call MSP init function */
- HAL_OPAMP_MspInit(hopamp);
-
- /* Set OPAMP parameters */
- /* Set bits according to hopamp->hopamp->Init.Mode value */
- /* Set bits according to hopamp->hopamp->Init.InvertingInput value */
- /* Set bits according to hopamp->hopamp->Init.NonInvertingInput value */
- /* Set bits according to hopamp->hopamp->Init.TimerControlledMuxmode value */
- /* Set bits according to hopamp->hopamp->Init.InvertingInputSecondary value */
- /* Set bits according to hopamp->hopamp->Init.NonInvertingInputSecondary value */
- /* Set bits according to hopamp->hopamp->Init.PgaConnect value */
- /* Set bits according to hopamp->hopamp->Init.PgaGain value */
- /* Set bits according to hopamp->hopamp->Init.UserTrimming value */
- /* Set bits according to hopamp->hopamp->Init.TrimmingValueP value */
- /* Set bits according to hopamp->hopamp->Init.TrimmingValueN value */
-
-
- /* check if OPAMP_PGA_MODE & in Follower mode */
- /* - InvertingInput */
- /* - InvertingInputSecondary */
- /* are Not Applicable */
-
- if ((hopamp->Init.Mode == OPAMP_PGA_MODE) || (hopamp->Init.Mode == OPAMP_FOLLOWER_MODE))
- {
- MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_UPDATE_PARAMETERS_INIT_MASK, \
- hopamp->Init.Mode | \
- hopamp->Init.NonInvertingInput | \
- hopamp->Init.TimerControlledMuxmode | \
- hopamp->Init.NonInvertingInputSecondary | \
- hopamp->Init.PgaConnect | \
- hopamp->Init.PgaGain | \
- hopamp->Init.UserTrimming | \
- (hopamp->Init.TrimmingValueP << OPAMP_INPUT_NONINVERTING) | \
- (hopamp->Init.TrimmingValueN << OPAMP_INPUT_INVERTING));
- }
- else /* OPAMP_STANDALONE_MODE */
- {
- MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_UPDATE_PARAMETERS_INIT_MASK, \
- hopamp->Init.Mode | \
- hopamp->Init.InvertingInput | \
- hopamp->Init.NonInvertingInput | \
- hopamp->Init.TimerControlledMuxmode | \
- hopamp->Init.InvertingInputSecondary | \
- hopamp->Init.NonInvertingInputSecondary | \
- hopamp->Init.PgaConnect | \
- hopamp->Init.PgaGain | \
- hopamp->Init.UserTrimming | \
- (hopamp->Init.TrimmingValueP << OPAMP_INPUT_NONINVERTING) | \
- (hopamp->Init.TrimmingValueN << OPAMP_INPUT_INVERTING));
- }
-
- /* Update the OPAMP state*/
- if (hopamp->State == HAL_OPAMP_STATE_RESET)
- {
- /* From RESET state to READY State */
- hopamp->State = HAL_OPAMP_STATE_READY;
- }
- /* else: remain in READY or BUSY state (no update) */
-
- return status;
- }
- }
- /**
- * @brief DeInitializes the OPAMP peripheral
- * @note Deinitialization can't be performed if the OPAMP configuration is locked.
- * To unlock the configuration, perform a system reset.
- * @param hopamp OPAMP handle
- * @retval HAL status
- */
- HAL_StatusTypeDef HAL_OPAMP_DeInit(OPAMP_HandleTypeDef *hopamp)
- {
- HAL_StatusTypeDef status = HAL_OK;
- /* Check the OPAMP handle allocation */
- /* DeInit not allowed if calibration is ongoing */
- if((hopamp == NULL) || (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY))
- {
- status = HAL_ERROR;
- }
- else
- {
- /* Check the parameter */
- assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
- /* Set OPAMP_CSR register to reset value */
- WRITE_REG(hopamp->Instance->CSR, OPAMP_CSR_RESET_VALUE);
- /* DeInit the low level hardware: GPIO, CLOCK and NVIC */
- /* When OPAMP is locked, unlocking can be achieved thanks to */
- /* __HAL_RCC_SYSCFG_CLK_DISABLE() call within HAL_OPAMP_MspDeInit */
- /* Note that __HAL_RCC_SYSCFG_CLK_DISABLE() also disables comparator */
- HAL_OPAMP_MspDeInit(hopamp);
- if (OPAMP_CSR_RESET_VALUE == hopamp->Instance->CSR)
- {
- /* Update the OPAMP state */
- hopamp->State = HAL_OPAMP_STATE_RESET;
- }
- else /* RESET STATE */
- {
- /* DeInit not complete */
- /* It can be the case if OPAMP was formerly locked */
- status = HAL_ERROR;
- /* The OPAMP state is NOT updated */
- }
- /* Process unlocked */
- __HAL_UNLOCK(hopamp);
- }
-
- return status;
- }
- /**
- * @brief Initializes the OPAMP MSP.
- * @param hopamp OPAMP handle
- * @retval None
- */
- __weak void HAL_OPAMP_MspInit(OPAMP_HandleTypeDef *hopamp)
- {
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hopamp);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_OPAMP_MspInit could be implemented in the user file
- */
- /* Example */
- }
- /**
- * @brief DeInitializes OPAMP MSP.
- * @param hopamp OPAMP handle
- * @retval None
- */
- __weak void HAL_OPAMP_MspDeInit(OPAMP_HandleTypeDef *hopamp)
- {
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hopamp);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_OPAMP_MspDeInit could be implemented in the user file
- */
- }
- /**
- * @}
- */
- /** @defgroup OPAMP_Exported_Functions_Group2 Input and Output operation functions
- * @brief Data transfers functions
- *
- @verbatim
- ===============================================================================
- ##### IO operation functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to manage the OPAMP data
- transfers.
- @endverbatim
- * @{
- */
- /**
- * @brief Start the opamp
- * @param hopamp OPAMP handle
- * @retval HAL status
- */
- HAL_StatusTypeDef HAL_OPAMP_Start(OPAMP_HandleTypeDef *hopamp)
- {
- HAL_StatusTypeDef status = HAL_OK;
-
- /* Check the OPAMP handle allocation */
- /* Check if OPAMP locked */
- if((hopamp == NULL) || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED))
-
- {
- status = HAL_ERROR;
- }
- else
- {
- /* Check the parameter */
- assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
-
- if(hopamp->State == HAL_OPAMP_STATE_READY)
- {
- /* Enable the selected opamp */
- SET_BIT (hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN);
- /* Update the OPAMP state*/
- /* From HAL_OPAMP_STATE_READY to HAL_OPAMP_STATE_BUSY */
- hopamp->State = HAL_OPAMP_STATE_BUSY;
- }
- else
- {
- status = HAL_ERROR;
- }
-
-
- }
- return status;
- }
- /**
- * @brief Stop the opamp
- * @param hopamp OPAMP handle
- * @retval HAL status
- */
- HAL_StatusTypeDef HAL_OPAMP_Stop(OPAMP_HandleTypeDef *hopamp)
- {
- HAL_StatusTypeDef status = HAL_OK;
-
- /* Check the OPAMP handle allocation */
- /* Check if OPAMP locked */
- /* Check if OPAMP calibration ongoing */
- if((hopamp == NULL) || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED) \
- || (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY))
- {
- status = HAL_ERROR;
- }
- else
- {
- /* Check the parameter */
- assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
- if(hopamp->State == HAL_OPAMP_STATE_BUSY)
- {
- /* Disable the selected opamp */
- CLEAR_BIT (hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN);
-
- /* Update the OPAMP state*/
- /* From HAL_OPAMP_STATE_BUSY to HAL_OPAMP_STATE_READY*/
- hopamp->State = HAL_OPAMP_STATE_READY;
- }
- else
- {
- status = HAL_ERROR;
- }
- }
- return status;
- }
- /**
- * @brief Run the self calibration of one OPAMP
- * @param hopamp handle
- * @retval Updated offset trimming values (PMOS & NMOS), user trimming is enabled
- * @retval HAL status
- * @note Calibration runs about 25 ms.
- */
- HAL_StatusTypeDef HAL_OPAMP_SelfCalibrate(OPAMP_HandleTypeDef *hopamp)
- {
- HAL_StatusTypeDef status = HAL_OK;
-
- uint32_t trimmingvaluen = 0U;
- uint32_t trimmingvaluep = 0U;
- uint32_t delta;
-
- /* Check the OPAMP handle allocation */
- /* Check if OPAMP locked */
- if((hopamp == NULL) || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED))
- {
- status = HAL_ERROR;
- }
- else
- {
-
- /* Check if OPAMP in calibration mode and calibration not yet enable */
- if(hopamp->State == HAL_OPAMP_STATE_READY)
- {
- /* Check the parameter */
- assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
- /* Set Calibration mode */
- /* Non-inverting input connected to calibration reference voltage. */
- SET_BIT(hopamp->Instance->CSR, OPAMP_CSR_FORCEVP);
- /* user trimming values are used for offset calibration */
- SET_BIT(hopamp->Instance->CSR, OPAMP_CSR_USERTRIM);
-
- /* Enable calibration */
- SET_BIT (hopamp->Instance->CSR, OPAMP_CSR_CALON);
-
- /* 1st calibration - N */
- /* Select 90U% VREF */
- MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_CALSEL, OPAMP_VREF_90VDDA);
-
- /* Enable the selected opamp */
- SET_BIT (hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN);
-
- /* Init trimming counter */
- /* Medium value */
- trimmingvaluen = 16U;
- delta = 8U;
-
- while (delta != 0U)
- {
- /* Set candidate trimming */
- MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_TRIMOFFSETN, trimmingvaluen<<OPAMP_INPUT_INVERTING);
-
- /* OFFTRIMmax delay 2 ms as per datasheet (electrical characteristics */
- /* Offset trim time: during calibration, minimum time needed between */
- /* two steps to have 1 mV accuracy */
- HAL_Delay(2U);
- if ((hopamp->Instance->CSR & OPAMP_CSR_OUTCAL) != RESET)
- {
- /* OPAMP_CSR_OUTCAL is HIGH try higher trimming */
- trimmingvaluen += delta;
- }
- else
- {
- /* OPAMP_CSR_OUTCAL is LOW try lower trimming */
- trimmingvaluen -= delta;
- }
-
- delta >>= 1U;
- }
- /* Still need to check if righ calibration is current value or un step below */
- /* Indeed the first value that causes the OUTCAL bit to change from 1 to 0 */
- MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_TRIMOFFSETN, trimmingvaluen<<OPAMP_INPUT_INVERTING);
-
- /* OFFTRIMmax delay 2 ms as per datasheet (electrical characteristics */
- /* Offset trim time: during calibration, minimum time needed between */
- /* two steps to have 1 mV accuracy */
- HAL_Delay(2U);
-
- if ((hopamp->Instance->CSR & OPAMP_CSR_OUTCAL) != RESET)
- {
- /* OPAMP_CSR_OUTCAL is actually one value more */
- trimmingvaluen++;
- /* Set right trimming */
- MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_TRIMOFFSETN, trimmingvaluen<<OPAMP_INPUT_INVERTING);
- }
-
- /* 2nd calibration - P */
- /* Select 10U% VREF */
- MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_CALSEL, OPAMP_VREF_10VDDA);
-
- /* Init trimming counter */
- /* Medium value */
- trimmingvaluep = 16U;
- delta = 8U;
-
- while (delta != 0U)
- {
- /* Set candidate trimming */
- MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_TRIMOFFSETP, trimmingvaluep<<OPAMP_INPUT_NONINVERTING);
-
- /* OFFTRIMmax delay 2 ms as per datasheet (electrical characteristics */
- /* Offset trim time: during calibration, minimum time needed between */
- /* two steps to have 1 mV accuracy */
- HAL_Delay(2U);
- if ((hopamp->Instance->CSR & OPAMP_CSR_OUTCAL) != RESET)
- {
- /* OPAMP_CSR_OUTCAL is HIGH try higher trimming */
- trimmingvaluep += delta;
- }
- else
- {
- trimmingvaluep -= delta;
- }
-
- delta >>= 1U;
- }
-
- /* Still need to check if righ calibration is current value or un step below */
- /* Indeed the first value that causes the OUTCAL bit to change from 1 to 0U */
- /* Set candidate trimming */
- MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_TRIMOFFSETP, trimmingvaluep<<OPAMP_INPUT_NONINVERTING);
- /* OFFTRIMmax delay 2 ms as per datasheet (electrical characteristics */
- /* Offset trim time: during calibration, minimum time needed between */
- /* two steps to have 1 mV accuracy */
- HAL_Delay(2U);
-
- if ((hopamp->Instance->CSR & OPAMP_CSR_OUTCAL) != RESET)
- {
- /* OPAMP_CSR_OUTCAL is actually one value more */
- trimmingvaluep++;
- /* Set right trimming */
- MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_TRIMOFFSETP, trimmingvaluep<<OPAMP_INPUT_NONINVERTING);
- }
-
- /* Disable calibration */
- CLEAR_BIT (hopamp->Instance->CSR, OPAMP_CSR_CALON);
- /* Disable the OPAMP */
- CLEAR_BIT (hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN);
-
- /* Set operating mode */
- /* Non-inverting input connected to calibration reference voltage. */
- CLEAR_BIT(hopamp->Instance->CSR, OPAMP_CSR_FORCEVP);
-
- /* Self calibration is successful */
- /* Store calibration(user timming) results in init structure. */
- /* Write calibration result N */
- hopamp->Init.TrimmingValueN = trimmingvaluen;
-
- /* Write calibration result P */
- hopamp->Init.TrimmingValueP = trimmingvaluep;
- /* Select user timming mode */
- /* And updated with calibrated settings */
- hopamp->Init.UserTrimming = OPAMP_TRIMMING_USER;
- MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_TRIMOFFSETP, trimmingvaluep<<OPAMP_INPUT_NONINVERTING);
- MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_TRIMOFFSETN, trimmingvaluen<<OPAMP_INPUT_INVERTING);
- }
- else
- {
- /* OPAMP can not be calibrated from this mode */
- status = HAL_ERROR;
- }
- }
- return status;
- }
- /**
- * @}
- */
- /** @defgroup OPAMP_Exported_Functions_Group3 Peripheral Control functions
- * @brief management functions
- *
- @verbatim
- ===============================================================================
- ##### Peripheral Control functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to control the OPAMP data
- transfers.
- @endverbatim
- * @{
- */
- /**
- * @brief Lock the selected opamp configuration.
- * @param hopamp OPAMP handle
- * @retval HAL status
- */
- HAL_StatusTypeDef HAL_OPAMP_Lock(OPAMP_HandleTypeDef *hopamp)
- {
- HAL_StatusTypeDef status = HAL_OK;
- /* Check the OPAMP handle allocation */
- /* Check if OPAMP locked */
- /* OPAMP can be locked when enabled and running in normal mode */
- /* It is meaningless otherwise */
- if((hopamp == NULL) || (hopamp->State == HAL_OPAMP_STATE_RESET) \
- || (hopamp->State == HAL_OPAMP_STATE_READY) \
- || (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY)\
- || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED))
-
- {
- status = HAL_ERROR;
- }
-
- else
- {
- /* Check the parameter */
- assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
-
- /* Lock OPAMP */
- SET_BIT (hopamp->Instance->CSR, OPAMP_CSR_LOCK);
-
- /* OPAMP state changed to locked */
- hopamp->State = HAL_OPAMP_STATE_BUSYLOCKED;
- }
- return status;
- }
- /**
- * @}
- */
- /** @defgroup OPAMP_Exported_Functions_Group4 Peripheral State functions
- * @brief Peripheral State functions
- *
- @verbatim
- ===============================================================================
- ##### Peripheral State functions #####
- ===============================================================================
- [..]
- This subsection permit to get in run-time the status of the peripheral
- and the data flow.
- @endverbatim
- * @{
- */
- /**
- * @brief Return the OPAMP state
- * @param hopamp OPAMP handle
- * @retval HAL state
- */
- HAL_OPAMP_StateTypeDef HAL_OPAMP_GetState(OPAMP_HandleTypeDef *hopamp)
- {
- /* Check the OPAMP handle allocation */
- if(hopamp == NULL)
- {
- return HAL_OPAMP_STATE_RESET;
- }
- /* Check the parameter */
- assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
- return hopamp->State;
- }
- /**
- * @brief Return the OPAMP factory trimming value
- * @param hopamp OPAMP handle
- * @param trimmingoffset Trimming offset (P or N)
- * @retval Trimming value (P or N): range: 0->31
- * or OPAMP_FACTORYTRIMMING_DUMMY if trimming value is not available
- */
- OPAMP_TrimmingValueTypeDef HAL_OPAMP_GetTrimOffset (OPAMP_HandleTypeDef *hopamp, uint32_t trimmingoffset)
- {
- uint32_t oldusertrimming = 0U;
- OPAMP_TrimmingValueTypeDef oldtrimmingvaluep = 0U, oldtrimmingvaluen = 0U, trimmingvalue = 0U;
-
- /* Check the OPAMP handle allocation */
- /* Value can be retrieved in HAL_OPAMP_STATE_READY state */
- if((hopamp == NULL) || (hopamp->State == HAL_OPAMP_STATE_RESET) \
- || (hopamp->State == HAL_OPAMP_STATE_BUSY) \
- || (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY)\
- || (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED))
- {
- return OPAMP_FACTORYTRIMMING_DUMMY;
- }
- else
- {
- /* Check the parameter */
- assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance));
- assert_param(IS_OPAMP_FACTORYTRIMMING(trimmingoffset));
-
- /* Check the trimming mode */
- if ((READ_BIT(hopamp->Instance->CSR,OPAMP_CSR_USERTRIM)) != RESET)
- {
- /* User trimming is used */
- oldusertrimming = OPAMP_TRIMMING_USER;
- /* Store the TrimmingValueP & TrimmingValueN */
- oldtrimmingvaluep = (hopamp->Instance->CSR & OPAMP_CSR_TRIMOFFSETP) >> OPAMP_INPUT_NONINVERTING;
- oldtrimmingvaluen = (hopamp->Instance->CSR & OPAMP_CSR_TRIMOFFSETN) >> OPAMP_INPUT_INVERTING;
- }
-
- /* Set factory timming mode */
- CLEAR_BIT (hopamp->Instance->CSR, OPAMP_CSR_USERTRIM);
-
- /* Get factory trimming */
- if (trimmingoffset == OPAMP_FACTORYTRIMMING_P)
- {
- /* Return TrimOffsetP */
- trimmingvalue = ((hopamp->Instance->CSR & OPAMP_CSR_TRIMOFFSETP) >> OPAMP_INPUT_NONINVERTING);
- }
- else
- {
- /* Return TrimOffsetN */
- trimmingvalue = ((hopamp->Instance->CSR & OPAMP_CSR_TRIMOFFSETN) >> OPAMP_INPUT_INVERTING);
- }
-
- /* Restore user trimming configuration if it was formerly set */
- /* Check if user trimming was used */
- if (oldusertrimming == OPAMP_TRIMMING_USER)
- {
- /* Restore user trimming */
- SET_BIT(hopamp->Instance->CSR,OPAMP_CSR_USERTRIM);
- MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_TRIMOFFSETP, oldtrimmingvaluep<<OPAMP_INPUT_NONINVERTING);
- MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_TRIMOFFSETN, oldtrimmingvaluen<<OPAMP_INPUT_INVERTING);
- }
- }
- return trimmingvalue;
- }
- /**
- * @}
- */
- /**
- * @}
- */
- /**
- * @}
- */
- #endif /* STM32F302xE || STM32F303xE || STM32F398xx || */
- /* STM32F302xC || STM32F303xC || STM32F358xx || */
- /* STM32F303x8 || STM32F334x8 || STM32F328xx || */
- /* STM32F301x8 || STM32F302x8 || STM32F318xx */
- #endif /* HAL_OPAMP_MODULE_ENABLED */
- /**
- * @}
- */
- /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|