Initial commit of firmware
This commit is contained in:
700
Libs/platform/emlib/src/em_opamp.c
Normal file
700
Libs/platform/emlib/src/em_opamp.c
Normal file
@@ -0,0 +1,700 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Operational Amplifier (OPAMP) peripheral API
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* 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. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#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 "sl_assert.h"
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
/***************************************************************************//**
|
||||
* @addtogroup opamp OPAMP - Operational Amplifier
|
||||
* @brief Operational Amplifier (OPAMP) peripheral API
|
||||
* @details
|
||||
* This module contains functions to:
|
||||
* @li OPAMP_Enable() Configure and enable OPAMP.
|
||||
* @li OPAMP_Disable() Disable OPAMP.
|
||||
*
|
||||
* @if DOXYDOC_P1_DEVICE
|
||||
* All OPAMP functions assume that the DAC clock is running. If DAC is not
|
||||
* used, the clock can be turned off when OPAMPs are configured.
|
||||
* @elseif DOXYDOC_P2_DEVICE
|
||||
* All OPAMP functions assume that the VDAC clock is running. If VDAC is not
|
||||
* used, the clock can be turned off when the OPAMPs are configured.
|
||||
* @endif
|
||||
*
|
||||
* If the available gain values don't 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
|
||||
* A pointer to the DAC peripheral register block.
|
||||
* @elseif DOXYDOC_P2_DEVICE
|
||||
* @param[in] dac
|
||||
* A pointer to the VDAC peripheral register block.
|
||||
* @endif
|
||||
*
|
||||
* @param[in] opa
|
||||
* Selects an OPA, valid values are OPA0, OPA1, and 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
|
||||
#if defined(VDAC_STATUS_OPA1ENS)
|
||||
} else if (opa == OPA1) {
|
||||
dac->CMD |= VDAC_CMD_OPA1DIS;
|
||||
while (dac->STATUS & VDAC_STATUS_OPA1ENS) {
|
||||
}
|
||||
#endif
|
||||
#if defined(VDAC_STATUS_OPA2ENS)
|
||||
} else if (opa == OPA2) {
|
||||
dac->CMD |= VDAC_CMD_OPA2DIS;
|
||||
while (dac->STATUS & VDAC_STATUS_OPA2ENS) {
|
||||
}
|
||||
#endif
|
||||
} else { /* OPA3 */
|
||||
#if defined(VDAC_STATUS_OPA3ENS)
|
||||
dac->CMD |= VDAC_CMD_OPA3DIS;
|
||||
while (dac->STATUS & VDAC_STATUS_OPA3ENS) {
|
||||
}
|
||||
#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
|
||||
* A pointer to the 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
|
||||
*
|
||||
* For example: @n
|
||||
* init.outPen = VDAC_OPA_OUT_ALTOUTPADEN_OUT0 | VDAC_OPA_OUT_ALTOUTPADEN_OUT4;
|
||||
* @param[in] dac
|
||||
* A pointer to the VDAC peripheral register block.
|
||||
* @endif
|
||||
*
|
||||
* @param[in] opa
|
||||
* Selects an OPA, valid values are OPA0, OPA1, and OPA2.
|
||||
*
|
||||
* @param[in] init
|
||||
* A pointer to a structure containing OPAMP initialization 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->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 defined(VDAC_STATUS_OPA3ENS)
|
||||
case OPA3:
|
||||
switch (init->drvStr) {
|
||||
case opaDrvStrLowerAccLowStr:
|
||||
calData = (init->ugBwScale ? DEVINFO->OPA3CAL0 : DEVINFO->OPA3CAL4);
|
||||
break;
|
||||
case opaDrvStrLowAccLowStr:
|
||||
calData = (init->ugBwScale ? DEVINFO->OPA3CAL1 : DEVINFO->OPA3CAL5);
|
||||
break;
|
||||
case opaDrvStrHighAccHighStr:
|
||||
calData = (init->ugBwScale ? DEVINFO->OPA3CAL2 : DEVINFO->OPA3CAL6);
|
||||
break;
|
||||
case opaDrvStrHigherAccHighStr:
|
||||
calData = (init->ugBwScale ? DEVINFO->OPA3CAL3 : DEVINFO->OPA3CAL7);
|
||||
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
|
||||
#if defined(VDAC_STATUS_OPA1ENS)
|
||||
} else if (opa == OPA1) {
|
||||
dac->CMD |= VDAC_CMD_OPA1EN;
|
||||
#endif
|
||||
#if defined(VDAC_STATUS_OPA2ENS)
|
||||
} else if (opa == OPA2) {
|
||||
dac->CMD |= VDAC_CMD_OPA2EN;
|
||||
#endif
|
||||
#if defined(VDAC_STATUS_OPA3ENS)
|
||||
} else { /* OPA3 */
|
||||
dac->CMD |= VDAC_CMD_OPA3EN;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @} (end addtogroup opamp) */
|
||||
|
||||
#endif /* (defined(OPAMP_PRESENT) && (OPAMP_COUNT == 1)
|
||||
|| defined(VDAC_PRESENT) && (VDAC_COUNT > 0) */
|
||||
Reference in New Issue
Block a user