summaryrefslogtreecommitdiff
path: root/firmware/drivers/adc.c
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2004-01-20 11:57:50 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2004-01-20 11:57:50 +0000
commit26f42605c2b19f7c9d9f4fe73d67a42ccab2757b (patch)
tree01c2d6440063cb7c339b3be1f04d386077edba54 /firmware/drivers/adc.c
parent14971f49cdb9fb05700522d584381adef80f393e (diff)
downloadrockbox-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
Diffstat (limited to 'firmware/drivers/adc.c')
-rw-r--r--firmware/drivers/adc.c85
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 25static 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
29static int current_group;
30static unsigned short adcdata[NUM_ADC_CHANNELS]; 26static unsigned short adcdata[NUM_ADC_CHANNELS];
27static 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
32static void adc_tick(void) 33static 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
59unsigned short adc_read(int channel) 46unsigned 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
64void adc_init(void) 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)
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
78void 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}