added prescaler for 16 bit pwm in LPC1347 target
Fork of mbed-dev by
Diff: targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/emlib/src/em_opamp.c
- Revision:
- 0:9b334a45a8ff
- Child:
- 50:a417edff4437
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/emlib/src/em_opamp.c Thu Oct 01 15:25:22 2015 +0300 @@ -0,0 +1,431 @@ +/**************************************************************************//** + * @file em_opamp.c + * @brief Operational Amplifier (OPAMP) peripheral API + * @version 3.20.12 + ****************************************************************************** + * @section License + * <b>(C) Copyright 2014 Silicon Labs, 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_device.h" +#if defined( OPAMP_PRESENT ) && ( OPAMP_COUNT == 1 ) + +#include "em_system.h" +#include "em_assert.h" +#include "em_opamp.h" + +/***************************************************************************//** + * @addtogroup EM_Library + * @{ + ******************************************************************************/ + + +/***************************************************************************//** + * @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. + * + * 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. + * + * 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 + * Use predefined macros @ref OPA_INIT_UNITY_GAIN and + * @ref OPA_INIT_UNITY_GAIN_OPA2. + * @verbatim + + |\ + ___________|+\ + | \_______ + ___|_ / | + | | / | + | |/ | + |___________| + @endverbatim + * + * \n<b>Non-inverting amplifier.</b>\n + * Use predefined macros @ref OPA_INIT_NON_INVERTING and + * @ref OPA_INIT_NON_INVERTING_OPA2. + * @verbatim + + |\ + ___________|+\ + | \_______ + ___|_ / | + | | / | + | |/ | + |_____R2____| + | + R1 + | + NEGPAD @endverbatim + * + * \n<b>Inverting amplifier.</b>\n + * Use predefined macros @ref OPA_INIT_INVERTING and + * @ref OPA_INIT_INVERTING_OPA2. + * @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 + * + * @{ + ******************************************************************************/ + +/******************************************************************************* + ************************** GLOBAL FUNCTIONS ******************************* + ******************************************************************************/ + +/***************************************************************************//** + * @brief + * Disable an Operational Amplifier. + * + * @param[in] dac + * Pointer to DAC peripheral register block. + * + * @param[in] opa + * Selects an OPA, valid vaules are @ref OPA0, @ref OPA1 and @ref OPA2. + ******************************************************************************/ +void OPAMP_Disable( DAC_TypeDef *dac, OPAMP_TypeDef opa ) +{ + 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; + } +} + + +/***************************************************************************//** + * @brief + * Configure and enable an Operational Amplifier. + * + * @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. + * + * @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( DAC_TypeDef *dac, OPAMP_TypeDef opa, const OPAMP_Init_TypeDef *init ) +{ + uint32_t offset; + + 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 ) + { + offset = SYSTEM_GetCalibrationValue( &dac->CAL ); + dac->CAL = ( dac->CAL & ~_DAC_CAL_CH0OFFSET_MASK ) | + ( offset & _DAC_CAL_CH0OFFSET_MASK ); + } + 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 ) + { + offset = SYSTEM_GetCalibrationValue( &dac->CAL ); + dac->CAL = ( dac->CAL & ~_DAC_CAL_CH1OFFSET_MASK ) | + ( offset & _DAC_CAL_CH1OFFSET_MASK ); + } + 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 ) + { + offset = SYSTEM_GetCalibrationValue( &dac->OPAOFFSET ); + dac->OPAOFFSET = ( dac->OPAOFFSET & ~_DAC_OPAOFFSET_OPA2OFFSET_MASK ) | + ( offset & _DAC_OPAOFFSET_OPA2OFFSET_MASK ); + } + 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 ); + } +} + +/** @} (end addtogroup OPAMP) */ +/** @} (end addtogroup EM_Library) */ + +#endif /* defined( OPAMP_PRESENT ) && ( OPAMP_COUNT == 1 ) */