em_dac.c

Go to the documentation of this file.
00001 /***************************************************************************/
00034 #include "em_dac.h"
00035 #if defined(DAC_COUNT) && (DAC_COUNT > 0)
00036 #include "em_cmu.h"
00037 #include "em_assert.h"
00038 #include "em_bitband.h"
00039 
00040 /***************************************************************************/
00045 /***************************************************************************/
00051 /*******************************************************************************
00052  *******************************   DEFINES   ***********************************
00053  ******************************************************************************/
00054 
00058 #define DAC_CH_VALID(ch)    ((ch) <= 1)
00059 
00061 #define DAC_MAX_CLOCK    1000000
00062 
00065 /*******************************************************************************
00066  **************************   GLOBAL FUNCTIONS   *******************************
00067  ******************************************************************************/
00068 
00069 /***************************************************************************/
00082 void DAC_Enable(DAC_TypeDef *dac, unsigned int ch, bool enable)
00083 {
00084   volatile uint32_t *reg;
00085 
00086   EFM_ASSERT(DAC_REF_VALID(dac));
00087   EFM_ASSERT(DAC_CH_VALID(ch));
00088 
00089   if (!ch)
00090   {
00091     reg = &(dac->CH0CTRL);
00092   }
00093   else
00094   {
00095     reg = &(dac->CH1CTRL);
00096   }
00097 
00098   BITBAND_Peripheral(reg, _DAC_CH0CTRL_EN_SHIFT, (unsigned int)enable);
00099 }
00100 
00101 
00102 /***************************************************************************/
00119 void DAC_Init(DAC_TypeDef *dac, const DAC_Init_TypeDef *init)
00120 {
00121   uint32_t tmp;
00122 
00123   EFM_ASSERT(DAC_REF_VALID(dac));
00124 
00125   /* Make sure both channels are disabled. */
00126   BITBAND_Peripheral(&(dac->CH0CTRL), _DAC_CH0CTRL_EN_SHIFT, 0);
00127   BITBAND_Peripheral(&(dac->CH1CTRL), _DAC_CH0CTRL_EN_SHIFT, 0);
00128 
00129   /* Load proper calibration data depending on selected reference */
00130   switch (init->reference)
00131   {
00132   case dacRef2V5:
00133     dac->CAL = DEVINFO->DAC0CAL1;
00134     break;
00135 
00136   case dacRefVDD:
00137     dac->CAL = DEVINFO->DAC0CAL2;
00138     break;
00139 
00140   default: /* 1.25V */
00141     dac->CAL = DEVINFO->DAC0CAL0;
00142     break;
00143   }
00144 
00145   tmp = ((uint32_t)(init->refresh) << _DAC_CTRL_REFRSEL_SHIFT) |
00146         (((uint32_t)(init->prescale) << _DAC_CTRL_PRESC_SHIFT) & _DAC_CTRL_PRESC_MASK) |
00147         ((uint32_t)(init->reference) << _DAC_CTRL_REFSEL_SHIFT) |
00148         ((uint32_t)(init->outMode) << _DAC_CTRL_OUTMODE_SHIFT) |
00149         ((uint32_t)(init->convMode) << _DAC_CTRL_CONVMODE_SHIFT);
00150 
00151   if (init->ch0ResetPre)
00152   {
00153     tmp |= DAC_CTRL_CH0PRESCRST;
00154   }
00155 
00156   if (init->outEnablePRS)
00157   {
00158     tmp |= DAC_CTRL_OUTENPRS;
00159   }
00160 
00161   if (init->sineEnable)
00162   {
00163     tmp |= DAC_CTRL_SINEMODE;
00164   }
00165 
00166   if (init->diff)
00167   {
00168     tmp |= DAC_CTRL_DIFF;
00169   }
00170 
00171   dac->CTRL = tmp;
00172 }
00173 
00174 
00175 /***************************************************************************/
00188 void DAC_InitChannel(DAC_TypeDef *dac,
00189                      const DAC_InitChannel_TypeDef *init,
00190                      unsigned int ch)
00191 {
00192   uint32_t tmp;
00193 
00194   EFM_ASSERT(DAC_REF_VALID(dac));
00195   EFM_ASSERT(DAC_CH_VALID(ch));
00196 
00197   tmp = (uint32_t)(init->prsSel) << _DAC_CH0CTRL_PRSSEL_SHIFT;
00198 
00199   if (init->enable)
00200   {
00201     tmp |= DAC_CH0CTRL_EN;
00202   }
00203 
00204   if (init->prsEnable)
00205   {
00206     tmp |= DAC_CH0CTRL_PRSEN;
00207   }
00208 
00209   if (init->refreshEnable)
00210   {
00211     tmp |= DAC_CH0CTRL_REFREN;
00212   }
00213 
00214   if (ch)
00215   {
00216     dac->CH1CTRL = tmp;
00217   }
00218   else
00219   {
00220     dac->CH0CTRL = tmp;
00221   }
00222 }
00223 
00224 
00225 /***************************************************************************/
00242 void DAC_ChannelOutputSet( DAC_TypeDef *dac,
00243                            unsigned int channel,
00244                            uint32_t     value )
00245 {
00246   switch(channel)
00247   {
00248   case 0:
00249     DAC_Channel0OutputSet(dac, value);
00250     break;
00251   case 1:
00252     DAC_Channel1OutputSet(dac, value);
00253     break;
00254   default:
00255     EFM_ASSERT(0);
00256     break;
00257   }
00258 }
00259 
00260 
00261 /***************************************************************************/
00282 uint8_t DAC_PrescaleCalc(uint32_t dacFreq, uint32_t hfperFreq)
00283 {
00284   uint32_t ret;
00285 
00286   /* Make sure selected DAC clock is below max value */
00287   if (dacFreq > DAC_MAX_CLOCK)
00288   {
00289     dacFreq = DAC_MAX_CLOCK;
00290   }
00291 
00292   /* Use current HFPER frequency? */
00293   if (!hfperFreq)
00294   {
00295     hfperFreq = CMU_ClockFreqGet(cmuClock_HFPER);
00296   }
00297 
00298   /* Iterate in order to determine best prescale value. Only a few possible */
00299   /* values. We start with lowest prescaler value in order to get first */
00300   /* equal or below wanted DAC frequency value. */
00301   for (ret = 0; ret <= (_DAC_CTRL_PRESC_MASK >> _DAC_CTRL_PRESC_SHIFT); ret++)
00302   {
00303     if ((hfperFreq >> ret) <= dacFreq)
00304       break;
00305   }
00306 
00307   /* If ret is higher than the max prescaler value, make sure to return
00308      the max value. */
00309   if (ret > (_DAC_CTRL_PRESC_MASK >> _DAC_CTRL_PRESC_SHIFT))
00310   {
00311     ret = _DAC_CTRL_PRESC_MASK >> _DAC_CTRL_PRESC_SHIFT;
00312   }
00313 
00314   return((uint8_t)ret);
00315 }
00316 
00317 
00318 /***************************************************************************/
00325 void DAC_Reset(DAC_TypeDef *dac)
00326 {
00327   /* Disable channels, before resetting other registers. */
00328   dac->CH0CTRL  = _DAC_CH0CTRL_RESETVALUE;
00329   dac->CH1CTRL  = _DAC_CH1CTRL_RESETVALUE;
00330   dac->CTRL     = _DAC_CTRL_RESETVALUE;
00331   dac->IEN      = _DAC_IEN_RESETVALUE;
00332   dac->IFC      = _DAC_IFC_MASK;
00333   dac->CAL      = DEVINFO->DAC0CAL0;
00334   dac->BIASPROG = _DAC_BIASPROG_RESETVALUE;
00335   /* Do not reset route register, setting should be done independently */
00336 }
00337 
00338 
00341 #endif /* defined(DAC_COUNT) && (DAC_COUNT > 0) */