diff options
author | Jens Arnold <amiconn@rockbox.org> | 2008-03-17 00:19:23 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2008-03-17 00:19:23 +0000 |
commit | c6b6bad18fcd68182574086c2eb2a1da30d36d25 (patch) | |
tree | 7be19582463e57623a64b674a69893fa771310f5 /firmware/target | |
parent | 648104a318e84bb4148eeff2a06e6b533deace40 (diff) | |
download | rockbox-c6b6bad18fcd68182574086c2eb2a1da30d36d25.tar.gz rockbox-c6b6bad18fcd68182574086c2eb2a1da30d36d25.zip |
iAudio M3: ADC driver, making buttons and battery voltage reading work. * Disable the multi-colour LED for now to save power. Proper handling will be added later. * Make reboot on button press work on iAudio X5, M5, M3 in panicf(), and on M3 in UIE().
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16684 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/coldfire/i2c-coldfire.c | 17 | ||||
-rw-r--r-- | firmware/target/coldfire/iaudio/m3/adc-m3.c | 91 | ||||
-rw-r--r-- | firmware/target/coldfire/iaudio/m3/adc-target.h | 29 | ||||
-rw-r--r-- | firmware/target/coldfire/iaudio/m3/button-m3.c | 4 | ||||
-rw-r--r-- | firmware/target/coldfire/iaudio/m3/power-m3.c | 4 | ||||
-rw-r--r-- | firmware/target/coldfire/iaudio/m3/powermgmt-m3.c | 57 | ||||
-rw-r--r-- | firmware/target/coldfire/iaudio/powermgmt-iaudio.c | 4 | ||||
-rw-r--r-- | firmware/target/coldfire/system-coldfire.c | 5 |
8 files changed, 189 insertions, 22 deletions
diff --git a/firmware/target/coldfire/i2c-coldfire.c b/firmware/target/coldfire/i2c-coldfire.c index 06c196792f..83d8db4048 100644 --- a/firmware/target/coldfire/i2c-coldfire.c +++ b/firmware/target/coldfire/i2c-coldfire.c | |||
@@ -56,15 +56,16 @@ void i2c_init(void) | |||
56 | 56 | ||
57 | /* I2C Clock divisor = 160 => 124.1556 MHz / 2 / 160 = 388.08 kHz */ | 57 | /* I2C Clock divisor = 160 => 124.1556 MHz / 2 / 160 = 388.08 kHz */ |
58 | MFDR = 0x0d; | 58 | MFDR = 0x0d; |
59 | MFDR2 = 0x0d; | ||
60 | 59 | ||
61 | #if defined(IAUDIO_X5) || defined(IAUDIO_M5) | 60 | #if defined(IAUDIO_M3) |
62 | MBCR = IEN; /* Enable interface */ | 61 | MBCR = IEN; /* Enable interface 1 */ |
63 | MBCR2 = IEN; | 62 | /* secondary channel is handled in the interrupt driven ADC driver */ |
64 | #endif | 63 | #elif defined(IAUDIO_X5) || defined(IAUDIO_M5) |
64 | MBCR = IEN; /* Enable interface 1 */ | ||
65 | 65 | ||
66 | #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES) | 66 | MFDR2 = 0x0d; |
67 | /* Audio Codec */ | 67 | MBCR2 = IEN; /* Enable interface 2 */ |
68 | #elif defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES) | ||
68 | MBDR = 0; /* iRiver firmware does this */ | 69 | MBDR = 0; /* iRiver firmware does this */ |
69 | MBCR = IEN; /* Enable interface */ | 70 | MBCR = IEN; /* Enable interface */ |
70 | #endif | 71 | #endif |
@@ -156,7 +157,7 @@ int i2c_read(volatile unsigned char *iface, unsigned char addr, | |||
156 | iface[O_MBCR] |= TXAK; | 157 | iface[O_MBCR] |= TXAK; |
157 | else if (i == 1) | 158 | else if (i == 1) |
158 | /* Generate STOP before reading last byte received */ | 159 | /* Generate STOP before reading last byte received */ |
159 | i2c_stop(iface); | 160 | i2c_stop(iface); |
160 | 161 | ||
161 | *buf++ = iface[O_MBDR]; | 162 | *buf++ = iface[O_MBDR]; |
162 | } | 163 | } |
diff --git a/firmware/target/coldfire/iaudio/m3/adc-m3.c b/firmware/target/coldfire/iaudio/m3/adc-m3.c index c4f8d92ae1..b0d7f7430b 100644 --- a/firmware/target/coldfire/iaudio/m3/adc-m3.c +++ b/firmware/target/coldfire/iaudio/m3/adc-m3.c | |||
@@ -18,15 +18,90 @@ | |||
18 | ****************************************************************************/ | 18 | ****************************************************************************/ |
19 | 19 | ||
20 | #include "config.h" | 20 | #include "config.h" |
21 | #include "cpu.h" | 21 | |
22 | #include "system.h" | ||
23 | #include "kernel.h" | ||
24 | #include "thread.h" | ||
25 | #include "adc.h" | 22 | #include "adc.h" |
23 | #include "i2c-coldfire.h" | ||
24 | #include "system.h" | ||
25 | |||
26 | #define ADC_I2C_ADDR 0xa0 | ||
27 | |||
28 | /* The M3 ADC is hooked exclusively to the secondary I²C bus, and requires | ||
29 | * very slow transfers (I²C clock <= 16kHz). So we start one 4-byte read | ||
30 | * transfer each tick, and handle it via an ISR. At 11MHz, one transfer | ||
31 | * takes too long to be started every tick, but it seems we have to live | ||
32 | * with that. */ | ||
33 | |||
34 | static unsigned char adc_data[NUM_ADC_CHANNELS] IBSS_ATTR; | ||
35 | static volatile bool data_ready = false; | ||
36 | |||
37 | |||
38 | static void adc_tick(void) | ||
39 | { | ||
40 | if ((MBSR2 & IBB) == 0) /* Bus is free */ | ||
41 | { | ||
42 | MBCR2 |= (MSTA|TXAK|MTX); /* Generate START and prepare for write */ | ||
43 | MBDR2 = ADC_I2C_ADDR|1; /* Send address */ | ||
44 | } | ||
45 | } | ||
26 | 46 | ||
27 | unsigned short adc_scan(int channel) | 47 | void IIC2(void) __attribute__((interrupt_handler)); |
48 | void IIC2(void) | ||
28 | { | 49 | { |
29 | /* TODO */ | 50 | static int bytenum = 0; |
30 | (void)channel; | 51 | |
31 | return 0xff; | 52 | MBSR2 &= ~IFF; /* Clear interrupt flag */ |
53 | |||
54 | if (MBSR2 & IAL) /* Arbitration lost - shouldn't happen */ | ||
55 | { /* normally, but CPU freq change might induce it */ | ||
56 | MBSR2 &= ~IAL; /* Clear flag */ | ||
57 | MBCR2 &= ~MSTA; /* STOP */ | ||
58 | } | ||
59 | else if (MBCR2 & MTX) /* Address phase */ | ||
60 | { | ||
61 | if (MBSR2 & RXAK) /* No ACK received */ | ||
62 | { | ||
63 | MBCR2 &= ~MSTA; /* STOP */ | ||
64 | return; | ||
65 | } | ||
66 | MBCR2 &= ~(MTX|TXAK); /* Switch to RX mode, enable TX ack generation */ | ||
67 | MBDR2; /* Dummy read */ | ||
68 | bytenum = 0; | ||
69 | } | ||
70 | else | ||
71 | { | ||
72 | switch (bytenum) | ||
73 | { | ||
74 | case 2: | ||
75 | MBCR2 |= TXAK; /* Don't ACK the last byte */ | ||
76 | break; | ||
77 | |||
78 | case 3: | ||
79 | MBCR2 &= ~MSTA; /* STOP before reading the last value */ | ||
80 | data_ready = true; /* Simplification - the last byte is a dummy. */ | ||
81 | break; | ||
82 | } | ||
83 | adc_data[bytenum++] = MBDR2; | ||
84 | } | ||
85 | |||
86 | } | ||
87 | |||
88 | unsigned short adc_read(int channel) | ||
89 | { | ||
90 | return adc_data[channel]; | ||
91 | } | ||
92 | |||
93 | void adc_init(void) | ||
94 | { | ||
95 | MFDR2 = 0x1f; /* I²C clock = SYSCLK / 3840 */ | ||
96 | MBCR2 = IEN; /* Enable interface */ | ||
97 | MBSR2 = 0; /* Clear flags */ | ||
98 | MBCR2 = (IEN|IIEN); /* Enable interrupts */ | ||
99 | |||
100 | and_l(~0x0f000000, &INTPRI8); | ||
101 | or_l( 0x04000000, &INTPRI8); /* INT62 - Priority 4 */ | ||
102 | |||
103 | tick_add_task(adc_tick); | ||
104 | |||
105 | while (!data_ready) | ||
106 | sleep(1); /* Ensure valid readings when adc_init returns */ | ||
32 | } | 107 | } |
diff --git a/firmware/target/coldfire/iaudio/m3/adc-target.h b/firmware/target/coldfire/iaudio/m3/adc-target.h new file mode 100644 index 0000000000..e5ff818647 --- /dev/null +++ b/firmware/target/coldfire/iaudio/m3/adc-target.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2008 by Jens Arnold | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #ifndef _ADC_TARGET_H_ | ||
21 | #define _ADC_TARGET_H_ | ||
22 | |||
23 | #define NUM_ADC_CHANNELS 4 | ||
24 | |||
25 | #define ADC_BUTTONS 0 | ||
26 | #define ADC_BATTERY 1 | ||
27 | #define ADC_REMOTE 2 | ||
28 | |||
29 | #endif /* _ADC_TARGET_H_ */ | ||
diff --git a/firmware/target/coldfire/iaudio/m3/button-m3.c b/firmware/target/coldfire/iaudio/m3/button-m3.c index c7c5b2e90f..ecea221a4c 100644 --- a/firmware/target/coldfire/iaudio/m3/button-m3.c +++ b/firmware/target/coldfire/iaudio/m3/button-m3.c | |||
@@ -56,7 +56,7 @@ int button_read_device(void) | |||
56 | 56 | ||
57 | if (!hold_button) | 57 | if (!hold_button) |
58 | { | 58 | { |
59 | data = adc_scan(ADC_BUTTONS); | 59 | data = adc_read(ADC_BUTTONS); |
60 | 60 | ||
61 | if (data < 0xc0) | 61 | if (data < 0xc0) |
62 | { | 62 | { |
@@ -82,7 +82,7 @@ int button_read_device(void) | |||
82 | } | 82 | } |
83 | 83 | ||
84 | /* remote buttons */ | 84 | /* remote buttons */ |
85 | data = remote_detect() ? adc_scan(ADC_REMOTE) : 0xff; | 85 | data = remote_detect() ? adc_read(ADC_REMOTE) : 0xff; |
86 | 86 | ||
87 | remote_hold_button_old = remote_hold_button; | 87 | remote_hold_button_old = remote_hold_button; |
88 | remote_hold_button = data < 0x14; | 88 | remote_hold_button = data < 0x14; |
diff --git a/firmware/target/coldfire/iaudio/m3/power-m3.c b/firmware/target/coldfire/iaudio/m3/power-m3.c index 7b5af43026..52a5de3460 100644 --- a/firmware/target/coldfire/iaudio/m3/power-m3.c +++ b/firmware/target/coldfire/iaudio/m3/power-m3.c | |||
@@ -36,6 +36,10 @@ void power_init(void) | |||
36 | /* Charger detect */ | 36 | /* Charger detect */ |
37 | and_l(~0x00000020, &GPIO1_ENABLE); | 37 | and_l(~0x00000020, &GPIO1_ENABLE); |
38 | or_l(0x00000020, &GPIO1_FUNCTION); | 38 | or_l(0x00000020, &GPIO1_FUNCTION); |
39 | |||
40 | /* FIXME: Just disable the multi-colour LED for now. */ | ||
41 | and_l(~0x00000210, &GPIO1_OUT); | ||
42 | and_l(~0x00008000, &GPIO_OUT); | ||
39 | } | 43 | } |
40 | 44 | ||
41 | bool charger_inserted(void) | 45 | bool charger_inserted(void) |
diff --git a/firmware/target/coldfire/iaudio/m3/powermgmt-m3.c b/firmware/target/coldfire/iaudio/m3/powermgmt-m3.c new file mode 100644 index 0000000000..8c94947785 --- /dev/null +++ b/firmware/target/coldfire/iaudio/m3/powermgmt-m3.c | |||
@@ -0,0 +1,57 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2008 Jens Arnold | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "config.h" | ||
21 | #include "adc.h" | ||
22 | #include "powermgmt.h" | ||
23 | |||
24 | const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = | ||
25 | { | ||
26 | 3540 | ||
27 | }; | ||
28 | |||
29 | const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = | ||
30 | { | ||
31 | 3500 | ||
32 | }; | ||
33 | |||
34 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ | ||
35 | const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = | ||
36 | { | ||
37 | /* average measured values from X5 and M5L */ | ||
38 | { 3500, 3650, 3720, 3740, 3760, 3790, 3840, 3900, 3950, 4040, 4120 } | ||
39 | }; | ||
40 | |||
41 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ | ||
42 | const unsigned short percent_to_volt_charge[11] = | ||
43 | { | ||
44 | /* TODO: This is identical to the discharge curve. | ||
45 | * Calibrate charging curve using a battery_bench log. */ | ||
46 | 3500, 3650, 3720, 3740, 3760, 3790, 3840, 3900, 3950, 4040, 4120 | ||
47 | }; | ||
48 | |||
49 | #define BATTERY_SCALE_FACTOR 5720 | ||
50 | /* full-scale ADC readout (2^8) in millivolt */ | ||
51 | |||
52 | /* Returns battery voltage from ADC [millivolts] */ | ||
53 | unsigned int battery_adc_voltage(void) | ||
54 | { | ||
55 | return (adc_read(ADC_BATTERY) * BATTERY_SCALE_FACTOR) >> 8; | ||
56 | } | ||
57 | |||
diff --git a/firmware/target/coldfire/iaudio/powermgmt-iaudio.c b/firmware/target/coldfire/iaudio/powermgmt-iaudio.c index c4d64e6155..6e2b19d9b6 100644 --- a/firmware/target/coldfire/iaudio/powermgmt-iaudio.c +++ b/firmware/target/coldfire/iaudio/powermgmt-iaudio.c | |||
@@ -53,10 +53,6 @@ const unsigned short percent_to_volt_charge[11] = | |||
53 | /* Returns battery voltage from ADC [millivolts] */ | 53 | /* Returns battery voltage from ADC [millivolts] */ |
54 | unsigned int battery_adc_voltage(void) | 54 | unsigned int battery_adc_voltage(void) |
55 | { | 55 | { |
56 | #ifdef IAUDIO_M3 | ||
57 | return 4000; /* FIXME: fake value - no ADC yet */ | ||
58 | #else | ||
59 | return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10; | 56 | return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10; |
60 | #endif | ||
61 | } | 57 | } |
62 | 58 | ||
diff --git a/firmware/target/coldfire/system-coldfire.c b/firmware/target/coldfire/system-coldfire.c index eca5440679..97e9d35aaa 100644 --- a/firmware/target/coldfire/system-coldfire.c +++ b/firmware/target/coldfire/system-coldfire.c | |||
@@ -144,6 +144,11 @@ default_interrupt (ADC); /* A/D converter */ | |||
144 | #define EXCP_BUTTON_MASK 0x0c000000 | 144 | #define EXCP_BUTTON_MASK 0x0c000000 |
145 | #define EXCP_BUTTON_VALUE 0x08000000 /* On button and !hold */ | 145 | #define EXCP_BUTTON_VALUE 0x08000000 /* On button and !hold */ |
146 | #define EXCP_PLLCR 0x10400000 | 146 | #define EXCP_PLLCR 0x10400000 |
147 | #elif defined(IAUDIO_M3) | ||
148 | #define EXCP_BUTTON_GPIO_READ GPIO1_READ | ||
149 | #define EXCP_BUTTON_MASK 0x00000202 | ||
150 | #define EXCP_BUTTON_VALUE 0x00000200 /* On button and !hold */ | ||
151 | #define EXCP_PLLCR 0x10800000 | ||
147 | #else | 152 | #else |
148 | #define EXCP_BUTTON_GPIO_READ GPIO1_READ | 153 | #define EXCP_BUTTON_GPIO_READ GPIO1_READ |
149 | #define EXCP_BUTTON_MASK 0x00000022 | 154 | #define EXCP_BUTTON_MASK 0x00000022 |