/**
******************************************************************************
* @file stm32l1xx_opamp.c
* @author MCD Application Team
* @version V1.2.0
* @date 22-February-2013
* @brief This file provides firmware functions to manage the following
* functionalities of the operational amplifiers (opamp) peripheral:
* + Initialization and configuration
* + Calibration management
*
* @verbatim
==============================================================================
##### How to use this driver #####
==============================================================================
[..] The device integrates three independent rail-to-rail operational amplifiers
OPAMP1, OPAMP2 and OPAMP3:
(+) Internal connections to the ADC.
(+) Internal connections to the DAC.
(+) Internal connection to COMP1 (only OPAMP3).
(+) Internal connection for unity gain (voltage follower) configuration.
(+) Calibration capability.
(+) Selectable gain-bandwidth (2MHz in normal mode, 500KHz in low power mode).
[..]
(#) COMP AHB clock must be enabled to get write access
to OPAMP registers using
(#) RCC_APB1PeriphClockCmd(RCC_APB1Periph_COMP, ENABLE)
(#) Configure the corresponding GPIO to OPAMPx INP, OPAMPx_INN (if used)
and OPAMPx_OUT in analog mode.
(#) Configure (close/open) the OPAMP switches using OPAMP_SwitchCmd()
(#) Enable the OPAMP peripheral using OPAMP_Cmd()
-@- In order to use OPAMP outputs as ADC inputs, the opamps must be enabled
and the ADC must use the OPAMP output channel number:
(+@) OPAMP1 output is connected to ADC channel 3.
(+@) OPAMP2 output is connected to ADC channel 8.
(+@) OPAMP3 output is connected to ADC channel 13 (SW1 switch must be closed).
* @endverbatim
*
******************************************************************************
* @attention
*
*
© COPYRIGHT 2013 STMicroelectronics
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32l1xx_opamp.h"
/** @addtogroup STM32L1xx_StdPeriph_Driver
* @{
*/
/** @defgroup OPAMP
* @brief OPAMP driver modules
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/** @defgroup OPAMP_Private_Functions
* @{
*/
/** @defgroup OPAMP_Group1 Initialization and configuration
* @brief Initialization and configuration
*
@verbatim
===============================================================================
##### Initialization and configuration #####
===============================================================================
@endverbatim
* @{
*/
/**
* @brief Deinitialize the OPAMPs register to its default reset value.
* @note At startup, OTR and LPOTR registers are set to factory programmed values.
* @param None.
* @retval None.
*/
void OPAMP_DeInit(void)
{
/*!< Set OPAMP_CSR register to reset value */
OPAMP->CSR = 0x00010101;
/*!< Set OPAMP_OTR register to reset value */
OPAMP->OTR = (uint32_t)(* (uint32_t*)FLASH_R_BASE + 0x00000038);
/*!< Set OPAMP_LPOTR register to reset value */
OPAMP->LPOTR = (uint32_t)(* (uint32_t*)FLASH_R_BASE + 0x0000003C);
}
/**
* @brief Close or Open the OPAMP switches.
* @param OPAMP_OPAMPxSwitchy: selects the OPAMPx switch.
* This parameter can be any combinations of the following values:
* @arg OPAMP_OPAMP1Switch3: used to connect internally OPAMP1 output to
* OPAMP1 negative input (internal follower)
* @arg OPAMP_OPAMP1Switch4: used to connect PA2 to OPAMP1 negative input
* @arg OPAMP_OPAMP1Switch5: used to connect PA1 to OPAMP1 positive input
* @arg OPAMP_OPAMP1Switch6: used to connect DAC_OUT1 to OPAMP1 positive input
* @arg OPAMP_OPAMP1SwitchANA: used to meet 1 nA input leakage
* @arg OPAMP_OPAMP2Switch3: used to connect internally OPAMP2 output to
* OPAMP2 negative input (internal follower)
* @arg OPAMP_OPAMP2Switch4: used to connect PA7 to OPAMP2 negative input
* @arg OPAMP_OPAMP2Switch5: used to connect PA6 to OPAMP2 positive input
* @arg OPAMP_OPAMP2Switch6: used to connect DAC_OUT1 to OPAMP2 positive input
* @arg OPAMP_OPAMP2Switch7: used to connect DAC_OUT2 to OPAMP2 positive input
* @arg OPAMP_OPAMP2SwitchANA: used to meet 1 nA input leakage
* @arg OPAMP_OPAMP3Switch3: used to connect internally OPAMP3 output to
* OPAMP3 negative input (internal follower)
* @arg OPAMP_OPAMP3Switch4: used to connect PC2 to OPAMP3 negative input
* @arg OPAMP_OPAMP3Switch5: used to connect PC1 to OPAMP3 positive input
* @arg OPAMP_OPAMP3Switch6: used to connect DAC_OUT1 to OPAMP3 positive input
* @arg OPAMP_OPAMP3SwitchANA: used to meet 1 nA input leakage on negative input
*
* @param NewState: New state of the OPAMP switch.
* This parameter can be:
* ENABLE to close the OPAMP switch
* or DISABLE to open the OPAMP switch
* @note OPAMP_OPAMP2Switch6 and OPAMP_OPAMP2Switch7 mustn't be closed together.
* @retval None
*/
void OPAMP_SwitchCmd(uint32_t OPAMP_OPAMPxSwitchy, FunctionalState NewState)
{
/* Check the parameter */
assert_param(IS_OPAMP_SWITCH(OPAMP_OPAMPxSwitchy));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Close the selected switches */
OPAMP->CSR |= (uint32_t) OPAMP_OPAMPxSwitchy;
}
else
{
/* Open the selected switches */
OPAMP->CSR &= (~(uint32_t)OPAMP_OPAMPxSwitchy);
}
}
/**
* @brief Enable or disable the OPAMP peripheral.
* @param OPAMP_Selection: the selected OPAMP.
* This parameter can be one of the following values:
* @arg OPAMP_Selection_OPAMP1: OPAMP1 is selected
* @arg OPAMP_Selection_OPAMP2: OPAMP2 is selected
* @arg OPAMP_Selection_OPAMP3: OPAMP3 is selected
* @param NewState: new state of the selected OPAMP peripheral.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void OPAMP_Cmd(uint32_t OPAMP_Selection, FunctionalState NewState)
{
/* Check the parameter */
assert_param(IS_OPAMP_ALL_PERIPH(OPAMP_Selection));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the selected OPAMP */
OPAMP->CSR &= (~(uint32_t) OPAMP_Selection);
}
else
{
/* Disable the selected OPAMP */
OPAMP->CSR |= (uint32_t) OPAMP_Selection;
}
}
/**
* @brief Enable or disable the low power mode for OPAMP peripheral.
* @param OPAMP_Selection: the selected OPAMP.
* This parameter can be one of the following values:
* @arg OPAMP_Selection_OPAMP1: OPAMP1 selected
* @arg OPAMP_Selection_OPAMP2: OPAMP2 selected
* @arg OPAMP_Selection_OPAMP3: OPAMP3 selected
* @param NewState: new low power state of the selected OPAMP peripheral.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void OPAMP_LowPowerCmd(uint32_t OPAMP_Selection, FunctionalState NewState)
{
/* Check the parameter */
assert_param(IS_OPAMP_ALL_PERIPH(OPAMP_Selection));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Set the selected OPAMP in low power mode */
OPAMP->CSR |= (uint32_t) (OPAMP_Selection << 7);
}
else
{
/* Disable the low power mode for the selected OPAMP */
OPAMP->CSR &= (~(uint32_t) (OPAMP_Selection << 7));
}
}
/**
* @brief Select the OPAMP power range.
* @note The OPAMP power range selection must be performed while OPAMPs are powered down.
* @param OPAMP_Range: the selected OPAMP power range.
* This parameter can be one of the following values:
* @arg OPAMP_PowerRange_Low: Low power range is selected (VDDA is lower than 2.4V).
* @arg OPAMP_PowerRange_High: High power range is selected (VDDA is higher than 2.4V).
* @retval None
*/
void OPAMP_PowerRangeSelect(uint32_t OPAMP_PowerRange)
{
/* Check the parameter */
assert_param(IS_OPAMP_RANGE(OPAMP_PowerRange));
/* Reset the OPAMP range bit */
OPAMP->CSR &= (~(uint32_t) (OPAMP_CSR_AOP_RANGE));
/* Select the OPAMP power range */
OPAMP->CSR |= OPAMP_PowerRange;
}
/**
* @}
*/
/** @defgroup OPAMP_Group2 Calibration functions
* @brief Calibration functions
*
@verbatim
===============================================================================
##### Calibration functions #####
===============================================================================
@endverbatim
* @{
*/
/**
* @brief Select the trimming mode.
* @param OffsetTrimming: the selected offset trimming mode.
* This parameter can be one of the following values:
* @arg OffsetTrimming_Factory: factory trimming values are used for offset
* calibration.
* @arg OffsetTrimming_User: user trimming values are used for offset
* calibration.
* @note When OffsetTrimming_User is selected, use OPAMP_OffsetTrimConfig()
* function or OPAMP_OffsetTrimLowPowerConfig() function to adjust
* trimming value.
* @retval None
*/
void OPAMP_OffsetTrimmingModeSelect(uint32_t OPAMP_Trimming)
{
/* Check the parameter */
assert_param(IS_OPAMP_TRIMMING(OPAMP_Trimming));
/* Reset the OPAMP_OTR range bit */
OPAMP->CSR &= (~(uint32_t) (OPAMP_OTR_OT_USER));
/* Select the OPAMP offset trimming */
OPAMP->CSR |= OPAMP_Trimming;
}
/**
* @brief Configure the trimming value of OPAMPs in normal mode.
* @param OPAMP_Selection: the selected OPAMP.
* This parameter can be one of the following values:
* @arg OPAMP_Selection_OPAMP1: OPAMP1 is selected to configure the trimming value.
* @arg OPAMP_Selection_OPAMP2: OPAMP2 is selected to configure the trimming value.
* @arg OPAMP_Selection_OPAMP3: OPAMP3 is selected to configure the trimming value.
* @param OPAMP_Input: the selected OPAMP input.
* This parameter can be one of the following values:
* @arg OPAMP_Input_NMOS: NMOS input is selected to configure the trimming value.
* @arg OPAMP_Input_PMOS: PMOS input is selected to configure the trimming value.
* @param OPAMP_TrimValue: the trimming value. This parameter can be any value lower
* or equal to 0x0000001F.
* @retval None
*/
void OPAMP_OffsetTrimConfig(uint32_t OPAMP_Selection, uint32_t OPAMP_Input, uint32_t OPAMP_TrimValue)
{
uint32_t tmpreg = 0;
/* Check the parameter */
assert_param(IS_OPAMP_ALL_PERIPH(OPAMP_Selection));
assert_param(IS_OPAMP_INPUT(OPAMP_Input));
assert_param(IS_OPAMP_TRIMMINGVALUE(OPAMP_TrimValue));
/* Get the OPAMP_OTR value */
tmpreg = OPAMP->OTR;
if(OPAMP_Selection == OPAMP_Selection_OPAMP1)
{
/* Reset the OPAMP inputs selection */
tmpreg &= (uint32_t)~(OPAMP_CSR_OPA1CAL_L | OPAMP_CSR_OPA1CAL_H);
/* Select the OPAMP input */
tmpreg |= OPAMP_Input;
if(OPAMP_Input == OPAMP_Input_PMOS)
{
/* Reset the trimming value corresponding to OPAMP1 PMOS input */
tmpreg &= (0xFFFFFFE0);
/* Set the new trimming value corresponding to OPAMP1 PMOS input */
tmpreg |= (OPAMP_TrimValue);
}
else
{
/* Reset the trimming value corresponding to OPAMP1 NMOS input */
tmpreg &= (0xFFFFFC1F);
/* Set the new trimming value corresponding to OPAMP1 NMOS input */
tmpreg |= (OPAMP_TrimValue<<5);
}
}
else if (OPAMP_Selection == OPAMP_Selection_OPAMP2)
{
/* Reset the OPAMP inputs selection */
tmpreg &= (uint32_t)~(OPAMP_CSR_OPA2CAL_L | OPAMP_CSR_OPA2CAL_H);
/* Select the OPAMP input */
tmpreg |= (uint32_t)(OPAMP_Input<<8);
if(OPAMP_Input == OPAMP_Input_PMOS)
{
/* Reset the trimming value corresponding to OPAMP2 PMOS input */
tmpreg &= (0xFFFF83FF);
/* Set the new trimming value corresponding to OPAMP2 PMOS input */
tmpreg |= (OPAMP_TrimValue<<10);
}
else
{
/* Reset the trimming value corresponding to OPAMP2 NMOS input */
tmpreg &= (0xFFF07FFF);
/* Set the new trimming value corresponding to OPAMP2 NMOS input */
tmpreg |= (OPAMP_TrimValue<<15);
}
}
else
{
/* Reset the OPAMP inputs selection */
tmpreg &= (uint32_t)~(OPAMP_CSR_OPA3CAL_L | OPAMP_CSR_OPA3CAL_H);
/* Select the OPAMP input */
tmpreg |= (uint32_t)(OPAMP_Input<<16);
if(OPAMP_Input == OPAMP_Input_PMOS)
{
/* Reset the trimming value corresponding to OPAMP3 PMOS input */
tmpreg &= (0xFE0FFFFF);
/* Set the new trimming value corresponding to OPAMP3 PMOS input */
tmpreg |= (OPAMP_TrimValue<<20);
}
else
{
/* Reset the trimming value corresponding to OPAMP3 NMOS input */
tmpreg &= (0xC1FFFFFF);
/* Set the new trimming value corresponding to OPAMP3 NMOS input */
tmpreg |= (OPAMP_TrimValue<<25);
}
}
/* Set the OPAMP_OTR register */
OPAMP->OTR = tmpreg;
}
/**
* @brief Configure the trimming value of OPAMPs in low power mode.
* @param OPAMP_Selection: the selected OPAMP.
* This parameter can be one of the following values:
* @arg OPAMP_Selection_OPAMP1: OPAMP1 is selected to configure the trimming value.
* @arg OPAMP_Selection_OPAMP2: OPAMP2 is selected to configure the trimming value.
* @arg OPAMP_Selection_OPAMP3: OPAMP3 is selected to configure the trimming value.
* @param OPAMP_Input: the selected OPAMP input.
* This parameter can be one of the following values:
* @arg OPAMP_Input_NMOS: NMOS input is selected to configure the trimming value.
* @arg OPAMP_Input_PMOS: PMOS input is selected to configure the trimming value.
* @param OPAMP_TrimValue: the trimming value.
* This parameter can be any value lower or equal to 0x0000001F.
* @retval None
*/
void OPAMP_OffsetTrimLowPowerConfig(uint32_t OPAMP_Selection, uint32_t OPAMP_Input, uint32_t OPAMP_TrimValue)
{
uint32_t tmpreg = 0;
/* Check the parameter */
assert_param(IS_OPAMP_ALL_PERIPH(OPAMP_Selection));
assert_param(IS_OPAMP_INPUT(OPAMP_Input));
assert_param(IS_OPAMP_TRIMMINGVALUE(OPAMP_TrimValue));
/* Get the OPAMP_LPOTR value */
tmpreg = OPAMP->LPOTR;
if(OPAMP_Selection == OPAMP_Selection_OPAMP1)
{
/* Reset the OPAMP inputs selection */
tmpreg &= (uint32_t)~(OPAMP_CSR_OPA1CAL_L | OPAMP_CSR_OPA1CAL_H);
/* Select the OPAMP input */
tmpreg |= OPAMP_Input;
if(OPAMP_Input == OPAMP_Input_PMOS)
{
/* Reset the trimming value corresponding to OPAMP1 PMOS input */
tmpreg &= (0xFFFFFFE0);
/* Set the new trimming value corresponding to OPAMP1 PMOS input */
tmpreg |= (OPAMP_TrimValue);
}
else
{
/* Reset the trimming value corresponding to OPAMP1 NMOS input */
tmpreg &= (0xFFFFFC1F);
/* Set the new trimming value corresponding to OPAMP1 NMOS input */
tmpreg |= (OPAMP_TrimValue<<5);
}
}
else if (OPAMP_Selection == OPAMP_Selection_OPAMP2)
{
/* Reset the OPAMP inputs selection */
tmpreg &= (uint32_t)~(OPAMP_CSR_OPA2CAL_L | OPAMP_CSR_OPA2CAL_H);
/* Select the OPAMP input */
tmpreg |= (uint32_t)(OPAMP_Input<<8);
if(OPAMP_Input == OPAMP_Input_PMOS)
{
/* Reset the trimming value corresponding to OPAMP2 PMOS input */
tmpreg &= (0xFFFF83FF);
/* Set the new trimming value corresponding to OPAMP2 PMOS input */
tmpreg |= (OPAMP_TrimValue<<10);
}
else
{
/* Reset the trimming value corresponding to OPAMP2 NMOS input */
tmpreg &= (0xFFF07FFF);
/* Set the new trimming value corresponding to OPAMP2 NMOS input */
tmpreg |= (OPAMP_TrimValue<<15);
}
}
else
{
/* Reset the OPAMP inputs selection */
tmpreg &= (uint32_t)~(OPAMP_CSR_OPA3CAL_L | OPAMP_CSR_OPA3CAL_H);
/* Select the OPAMP input */
tmpreg |= (uint32_t)(OPAMP_Input<<16);
if(OPAMP_Input == OPAMP_Input_PMOS)
{
/* Reset the trimming value corresponding to OPAMP3 PMOS input */
tmpreg &= (0xFE0FFFFF);
/* Set the new trimming value corresponding to OPAMP3 PMOS input */
tmpreg |= (OPAMP_TrimValue<<20);
}
else
{
/* Reset the trimming value corresponding to OPAMP3 NMOS input */
tmpreg &= (0xC1FFFFFF);
/* Set the new trimming value corresponding to OPAMP3 NMOS input */
tmpreg |= (OPAMP_TrimValue<<25);
}
}
/* Set the OPAMP_LPOTR register */
OPAMP->LPOTR = tmpreg;
}
/**
* @brief Checks whether the specified OPAMP calibration flag is set or not.
* @note User should wait until calibration flag change the value when changing
* the trimming value.
* @param OPAMP_Selection: the selected OPAMP.
* This parameter can be one of the following values:
* @arg OPAMP_Selection_OPAMP1: OPAMP1 is selected.
* @arg OPAMP_Selection_OPAMP2: OPAMP2 is selected.
* @arg OPAMP_Selection_OPAMP3: OPAMP3 is selected.
* @retval The new state of the OPAMP calibration flag (SET or RESET).
*/
FlagStatus OPAMP_GetFlagStatus(uint32_t OPAMP_Selection)
{
FlagStatus bitstatus = RESET;
uint32_t tmpreg = 0;
/* Check the parameter */
assert_param(IS_OPAMP_ALL_PERIPH(OPAMP_Selection));
/* Get the CSR register value */
tmpreg = OPAMP->CSR;
/* Check if OPAMP1 is selected */
if(OPAMP_Selection == OPAMP_Selection_OPAMP1)
{
/* Check OPAMP1 CAL bit status */
if ((tmpreg & OPAMP_CSR_OPA1CALOUT) != (uint32_t)RESET)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
}
/* Check if OPAMP2 is selected */
else if(OPAMP_Selection == OPAMP_Selection_OPAMP2)
{
/* Check OPAMP2 CAL bit status */
if ((tmpreg & OPAMP_CSR_OPA2CALOUT) != (uint32_t)RESET)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
}
else
{
/* Check OPAMP3 CAL bit status */
if ((tmpreg & OPAMP_CSR_OPA3CALOUT) != (uint32_t)RESET)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
}
return bitstatus;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/