AVR1631 - Energy Meter Reference Design with ATxmega32A4  Rev 1.0
 All Data Structures Files Functions Variables Typedefs Macros
adc_driver.c
Go to the documentation of this file.
1 /* This file has been prepared for Doxygen automatic documentation generation.*/
67 #include "adc_driver.h"
68 
69 
77 void ADC_CalibrationValues_Load(ADC_t * adc)
78 {
79  if(&ADCA == adc){
80  /* Get ADCACAL0 from production signature . */
81  adc->CALL = SP_ReadCalibrationByte( PROD_SIGNATURES_START + ADCACAL0_offset );
82  adc->CALH = SP_ReadCalibrationByte( PROD_SIGNATURES_START + ADCACAL1_offset );
83 // adc->CALL = 0x77;
84 // adc->CALH = 0x07;
85  }else {
86  /* Get ADCBCAL0 from production signature */
87  adc->CALL = SP_ReadCalibrationByte( PROD_SIGNATURES_START + ADCBCAL0_offset );
88  adc->CALH = SP_ReadCalibrationByte( PROD_SIGNATURES_START + ADCBCAL1_offset );
89  }
90 }
91 
92 
102 uint16_t ADC_ResultCh_GetWord_Unsigned(ADC_CH_t * adc_ch, uint16_t offset)
103 {
104  uint16_t answer;
105 
106  /* Clear interrupt flag.*/
107  adc_ch->INTFLAGS = ADC_CH_CHIF_bm;
108 
109  /* Return result register contents*/
110  answer = adc_ch->RES - offset;
111 
112  return answer;
113 }
114 
115 
125 int16_t ADC_ResultCh_GetWord_Signed(ADC_CH_t * adc_ch, int16_t signedOffset)
126 {
127  int16_t answer;
128 
129  /* Clear interrupt flag.*/
130  adc_ch->INTFLAGS = ADC_CH_CHIF_bm;
131 
132  /* Return result register contents*/
133  answer = adc_ch->RES - signedOffset;
134 
135  return answer;
136 }
137 
146 uint16_t ADC_ResultCh_GetWord(ADC_CH_t * adc_ch)
147 {
148  /* Clear interrupt flag.*/
149  adc_ch->INTFLAGS = ADC_CH_CHIF_bm;
150 
151  /* Return result register contents*/
152  return adc_ch->RES;;
153 }
154 
155 
168 uint8_t ADC_ResultCh_GetLowByte(ADC_CH_t * adc_ch)
169 {
170  /* Clear interrupt flag.*/
171  adc_ch->INTFLAGS = ADC_CH_CHIF_bm;
172  /* Return result register contents*/
173  return adc_ch->RESL;
174 }
175 
188 uint8_t ADC_ResultCh_GetHighByte(ADC_CH_t * adc_ch)
189 {
190  /* Clear interrupt flag.*/
191  adc_ch->INTFLAGS = ADC_CH_CHIF_bm;
192 
193  /* Return low byte result register contents.*/
194  return adc_ch->RESH;
195 }
196 
210 void ADC_Wait_8MHz(ADC_t * adc)
211 {
212  /* Store old prescaler value. */
213  uint8_t prescaler_val = adc->PRESCALER;
214 
215  /* Set prescaler value to minimum value. */
216  adc->PRESCALER = ADC_PRESCALER_DIV4_gc;
217 
218  /* Wait 4*COMMON_MODE_CYCLES for common mode to settle. */
219  delay_us(4*COMMON_MODE_CYCLES);
220 
221  /* Set prescaler to old value*/
222  adc->PRESCALER = prescaler_val;
223 }
224 
225 
242 void ADC_Wait_32MHz(ADC_t * adc)
243 {
244  /* Store old prescaler value. */
245  uint8_t prescaler_val = adc->PRESCALER;
246 
247  /* Set prescaler value to minimum value. */
248  adc->PRESCALER = ADC_PRESCALER_DIV8_gc;
249 
250  /* wait 8*COMMON_MODE_CYCLES for common mode to settle*/
251  delay_us(8*COMMON_MODE_CYCLES);
252 
253  /* Set prescaler to old value*/
254  adc->PRESCALER = prescaler_val;
255 }
256 
273 uint16_t ADC_Offset_Get_Unsigned(ADC_t * adc, ADC_CH_t *ch, bool oversampling)
274 {
275  if (oversampling)
276  {
277  uint16_t offset=0;
278  for (int i=0; i<4; i++)
279  {
280  /* Do one conversion to find offset. */
282 
283  do{
284  }while(!ADC_Ch_Conversion_Complete(ch));
285  offset += ADC_ResultCh_GetWord_Unsigned(ch, 0x00);
286  }
287  return ((uint16_t)(offset>>2));
288  }
289  else
290  {
291  uint16_t offset=0;
292 
293  /* Do one conversion to find offset. */
295 
296  do{
297  }while(!ADC_Ch_Conversion_Complete(ch));
298  offset = (uint16_t)ADC_ResultCh_GetWord(ch);
299 
300  return offset;
301  }
302 }
303 
320 int16_t ADC_Offset_Get_Signed(ADC_t * adc, ADC_CH_t *ch, bool oversampling)
321 {
322  if (oversampling)
323  {
324  int16_t offset_calc=0;
325  for (int i=0; i<4; i++)
326  {
327  /* Do one conversion to find offset. */
329 
330  do{
331  }while(!ADC_Ch_Conversion_Complete(ch));
332  offset_calc += ADC_ResultCh_GetWord_Signed(ch, 0x0000);
333  }
334  return ((int16_t)(offset_calc/4));
335  }
336  else
337  {
338  int16_t offset_calc=0;
339 
340  /* Do one conversion to find offset. */
342 
343  do{
344  }while(!ADC_Ch_Conversion_Complete(ch));
345  offset_calc = (uint16_t)ADC_ResultCh_GetWord_Signed(ch, 0x0000);
346 
347  return offset_calc;
348  }
349 }
350 
351 
352 #ifdef __GNUC__
353 
362 uint8_t SP_ReadCalibrationByte( uint8_t index )
363 {
364  uint8_t result;
365 
366  /* Load the NVM Command register to read the calibration row. */
367  NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc;
368  result = pgm_read_byte(index);
369 
370  /* Clean up NVM Command register. */
371  NVM_CMD = NVM_CMD_NO_OPERATION_gc;
372 
373  return result;
374 }
375 
376 #endif