EFM32 Gecko Software Documentation  efm32g-doc-4.2.1
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 /***************************************************************************/
50 /*******************************************************************************
51  ******************************* DEFINES ***********************************
52  ******************************************************************************/
53 
57 #define DAC_CH_VALID(ch) ((ch) <= 1)
58 
60 #define DAC_MAX_CLOCK 1000000
61 
64 /*******************************************************************************
65  ************************** GLOBAL FUNCTIONS *******************************
66  ******************************************************************************/
67 
68 /***************************************************************************/
81 void DAC_Enable(DAC_TypeDef *dac, unsigned int ch, bool enable)
82 {
83  volatile uint32_t *reg;
84 
85  EFM_ASSERT(DAC_REF_VALID(dac));
86  EFM_ASSERT(DAC_CH_VALID(ch));
87 
88  if (!ch)
89  {
90  reg = &(dac->CH0CTRL);
91  }
92  else
93  {
94  reg = &(dac->CH1CTRL);
95  }
96 
98 }
99 
100 
101 /***************************************************************************/
118 void DAC_Init(DAC_TypeDef *dac, const DAC_Init_TypeDef *init)
119 {
120  uint32_t tmp;
121 
122  EFM_ASSERT(DAC_REF_VALID(dac));
123 
124  /* Make sure both channels are disabled. */
127 
128  /* Load proper calibration data depending on selected reference */
129  switch (init->reference)
130  {
131  case dacRef2V5:
132  dac->CAL = DEVINFO->DAC0CAL1;
133  break;
134 
135  case dacRefVDD:
136  dac->CAL = DEVINFO->DAC0CAL2;
137  break;
138 
139  default: /* 1.25V */
140  dac->CAL = DEVINFO->DAC0CAL0;
141  break;
142  }
143 
144  tmp = ((uint32_t)(init->refresh) << _DAC_CTRL_REFRSEL_SHIFT)
145  | (((uint32_t)(init->prescale) << _DAC_CTRL_PRESC_SHIFT)
147  | ((uint32_t)(init->reference) << _DAC_CTRL_REFSEL_SHIFT)
148  | ((uint32_t)(init->outMode) << _DAC_CTRL_OUTMODE_SHIFT)
149  | ((uint32_t)(init->convMode) << _DAC_CTRL_CONVMODE_SHIFT);
150 
151  if (init->ch0ResetPre)
152  {
153  tmp |= DAC_CTRL_CH0PRESCRST;
154  }
155 
156  if (init->outEnablePRS)
157  {
158  tmp |= DAC_CTRL_OUTENPRS;
159  }
160 
161  if (init->sineEnable)
162  {
163  tmp |= DAC_CTRL_SINEMODE;
164  }
165 
166  if (init->diff)
167  {
168  tmp |= DAC_CTRL_DIFF;
169  }
170 
171  dac->CTRL = tmp;
172 }
173 
174 
175 /***************************************************************************/
189  const DAC_InitChannel_TypeDef *init,
190  unsigned int ch)
191 {
192  uint32_t tmp;
193 
194  EFM_ASSERT(DAC_REF_VALID(dac));
195  EFM_ASSERT(DAC_CH_VALID(ch));
196 
197  tmp = (uint32_t)(init->prsSel) << _DAC_CH0CTRL_PRSSEL_SHIFT;
198 
199  if (init->enable)
200  {
201  tmp |= DAC_CH0CTRL_EN;
202  }
203 
204  if (init->prsEnable)
205  {
206  tmp |= DAC_CH0CTRL_PRSEN;
207  }
208 
209  if (init->refreshEnable)
210  {
211  tmp |= DAC_CH0CTRL_REFREN;
212  }
213 
214  if (ch)
215  {
216  dac->CH1CTRL = tmp;
217  }
218  else
219  {
220  dac->CH0CTRL = tmp;
221  }
222 }
223 
224 
225 /***************************************************************************/
243  unsigned int channel,
244  uint32_t value )
245 {
246  switch(channel)
247  {
248  case 0:
249  DAC_Channel0OutputSet(dac, value);
250  break;
251  case 1:
252  DAC_Channel1OutputSet(dac, value);
253  break;
254  default:
255  EFM_ASSERT(0);
256  break;
257  }
258 }
259 
260 
261 /***************************************************************************/
282 uint8_t DAC_PrescaleCalc(uint32_t dacFreq, uint32_t hfperFreq)
283 {
284  uint32_t ret;
285 
286  /* Make sure selected DAC clock is below max value */
287  if (dacFreq > DAC_MAX_CLOCK)
288  {
289  dacFreq = DAC_MAX_CLOCK;
290  }
291 
292  /* Use current HFPER frequency? */
293  if (!hfperFreq)
294  {
295  hfperFreq = CMU_ClockFreqGet(cmuClock_HFPER);
296  }
297 
298  /* Iterate in order to determine best prescale value. Only a few possible */
299  /* values. We start with lowest prescaler value in order to get first */
300  /* equal or below wanted DAC frequency value. */
301  for (ret = 0; ret <= (_DAC_CTRL_PRESC_MASK >> _DAC_CTRL_PRESC_SHIFT); ret++)
302  {
303  if ((hfperFreq >> ret) <= dacFreq)
304  break;
305  }
306 
307  /* If ret is higher than the max prescaler value, make sure to return
308  the max value. */
310  {
312  }
313 
314  return (uint8_t)ret;
315 }
316 
317 
318 /***************************************************************************/
326 {
327  /* Disable channels, before resetting other registers. */
330  dac->CTRL = _DAC_CTRL_RESETVALUE;
331  dac->IEN = _DAC_IEN_RESETVALUE;
332  dac->IFC = _DAC_IFC_MASK;
333  dac->CAL = DEVINFO->DAC0CAL0;
335  /* Do not reset route register, setting should be done independently */
336 }
337 
338 
341 #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.
__IO uint32_t IFC
Definition: efm32g_dac.h:50
#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:81
#define _DAC_CTRL_CONVMODE_SHIFT
Definition: efm32g_dac.h:76
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:188
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:282
#define DAC_CTRL_SINEMODE
Definition: efm32g_dac.h:71
#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
#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.
__IO uint32_t IEN
Definition: efm32g_dac.h:47
__IO uint32_t BIASPROG
Definition: efm32g_dac.h:55
__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
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
__IO uint32_t CAL
Definition: efm32g_dac.h:54
#define _DAC_CH0CTRL_RESETVALUE
Definition: efm32g_dac.h:152
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
__IO uint32_t CH0CTRL
Definition: efm32g_dac.h:45
void DAC_Reset(DAC_TypeDef *dac)
Reset DAC to same state as after a HW reset.
Definition: em_dac.c:325
#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:146
__IO uint32_t CH1CTRL
Definition: efm32g_dac.h:46
uint32_t CMU_ClockFreqGet(CMU_Clock_TypeDef clock)
Get clock frequency for a clock point.
Definition: em_cmu.c:1482
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:242
void DAC_Init(DAC_TypeDef *dac, const DAC_Init_TypeDef *init)
Initialize DAC.
Definition: em_dac.c:118
__IO uint32_t CTRL
Definition: efm32g_dac.h:43