diff options
author | Linus Nielsen Feltzing <linus@haxx.se> | 2004-01-20 11:57:50 +0000 |
---|---|---|
committer | Linus Nielsen Feltzing <linus@haxx.se> | 2004-01-20 11:57:50 +0000 |
commit | 26f42605c2b19f7c9d9f4fe73d67a42ccab2757b (patch) | |
tree | 01c2d6440063cb7c339b3be1f04d386077edba54 | |
parent | 14971f49cdb9fb05700522d584381adef80f393e (diff) | |
download | rockbox-26f42605c2b19f7c9d9f4fe73d67a42ccab2757b.tar.gz rockbox-26f42605c2b19f7c9d9f4fe73d67a42ccab2757b.zip |
Reverted to the old ADC driver, since it appeared to cause fake OFF keypresses (weird indeed, since the OFF key doesn't use the ADC on the plain Recorder). However, I did fix the batch convert, since it caused fake keypresses at boot time.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4260 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/drivers/adc.c | 85 |
1 files changed, 48 insertions, 37 deletions
diff --git a/firmware/drivers/adc.c b/firmware/drivers/adc.c index 4c9206e62b..7be9baf5d5 100644 --- a/firmware/drivers/adc.c +++ b/firmware/drivers/adc.c | |||
@@ -22,38 +22,25 @@ | |||
22 | #include "thread.h" | 22 | #include "thread.h" |
23 | #include "adc.h" | 23 | #include "adc.h" |
24 | 24 | ||
25 | /* This driver updates the adcdata[] array by converting one A/D channel | 25 | static int current_channel; |
26 | group on each system tick. Each group is 4 channels, which means that | ||
27 | it takes 2 ticks to convert all 8 channels. */ | ||
28 | |||
29 | static int current_group; | ||
30 | static unsigned short adcdata[NUM_ADC_CHANNELS]; | 26 | static unsigned short adcdata[NUM_ADC_CHANNELS]; |
27 | static unsigned int adcreg[NUM_ADC_CHANNELS] = | ||
28 | { | ||
29 | ADDRAH_ADDR, ADDRBH_ADDR, ADDRCH_ADDR, ADDRDH_ADDR, | ||
30 | ADDRAH_ADDR, ADDRBH_ADDR, ADDRCH_ADDR, ADDRDH_ADDR | ||
31 | }; | ||
31 | 32 | ||
32 | static void adc_tick(void) | 33 | static void adc_tick(void) |
33 | { | 34 | { |
34 | /* Copy the data from the previous conversion */ | 35 | /* Read the data that has bee converted since the last tick */ |
35 | if(current_group) | 36 | adcdata[current_channel] = |
36 | { | 37 | *(unsigned short *)adcreg[current_channel] >> 6; |
37 | adcdata[4] = ADDRA >> 6; | ||
38 | adcdata[5] = ADDRB >> 6; | ||
39 | adcdata[6] = ADDRC >> 6; | ||
40 | adcdata[7] = ADDRD >> 6; | ||
41 | } | ||
42 | else | ||
43 | { | ||
44 | adcdata[0] = ADDRA >> 6; | ||
45 | adcdata[1] = ADDRB >> 6; | ||
46 | adcdata[2] = ADDRC >> 6; | ||
47 | adcdata[3] = ADDRD >> 6; | ||
48 | } | ||
49 | 38 | ||
50 | /* Start converting the next group */ | 39 | /* Start a conversion on the next channel */ |
51 | current_group = !current_group; | 40 | current_channel++; |
52 | ADCSR = ADCSR_ADST | ADCSR_SCAN | (current_group?4:0) | 3; | 41 | if(current_channel == NUM_ADC_CHANNELS) |
53 | 42 | current_channel = 0; | |
54 | /* The conversion will be ready when we serve the next tick interrupt. | 43 | ADCSR = ADCSR_ADST | current_channel; |
55 | No need to check ADCSR for finished conversion since the conversion | ||
56 | will be ready long before the next tick. */ | ||
57 | } | 44 | } |
58 | 45 | ||
59 | unsigned short adc_read(int channel) | 46 | unsigned short adc_read(int channel) |
@@ -61,20 +48,44 @@ unsigned short adc_read(int channel) | |||
61 | return adcdata[channel]; | 48 | return adcdata[channel]; |
62 | } | 49 | } |
63 | 50 | ||
64 | void adc_init(void) | 51 | /* Batch convert 4 analog channels. If lower is true, convert AN0-AN3, |
52 | * otherwise AN4-AN7. | ||
53 | */ | ||
54 | static void adc_batch_convert(bool lower) | ||
65 | { | 55 | { |
66 | ADCR = 0x7f; /* No external trigger; other bits should be 1 according | 56 | int reg = lower ? 0 : 4; |
67 | to the manual... */ | 57 | volatile unsigned short* ANx = ((unsigned short*) ADDRAH_ADDR); |
58 | int i; | ||
59 | |||
60 | ADCSR = ADCSR_ADST | ADCSR_SCAN | reg | 3; | ||
68 | 61 | ||
69 | /* Make sure that there is no conversion running */ | 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 */ | ||
70 | ADCSR = 0; | 69 | ADCSR = 0; |
71 | 70 | ||
72 | /* Start with converting group 0 by setting current_group to 1 */ | 71 | for (i = 0; i < 4; i++) |
73 | current_group = 1; | 72 | { |
73 | /* Read converted values */ | ||
74 | adcdata[reg++] = ANx[i] >> 6; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | void adc_init(void) | ||
79 | { | ||
80 | ADCR = 0x7f; /* No external trigger; other bits should be 1 according to the manual... */ | ||
81 | |||
82 | current_channel = 0; | ||
83 | |||
84 | /* Do a first scan to initialize all values */ | ||
85 | /* AN4 to AN7 */ | ||
86 | adc_batch_convert(false); | ||
87 | /* AN0 to AN3 */ | ||
88 | adc_batch_convert(true); | ||
74 | 89 | ||
75 | tick_add_task(adc_tick); | 90 | tick_add_task(adc_tick); |
76 | |||
77 | /* Wait until both groups have been converted before we continue, | ||
78 | so adcdata[] contains valid data */ | ||
79 | sleep(2); | ||
80 | } | 91 | } |