hw_adc.c

Go to the documentation of this file.
00001 
00042 #include "hw/hw_adc.h"
00043 
00044 
00045 #include <cfg/macros.h>
00046 
00047 #include <drv/timer.h>
00048 
00049 #include <avr/io.h>
00050 
00052 void adc_set_active_ain(int ai)
00053 {
00054     /* If number of channels is <= 4 we use the first two MUX bits */
00055     STATIC_ASSERT(ADC_CHANNEL_NUM <= 4);
00056 
00057     ai &= BV(0) | BV(1);
00058     ADMUX &= ~BV(MUX0);
00059     ADMUX &= ~BV(MUX1);
00060     ADMUX |= ai;
00061 }
00062 
00064 void adc_init(void)
00065 {
00066     /* Set analog IN as input */
00067     DDRF &= ~(BV(PF0) | BV(PF1) | BV(PF2) | BV(PF3));
00068 
00069     /* Disable pull-up */
00070     PORTF &= ~(BV(PF0) | BV(PF1) | BV(PF2) | BV(PF3));
00071 
00072     ENABLE_ADC;
00073     adc_set_vref_avcc();
00074     SET_AI_ADLAR;
00075 
00076     /* Set the Division Factor to 128 */
00077     ADCSRA |= (BV(ADPS0) | BV(ADPS1) | BV(ADPS2));
00078 }
00079 
00081 void adc_set_vref_avcc(void)
00082 {
00083     ADMUX &= ~BV(REFS1);
00084     ADMUX |= BV(REFS0);
00085 }
00086 
00088 int adc_read_ai_channel(int channel)
00089 {
00090     adc_set_active_ain(channel);
00091     timer_udelay(STABILIZING_AI_CHANNEL_TIME);
00092     START_CONVERTION;
00093 
00094     while(ADCSRA & BV(ADSC))
00095     {
00096         /*
00097          * Intentionally empty loop.
00098          * It waits the convertion to be completed by ADC
00099          */
00100     }
00101 
00102     ADCSRA |= BV(ADIF);
00103 
00104     uint16_t val;
00105     val = ADCL;
00106     val |= (uint16_t)ADCH << 8;
00107 
00108     return val;
00109 }