EFM32 Gecko Software Documentation  efm32g-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 
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. */
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)
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 /***************************************************************************/
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 /***************************************************************************/
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. */
315  {
317  }
318 
319  return (uint8_t)ret;
320 }
321 
322 
323 /***************************************************************************/
331 {
332  /* Disable channels, before resetting other registers. */
335  dac->CTRL = _DAC_CTRL_RESETVALUE;
336  dac->IEN = _DAC_IEN_RESETVALUE;
337  dac->IFC = _DAC_IFC_MASK;
338  dac->CAL = DEVINFO->DAC0CAL0;
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.
#define _DAC_CH1CTRL_RESETVALUE
Definition: efm32g_dac.h:191
#define _DAC_CTRL_REFSEL_SHIFT
Definition: efm32g_dac.h:108
#define DAC_CTRL_OUTENPRS
Definition: efm32g_dac.h:98
Emlib peripheral API "assert" implementation.
#define _DAC_CTRL_PRESC_SHIFT
Definition: efm32g_dac.h:118
void DAC_Enable(DAC_TypeDef *dac, unsigned int ch, bool enable)
Enable/disable DAC channel.
Definition: em_dac.c:86
#define _DAC_CTRL_CONVMODE_SHIFT
Definition: efm32g_dac.h:76
__IOM uint32_t IEN
Definition: efm32g_dac.h:47
RAM and peripheral bit-field set and clear API.
DAC_Ref_TypeDef reference
Definition: em_dac.h:151
#define DAC_CTRL_CH0PRESCRST
Definition: efm32g_dac.h:103
void DAC_InitChannel(DAC_TypeDef *dac, const DAC_InitChannel_TypeDef *init, unsigned int ch)
Initialize DAC channel.
Definition: em_dac.c:193
bool outEnablePRS
Definition: em_dac.h:172
#define _DAC_CH0CTRL_EN_SHIFT
Definition: efm32g_dac.h:155
uint8_t DAC_PrescaleCalc(uint32_t dacFreq, uint32_t hfperFreq)
Calculate prescaler value used to determine DAC clock.
Definition: em_dac.c:287
#define DAC_CTRL_SINEMODE
Definition: efm32g_dac.h:71
__IOM uint32_t CH1CTRL
Definition: efm32g_dac.h:46
#define DEVINFO
#define DAC_CH0CTRL_REFREN
Definition: efm32g_dac.h:159
DAC_Refresh_TypeDef refresh
Definition: em_dac.h:148
#define _DAC_CH0CTRL_PRSSEL_SHIFT
Definition: efm32g_dac.h:169
__IOM uint32_t IFC
Definition: efm32g_dac.h:50
__IOM uint32_t CAL
Definition: efm32g_dac.h:54
#define _DAC_CTRL_OUTMODE_SHIFT
Definition: efm32g_dac.h:86
#define _DAC_CTRL_RESETVALUE
Definition: efm32g_dac.h:64
#define DAC_CTRL_DIFF
Definition: efm32g_dac.h:66
Digital to Analog Converter (DAC) peripheral API.
__STATIC_INLINE void DAC_Channel0OutputSet(DAC_TypeDef *dac, uint32_t value)
Set the output signal of DAC channel 0 to a given value.
Definition: em_dac.h:259
__STATIC_INLINE void DAC_Channel1OutputSet(DAC_TypeDef *dac, uint32_t value)
Set the output signal of DAC channel 1 to a given value.
Definition: em_dac.h:281
__IOM uint32_t CTRL
Definition: efm32g_dac.h:43
DAC_Output_TypeDef outMode
Definition: em_dac.h:154
bool sineEnable
Definition: em_dac.h:175
#define DAC_CH0CTRL_EN
Definition: efm32g_dac.h:154
#define _DAC_CTRL_PRESC_MASK
Definition: efm32g_dac.h:119
#define _DAC_CTRL_REFRSEL_SHIFT
Definition: efm32g_dac.h:124
#define _DAC_IFC_MASK
Definition: efm32g_dac.h:303
#define _DAC_CH0CTRL_RESETVALUE
Definition: efm32g_dac.h:152
__IOM uint32_t CH0CTRL
Definition: efm32g_dac.h:45
uint8_t prescale
Definition: em_dac.h:163
DAC_ConvMode_TypeDef convMode
Definition: em_dac.h:157
#define DAC_CH0CTRL_PRSEN
Definition: efm32g_dac.h:164
void DAC_Reset(DAC_TypeDef *dac)
Reset DAC to same state as after a HW reset.
Definition: em_dac.c:330
#define _DAC_IEN_RESETVALUE
Definition: efm32g_dac.h:230
#define _DAC_BIASPROG_RESETVALUE
Definition: efm32g_dac.h:370
DAC_PRSSEL_TypeDef prsSel
Definition: em_dac.h:219
__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
__IOM uint32_t BIASPROG
Definition: efm32g_dac.h:55
bool ch0ResetPre
Definition: em_dac.h:169
void DAC_ChannelOutputSet(DAC_TypeDef *dac, unsigned int channel, uint32_t value)
Set the output signal of a DAC channel to a given value.
Definition: em_dac.c:247
void DAC_Init(DAC_TypeDef *dac, const DAC_Init_TypeDef *init)
Initialize DAC.
Definition: em_dac.c:123