summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2007-07-30 23:48:03 +0000
committerJens Arnold <amiconn@rockbox.org>2007-07-30 23:48:03 +0000
commit4e8b171fc4cc3b62a1656ae67e92944ff855dcd3 (patch)
tree61ea62ef4b5b483cd86c778028d2b1979547178d
parent35274ce1196b8055e189d18d8295edf2e5b0b65c (diff)
downloadrockbox-4e8b171fc4cc3b62a1656ae67e92944ff855dcd3.tar.gz
rockbox-4e8b171fc4cc3b62a1656ae67e92944ff855dcd3.zip
Interrupt driven ADC reading on the 2nd gen.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14086 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c55
-rw-r--r--firmware/target/arm/system-pp5002.c14
2 files changed, 50 insertions, 19 deletions
diff --git a/firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c b/firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c
index 759b6fb592..8866c3dcde 100644
--- a/firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c
+++ b/firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c
@@ -24,18 +24,22 @@
24 24
25static struct mutex adc_mutex NOCACHEBSS_ATTR; 25static struct mutex adc_mutex NOCACHEBSS_ATTR;
26 26
27/* used in the 2nd gen ADC interrupt */
28static unsigned int_data;
29static int int_status = -1;
30
27unsigned short adc_scan(int channel) 31unsigned short adc_scan(int channel)
28{ 32{
29 int i, j;
30 unsigned short data = 0; 33 unsigned short data = 0;
31 unsigned pval;
32 34
33 (void)channel; /* there is only one */ 35 (void)channel; /* there is only one */
34 spinlock_lock(&adc_mutex); 36 spinlock_lock(&adc_mutex);
35 37
36 if ((IPOD_HW_REVISION >> 16) == 1) 38 if ((IPOD_HW_REVISION >> 16) == 1)
37 { 39 {
38 pval = GPIOB_OUTPUT_VAL; 40 int i, j;
41 unsigned pval = GPIOB_OUTPUT_VAL;
42
39 GPIOB_OUTPUT_VAL = pval | 0x04; /* B2 -> high */ 43 GPIOB_OUTPUT_VAL = pval | 0x04; /* B2 -> high */
40 for (i = 32; i > 0; --i); 44 for (i = 32; i > 0; --i);
41 45
@@ -55,26 +59,43 @@ unsigned short adc_scan(int channel)
55 } 59 }
56 else if ((IPOD_HW_REVISION >> 16) == 2) 60 else if ((IPOD_HW_REVISION >> 16) == 2)
57 { 61 {
58 pval = GPIOB_OUTPUT_VAL; 62 int_status = 0;
59 GPIOB_OUTPUT_VAL = pval | 0x0a; /* B1, B3 -> high */ 63 GPIOB_INT_LEV |= 0x04; /* high active */
60 while (!(GPIOB_INPUT_VAL & 0x04)); /* wait for B2 == 1 */ 64 GPIOB_INT_EN |= 0x04; /* enable interrupt */
65 GPIOB_OUTPUT_VAL |= 0x0a; /* B1, B3 -> high: start conversion */
61 66
62 GPIOB_OUTPUT_VAL = pval; /* B1, B3 -> low */ 67 while (int_status >= 0)
63 while (GPIOB_INPUT_VAL & 0x04); /* wait for B2 == 0 */ 68 yield();
64 69
65 for (j = 0; j < 8; j++) 70 data = int_data & 0xff;
66 { 71 }
67 GPIOB_OUTPUT_VAL = pval | 0x02; /* B1 -> high */ 72 spinlock_unlock(&adc_mutex);
68 while (!(GPIOB_INPUT_VAL & 0x04)); /* wait for B2 == 1 */ 73 return data;
74}
69 75
70 data = (data << 1) | ((GPIOB_INPUT_VAL & 0x10) >> 4); 76/* Used for 2nd gen only. Conversion can take several milliseconds there. */
77void ipod_2g_adc_int(void)
78{
79 if (GPIOB_INPUT_VAL & 0x04)
80 {
81 int_data = (int_data << 1) | ((GPIOB_INPUT_VAL & 0x10) >> 4);
71 82
72 GPIOB_OUTPUT_VAL = pval; /* B1 -> low */ 83 GPIOB_OUTPUT_VAL &= ~0x0a; /* B1, B3 -> low */
73 while (GPIOB_INPUT_VAL & 0x04); /* wait for B2 == 0 */ 84 /* B3 needs to be set low in the first call only, but then stays low
85 * anyway so no need for special handling */
86 }
87 else
88 {
89 if (++int_status > 8)
90 {
91 GPIOB_INT_EN &= ~0x04;
92 int_status = -1;
74 } 93 }
94 else
95 GPIOB_OUTPUT_VAL |= 0x02; /* B1 -> high */
75 } 96 }
76 spinlock_unlock(&adc_mutex); 97 GPIOB_INT_LEV ^= 0x04; /* toggle interrupt level */
77 return data; 98 GPIOB_INT_CLR = 0x04; /* acknowledge interrupt */
78} 99}
79 100
80void adc_init(void) 101void adc_init(void)
diff --git a/firmware/target/arm/system-pp5002.c b/firmware/target/arm/system-pp5002.c
index 6d32d258cc..38dfe5b49c 100644
--- a/firmware/target/arm/system-pp5002.c
+++ b/firmware/target/arm/system-pp5002.c
@@ -22,6 +22,7 @@
22extern void TIMER1(void); 22extern void TIMER1(void);
23extern void TIMER2(void); 23extern void TIMER2(void);
24extern void ipod_3g_button_int(void); 24extern void ipod_3g_button_int(void);
25extern void ipod_2g_adc_int(void);
25 26
26void irq(void) 27void irq(void)
27{ 28{
@@ -32,8 +33,17 @@ void irq(void)
32 else if (CPU_INT_STAT & TIMER2_MASK) 33 else if (CPU_INT_STAT & TIMER2_MASK)
33 TIMER2(); 34 TIMER2();
34 else if (CPU_INT_STAT & GPIO_MASK) 35 else if (CPU_INT_STAT & GPIO_MASK)
35 ipod_3g_button_int(); 36 {
36 } else { 37 if (GPIOA_INT_STAT)
38 ipod_3g_button_int();
39#ifdef IPOD_1G2G
40 if (GPIOB_INT_STAT & 0x04)
41 ipod_2g_adc_int();
42#endif
43 }
44 }
45 else
46 {
37 if (COP_INT_STAT & TIMER1_MASK) 47 if (COP_INT_STAT & TIMER1_MASK)
38 TIMER1(); 48 TIMER1();
39 else if (COP_INT_STAT & TIMER2_MASK) 49 else if (COP_INT_STAT & TIMER2_MASK)