mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
targets/TARGET_Silicon_Labs/TARGET_EFM32/emlib/src/em_opamp.c
- Committer:
- AnnaBridge
- Date:
- 2019-02-20
- Revision:
- 189:f392fc9709a3
- Parent:
- 179:b0033dcd6934
File content as of revision 189:f392fc9709a3:
/***************************************************************************//** * @file em_opamp.c * @brief Operational Amplifier (OPAMP) peripheral API * @version 5.3.3 ****************************************************************************** * # License * <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b> ******************************************************************************* * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. * * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no * obligation to support this Software. Silicon Labs is providing the * Software "AS IS", with no express or implied warranties of any kind, * including, but not limited to, any implied warranties of merchantability * or fitness for any particular purpose or warranties against infringement * of any proprietary rights of a third party. * * Silicon Labs will not be liable for any consequential, incidental, or * special damages, or any other relief, or for any claim by any third party, * arising from your use of this Software. * ******************************************************************************/ #include "em_opamp.h" #if ((defined(_SILICON_LABS_32B_SERIES_0) && defined(OPAMP_PRESENT) && (OPAMP_COUNT == 1)) \ || (defined(_SILICON_LABS_32B_SERIES_1) && defined(VDAC_PRESENT) && (VDAC_COUNT > 0))) #include "em_system.h" #include "em_assert.h" /***************************************************************************//** * @addtogroup emlib * @{ ******************************************************************************/ /* *INDENT-OFF* */ /***************************************************************************//** * @addtogroup OPAMP * @brief Operational Amplifier (OPAMP) peripheral API * @details * This module contains functions to: * @li OPAMP_Enable() Configure and enable an opamp. * @li OPAMP_Disable() Disable an opamp. * * @if DOXYDOC_P1_DEVICE * All OPAMP functions assume that the DAC clock is running. If the DAC is not * used, the clock can be turned off when the opamp's are configured. * @elseif DOXYDOC_P2_DEVICE * All OPAMP functions assume that the VDAC clock is running. If the VDAC is not * used, the clock can be turned off when the opamp's are configured. * @endif * * If the available gain values dont suit the application at hand, the resistor * ladders can be disabled and external gain programming resistors used. * * A number of predefined opamp setup macros are available for configuration * of the most common opamp topologies (see figures below). * * @note * <em>The terms POSPAD and NEGPAD in the figures are used to indicate that these * pads should be connected to a suitable signal ground.</em> * * \n<b>Unity gain voltage follower.</b>\n * @if DOXYDOC_P1_DEVICE * Use predefined macros @ref OPA_INIT_UNITY_GAIN and * @ref OPA_INIT_UNITY_GAIN_OPA2. * @elseif DOXYDOC_P2_DEVICE * Use predefined macro @ref OPA_INIT_UNITY_GAIN. * @endif * @verbatim |\ ___________|+\ | \_______ ___|_ / | | | / | | |/ | |___________| @endverbatim * * \n<b>Non-inverting amplifier.</b>\n * @if DOXYDOC_P1_DEVICE * Use predefined macros @ref OPA_INIT_NON_INVERTING and * @ref OPA_INIT_NON_INVERTING_OPA2. * @elseif DOXYDOC_P2_DEVICE * Use predefined macro @ref OPA_INIT_NON_INVERTING. * @endif * @verbatim |\ ___________|+\ | \_______ ___|_ / | | | / | | |/ | |_____R2____| | R1 | NEGPAD @endverbatim * * \n<b>Inverting amplifier.</b>\n * @if DOXYDOC_P1_DEVICE * Use predefined macros @ref OPA_INIT_INVERTING and * @ref OPA_INIT_INVERTING_OPA2. * @elseif DOXYDOC_P2_DEVICE * Use predefined macro @ref OPA_INIT_INVERTING. * @endif * @verbatim _____R2____ | | | |\ | ____R1_|___|_\ | | \____|___ ___| / | |+/ | |/ | POSPAD @endverbatim * * \n<b>Cascaded non-inverting amplifiers.</b>\n * Use predefined macros @ref OPA_INIT_CASCADED_NON_INVERTING_OPA0, * @ref OPA_INIT_CASCADED_NON_INVERTING_OPA1 and * @ref OPA_INIT_CASCADED_NON_INVERTING_OPA2. * @verbatim |\ |\ |\ ___________|+\ OPA0 ___________|+\ OPA1 ___________|+\ OPA2 | \_________| | \_________| | \_______ ___|_ / | ___|_ / | ___|_ / | | | / | | | / | | | / | | |/ | | |/ | | |/ | |_____R2____| |_____R2____| |_____R2____| | | | R1 R1 R1 | | | NEGPAD NEGPAD NEGPAD @endverbatim * * \n<b>Cascaded inverting amplifiers.</b>\n * Use predefined macros @ref OPA_INIT_CASCADED_INVERTING_OPA0, * @ref OPA_INIT_CASCADED_INVERTING_OPA1 and * @ref OPA_INIT_CASCADED_INVERTING_OPA2. * @verbatim _____R2____ _____R2____ _____R2____ | | | | | | | |\ | | |\ | | |\ | ____R1_|___|_\ | ____R1_|___|_\ | ____R1_|___|_\ | | \____|____| | \____|___| | \____|__ ___| / ___| / ___| / | |+/ OPA0 | |+/ OPA1 | |+/ OPA2 | |/ | |/ | |/ | | | POSPAD POSPAD POSPAD @endverbatim * * \n<b>Differential driver with two opamp's.</b>\n * Use predefined macros @ref OPA_INIT_DIFF_DRIVER_OPA0 and * @ref OPA_INIT_DIFF_DRIVER_OPA1. * @verbatim __________________________ | + | _____R2____ |\ | | | ___________|+\ OPA0 | | |\ OPA1 | | \_________|____R1_|___|_\ | _ ___|_ / | | \____|______ | | / | ___| / | |/ | | |+/ |________________| | |/ | POSPAD @endverbatim * * \n<b>Differential receiver with three opamp's.</b>\n * Use predefined macros @ref OPA_INIT_DIFF_RECEIVER_OPA0, * @ref OPA_INIT_DIFF_RECEIVER_OPA1 and @ref OPA_INIT_DIFF_RECEIVER_OPA2. * @verbatim |\ __________|+\ OPA1 _ | \_________ ___|_ / | | _____R2____ | | / | | | | | |/ | | | |\ | |___________| |____R1_|___|_\ | | \____|___ |\ ____R1_ ___| / +__________|+\ OPA0 | | |+/ OPA2 | \_________| | |/ ___|_ / | R2 | | / | | | |/ | NEGPAD OPA0 |___________| @endverbatim * * @if DOXYDOC_P2_DEVICE * \n<b>Instrumentation amplifier.</b>\n * Use predefined macros @ref OPA_INIT_INSTR_AMP_OPA0 and * @ref OPA_INIT_INSTR_AMP_OPA1. * @verbatim |\ __________|+\ OPA1 | \______________ ___|_ / | | | / | | |/ R2 |____________| | R1 | R1 ____________| | | | R2 | |\ | |___|+\ OPA0 | | \_____|________ __________|_ / | / |/ @endverbatim * @endif * * @{ ******************************************************************************/ /* *INDENT-ON* */ /******************************************************************************* ************************** GLOBAL FUNCTIONS ******************************* ******************************************************************************/ /***************************************************************************//** * @brief * Disable an Operational Amplifier. * * @if DOXYDOC_P1_DEVICE * @param[in] dac * Pointer to DAC peripheral register block. * @elseif DOXYDOC_P2_DEVICE * @param[in] dac * Pointer to VDAC peripheral register block. * @endif * * * @param[in] opa * Selects an OPA, valid vaules are @ref OPA0, @ref OPA1 and @ref OPA2. ******************************************************************************/ void OPAMP_Disable( #if defined(_SILICON_LABS_32B_SERIES_0) DAC_TypeDef *dac, #elif defined(_SILICON_LABS_32B_SERIES_1) VDAC_TypeDef *dac, #endif OPAMP_TypeDef opa) { #if defined(_SILICON_LABS_32B_SERIES_0) EFM_ASSERT(DAC_REF_VALID(dac)); EFM_ASSERT(DAC_OPA_VALID(opa)); if (opa == OPA0) { dac->CH0CTRL &= ~DAC_CH0CTRL_EN; dac->OPACTRL &= ~DAC_OPACTRL_OPA0EN; } else if (opa == OPA1) { dac->CH1CTRL &= ~DAC_CH1CTRL_EN; dac->OPACTRL &= ~DAC_OPACTRL_OPA1EN; } else { /* OPA2 */ dac->OPACTRL &= ~DAC_OPACTRL_OPA2EN; } #elif defined(_SILICON_LABS_32B_SERIES_1) EFM_ASSERT(VDAC_REF_VALID(dac)); EFM_ASSERT(VDAC_OPA_VALID(opa)); if (opa == OPA0) { #if defined(VDAC_STATUS_OPA0ENS) dac->CMD |= VDAC_CMD_OPA0DIS; while (dac->STATUS & VDAC_STATUS_OPA0ENS) { } #endif } else if (opa == OPA1) { #if defined(VDAC_STATUS_OPA1ENS) dac->CMD |= VDAC_CMD_OPA1DIS; while (dac->STATUS & VDAC_STATUS_OPA1ENS) { } #endif } else { /* OPA2 */ #if defined(VDAC_STATUS_OPA2ENS) dac->CMD |= VDAC_CMD_OPA2DIS; while (dac->STATUS & VDAC_STATUS_OPA2ENS) { } #endif } #endif } /***************************************************************************//** * @brief * Configure and enable an Operational Amplifier. * * @if DOXYDOC_P1_DEVICE * @note * The value of the alternate output enable bit mask in the OPAMP_Init_TypeDef * structure should consist of one or more of the * DAC_OPA[opa#]MUX_OUTPEN_OUT[output#] flags * (defined in \<part_name\>_dac.h) OR'ed together. @n @n * For OPA0: * @li DAC_OPA0MUX_OUTPEN_OUT0 * @li DAC_OPA0MUX_OUTPEN_OUT1 * @li DAC_OPA0MUX_OUTPEN_OUT2 * @li DAC_OPA0MUX_OUTPEN_OUT3 * @li DAC_OPA0MUX_OUTPEN_OUT4 * * For OPA1: * @li DAC_OPA1MUX_OUTPEN_OUT0 * @li DAC_OPA1MUX_OUTPEN_OUT1 * @li DAC_OPA1MUX_OUTPEN_OUT2 * @li DAC_OPA1MUX_OUTPEN_OUT3 * @li DAC_OPA1MUX_OUTPEN_OUT4 * * For OPA2: * @li DAC_OPA2MUX_OUTPEN_OUT0 * @li DAC_OPA2MUX_OUTPEN_OUT1 * * E.g: @n * init.outPen = DAC_OPA0MUX_OUTPEN_OUT0 | DAC_OPA0MUX_OUTPEN_OUT4; * * @param[in] dac * Pointer to DAC peripheral register block. * @elseif DOXYDOC_P2_DEVICE * @note * The value of the alternate output enable bit mask in the OPAMP_Init_TypeDef * structure should consist of one or more of the * VDAC_OPA_OUT_ALTOUTPADEN_OUT[output#] flags * (defined in \<part_name\>_vdac.h) OR'ed together. @n @n * @li VDAC_OPA_OUT_ALTOUTPADEN_OUT0 * @li VDAC_OPA_OUT_ALTOUTPADEN_OUT1 * @li VDAC_OPA_OUT_ALTOUTPADEN_OUT2 * @li VDAC_OPA_OUT_ALTOUTPADEN_OUT3 * @li VDAC_OPA_OUT_ALTOUTPADEN_OUT4 * * E.g: @n * init.outPen = VDAC_OPA_OUT_ALTOUTPADEN_OUT0 | VDAC_OPA_OUT_ALTOUTPADEN_OUT4; * @param[in] dac * Pointer to VDAC peripheral register block. * @endif * * @param[in] opa * Selects an OPA, valid vaules are @ref OPA0, @ref OPA1 and @ref OPA2. * * @param[in] init * Pointer to a structure containing OPAMP init information. ******************************************************************************/ void OPAMP_Enable( #if defined(_SILICON_LABS_32B_SERIES_0) DAC_TypeDef *dac, #elif defined(_SILICON_LABS_32B_SERIES_1) VDAC_TypeDef *dac, #endif OPAMP_TypeDef opa, const OPAMP_Init_TypeDef *init) { #if defined(_SILICON_LABS_32B_SERIES_0) uint32_t gain; EFM_ASSERT(DAC_REF_VALID(dac)); EFM_ASSERT(DAC_OPA_VALID(opa)); EFM_ASSERT(init->bias <= (_DAC_BIASPROG_BIASPROG_MASK >> _DAC_BIASPROG_BIASPROG_SHIFT)); if (opa == OPA0) { EFM_ASSERT((init->outPen & ~_DAC_OPA0MUX_OUTPEN_MASK) == 0); dac->BIASPROG = (dac->BIASPROG & ~(_DAC_BIASPROG_BIASPROG_MASK | DAC_BIASPROG_HALFBIAS)) | (init->bias << _DAC_BIASPROG_BIASPROG_SHIFT) | (init->halfBias ? DAC_BIASPROG_HALFBIAS : 0); if (init->defaultOffset) { gain = dac->CAL & _DAC_CAL_GAIN_MASK; SYSTEM_GetCalibrationValue(&dac->CAL); dac->CAL = (dac->CAL & ~_DAC_CAL_GAIN_MASK) | gain; } else { EFM_ASSERT(init->offset <= (_DAC_CAL_CH0OFFSET_MASK >> _DAC_CAL_CH0OFFSET_SHIFT)); dac->CAL = (dac->CAL & ~_DAC_CAL_CH0OFFSET_MASK) | (init->offset << _DAC_CAL_CH0OFFSET_SHIFT); } dac->OPA0MUX = (uint32_t)init->resSel | (uint32_t)init->outMode | init->outPen | (uint32_t)init->resInMux | (uint32_t)init->negSel | (uint32_t)init->posSel | (init->nextOut ? DAC_OPA0MUX_NEXTOUT : 0) | (init->npEn ? DAC_OPA0MUX_NPEN : 0) | (init->ppEn ? DAC_OPA0MUX_PPEN : 0); dac->CH0CTRL |= DAC_CH0CTRL_EN; dac->OPACTRL = (dac->OPACTRL & ~(DAC_OPACTRL_OPA0SHORT | _DAC_OPACTRL_OPA0LPFDIS_MASK | DAC_OPACTRL_OPA0HCMDIS)) | (init->shortInputs ? DAC_OPACTRL_OPA0SHORT : 0) | (init->lpfPosPadDisable ? DAC_OPACTRL_OPA0LPFDIS_PLPFDIS : 0) | (init->lpfNegPadDisable ? DAC_OPACTRL_OPA0LPFDIS_NLPFDIS : 0) | (init->hcmDisable ? DAC_OPACTRL_OPA0HCMDIS : 0) | DAC_OPACTRL_OPA0EN; } else if ( opa == OPA1 ) { EFM_ASSERT((init->outPen & ~_DAC_OPA1MUX_OUTPEN_MASK) == 0); dac->BIASPROG = (dac->BIASPROG & ~(_DAC_BIASPROG_BIASPROG_MASK | DAC_BIASPROG_HALFBIAS)) | (init->bias << _DAC_BIASPROG_BIASPROG_SHIFT) | (init->halfBias ? DAC_BIASPROG_HALFBIAS : 0); if (init->defaultOffset) { gain = dac->CAL & _DAC_CAL_GAIN_MASK; SYSTEM_GetCalibrationValue(&dac->CAL); dac->CAL = (dac->CAL & ~_DAC_CAL_GAIN_MASK) | gain; } else { EFM_ASSERT(init->offset <= (_DAC_CAL_CH1OFFSET_MASK >> _DAC_CAL_CH1OFFSET_SHIFT)); dac->CAL = (dac->CAL & ~_DAC_CAL_CH1OFFSET_MASK) | (init->offset << _DAC_CAL_CH1OFFSET_SHIFT); } dac->OPA1MUX = (uint32_t)init->resSel | (uint32_t)init->outMode | init->outPen | (uint32_t)init->resInMux | (uint32_t)init->negSel | (uint32_t)init->posSel | (init->nextOut ? DAC_OPA1MUX_NEXTOUT : 0) | (init->npEn ? DAC_OPA1MUX_NPEN : 0) | (init->ppEn ? DAC_OPA1MUX_PPEN : 0); dac->CH1CTRL |= DAC_CH1CTRL_EN; dac->OPACTRL = (dac->OPACTRL & ~(DAC_OPACTRL_OPA1SHORT | _DAC_OPACTRL_OPA1LPFDIS_MASK | DAC_OPACTRL_OPA1HCMDIS)) | (init->shortInputs ? DAC_OPACTRL_OPA1SHORT : 0) | (init->lpfPosPadDisable ? DAC_OPACTRL_OPA1LPFDIS_PLPFDIS : 0) | (init->lpfNegPadDisable ? DAC_OPACTRL_OPA1LPFDIS_NLPFDIS : 0) | (init->hcmDisable ? DAC_OPACTRL_OPA1HCMDIS : 0) | DAC_OPACTRL_OPA1EN; } else { /* OPA2 */ EFM_ASSERT((init->posSel == DAC_OPA2MUX_POSSEL_DISABLE) || (init->posSel == DAC_OPA2MUX_POSSEL_POSPAD) || (init->posSel == DAC_OPA2MUX_POSSEL_OPA1INP) || (init->posSel == DAC_OPA2MUX_POSSEL_OPATAP)); EFM_ASSERT((init->outMode & ~DAC_OPA2MUX_OUTMODE) == 0); EFM_ASSERT((init->outPen & ~_DAC_OPA2MUX_OUTPEN_MASK) == 0); dac->BIASPROG = (dac->BIASPROG & ~(_DAC_BIASPROG_OPA2BIASPROG_MASK | DAC_BIASPROG_OPA2HALFBIAS)) | (init->bias << _DAC_BIASPROG_OPA2BIASPROG_SHIFT) | (init->halfBias ? DAC_BIASPROG_OPA2HALFBIAS : 0); if (init->defaultOffset) { SYSTEM_GetCalibrationValue(&dac->OPAOFFSET); } else { EFM_ASSERT(init->offset <= (_DAC_OPAOFFSET_OPA2OFFSET_MASK >> _DAC_OPAOFFSET_OPA2OFFSET_SHIFT)); dac->OPAOFFSET = (dac->OPAOFFSET & ~_DAC_OPAOFFSET_OPA2OFFSET_MASK) | (init->offset << _DAC_OPAOFFSET_OPA2OFFSET_SHIFT); } dac->OPA2MUX = (uint32_t)init->resSel | (uint32_t)init->outMode | init->outPen | (uint32_t)init->resInMux | (uint32_t)init->negSel | (uint32_t)init->posSel | (init->nextOut ? DAC_OPA2MUX_NEXTOUT : 0) | (init->npEn ? DAC_OPA2MUX_NPEN : 0) | (init->ppEn ? DAC_OPA2MUX_PPEN : 0); dac->OPACTRL = (dac->OPACTRL & ~(DAC_OPACTRL_OPA2SHORT | _DAC_OPACTRL_OPA2LPFDIS_MASK | DAC_OPACTRL_OPA2HCMDIS)) | (init->shortInputs ? DAC_OPACTRL_OPA2SHORT : 0) | (init->lpfPosPadDisable ? DAC_OPACTRL_OPA2LPFDIS_PLPFDIS : 0) | (init->lpfNegPadDisable ? DAC_OPACTRL_OPA2LPFDIS_NLPFDIS : 0) | (init->hcmDisable ? DAC_OPACTRL_OPA2HCMDIS : 0) | DAC_OPACTRL_OPA2EN; } #elif defined(_SILICON_LABS_32B_SERIES_1) uint32_t calData = 0; uint32_t warmupTime; EFM_ASSERT(VDAC_REF_VALID(dac)); EFM_ASSERT(VDAC_OPA_VALID(opa)); EFM_ASSERT(init->settleTime <= (_VDAC_OPA_TIMER_SETTLETIME_MASK >> _VDAC_OPA_TIMER_SETTLETIME_SHIFT)); EFM_ASSERT(init->startupDly <= (_VDAC_OPA_TIMER_STARTUPDLY_MASK >> _VDAC_OPA_TIMER_STARTUPDLY_SHIFT)); EFM_ASSERT((init->outPen & ~_VDAC_OPA_OUT_ALTOUTPADEN_MASK) == 0); EFM_ASSERT(!((init->gain3xEn == true) && ((init->negSel == opaNegSelResTap) || (init->posSel == opaPosSelResTap)))); EFM_ASSERT((init->drvStr == opaDrvStrLowerAccLowStr) || (init->drvStr == opaDrvStrLowAccLowStr) || (init->drvStr == opaDrvStrHighAccHighStr) || (init->drvStr == opaDrvStrHigherAccHighStr)); /* Disable OPAMP before writing to registers. */ OPAMP_Disable(dac, opa); /* Get the calibration value based on OPAMP, Drive Strength, and INCBW. */ switch (opa) { #if defined(VDAC_STATUS_OPA0ENS) case OPA0: switch (init->drvStr) { case opaDrvStrLowerAccLowStr: calData = (init->ugBwScale ? DEVINFO->OPA0CAL0 : DEVINFO->OPA0CAL4); break; case opaDrvStrLowAccLowStr: calData = (init->ugBwScale ? DEVINFO->OPA0CAL1 : DEVINFO->OPA0CAL5); break; case opaDrvStrHighAccHighStr: calData = (init->ugBwScale ? DEVINFO->OPA0CAL2 : DEVINFO->OPA0CAL6); break; case opaDrvStrHigherAccHighStr: calData = (init->ugBwScale ? DEVINFO->OPA0CAL3 : DEVINFO->OPA0CAL7); break; } break; #endif #if defined(VDAC_STATUS_OPA1ENS) case OPA1: switch (init->drvStr) { case opaDrvStrLowerAccLowStr: calData = (init->ugBwScale ? DEVINFO->OPA1CAL0 : DEVINFO->OPA1CAL4); break; case opaDrvStrLowAccLowStr: calData = (init->ugBwScale ? DEVINFO->OPA1CAL1 : DEVINFO->OPA1CAL5); break; case opaDrvStrHighAccHighStr: calData = (init->ugBwScale ? DEVINFO->OPA1CAL2 : DEVINFO->OPA1CAL6); break; case opaDrvStrHigherAccHighStr: calData = (init->ugBwScale ? DEVINFO->OPA1CAL3 : DEVINFO->OPA1CAL7); break; } break; #endif #if defined(VDAC_STATUS_OPA2ENS) case OPA2: switch (init->drvStr) { case opaDrvStrLowerAccLowStr: calData = (init->ugBwScale ? DEVINFO->OPA2CAL0 : DEVINFO->OPA2CAL4); break; case opaDrvStrLowAccLowStr: calData = (init->ugBwScale ? DEVINFO->OPA2CAL1 : DEVINFO->OPA2CAL5); break; case opaDrvStrHighAccHighStr: calData = (init->ugBwScale ? DEVINFO->OPA2CAL2 : DEVINFO->OPA2CAL6); break; case opaDrvStrHigherAccHighStr: calData = (init->ugBwScale ? DEVINFO->OPA2CAL3 : DEVINFO->OPA2CAL7); break; } break; #endif } if (!init->defaultOffsetN) { EFM_ASSERT(init->offsetN <= (_VDAC_OPA_CAL_OFFSETN_MASK >> _VDAC_OPA_CAL_OFFSETN_SHIFT)); calData = (calData & ~_VDAC_OPA_CAL_OFFSETN_MASK) | (init->offsetN << _VDAC_OPA_CAL_OFFSETN_SHIFT); } if (!init->defaultOffsetP) { EFM_ASSERT(init->offsetP <= (_VDAC_OPA_CAL_OFFSETP_MASK >> _VDAC_OPA_CAL_OFFSETP_SHIFT)); calData = (calData & ~_VDAC_OPA_CAL_OFFSETP_MASK) | (init->offsetP << _VDAC_OPA_CAL_OFFSETP_SHIFT); } dac->OPA[opa].CAL = (calData & _VDAC_OPA_CAL_MASK); dac->OPA[opa].MUX = (uint32_t)init->resSel | (init->gain3xEn ? VDAC_OPA_MUX_GAIN3X : 0) | (uint32_t)init->resInMux | (uint32_t)init->negSel | (uint32_t)init->posSel; dac->OPA[opa].OUT = (uint32_t)init->outMode | (uint32_t)init->outPen; switch (init->drvStr) { case opaDrvStrHigherAccHighStr: warmupTime = 6; break; case opaDrvStrHighAccHighStr: warmupTime = 8; break; case opaDrvStrLowAccLowStr: warmupTime = 85; break; case opaDrvStrLowerAccLowStr: default: warmupTime = 100; break; } dac->OPA[opa].TIMER = (uint32_t)(init->settleTime << _VDAC_OPA_TIMER_SETTLETIME_SHIFT) | (uint32_t)(warmupTime << _VDAC_OPA_TIMER_WARMUPTIME_SHIFT) | (uint32_t)(init->startupDly << _VDAC_OPA_TIMER_STARTUPDLY_SHIFT); dac->OPA[opa].CTRL = (init->aportYMasterDisable ? VDAC_OPA_CTRL_APORTYMASTERDIS : 0) | (init->aportXMasterDisable ? VDAC_OPA_CTRL_APORTXMASTERDIS : 0) | (uint32_t)init->prsOutSel | (uint32_t)init->prsSel | (uint32_t)init->prsMode | (init->prsEn ? VDAC_OPA_CTRL_PRSEN : 0) | (init->halfDrvStr ? VDAC_OPA_CTRL_OUTSCALE_HALF : VDAC_OPA_CTRL_OUTSCALE_FULL) | (init->hcmDisable ? VDAC_OPA_CTRL_HCMDIS : 0) | (init->ugBwScale ? VDAC_OPA_CTRL_INCBW : 0) | (uint32_t)init->drvStr; if (opa == OPA0) { #if defined(VDAC_STATUS_OPA0ENS) dac->CMD |= VDAC_CMD_OPA0EN; #endif } else if (opa == OPA1) { #if defined(VDAC_STATUS_OPA1ENS) dac->CMD |= VDAC_CMD_OPA1EN; #endif } else { /* OPA2 */ #if defined(VDAC_STATUS_OPA2ENS) dac->CMD |= VDAC_CMD_OPA2EN; #endif } #endif } /** @} (end addtogroup OPAMP) */ /** @} (end addtogroup emlib) */ #endif /* (defined(OPAMP_PRESENT) && (OPAMP_COUNT == 1) || defined(VDAC_PRESENT) && (VDAC_COUNT > 0) */