4 * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
9 * \brief ADC hardware-specific definition
12 * \author Francesco Sacchi <batt@develer.com>
18 #include <appconfig.h>
20 #include <cfg/macros.h>
21 #include <cfg/compiler.h>
24 #include <avr/interrupt.h>
26 #define ADC_AVR_AREF 0
27 #define ADC_AVR_AVCC 1
28 #define ADC_AVR_INT256 2
31 #include <cfg/module.h>
32 #include <config_kern.h>
33 #include <kern/proc.h>
34 #include <kern/signal.h>
37 #if !CONFIG_KERN_SIGNALS
38 #error Signals must be active to use ADC with kernel
41 /* Signal adc convertion end */
42 #define SIG_ADC_COMPLETE SIG_SINGLE
44 /* ADC waiting process */
45 static struct Process *adc_process;
49 * Simply signal the adc process that convertion is complete.
53 sig_signal(adc_process, SIG_ADC_COMPLETE);
55 #endif /* CONFIG_KERNEL */
58 * Select mux channel \a ch.
59 * \todo only first 8 channels are selectable!
61 INLINE void adc_hw_select_ch(uint8_t ch)
63 /* Set to 0 all mux registers */
64 ADMUX &= ~(BV(MUX3) | BV(MUX3) | BV(MUX2) | BV(MUX1) | BV(MUX0));
66 /* Select channel, only first 8 channel modes are supported for now */
72 * Start an ADC convertion.
73 * If a kernel is present, preempt until convertion is complete, otherwise
74 * a busy wait on ADCS bit is done.
76 INLINE uint16_t adc_hw_read(void)
78 // Ensure another convertion is not running.
79 ASSERT(!(ADCSRA & BV(ADSC)));
85 // Ensure IRQs enabled.
86 ASSERT(IRQ_ENABLED());
87 adc_process = proc_current();
88 sig_wait(SIG_ADC_COMPLETE);
90 //Wait in polling until is done
91 while (ADCSRA & BV(ADSC)) ;
100 INLINE void adc_hw_init(void)
103 * Select channel 0 as default,
104 * result right adjusted.
108 #if CONFIG_ADC_AVR_REF == ADC_AVR_AREF
109 /* External voltage at AREF as analog ref source */
111 #elif CONFIG_ADC_AVR_REF == ADC_AVR_AVCC
112 /* AVCC as analog ref source */
114 #elif CONFIG_ADC_AVR_REF == ADC_AVR_INT256
115 /* Internal 2.56V as ref source */
116 ADMUX |= BV(REFS1) | BV(REFS0);
118 #error Unsupported ADC ref value.
121 /* Disable Auto trigger source: ADC in Free running mode. */
124 /* Enable ADC, disable autotrigger mode. */
132 /* Set convertion frequency */
133 #if CONFIG_ADC_AVR_DIVISOR == 2
135 #elif CONFIG_ADC_AVR_DIVISOR == 4
137 #elif CONFIG_ADC_AVR_DIVISOR == 8
138 ADCSRA |= BV(ADPS1) | BV(ADPS0);
139 #elif CONFIG_ADC_AVR_DIVISOR == 16
141 #elif CONFIG_ADC_AVR_DIVISOR == 32
142 ADCSRA |= BV(ADPS2) | BV(ADPS0);
143 #elif CONFIG_ADC_AVR_DIVISOR == 64
144 ADCSRA |= BV(ADPS2) | BV(ADPS1);
145 #elif CONFIG_ADC_AVR_DIVISOR == 128
146 ADCSRA |= BV(ADPS2) | BV(ADPS1) | BV(ADPS0);
148 #error Unsupported ADC prescaler value.
151 /* Start a convertion to init ADC hw */