em_idac.c

Go to the documentation of this file.
00001 /***************************************************************************/
00034 #include "em_idac.h"
00035 #if defined(IDAC_COUNT) && (IDAC_COUNT > 0)
00036 #include "em_cmu.h"
00037 #include "em_assert.h"
00038 #include "em_bitband.h"
00039 
00040 /***************************************************************************/
00045 /***************************************************************************/
00052 /* Fix for errata IDAC_E101 - IDAC output current degradation */
00053 #if defined(_EFM32_ZERO_FAMILY)
00054 #define ERRATA_FIX_IDAC_E101_EN
00055 #elif defined(_EFM32_HAPPY_FAMILY)
00056 #define ERRATA_FIX_IDAC_E101_EN
00057 #endif
00058 
00060 /*******************************************************************************
00061  **************************   GLOBAL FUNCTIONS   *******************************
00062  ******************************************************************************/
00063 /***************************************************************************/
00080 void IDAC_Init(IDAC_TypeDef *idac, const IDAC_Init_TypeDef *init)
00081 {
00082   uint32_t tmp;
00083 
00084   EFM_ASSERT(IDAC_REF_VALID(idac));
00085 
00086   tmp = (uint32_t)(init->prsSel);
00087 
00088   tmp |= init->outMode;
00089 
00090   if (init->enable)
00091   {
00092     tmp |= IDAC_CTRL_EN;
00093   }
00094   if (init->prsEnable)
00095   {
00096     tmp |= IDAC_CTRL_OUTENPRS;
00097   }
00098   if (init->sinkEnable)
00099   {
00100     tmp |= IDAC_CTRL_CURSINK;
00101   }
00102 
00103   idac->CTRL = tmp;
00104 }
00105 
00106 
00107 /***************************************************************************/
00117 void IDAC_Enable(IDAC_TypeDef *idac, bool enable)
00118 {
00119   volatile uint32_t *reg;
00120 
00121   EFM_ASSERT(IDAC_REF_VALID(idac));
00122 
00123   reg = &(idac->CTRL);
00124 
00125   BITBAND_Peripheral(reg, _IDAC_CTRL_EN_SHIFT, (unsigned int) enable);
00126 }
00127 
00128 
00129 /***************************************************************************/
00136 void IDAC_Reset(IDAC_TypeDef *idac)
00137 {
00138   EFM_ASSERT(IDAC_REF_VALID(idac));
00139 
00140 #if defined(ERRATA_FIX_IDAC_E101_EN)
00141   /* Fix for errata IDAC_E101 - IDAC output current degradation:
00142      Instead of disabling it we will put it in it’s lowest power state (50 nA)
00143      to avoid degradation over time */
00144 
00145   /* Make sure IDAC is enabled with disabled output */
00146   idac->CTRL = _IDAC_CTRL_RESETVALUE | IDAC_CTRL_EN;
00147 
00148   /* Set lowest current (50 nA) */
00149   idac->CURPROG = IDAC_CURPROG_RANGESEL_RANGE0 |
00150                   (0x0 << _IDAC_CURPROG_STEPSEL_SHIFT);
00151 
00152   /* Enable duty-cycling for all energy modes */
00153   idac->DUTYCONFIG = IDAC_DUTYCONFIG_DUTYCYCLEEN;
00154 #else
00155   idac->CTRL       = _IDAC_CTRL_RESETVALUE;
00156   idac->CURPROG    = _IDAC_CURPROG_RESETVALUE;
00157   idac->DUTYCONFIG = _IDAC_DUTYCONFIG_RESETVALUE;
00158 #endif
00159   idac->CAL        = _IDAC_CAL_RESETVALUE;
00160 }
00161 
00162 
00163 /***************************************************************************/
00173 void IDAC_MinimalOutputTransitionMode(IDAC_TypeDef *idac, bool enable)
00174 {
00175   volatile uint32_t *reg;
00176 
00177   EFM_ASSERT(IDAC_REF_VALID(idac));
00178 
00179   reg = &(idac->CTRL);
00180 
00181   BITBAND_Peripheral(reg, _IDAC_CTRL_MINOUTTRANS_SHIFT, (unsigned int) enable);
00182 }
00183 
00184 
00185 /***************************************************************************/
00201 void IDAC_RangeSet(IDAC_TypeDef *idac, const IDAC_Range_TypeDef range)
00202 {
00203   uint32_t tmp;
00204 
00205   EFM_ASSERT(IDAC_REF_VALID(idac));
00206   EFM_ASSERT((range >> _IDAC_CURPROG_RANGESEL_SHIFT) <= (_IDAC_CURPROG_RANGESEL_MASK >> _IDAC_CURPROG_RANGESEL_SHIFT));
00207 
00208   /* Load proper calibration data depending on selected range */
00209   switch ((IDAC_Range_TypeDef) range)
00210   {
00211   case idacCurrentRange0:
00212     idac->CAL = (DEVINFO->IDAC0CAL0 & _DEVINFO_IDAC0CAL0_RANGE0_MASK) >> _DEVINFO_IDAC0CAL0_RANGE0_SHIFT;
00213     break;
00214   case idacCurrentRange1:
00215     idac->CAL = (DEVINFO->IDAC0CAL0 & _DEVINFO_IDAC0CAL0_RANGE1_MASK) >> _DEVINFO_IDAC0CAL0_RANGE1_SHIFT;
00216     break;
00217   case idacCurrentRange2:
00218     idac->CAL = (DEVINFO->IDAC0CAL0 & _DEVINFO_IDAC0CAL0_RANGE2_MASK) >> _DEVINFO_IDAC0CAL0_RANGE2_SHIFT;
00219     break;
00220   case idacCurrentRange3:
00221     idac->CAL = (DEVINFO->IDAC0CAL0 & _DEVINFO_IDAC0CAL0_RANGE3_MASK) >> _DEVINFO_IDAC0CAL0_RANGE3_SHIFT;
00222     break;
00223   }
00224 
00225   tmp  = idac->CURPROG & ~_IDAC_CURPROG_RANGESEL_MASK;
00226   tmp |= (uint32_t) range;
00227 
00228   idac->CURPROG = tmp;
00229 }
00230 
00231 
00232 /***************************************************************************/
00242 void IDAC_StepSet(IDAC_TypeDef *idac, const uint32_t step)
00243 {
00244   uint32_t tmp;
00245 
00246   EFM_ASSERT(IDAC_REF_VALID(idac));
00247   EFM_ASSERT(step <= (_IDAC_CURPROG_STEPSEL_MASK >> _IDAC_CURPROG_STEPSEL_SHIFT));
00248 
00249   tmp  = idac->CURPROG & ~_IDAC_CURPROG_STEPSEL_MASK;
00250   tmp |= step << _IDAC_CURPROG_STEPSEL_SHIFT;
00251 
00252   idac->CURPROG = tmp;
00253 }
00254 
00255 
00256 /***************************************************************************/
00266 void IDAC_OutEnable(IDAC_TypeDef *idac, bool enable)
00267 {
00268   volatile uint32_t *reg;
00269 
00270   EFM_ASSERT(IDAC_REF_VALID(idac));
00271 
00272   reg = &(idac->CTRL);
00273 
00274   BITBAND_Peripheral(reg, _IDAC_CTRL_OUTEN_SHIFT, (unsigned int) enable);
00275 }
00276 
00277 
00281 #endif /* defined(IDAC_COUNT) && (IDAC_COUNT > 0) */