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_idac.c
- Revision:
- 144:ef7eb2e8f9f7
- Parent:
- 50:a417edff4437
diff -r 423e1876dc07 -r ef7eb2e8f9f7 targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/emlib/src/em_idac.c --- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/emlib/src/em_idac.c Tue Aug 02 14:07:36 2016 +0000 +++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/emlib/src/em_idac.c Fri Sep 02 15:07:44 2016 +0100 @@ -1,372 +1,372 @@ -/***************************************************************************//** - * @file em_idac.c - * @brief Current Digital to Analog Converter (IDAC) peripheral API - * @version 4.2.1 - ******************************************************************************* - * @section License - * <b>(C) Copyright 2015 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_idac.h" -#if defined(IDAC_COUNT) && (IDAC_COUNT > 0) -#include "em_cmu.h" -#include "em_assert.h" -#include "em_bus.h" - -/***************************************************************************//** - * @addtogroup EM_Library - * @{ - ******************************************************************************/ - -/***************************************************************************//** - * @addtogroup IDAC - * @brief Current Digital to Analog Conversion (IDAC) Peripheral API - * @{ - ******************************************************************************/ - -/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */ -/* Fix for errata IDAC_E101 - IDAC output current degradation */ -#if defined(_EFM32_ZERO_FAMILY) || defined(_EFM32_HAPPY_FAMILY) -#define ERRATA_FIX_IDAC_E101_EN -#endif -/** @endcond */ - -/******************************************************************************* - ************************** GLOBAL FUNCTIONS ******************************* - ******************************************************************************/ -/***************************************************************************//** - * @brief - * Initialize IDAC. - * - * @details - * Initializes IDAC according to the initialization structure parameter, and - * sets the default calibration value stored in the DEVINFO structure. - * - * @note - * This function will disable the IDAC prior to configuration. - * - * @param[in] idac - * Pointer to IDAC peripheral register block. - * - * @param[in] init - * Pointer to IDAC initialization structure. - ******************************************************************************/ -void IDAC_Init(IDAC_TypeDef *idac, const IDAC_Init_TypeDef *init) -{ - uint32_t tmp; - - EFM_ASSERT(IDAC_REF_VALID(idac)); - - tmp = (uint32_t)(init->prsSel); - - tmp |= init->outMode; - - if (init->enable) - { - tmp |= IDAC_CTRL_EN; - } - if (init->prsEnable) - { - tmp |= IDAC_CTRL_OUTENPRS; - } - if (init->sinkEnable) - { - tmp |= IDAC_CTRL_CURSINK; - } - - idac->CTRL = tmp; -} - - -/***************************************************************************//** - * @brief - * Enable/disable IDAC. - * - * @param[in] idac - * Pointer to IDAC peripheral register block. - * - * @param[in] enable - * true to enable IDAC, false to disable. - ******************************************************************************/ -void IDAC_Enable(IDAC_TypeDef *idac, bool enable) -{ - volatile uint32_t *reg; - - EFM_ASSERT(IDAC_REF_VALID(idac)); - - reg = &(idac->CTRL); - - BUS_RegBitWrite(reg, _IDAC_CTRL_EN_SHIFT, enable); -} - - -/***************************************************************************//** - * @brief - * Reset IDAC to same state as after a HW reset. - * - * @param[in] idac - * Pointer to IDAC peripheral register block. - ******************************************************************************/ -void IDAC_Reset(IDAC_TypeDef *idac) -{ - EFM_ASSERT(IDAC_REF_VALID(idac)); - -#if defined(ERRATA_FIX_IDAC_E101_EN) - /* Fix for errata IDAC_E101 - IDAC output current degradation: - Instead of disabling it we will put it in it's lowest power state (50 nA) - to avoid degradation over time */ - - /* Make sure IDAC is enabled with disabled output */ - idac->CTRL = _IDAC_CTRL_RESETVALUE | IDAC_CTRL_EN; - - /* Set lowest current (50 nA) */ - idac->CURPROG = IDAC_CURPROG_RANGESEL_RANGE0 | - (0x0 << _IDAC_CURPROG_STEPSEL_SHIFT); - - /* Enable duty-cycling for all energy modes */ - idac->DUTYCONFIG = IDAC_DUTYCONFIG_DUTYCYCLEEN; -#else - idac->CTRL = _IDAC_CTRL_RESETVALUE; - idac->CURPROG = _IDAC_CURPROG_RESETVALUE; - idac->DUTYCONFIG = _IDAC_DUTYCONFIG_RESETVALUE; -#endif -#if defined ( _IDAC_CAL_MASK ) - idac->CAL = _IDAC_CAL_RESETVALUE; -#endif -} - - -/***************************************************************************//** - * @brief - * Enable/disable Minimal Output Transition mode. - * - * @param[in] idac - * Pointer to IDAC peripheral register block. - * - * @param[in] enable - * true to enable Minimal Output Transition mode, false to disable. - ******************************************************************************/ -void IDAC_MinimalOutputTransitionMode(IDAC_TypeDef *idac, bool enable) -{ - volatile uint32_t *reg; - - EFM_ASSERT(IDAC_REF_VALID(idac)); - - reg = &(idac->CTRL); - - BUS_RegBitWrite(reg, _IDAC_CTRL_MINOUTTRANS_SHIFT, enable); -} - - -/***************************************************************************//** - * @brief - * Set the current range of the IDAC output. - * - * @details - * This function sets the current range of the IDAC output. The function - * also updates the IDAC calibration register (IDAC_CAL) with the default - * calibration value (from DEVINFO, factory setting) corresponding to the - * specified range. - * - * @param[in] idac - * Pointer to IDAC peripheral register block. - * - * @param[in] range - * Current range value. - ******************************************************************************/ -void IDAC_RangeSet(IDAC_TypeDef *idac, const IDAC_Range_TypeDef range) -{ - uint32_t tmp; -#if defined( _IDAC_CURPROG_TUNING_MASK ) - uint32_t diCal0; - uint32_t diCal1; -#endif - - EFM_ASSERT(IDAC_REF_VALID(idac)); - EFM_ASSERT(((uint32_t)range >> _IDAC_CURPROG_RANGESEL_SHIFT) - <= (_IDAC_CURPROG_RANGESEL_MASK >> _IDAC_CURPROG_RANGESEL_SHIFT)); - -#if defined ( _IDAC_CAL_MASK ) - - /* Load proper calibration data depending on selected range */ - switch ((IDAC_Range_TypeDef)range) - { - case idacCurrentRange0: - idac->CAL = (DEVINFO->IDAC0CAL0 & _DEVINFO_IDAC0CAL0_RANGE0_MASK) - >> _DEVINFO_IDAC0CAL0_RANGE0_SHIFT; - break; - case idacCurrentRange1: - idac->CAL = (DEVINFO->IDAC0CAL0 & _DEVINFO_IDAC0CAL0_RANGE1_MASK) - >> _DEVINFO_IDAC0CAL0_RANGE1_SHIFT; - break; - case idacCurrentRange2: - idac->CAL = (DEVINFO->IDAC0CAL0 & _DEVINFO_IDAC0CAL0_RANGE2_MASK) - >> _DEVINFO_IDAC0CAL0_RANGE2_SHIFT; - break; - case idacCurrentRange3: - idac->CAL = (DEVINFO->IDAC0CAL0 & _DEVINFO_IDAC0CAL0_RANGE3_MASK) - >> _DEVINFO_IDAC0CAL0_RANGE3_SHIFT; - break; - } - - tmp = idac->CURPROG & ~_IDAC_CURPROG_RANGESEL_MASK; - tmp |= (uint32_t)range; - -#elif defined( _IDAC_CURPROG_TUNING_MASK ) - - /* Load calibration data depending on selected range and sink/source mode */ - /* TUNING (calibration) field in CURPROG register. */ - if (idac == IDAC0) - { - diCal0 = DEVINFO->IDAC0CAL0; - diCal1 = DEVINFO->IDAC0CAL1; - } - else - { - EFM_ASSERT(false); - } - - tmp = idac->CURPROG & ~(_IDAC_CURPROG_TUNING_MASK - | _IDAC_CURPROG_RANGESEL_MASK); - if (idac->CTRL & IDAC_CTRL_CURSINK) - { - switch (range) - { - case idacCurrentRange0: - tmp |= ((diCal1 & _DEVINFO_IDAC0CAL1_SINKRANGE0TUNING_MASK) - >> _DEVINFO_IDAC0CAL1_SINKRANGE0TUNING_SHIFT) - << _IDAC_CURPROG_TUNING_SHIFT; - break; - - case idacCurrentRange1: - tmp |= ((diCal1 & _DEVINFO_IDAC0CAL1_SINKRANGE1TUNING_MASK) - >> _DEVINFO_IDAC0CAL1_SINKRANGE1TUNING_SHIFT) - << _IDAC_CURPROG_TUNING_SHIFT; - break; - - case idacCurrentRange2: - tmp |= ((diCal1 & _DEVINFO_IDAC0CAL1_SINKRANGE2TUNING_MASK) - >> _DEVINFO_IDAC0CAL1_SINKRANGE2TUNING_SHIFT) - << _IDAC_CURPROG_TUNING_SHIFT; - break; - - case idacCurrentRange3: - tmp |= ((diCal1 & _DEVINFO_IDAC0CAL1_SINKRANGE3TUNING_MASK) - >> _DEVINFO_IDAC0CAL1_SINKRANGE3TUNING_SHIFT) - << _IDAC_CURPROG_TUNING_SHIFT; - break; - } - } - else - { - switch (range) - { - case idacCurrentRange0: - tmp |= ((diCal0 & _DEVINFO_IDAC0CAL0_SOURCERANGE0TUNING_MASK) - >> _DEVINFO_IDAC0CAL0_SOURCERANGE0TUNING_SHIFT) - << _IDAC_CURPROG_TUNING_SHIFT; - break; - - case idacCurrentRange1: - tmp |= ((diCal0 & _DEVINFO_IDAC0CAL0_SOURCERANGE1TUNING_MASK) - >> _DEVINFO_IDAC0CAL0_SOURCERANGE1TUNING_SHIFT) - << _IDAC_CURPROG_TUNING_SHIFT; - break; - - case idacCurrentRange2: - tmp |= ((diCal0 & _DEVINFO_IDAC0CAL0_SOURCERANGE2TUNING_MASK) - >> _DEVINFO_IDAC0CAL0_SOURCERANGE2TUNING_SHIFT) - << _IDAC_CURPROG_TUNING_SHIFT; - break; - - case idacCurrentRange3: - tmp |= ((diCal0 & _DEVINFO_IDAC0CAL0_SOURCERANGE3TUNING_MASK) - >> _DEVINFO_IDAC0CAL0_SOURCERANGE3TUNING_SHIFT) - << _IDAC_CURPROG_TUNING_SHIFT; - break; - } - } - - tmp |= (uint32_t)range; - -#else -#warning "IDAC calibration register definition unknown." -#endif - - idac->CURPROG = tmp; -} - - -/***************************************************************************//** - * @brief - * Set the current step of the IDAC output. - * - * @param[in] idac - * Pointer to IDAC peripheral register block. - * - * @param[in] step - * Step value for IDAC output. Valid range is 0-31. - ******************************************************************************/ -void IDAC_StepSet(IDAC_TypeDef *idac, const uint32_t step) -{ - uint32_t tmp; - - EFM_ASSERT(IDAC_REF_VALID(idac)); - EFM_ASSERT(step <= (_IDAC_CURPROG_STEPSEL_MASK >> _IDAC_CURPROG_STEPSEL_SHIFT)); - - tmp = idac->CURPROG & ~_IDAC_CURPROG_STEPSEL_MASK; - tmp |= step << _IDAC_CURPROG_STEPSEL_SHIFT; - - idac->CURPROG = tmp; -} - - -/***************************************************************************//** - * @brief - * Enable/disable the IDAC OUT pin. - * - * @param[in] idac - * Pointer to IDAC peripheral register block. - * - * @param[in] enable - * true to enable the IDAC OUT pin, false to disable. - ******************************************************************************/ -void IDAC_OutEnable(IDAC_TypeDef *idac, bool enable) -{ - volatile uint32_t *reg; - - EFM_ASSERT(IDAC_REF_VALID(idac)); - - reg = &(idac->CTRL); - - BUS_RegBitWrite(reg, _IDAC_CTRL_OUTEN_SHIFT, enable); -} - - -/** @} (end addtogroup IDAC) */ -/** @} (end addtogroup EM_Library) */ - -#endif /* defined(IDAC_COUNT) && (IDAC_COUNT > 0) */ +/***************************************************************************//** + * @file em_idac.c + * @brief Current Digital to Analog Converter (IDAC) peripheral API + * @version 4.2.1 + ******************************************************************************* + * @section License + * <b>(C) Copyright 2015 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_idac.h" +#if defined(IDAC_COUNT) && (IDAC_COUNT > 0) +#include "em_cmu.h" +#include "em_assert.h" +#include "em_bus.h" + +/***************************************************************************//** + * @addtogroup EM_Library + * @{ + ******************************************************************************/ + +/***************************************************************************//** + * @addtogroup IDAC + * @brief Current Digital to Analog Conversion (IDAC) Peripheral API + * @{ + ******************************************************************************/ + +/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */ +/* Fix for errata IDAC_E101 - IDAC output current degradation */ +#if defined(_EFM32_ZERO_FAMILY) || defined(_EFM32_HAPPY_FAMILY) +#define ERRATA_FIX_IDAC_E101_EN +#endif +/** @endcond */ + +/******************************************************************************* + ************************** GLOBAL FUNCTIONS ******************************* + ******************************************************************************/ +/***************************************************************************//** + * @brief + * Initialize IDAC. + * + * @details + * Initializes IDAC according to the initialization structure parameter, and + * sets the default calibration value stored in the DEVINFO structure. + * + * @note + * This function will disable the IDAC prior to configuration. + * + * @param[in] idac + * Pointer to IDAC peripheral register block. + * + * @param[in] init + * Pointer to IDAC initialization structure. + ******************************************************************************/ +void IDAC_Init(IDAC_TypeDef *idac, const IDAC_Init_TypeDef *init) +{ + uint32_t tmp; + + EFM_ASSERT(IDAC_REF_VALID(idac)); + + tmp = (uint32_t)(init->prsSel); + + tmp |= init->outMode; + + if (init->enable) + { + tmp |= IDAC_CTRL_EN; + } + if (init->prsEnable) + { + tmp |= IDAC_CTRL_OUTENPRS; + } + if (init->sinkEnable) + { + tmp |= IDAC_CTRL_CURSINK; + } + + idac->CTRL = tmp; +} + + +/***************************************************************************//** + * @brief + * Enable/disable IDAC. + * + * @param[in] idac + * Pointer to IDAC peripheral register block. + * + * @param[in] enable + * true to enable IDAC, false to disable. + ******************************************************************************/ +void IDAC_Enable(IDAC_TypeDef *idac, bool enable) +{ + volatile uint32_t *reg; + + EFM_ASSERT(IDAC_REF_VALID(idac)); + + reg = &(idac->CTRL); + + BUS_RegBitWrite(reg, _IDAC_CTRL_EN_SHIFT, enable); +} + + +/***************************************************************************//** + * @brief + * Reset IDAC to same state as after a HW reset. + * + * @param[in] idac + * Pointer to IDAC peripheral register block. + ******************************************************************************/ +void IDAC_Reset(IDAC_TypeDef *idac) +{ + EFM_ASSERT(IDAC_REF_VALID(idac)); + +#if defined(ERRATA_FIX_IDAC_E101_EN) + /* Fix for errata IDAC_E101 - IDAC output current degradation: + Instead of disabling it we will put it in it's lowest power state (50 nA) + to avoid degradation over time */ + + /* Make sure IDAC is enabled with disabled output */ + idac->CTRL = _IDAC_CTRL_RESETVALUE | IDAC_CTRL_EN; + + /* Set lowest current (50 nA) */ + idac->CURPROG = IDAC_CURPROG_RANGESEL_RANGE0 | + (0x0 << _IDAC_CURPROG_STEPSEL_SHIFT); + + /* Enable duty-cycling for all energy modes */ + idac->DUTYCONFIG = IDAC_DUTYCONFIG_DUTYCYCLEEN; +#else + idac->CTRL = _IDAC_CTRL_RESETVALUE; + idac->CURPROG = _IDAC_CURPROG_RESETVALUE; + idac->DUTYCONFIG = _IDAC_DUTYCONFIG_RESETVALUE; +#endif +#if defined ( _IDAC_CAL_MASK ) + idac->CAL = _IDAC_CAL_RESETVALUE; +#endif +} + + +/***************************************************************************//** + * @brief + * Enable/disable Minimal Output Transition mode. + * + * @param[in] idac + * Pointer to IDAC peripheral register block. + * + * @param[in] enable + * true to enable Minimal Output Transition mode, false to disable. + ******************************************************************************/ +void IDAC_MinimalOutputTransitionMode(IDAC_TypeDef *idac, bool enable) +{ + volatile uint32_t *reg; + + EFM_ASSERT(IDAC_REF_VALID(idac)); + + reg = &(idac->CTRL); + + BUS_RegBitWrite(reg, _IDAC_CTRL_MINOUTTRANS_SHIFT, enable); +} + + +/***************************************************************************//** + * @brief + * Set the current range of the IDAC output. + * + * @details + * This function sets the current range of the IDAC output. The function + * also updates the IDAC calibration register (IDAC_CAL) with the default + * calibration value (from DEVINFO, factory setting) corresponding to the + * specified range. + * + * @param[in] idac + * Pointer to IDAC peripheral register block. + * + * @param[in] range + * Current range value. + ******************************************************************************/ +void IDAC_RangeSet(IDAC_TypeDef *idac, const IDAC_Range_TypeDef range) +{ + uint32_t tmp; +#if defined( _IDAC_CURPROG_TUNING_MASK ) + uint32_t diCal0; + uint32_t diCal1; +#endif + + EFM_ASSERT(IDAC_REF_VALID(idac)); + EFM_ASSERT(((uint32_t)range >> _IDAC_CURPROG_RANGESEL_SHIFT) + <= (_IDAC_CURPROG_RANGESEL_MASK >> _IDAC_CURPROG_RANGESEL_SHIFT)); + +#if defined ( _IDAC_CAL_MASK ) + + /* Load proper calibration data depending on selected range */ + switch ((IDAC_Range_TypeDef)range) + { + case idacCurrentRange0: + idac->CAL = (DEVINFO->IDAC0CAL0 & _DEVINFO_IDAC0CAL0_RANGE0_MASK) + >> _DEVINFO_IDAC0CAL0_RANGE0_SHIFT; + break; + case idacCurrentRange1: + idac->CAL = (DEVINFO->IDAC0CAL0 & _DEVINFO_IDAC0CAL0_RANGE1_MASK) + >> _DEVINFO_IDAC0CAL0_RANGE1_SHIFT; + break; + case idacCurrentRange2: + idac->CAL = (DEVINFO->IDAC0CAL0 & _DEVINFO_IDAC0CAL0_RANGE2_MASK) + >> _DEVINFO_IDAC0CAL0_RANGE2_SHIFT; + break; + case idacCurrentRange3: + idac->CAL = (DEVINFO->IDAC0CAL0 & _DEVINFO_IDAC0CAL0_RANGE3_MASK) + >> _DEVINFO_IDAC0CAL0_RANGE3_SHIFT; + break; + } + + tmp = idac->CURPROG & ~_IDAC_CURPROG_RANGESEL_MASK; + tmp |= (uint32_t)range; + +#elif defined( _IDAC_CURPROG_TUNING_MASK ) + + /* Load calibration data depending on selected range and sink/source mode */ + /* TUNING (calibration) field in CURPROG register. */ + if (idac == IDAC0) + { + diCal0 = DEVINFO->IDAC0CAL0; + diCal1 = DEVINFO->IDAC0CAL1; + } + else + { + EFM_ASSERT(false); + } + + tmp = idac->CURPROG & ~(_IDAC_CURPROG_TUNING_MASK + | _IDAC_CURPROG_RANGESEL_MASK); + if (idac->CTRL & IDAC_CTRL_CURSINK) + { + switch (range) + { + case idacCurrentRange0: + tmp |= ((diCal1 & _DEVINFO_IDAC0CAL1_SINKRANGE0TUNING_MASK) + >> _DEVINFO_IDAC0CAL1_SINKRANGE0TUNING_SHIFT) + << _IDAC_CURPROG_TUNING_SHIFT; + break; + + case idacCurrentRange1: + tmp |= ((diCal1 & _DEVINFO_IDAC0CAL1_SINKRANGE1TUNING_MASK) + >> _DEVINFO_IDAC0CAL1_SINKRANGE1TUNING_SHIFT) + << _IDAC_CURPROG_TUNING_SHIFT; + break; + + case idacCurrentRange2: + tmp |= ((diCal1 & _DEVINFO_IDAC0CAL1_SINKRANGE2TUNING_MASK) + >> _DEVINFO_IDAC0CAL1_SINKRANGE2TUNING_SHIFT) + << _IDAC_CURPROG_TUNING_SHIFT; + break; + + case idacCurrentRange3: + tmp |= ((diCal1 & _DEVINFO_IDAC0CAL1_SINKRANGE3TUNING_MASK) + >> _DEVINFO_IDAC0CAL1_SINKRANGE3TUNING_SHIFT) + << _IDAC_CURPROG_TUNING_SHIFT; + break; + } + } + else + { + switch (range) + { + case idacCurrentRange0: + tmp |= ((diCal0 & _DEVINFO_IDAC0CAL0_SOURCERANGE0TUNING_MASK) + >> _DEVINFO_IDAC0CAL0_SOURCERANGE0TUNING_SHIFT) + << _IDAC_CURPROG_TUNING_SHIFT; + break; + + case idacCurrentRange1: + tmp |= ((diCal0 & _DEVINFO_IDAC0CAL0_SOURCERANGE1TUNING_MASK) + >> _DEVINFO_IDAC0CAL0_SOURCERANGE1TUNING_SHIFT) + << _IDAC_CURPROG_TUNING_SHIFT; + break; + + case idacCurrentRange2: + tmp |= ((diCal0 & _DEVINFO_IDAC0CAL0_SOURCERANGE2TUNING_MASK) + >> _DEVINFO_IDAC0CAL0_SOURCERANGE2TUNING_SHIFT) + << _IDAC_CURPROG_TUNING_SHIFT; + break; + + case idacCurrentRange3: + tmp |= ((diCal0 & _DEVINFO_IDAC0CAL0_SOURCERANGE3TUNING_MASK) + >> _DEVINFO_IDAC0CAL0_SOURCERANGE3TUNING_SHIFT) + << _IDAC_CURPROG_TUNING_SHIFT; + break; + } + } + + tmp |= (uint32_t)range; + +#else +#warning "IDAC calibration register definition unknown." +#endif + + idac->CURPROG = tmp; +} + + +/***************************************************************************//** + * @brief + * Set the current step of the IDAC output. + * + * @param[in] idac + * Pointer to IDAC peripheral register block. + * + * @param[in] step + * Step value for IDAC output. Valid range is 0-31. + ******************************************************************************/ +void IDAC_StepSet(IDAC_TypeDef *idac, const uint32_t step) +{ + uint32_t tmp; + + EFM_ASSERT(IDAC_REF_VALID(idac)); + EFM_ASSERT(step <= (_IDAC_CURPROG_STEPSEL_MASK >> _IDAC_CURPROG_STEPSEL_SHIFT)); + + tmp = idac->CURPROG & ~_IDAC_CURPROG_STEPSEL_MASK; + tmp |= step << _IDAC_CURPROG_STEPSEL_SHIFT; + + idac->CURPROG = tmp; +} + + +/***************************************************************************//** + * @brief + * Enable/disable the IDAC OUT pin. + * + * @param[in] idac + * Pointer to IDAC peripheral register block. + * + * @param[in] enable + * true to enable the IDAC OUT pin, false to disable. + ******************************************************************************/ +void IDAC_OutEnable(IDAC_TypeDef *idac, bool enable) +{ + volatile uint32_t *reg; + + EFM_ASSERT(IDAC_REF_VALID(idac)); + + reg = &(idac->CTRL); + + BUS_RegBitWrite(reg, _IDAC_CTRL_OUTEN_SHIFT, enable); +} + + +/** @} (end addtogroup IDAC) */ +/** @} (end addtogroup EM_Library) */ + +#endif /* defined(IDAC_COUNT) && (IDAC_COUNT > 0) */