summaryrefslogtreecommitdiffstats
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
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
-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 @@
#include "thread.h"
#include "adc.h"
-/* This driver updates the adcdata[] array by converting one A/D channel
- group on each system tick. Each group is 4 channels, which means that
- it takes 2 ticks to convert all 8 channels. */
-
-static int current_group;
+static int current_channel;
static unsigned short adcdata[NUM_ADC_CHANNELS];
+static unsigned int adcreg[NUM_ADC_CHANNELS] =
+{
+ ADDRAH_ADDR, ADDRBH_ADDR, ADDRCH_ADDR, ADDRDH_ADDR,
+ ADDRAH_ADDR, ADDRBH_ADDR, ADDRCH_ADDR, ADDRDH_ADDR
+};
static void adc_tick(void)
{
- /* Copy the data from the previous conversion */
- if(current_group)
- {
- adcdata[4] = ADDRA >> 6;
- adcdata[5] = ADDRB >> 6;
- adcdata[6] = ADDRC >> 6;
- adcdata[7] = ADDRD >> 6;
- }
- else
- {
- adcdata[0] = ADDRA >> 6;
- adcdata[1] = ADDRB >> 6;
- adcdata[2] = ADDRC >> 6;
- adcdata[3] = ADDRD >> 6;
- }
+ /* Read the data that has bee converted since the last tick */
+ adcdata[current_channel] =
+ *(unsigned short *)adcreg[current_channel] >> 6;
- /* Start converting the next group */
- current_group = !current_group;
- ADCSR = ADCSR_ADST | ADCSR_SCAN | (current_group?4:0) | 3;
-
- /* The conversion will be ready when we serve the next tick interrupt.
- No need to check ADCSR for finished conversion since the conversion
- will be ready long before the next tick. */
+ /* Start a conversion on the next channel */
+ current_channel++;
+ if(current_channel == NUM_ADC_CHANNELS)
+ current_channel = 0;
+ ADCSR = ADCSR_ADST | current_channel;
}
unsigned short adc_read(int channel)
@@ -61,20 +48,44 @@ unsigned short adc_read(int channel)
return adcdata[channel];
}
-void adc_init(void)
+/* Batch convert 4 analog channels. If lower is true, convert AN0-AN3,
+ * otherwise AN4-AN7.
+ */
+static void adc_batch_convert(bool lower)
{
- ADCR = 0x7f; /* No external trigger; other bits should be 1 according
- to the manual... */
+ int reg = lower ? 0 : 4;
+ volatile unsigned short* ANx = ((unsigned short*) ADDRAH_ADDR);
+ int i;
+
+ ADCSR = ADCSR_ADST | ADCSR_SCAN | reg | 3;
- /* Make sure that there is no conversion running */
+ /* Busy wait until conversion is complete. A bit ugly perhaps, but
+ * we should only need to wait about 4 * 14 Ás */
+ while(!(ADCSR & ADCSR_ADF))
+ {
+ }
+
+ /* Stop scanning */
ADCSR = 0;
- /* Start with converting group 0 by setting current_group to 1 */
- current_group = 1;
+ for (i = 0; i < 4; i++)
+ {
+ /* Read converted values */
+ adcdata[reg++] = ANx[i] >> 6;
+ }
+}
+
+void adc_init(void)
+{
+ ADCR = 0x7f; /* No external trigger; other bits should be 1 according to the manual... */
+
+ current_channel = 0;
+
+ /* Do a first scan to initialize all values */
+ /* AN4 to AN7 */
+ adc_batch_convert(false);
+ /* AN0 to AN3 */
+ adc_batch_convert(true);
tick_add_task(adc_tick);
-
- /* Wait until both groups have been converted before we continue,
- so adcdata[] contains valid data */
- sleep(2);
}