/* * Copyright (c) 2020, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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. * * * Neither the name of Texas Instruments Incorporated 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 OWNER 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. */ /*!**************************************************************************** * @file dl_opa.h * @brief Op-Amp (OPA) Driver Library * @defgroup OPA Op-Amp (OPA) * * @anchor ti_dl_dl_opa_Overview * # Overview * * The OP-Amp Driver Library allows full configuration of the MSPM0 OPA module. * The OPA is a zero-drift chopper stabilized operational amplifier with a * programmable gain stage. * *
****************************************************************************** */ /** @addtogroup OPA * @{ */ #ifndef ti_dl_dl_opa__include #define ti_dl_dl_opa__include #include #include #include #include #ifdef __MSPM0_HAS_OA__ #ifdef __cplusplus extern "C" { #endif /*! @enum DL_OPA_CHOPPING_MODE */ typedef enum { /*! Disable chopping mode */ DL_OPA_CHOPPING_MODE_DISABLE = OA_CFG_CHOP_OFF, /*! Enable standard chopping mode */ DL_OPA_CHOPPING_MODE_STANDARD = OA_CFG_CHOP_ON, /*! Enable ADC assisted chopping mode. Requires OPA output to be connected to an ADC input with hardware averaging. */ DL_OPA_CHOPPING_MODE_ADC_AVERAGING = OA_CFG_CHOP_AVGON, } DL_OPA_CHOPPING_MODE; /*! @enum DL_OPA_OUTPUT_PIN_STATE */ typedef enum { /*! Output pin is enabled */ DL_OPA_OUTPUT_PIN_ENABLED = OA_CFG_OUTPIN_ENABLED, /*! Outpin pin is disabled */ DL_OPA_OUTPUT_PIN_DISABLED = OA_CFG_OUTPIN_DISABLED, } DL_OPA_OUTPUT_PIN_STATE; /*! @enum DL_OPA_PSEL */ typedef enum { /*! Non-inverting input channel is Open */ DL_OPA_PSEL_OPEN = OA_CFG_PSEL_NC, /*! Non-inverting input is OPAx_IN0+ */ DL_OPA_PSEL_IN0_POS = OA_CFG_PSEL_EXTPIN0, /*! Non-inverting input is OPAx_IN1+ */ DL_OPA_PSEL_IN1_POS = OA_CFG_PSEL_EXTPIN1, /*! Non-inverting input is DAC_OUT */ DL_OPA_PSEL_DAC_OUT = OA_CFG_PSEL_DAC12OUT, /*! Non-inverting input is DAC8.x_OUT */ DL_OPA_PSEL_DAC8_OUT = OA_CFG_PSEL_DAC8OUT, /*! Non-inverting input is VREF */ DL_OPA_PSEL_VREF = OA_CFG_PSEL_VREF, /*! Non-inverting input is OPA[x-1]_RTOP */ DL_OPA_PSEL_RTOP = OA_CFG_PSEL_OANM1RTOP, /*! Non-inverting input is GPAMP OUT*/ DL_OPA_PSEL_GPAMP_OUT = OA_CFG_PSEL_GPAMP_OUT_INT, /*! Non-inverting input is GND */ DL_OPA_PSEL_GND = OA_CFG_PSEL_VSS, } DL_OPA_PSEL; /*! @enum DL_OPA_NSEL */ typedef enum { /*! Inverting input channel is Open */ DL_OPA_NSEL_OPEN = OA_CFG_NSEL_NC, /*! Inverting input channel is OPAx_IN0- */ DL_OPA_NSEL_IN0_NEG = OA_CFG_NSEL_EXTPIN0, /*! Inverting input channel is OPAx_IN1- */ DL_OPA_NSEL_IN1_NEG = OA_CFG_NSEL_EXTPIN1, /*! Inverting input channel is OPA[x-1]_RBOT */ DL_OPA_NSEL_RBOT = OA_CFG_NSEL_OANP1RBOT, /*! Inverting input channel is RTAP */ DL_OPA_NSEL_RTAP = OA_CFG_NSEL_OANRTAP, /*! Inverting input channel is RTOP */ DL_OPA_NSEL_RTOP = OA_CFG_NSEL_OANRTOP, /*! Spare input for inverting channel */ DL_OPA_NSEL_SPARE = OA_CFG_NSEL_SPARE, } DL_OPA_NSEL; /*! @enum DL_OPA_MSEL */ typedef enum { /*! M-MUX input channel is Open */ DL_OPA_MSEL_OPEN = OA_CFG_MSEL_NC, /*! M-MUX input channel is OPAx_IN1- */ DL_OPA_MSEL_IN1_NEG = OA_CFG_MSEL_EXTNPIN1, /*! M-MUX input channel is GND */ DL_OPA_MSEL_GND = OA_CFG_MSEL_VSS, /*! M-MUX input channel is DAC_OUT */ DL_OPA_MSEL_DAC_OUT = OA_CFG_MSEL_DAC12OUT, /*! M-MUX input channel is OPA[x-1]_RTOP */ DL_OPA_MSEL_RTOP = OA_CFG_MSEL_OANM1RTOP, } DL_OPA_MSEL; /*! @enum DL_OPA_GBW */ typedef enum { /*! High gain bandwidth (GBW). See device specific datasheet for values. */ DL_OPA_GBW_HIGH = OA_CFGBASE_GBW_HIGHGAIN, /*! Low gain bandwidth (GBW). See device specific datasheet for values. */ DL_OPA_GBW_LOW = OA_CFGBASE_GBW_LOWGAIN, } DL_OPA_GBW; /*! @enum DL_OPA_GAIN */ typedef enum { /*! Gain value is Not Valid in Non-inverting and inverting PGA modes */ DL_OPA_GAIN_N0_P1 = (((uint32_t) 0x0) << OA_CFG_GAIN_OFS), /*! Gain value is -1x in Inverting PGA mode, and 2x in Non-inverting * PGA mode */ DL_OPA_GAIN_N1_P2 = (((uint32_t) 0x1) << OA_CFG_GAIN_OFS), /*! Gain value is -3x in Inverting PGA mode, and 4x in Non-inverting * PGA mode */ DL_OPA_GAIN_N3_P4 = (((uint32_t) 0x2) << OA_CFG_GAIN_OFS), /*! Gain value is -7x in Inverting PGA mode, and 8x in Non-inverting * PGA mode */ DL_OPA_GAIN_N7_P8 = (((uint32_t) 0x3) << OA_CFG_GAIN_OFS), /*! Gain value is -15x in Inverting PGA mode, and 16x in Non-inverting * PGA mode */ DL_OPA_GAIN_N15_P16 = (((uint32_t) 0x4) << OA_CFG_GAIN_OFS), /*! Gain value is -31x in Inverting PGA mode, and 32x in Non-inverting * PGA mode */ DL_OPA_GAIN_N31_P32 = (((uint32_t) 0x5) << OA_CFG_GAIN_OFS), } DL_OPA_GAIN; /*! * @brief Configuration struct for @ref DL_OPA_init */ typedef struct { /*! The chopping mode to set. One of @ref DL_OPA_CHOPPING_MODE */ DL_OPA_CHOPPING_MODE choppingMode; /*! The state of the output pin. One of @ref DL_OPA_OUTPUT_PIN_STATE. */ DL_OPA_OUTPUT_PIN_STATE outputPinState; /*! The non-inverting input channel to set. One of @ref DL_OPA_PSEL */ DL_OPA_PSEL pselChannel; /*! The inverting input channel to set. One of @ref DL_OPA_NSEL */ DL_OPA_NSEL nselChannel; /*! The M-MUX input channel to set. One of @ref DL_OPA_MSEL */ DL_OPA_MSEL mselChannel; /*! The gain to set. Value between 0-7. */ DL_OPA_GAIN gain; } DL_OPA_Config; /** * @brief Enables the Peripheral Write Enable (PWREN) register for the OPA * * Before any peripheral registers can be configured by software, the * peripheral itself must be enabled by writing the ENABLE bit together with * the appropriate KEY value to the peripheral's PWREN register. * * @note For power savings, please refer to @ref DL_OPA_enable * * @param[in] opa Pointer to the register overlay for the peripheral */ __STATIC_INLINE void DL_OPA_enablePower(OA_Regs *opa) { opa->GPRCM.PWREN = (OA_PWREN_KEY_UNLOCK_W | OA_PWREN_ENABLE_ENABLE); } /** * @brief Disables the Peripheral Write Enable (PWREN) register for the OPA * * When the PWREN.ENABLE bit is cleared, the peripheral's registers are not * accessible for read/write operations. * * @note This API does not provide large power savings. For power savings, * please refer to @ref DL_OPA_enable * * @param[in] opa Pointer to the register overlay for the peripheral */ __STATIC_INLINE void DL_OPA_disablePower(OA_Regs *opa) { opa->GPRCM.PWREN = (OA_PWREN_KEY_UNLOCK_W | OA_PWREN_ENABLE_DISABLE); } /** * @brief Returns if the Peripheral Write Enable (PWREN) register for the OPA * is enabled * * Before any peripheral registers can be configured by software, the * peripheral itself must be enabled by writing the ENABLE bit together with * the appropriate KEY value to the peripheral's PWREN register. * * When the PWREN.ENABLE bit is cleared, the peripheral's registers are not * accessible for read/write operations. * * @param[in] opa Pointer to the register overlay for the peripheral * * @return true if peripheral register access is enabled * @return false if peripheral register access is disabled */ __STATIC_INLINE bool DL_OPA_isPowerEnabled(const OA_Regs *opa) { return ( (opa->GPRCM.PWREN & OA_PWREN_ENABLE_MASK) == OA_PWREN_ENABLE_ENABLE); } /** * @brief Resets OPA peripheral * * @param[in] opa Pointer to the register overlay for the peripheral */ __STATIC_INLINE void DL_OPA_reset(OA_Regs *opa) { opa->GPRCM.RSTCTL = (OA_RSTCTL_KEY_UNLOCK_W | OA_RSTCTL_RESETSTKYCLR_CLR | OA_RSTCTL_RESETASSERT_ASSERT); } /** * @brief Returns if OPA peripheral was reset * * @param[in] opa Pointer to the register overlay for the peripheral * * @return true if peripheral was reset * @return false if peripheral wasn't reset * */ __STATIC_INLINE bool DL_OPA_isReset(const OA_Regs *opa) { return ((opa->GPRCM.STAT & OA_GPRCM_STAT_RESETSTKY_MASK) == OA_GPRCM_STAT_RESETSTKY_RESET); } /** * @brief Enable the OPA peripheral * * @param[in] opa Pointer to the register overlay for the peripheral */ __STATIC_INLINE void DL_OPA_enable(OA_Regs *opa) { opa->CTL |= OA_CTL_ENABLE_ON; } /** * @brief Checks if the OPA peripheral is enabled * * @param[in] opa Pointer to the register overlay for the peripheral * * @return Returns the enabled status of the OPA * * @retval true The OPA peripheral is enabled * @retval false The OPA peripheral is disabled */ __STATIC_INLINE bool DL_OPA_isEnabled(const OA_Regs *opa) { return ((opa->CTL & OA_CTL_ENABLE_MASK) == OA_CTL_ENABLE_ON); } /** * @brief Disable the OPA peripheral * * @param[in] opa Pointer to the register overlay for the peripheral */ __STATIC_INLINE void DL_OPA_disable(OA_Regs *opa) { opa->CTL &= ~(OA_CTL_ENABLE_MASK); } /** * @brief Initialize the OPA peripheral * * Initializes all the common configurable options for the OPA peripheral. Any * other custom configuration can be done after calling this API. The OPA is * not enabled in this API. * * @param[in] opa Pointer to the register overlay for the peripheral * @param[in] config Configuration for OPA peripheral */ __STATIC_INLINE void DL_OPA_init(OA_Regs *opa, const DL_OPA_Config *config) { DL_Common_updateReg(&opa->CFG, (uint32_t) config->choppingMode | (uint32_t) config->outputPinState | (uint32_t) config->pselChannel | (uint32_t) config->nselChannel | (uint32_t) config->mselChannel | (uint32_t) config->gain, OA_CFG_CHOP_MASK | OA_CFG_OUTPIN_MASK | OA_CFG_PSEL_MASK | OA_CFG_NSEL_MASK | OA_CFG_MSEL_MASK | OA_CFG_GAIN_MASK); } /** * @brief Set the gain bandwidth (GBW) * * @param[in] opa Pointer to the register overlay for the peripheral * @param[in] bandwidth The gain bandwidth to set. One of @ref DL_OPA_GBW * * * @pre The OPA must be ready (STAT.RDY == 1) before setting * this configuration. * */ __STATIC_INLINE void DL_OPA_setGainBandwidth( OA_Regs *opa, DL_OPA_GBW bandwidth) { opa->CFGBASE |= ((uint32_t) bandwidth); } /** * @brief Get the gain bandwidth (GBW) * * @param[in] opa Pointer to the register overlay for the peripheral * * @return The current gain bandwidth * * @retval One of @ref DL_OPA_GBW */ __STATIC_INLINE DL_OPA_GBW DL_OPA_getGainBandwidth(const OA_Regs *opa) { uint32_t bandwidth = (opa->CFGBASE & OA_CFGBASE_GBW_MASK); return (DL_OPA_GBW)(bandwidth); } /** * @brief Enable the rail-to-rail input (RRI) * * @param[in] opa Pointer to the register overlay for the peripheral * * * @pre The OPA must be ready (STAT.RDY == 1) before setting * this configuration. * */ __STATIC_INLINE void DL_OPA_enableRailToRailInput(OA_Regs *opa) { opa->CFGBASE |= OA_CFGBASE_RRI_ON; } /** * @brief Checks if the the rail-to-rail input (RRI) is enabled * * @param[in] opa Pointer to the register overlay for the peripheral * * @return Returns the rail-to-rail input status of the OPA * * @retval true The rail-to-rail input is enabled * @retval false The rail-to-rail input is disabled */ __STATIC_INLINE bool DL_OPA_isRailToRailInputEnabled(OA_Regs *opa) { return ((opa->CFGBASE &= OA_CFGBASE_RRI_MASK) == OA_CFGBASE_RRI_ON); } /** * @brief Disable the rail-to-rail input (RRI) * * @param[in] opa Pointer to the register overlay for the peripheral */ __STATIC_INLINE void DL_OPA_disableRailToRailInput(OA_Regs *opa) { opa->CFGBASE &= ~(OA_CFGBASE_RRI_MASK); } /** * @brief Set and enable the chopping mode * * @param[in] opa Pointer to the register overlay for the peripheral * @param[in] mode The chopping mode to set. * One of @ref DL_OPA_CHOPPING_MODE */ __STATIC_INLINE void DL_OPA_setChoppingMode( OA_Regs *opa, DL_OPA_CHOPPING_MODE mode) { DL_Common_updateReg(&opa->CFG, (uint32_t) mode, OA_CFG_CHOP_MASK); } /** * @brief Get the chopping mode * * @param[in] opa Pointer to the register overlay for the peripheral * * @return The current chopping mode * * @retval One of @ref DL_OPA_CHOPPING_MODE */ __STATIC_INLINE DL_OPA_CHOPPING_MODE DL_OPA_getChoppingMode(const OA_Regs *opa) { uint32_t mode = (opa->CFG & OA_CFG_CHOP_MASK); return (DL_OPA_CHOPPING_MODE)(mode); } /** * @brief Set the state of the output pin * * When the output pin is enabled, the OPA output goes to the device pin while * still maintaining connection to the programmable gain stage and other analog * peripherals. * When disabled, the OPA output is a purely internal signal and is internally * connected to the programmable gain stage and capable of being routed to * other on-board analog peripherals. * * @param[in] opa Pointer to the register overlay for the peripheral * @param[in] state The state to set the output pin to * One of @ref DL_OPA_OUTPUT_PIN_STATE */ __STATIC_INLINE void DL_OPA_setOutputPinState( OA_Regs *opa, DL_OPA_OUTPUT_PIN_STATE state) { DL_Common_updateReg(&opa->CFG, (uint32_t) state, OA_CFG_OUTPIN_MASK); } /** * @brief Get the state of the output pin * * When the output pin is enabled, the OPA output goes to the device pin while * still maintaining connection to the programmable gain stage and other analog * peripherals. * When disabled, the OPA output is a purely internal signal and is internally * connected to the programmable gain stage and capable of being routed to * other on-board analog peripherals. * * @param[in] opa Pointer to the register overlay for the peripheral * * @return The state of the output pin * * @retval One of @ref DL_OPA_OUTPUT_PIN_STATE */ __STATIC_INLINE DL_OPA_OUTPUT_PIN_STATE DL_OPA_getOutputPinState( const OA_Regs *opa) { uint32_t state = (opa->CFG & OA_CFG_OUTPIN_MASK); return (DL_OPA_OUTPUT_PIN_STATE)(state); } /** * @brief Disable the OPA output signal to be accessed by a device pin * * When disabled, the OPA output is a purely internal signal and is internally * connected to the programmable gain stage and capable of being routed to * other on-board analog peripherals. * * @param[in] opa Pointer to the register overlay for the peripheral */ __STATIC_INLINE void DL_OPA_disableOutputPin(OA_Regs *opa) { opa->CFG &= ~(OA_CFG_OUTPIN_MASK); } /** * @brief Set the non-inverting input channel * * This API sets the PSEL control bit to select the non-inverting input * channel of the amplifier. * * @param[in] opa Pointer to the register overlay for the peripheral * @param[in] inputChannel The non-inverting input channel to set. * One of @ref DL_OPA_PSEL. */ __STATIC_INLINE void DL_OPA_setNonInvertingInputChannel( OA_Regs *opa, DL_OPA_PSEL inputChannel) { DL_Common_updateReg(&opa->CFG, (uint32_t) inputChannel, OA_CFG_PSEL_MASK); } /** * @brief Get the non-inverting input channel * * @param[in] opa Pointer to the register overlay for the peripheral * * @return The current non-inverting input channel * * @retval One of @ref DL_OPA_PSEL */ __STATIC_INLINE DL_OPA_PSEL DL_OPA_getNonInvertingInputChannel( const OA_Regs *opa) { uint32_t inputChannel = (opa->CFG & OA_CFG_PSEL_MASK); return (DL_OPA_PSEL)(inputChannel); } /** * @brief Set the inverting input channel * * This API sets the NSEL control bit to select the inverting input * channel of the amplifier. * * @param[in] opa Pointer to the register overlay for the peripheral * @param[in] inputChannel The inverting input channel to set. * One of @ref DL_OPA_NSEL. */ __STATIC_INLINE void DL_OPA_setInvertingInputChannel( OA_Regs *opa, DL_OPA_NSEL inputChannel) { DL_Common_updateReg(&opa->CFG, (uint32_t) inputChannel, OA_CFG_NSEL_MASK); } /** * @brief Get the inverting input channel * * @param[in] opa Pointer to the register overlay for the peripheral * * @return The current inverting input channel * * @retval One of @ref DL_OPA_NSEL */ __STATIC_INLINE DL_OPA_NSEL DL_OPA_getInvertingInputChannel(const OA_Regs *opa) { uint32_t inputChannel = (opa->CFG & OA_CFG_NSEL_MASK); return (DL_OPA_NSEL)(inputChannel); } /** * @brief Set the M-MUX input channel * * This API sets the MSEL control bit to select the input channel for M-MUX, * which is connected to the programmable gain stage resistor ladder. * * @param[in] opa Pointer to the register overlay for the peripheral * @param[in] inputChannel The M-MUX input channel to set. * One of @ref DL_OPA_MSEL. */ __STATIC_INLINE void DL_OPA_setMMUXInputChannel( OA_Regs *opa, DL_OPA_MSEL inputChannel) { DL_Common_updateReg(&opa->CFG, (uint32_t) inputChannel, OA_CFG_MSEL_MASK); } /** * @brief Get the M-MUX input channel * * @param[in] opa Pointer to the register overlay for the peripheral * * @return The current M-MUX input channel * * @retval One of @ref DL_OPA_MSEL */ __STATIC_INLINE DL_OPA_MSEL DL_OPA_getMMUXInputChannel(const OA_Regs *opa) { uint32_t inputChannel = (opa->CFG & OA_CFG_MSEL_MASK); return (DL_OPA_MSEL)(inputChannel); } /** * @brief Set the gain for the programmable gain stage * * The OPA integrates a programmable gain stage in the feedback loop to * configure the OPA as a PGA(programmable gain amplifier). The gain stage * is a feedback resistance ladder and it supports up to 32x amplification. * * Refer to the TRM for gain enumeration information. * * @param[in] opa Pointer to the register overlay for the peripheral * @param[in] gain The gain to set. One of @ref DL_OPA_GAIN. */ __STATIC_INLINE void DL_OPA_setGain(OA_Regs *opa, DL_OPA_GAIN gain) { DL_Common_updateReg(&opa->CFG, (uint32_t) gain, OA_CFG_GAIN_MASK); } /** * @brief Get the gain from the programmable gain stage * * Refer to the TRM for gain enumeration information. * * @param[in] opa Pointer to the register overlay for the peripheral * * @return The gain * * @retval The gain. One of @ref DL_OPA_GAIN */ __STATIC_INLINE DL_OPA_GAIN DL_OPA_getGain(const OA_Regs *opa) { uint32_t gain = (opa->CFG & OA_CFG_GAIN_MASK); return (DL_OPA_GAIN)(gain); } /** * @brief Increment gain to the next @ref DL_OPA_GAIN enum value * * The OPA allows dynamic gain changes. If the gain is already at the maximum * setting DL_OPA_GAIN_N31_P32 (CFG.GAIN = 0x5), this function does nothing. * * Refer to the TRM for more information about changing gain dynamically. * * @param[in] opa Pointer to the register overlay for the peripheral * * @return The gain at the end of the operation. * * @retval The applied gain. One of @ref DL_OPA_GAIN */ DL_OPA_GAIN DL_OPA_increaseGain(OA_Regs *opa); /** * @brief Decrement gain to the next @ref DL_OPA_GAIN enum value * * The OPA allows dynamic gain changes. If the gain is at the minimum setting * DL_OPA_GAIN_N1_P2 (CFG.GAIN = 0x1), this function does nothing. * * Refer to the TRM for more information about changing gain dynamically. * * @param[in] opa Pointer to the register overlay for the peripheral * * @return The gain at the end of the operation. * * @retval The applied gain. One of @ref DL_OPA_GAIN */ DL_OPA_GAIN DL_OPA_decreaseGain(OA_Regs *opa); /** * @brief Checks if the OPA is ready * * @param[in] opa Pointer to the register overlay for the peripheral * * @return The status of the OPA ready bit * * @retval true The OPA is ready * @retval false The OPA is not ready * */ __STATIC_INLINE bool DL_OPA_isReady(const OA_Regs *opa) { return ((opa->STAT & OA_STAT_RDY_MASK) == OA_STAT_RDY_TRUE); } #ifdef __cplusplus } #endif #endif /* __MSPM0_HAS_OA__ */ #endif /* ti_dl_dl_opa__include */ /** @}*/