summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/drivers/adc.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/firmware/drivers/adc.c b/firmware/drivers/adc.c
index 861be80987..2bb5edf3bf 100644
--- a/firmware/drivers/adc.c
+++ b/firmware/drivers/adc.c
@@ -48,10 +48,45 @@ unsigned short adc_read(int channel)
48 return adcdata[channel]; 48 return adcdata[channel];
49} 49}
50 50
51/* Batch convert 4 analog channels. If lower is true, convert AN0-AN3,
52 * otherwise AN4-AN7.
53 */
54static void adc_batch_convert(bool lower)
55{
56 int reg = lower ? 0 : 4;
57 volatile unsigned short* ANx = ((unsigned short*) ADDRAH_ADDR);
58 int i;
59
60 ADCSR = ADCSR_ADST | ADCSR_SCAN | ADCSR_CKS | reg | 3;
61
62 /* Busy wait until conversion is complete. A bit ugly perhaps, but
63 * we should only need to wait about 4 * 14 µs */
64 while(!(ADCSR & ADCSR_ADF))
65 {
66 }
67
68 /* Stop scanning */
69 ADCSR = 0;
70
71 for (i = 0; i < 4; i++)
72 {
73 /* Read converted values */
74 adcdata[reg++] = ANx[i] >> 6;
75 }
76}
77
51void adc_init(void) 78void adc_init(void)
52{ 79{
53 ADCR = 0; /* No external trigger */ 80 int i;
54 81 ADCR = 0x7f; /* No external trigger; other bits should be 1 according to the manual... */
82
55 current_channel = 0; 83 current_channel = 0;
84
85 /* Do a first scan to initialize all values */
86 /* AN0 to AN3 */
87 adc_batch_convert(true);
88 /* AN4 to AN7 */
89 adc_batch_convert(false);
90
56 tick_add_task(adc_tick); 91 tick_add_task(adc_tick);
57} 92}