mbed library sources
Dependents: frdm_kl05z_gpio_test
Fork of mbed-src by
Diff: targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_opamp.c
- Revision:
- 76:aeb1df146756
- Child:
- 80:66393a7b209d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/cmsis/TARGET_STM/TARGET_NUCLEO_L152RE/stm32l1xx_opamp.c Mon Jan 27 14:30:07 2014 +0000 @@ -0,0 +1,557 @@ +/** + ****************************************************************************** + * @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 + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + * + * 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****/