EFM32 Pearl Gecko 12 Software Documentation  efm32pg12-doc-5.1.2
em_dac.c
Go to the documentation of this file.
1 /***************************************************************************/
33 #include "em_dac.h"
34 #if defined(DAC_COUNT) && (DAC_COUNT > 0)
35 #include "em_cmu.h"
36 #include "em_assert.h"
37 #include "em_bus.h"
38 
39 /***************************************************************************/
44 /***************************************************************************/
55 /*******************************************************************************
56  ******************************* DEFINES ***********************************
57  ******************************************************************************/
58 
62 #define DAC_CH_VALID(ch) ((ch) <= 1)
63 
65 #define DAC_MAX_CLOCK 1000000
66 
69 /*******************************************************************************
70  ************************** GLOBAL FUNCTIONS *******************************
71  ******************************************************************************/
72 
73 /***************************************************************************/
86 void DAC_Enable(DAC_TypeDef *dac, unsigned int ch, bool enable)
87 {
88  volatile uint32_t *reg;
89 
90  EFM_ASSERT(DAC_REF_VALID(dac));
91  EFM_ASSERT(DAC_CH_VALID(ch));
92 
93  if (!ch)
94  {
95  reg = &(dac->CH0CTRL);
96  }
97  else
98  {
99  reg = &(dac->CH1CTRL);
100  }
101 
102  BUS_RegBitWrite(reg, _DAC_CH0CTRL_EN_SHIFT, enable);
103 }
104 
105 
106 /***************************************************************************/
123 void DAC_Init(DAC_TypeDef *dac, const DAC_Init_TypeDef *init)
124 {
125  uint32_t tmp;
126 
127  EFM_ASSERT(DAC_REF_VALID(dac));
128 
129  /* Make sure both channels are disabled. */
130  BUS_RegBitWrite(&(dac->CH0CTRL), _DAC_CH0CTRL_EN_SHIFT, 0);
131  BUS_RegBitWrite(&(dac->CH1CTRL), _DAC_CH0CTRL_EN_SHIFT, 0);
132 
133  /* Load proper calibration data depending on selected reference */
134  switch (init->reference)
135  {
136  case dacRef2V5:
137  dac->CAL = DEVINFO->DAC0CAL1;
138  break;
139 
140  case dacRefVDD:
141  dac->CAL = DEVINFO->DAC0CAL2;
142  break;
143 
144  default: /* 1.25V */
145  dac->CAL = DEVINFO->DAC0CAL0;
146  break;
147  }
148 
149  tmp = ((uint32_t)(init->refresh) << _DAC_CTRL_REFRSEL_SHIFT)
150  | (((uint32_t)(init->prescale) << _DAC_CTRL_PRESC_SHIFT)
151  & _DAC_CTRL_PRESC_MASK)
152  | ((uint32_t)(init->reference) << _DAC_CTRL_REFSEL_SHIFT)
153  | ((uint32_t)(init->outMode) << _DAC_CTRL_OUTMODE_SHIFT)
154  | ((uint32_t)(init->convMode) << _DAC_CTRL_CONVMODE_SHIFT);
155 
156  if (init->ch0ResetPre)
157  {
158  tmp |= DAC_CTRL_CH0PRESCRST;
159  }
160 
161  if (init->outEnablePRS)
162  {
163  tmp |= DAC_CTRL_OUTENPRS;
164  }
165 
166  if (init->sineEnable)
167  {
168  tmp |= DAC_CTRL_SINEMODE;
169  }
170 
171  if (init->diff)
172  {
173  tmp |= DAC_CTRL_DIFF;
174  }
175 
176  dac->CTRL = tmp;
177 }
178 
179 
180 /***************************************************************************/
193 void DAC_InitChannel(DAC_TypeDef *dac,
194  const DAC_InitChannel_TypeDef *init,
195  unsigned int ch)
196 {
197  uint32_t tmp;
198 
199  EFM_ASSERT(DAC_REF_VALID(dac));
200  EFM_ASSERT(DAC_CH_VALID(ch));
201 
202  tmp = (uint32_t)(init->prsSel) << _DAC_CH0CTRL_PRSSEL_SHIFT;
203 
204  if (init->enable)
205  {
206  tmp |= DAC_CH0CTRL_EN;
207  }
208 
209  if (init->prsEnable)
210  {
211  tmp |= DAC_CH0CTRL_PRSEN;
212  }
213 
214  if (init->refreshEnable)
215  {
216  tmp |= DAC_CH0CTRL_REFREN;
217  }
218 
219  if (ch)
220  {
221  dac->CH1CTRL = tmp;
222  }
223  else
224  {
225  dac->CH0CTRL = tmp;
226  }
227 }
228 
229 
230 /***************************************************************************/
247 void DAC_ChannelOutputSet( DAC_TypeDef *dac,
248  unsigned int channel,
249  uint32_t value )
250 {
251  switch(channel)
252  {
253  case 0:
254  DAC_Channel0OutputSet(dac, value);
255  break;
256  case 1:
257  DAC_Channel1OutputSet(dac, value);
258  break;
259  default:
260  EFM_ASSERT(0);
261  break;
262  }
263 }
264 
265 
266 /***************************************************************************/
287 uint8_t DAC_PrescaleCalc(uint32_t dacFreq, uint32_t hfperFreq)
288 {
289  uint32_t ret;
290 
291  /* Make sure selected DAC clock is below max value */
292  if (dacFreq > DAC_MAX_CLOCK)
293  {
294  dacFreq = DAC_MAX_CLOCK;
295  }
296 
297  /* Use current HFPER frequency? */
298  if (!hfperFreq)
299  {
300  hfperFreq = CMU_ClockFreqGet(cmuClock_HFPER);
301  }
302 
303  /* Iterate in order to determine best prescale value. Only a few possible */
304  /* values. We start with lowest prescaler value in order to get first */
305  /* equal or below wanted DAC frequency value. */
306  for (ret = 0; ret <= (_DAC_CTRL_PRESC_MASK >> _DAC_CTRL_PRESC_SHIFT); ret++)
307  {
308  if ((hfperFreq >> ret) <= dacFreq)
309  break;
310  }
311 
312  /* If ret is higher than the max prescaler value, make sure to return
313  the max value. */
314  if (ret > (_DAC_CTRL_PRESC_MASK >> _DAC_CTRL_PRESC_SHIFT))
315  {
316  ret = _DAC_CTRL_PRESC_MASK >> _DAC_CTRL_PRESC_SHIFT;
317  }
318 
319  return (uint8_t)ret;
320 }
321 
322 
323 /***************************************************************************/
330 void DAC_Reset(DAC_TypeDef *dac)
331 {
332  /* Disable channels, before resetting other registers. */
333  dac->CH0CTRL = _DAC_CH0CTRL_RESETVALUE;
334  dac->CH1CTRL = _DAC_CH1CTRL_RESETVALUE;
335  dac->CTRL = _DAC_CTRL_RESETVALUE;
336  dac->IEN = _DAC_IEN_RESETVALUE;
337  dac->IFC = _DAC_IFC_MASK;
338  dac->CAL = DEVINFO->DAC0CAL0;
339  dac->BIASPROG = _DAC_BIASPROG_RESETVALUE;
340  /* Do not reset route register, setting should be done independently */
341 }
342 
343 
346 #endif /* defined(DAC_COUNT) && (DAC_COUNT > 0) */
Clock management unit (CMU) API.
Emlib peripheral API "assert" implementation.
RAM and peripheral bit-field set and clear API.
#define DEVINFO
Digital to Analog Converter (DAC) peripheral API.
__STATIC_INLINE void BUS_RegBitWrite(volatile uint32_t *addr, unsigned int bit, unsigned int val)
Perform a single-bit write operation on a peripheral register.
Definition: em_bus.h:148
uint32_t CMU_ClockFreqGet(CMU_Clock_TypeDef clock)
Get clock frequency for a clock point.
Definition: em_cmu.c:1550