summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2008-03-17 00:19:23 +0000
committerJens Arnold <amiconn@rockbox.org>2008-03-17 00:19:23 +0000
commitc6b6bad18fcd68182574086c2eb2a1da30d36d25 (patch)
tree7be19582463e57623a64b674a69893fa771310f5
parent648104a318e84bb4148eeff2a06e6b533deace40 (diff)
downloadrockbox-c6b6bad18fcd68182574086c2eb2a1da30d36d25.zip
rockbox-c6b6bad18fcd68182574086c2eb2a1da30d36d25.tar.gz
rockbox-c6b6bad18fcd68182574086c2eb2a1da30d36d25.tar.bz2
rockbox-c6b6bad18fcd68182574086c2eb2a1da30d36d25.tar.xz
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
-rw-r--r--firmware/SOURCES2
-rw-r--r--firmware/panic.c8
-rw-r--r--firmware/target/coldfire/i2c-coldfire.c17
-rw-r--r--firmware/target/coldfire/iaudio/m3/adc-m3.c91
-rw-r--r--firmware/target/coldfire/iaudio/m3/adc-target.h29
-rw-r--r--firmware/target/coldfire/iaudio/m3/button-m3.c4
-rw-r--r--firmware/target/coldfire/iaudio/m3/power-m3.c4
-rw-r--r--firmware/target/coldfire/iaudio/m3/powermgmt-m3.c57
-rw-r--r--firmware/target/coldfire/iaudio/powermgmt-iaudio.c4
-rw-r--r--firmware/target/coldfire/system-coldfire.c5
10 files changed, 195 insertions, 26 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index ea8ce46..cf96d48 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -504,9 +504,9 @@ target/coldfire/iaudio/m3/button-m3.c
target/coldfire/iaudio/m3/fmradio_i2c-m3.c
target/coldfire/iaudio/m3/lcd-m3.c
target/coldfire/iaudio/m3/power-m3.c
+target/coldfire/iaudio/m3/powermgmt-m3.c
target/coldfire/iaudio/m3/system-m3.c
target/coldfire/iaudio/m3/usb-m3.c
-target/coldfire/iaudio/powermgmt-iaudio.c
#ifndef BOOTLOADER
target/coldfire/iaudio/m3/audio-m3.c
#endif
diff --git a/firmware/panic.c b/firmware/panic.c
index 58f6d1d..0ac4589 100644
--- a/firmware/panic.c
+++ b/firmware/panic.c
@@ -108,10 +108,12 @@ void panicf( const char *fmt, ...)
#define system_reboot() nop
#elif defined (TOSHIBA_GIGABEAT_F)
if ((GPGDAT & (1 << 0)) != 0)
-#elif defined (IRIVER_H100_SERIES)
- if ((GPIO1_READ & 0x22) == 0) /* check for ON button and !hold */
-#elif defined(IRIVER_H300_SERIES)
+#elif defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
if ((GPIO1_READ & 0x22) == 0) /* check for ON button and !hold */
+#elif defined(IAUDIO_X5) || defined(IAUDIO_M5)
+ if ((GPIO_READ & 0x0c000000) == 0x08000000) /* check for ON button and !hold */
+#elif defined(IAUDIO_M3)
+ if ((GPIO1_READ & 0x202) == 0x200) /* check for ON button and !hold */
#elif CONFIG_CPU == SH7034
#if CONFIG_KEYPAD == PLAYER_PAD
if (!(PADRL & 0x20))
diff --git a/firmware/target/coldfire/i2c-coldfire.c b/firmware/target/coldfire/i2c-coldfire.c
index 06c1967..83d8db4 100644
--- a/firmware/target/coldfire/i2c-coldfire.c
+++ b/firmware/target/coldfire/i2c-coldfire.c
@@ -56,15 +56,16 @@ void i2c_init(void)
/* I2C Clock divisor = 160 => 124.1556 MHz / 2 / 160 = 388.08 kHz */
MFDR = 0x0d;
- MFDR2 = 0x0d;
-#if defined(IAUDIO_X5) || defined(IAUDIO_M5)
- MBCR = IEN; /* Enable interface */
- MBCR2 = IEN;
-#endif
+#if defined(IAUDIO_M3)
+ MBCR = IEN; /* Enable interface 1 */
+ /* secondary channel is handled in the interrupt driven ADC driver */
+#elif defined(IAUDIO_X5) || defined(IAUDIO_M5)
+ MBCR = IEN; /* Enable interface 1 */
-#if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
- /* Audio Codec */
+ MFDR2 = 0x0d;
+ MBCR2 = IEN; /* Enable interface 2 */
+#elif defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
MBDR = 0; /* iRiver firmware does this */
MBCR = IEN; /* Enable interface */
#endif
@@ -156,7 +157,7 @@ int i2c_read(volatile unsigned char *iface, unsigned char addr,
iface[O_MBCR] |= TXAK;
else if (i == 1)
/* Generate STOP before reading last byte received */
- i2c_stop(iface);
+ i2c_stop(iface);
*buf++ = iface[O_MBDR];
}
diff --git a/firmware/target/coldfire/iaudio/m3/adc-m3.c b/firmware/target/coldfire/iaudio/m3/adc-m3.c
index c4f8d92..b0d7f74 100644
--- a/firmware/target/coldfire/iaudio/m3/adc-m3.c
+++ b/firmware/target/coldfire/iaudio/m3/adc-m3.c
@@ -18,15 +18,90 @@
****************************************************************************/
#include "config.h"
-#include "cpu.h"
-#include "system.h"
-#include "kernel.h"
-#include "thread.h"
+
#include "adc.h"
+#include "i2c-coldfire.h"
+#include "system.h"
+
+#define ADC_I2C_ADDR 0xa0
+
+/* The M3 ADC is hooked exclusively to the secondary I²C bus, and requires
+ * very slow transfers (I²C clock <= 16kHz). So we start one 4-byte read
+ * transfer each tick, and handle it via an ISR. At 11MHz, one transfer
+ * takes too long to be started every tick, but it seems we have to live
+ * with that. */
+
+static unsigned char adc_data[NUM_ADC_CHANNELS] IBSS_ATTR;
+static volatile bool data_ready = false;
+
+
+static void adc_tick(void)
+{
+ if ((MBSR2 & IBB) == 0) /* Bus is free */
+ {
+ MBCR2 |= (MSTA|TXAK|MTX); /* Generate START and prepare for write */
+ MBDR2 = ADC_I2C_ADDR|1; /* Send address */
+ }
+}
-unsigned short adc_scan(int channel)
+void IIC2(void) __attribute__((interrupt_handler));
+void IIC2(void)
{
- /* TODO */
- (void)channel;
- return 0xff;
+ static int bytenum = 0;
+
+ MBSR2 &= ~IFF; /* Clear interrupt flag */
+
+ if (MBSR2 & IAL) /* Arbitration lost - shouldn't happen */
+ { /* normally, but CPU freq change might induce it */
+ MBSR2 &= ~IAL; /* Clear flag */
+ MBCR2 &= ~MSTA; /* STOP */
+ }
+ else if (MBCR2 & MTX) /* Address phase */
+ {
+ if (MBSR2 & RXAK) /* No ACK received */
+ {
+ MBCR2 &= ~MSTA; /* STOP */
+ return;
+ }
+ MBCR2 &= ~(MTX|TXAK); /* Switch to RX mode, enable TX ack generation */
+ MBDR2; /* Dummy read */
+ bytenum = 0;
+ }
+ else
+ {
+ switch (bytenum)
+ {
+ case 2:
+ MBCR2 |= TXAK; /* Don't ACK the last byte */
+ break;
+
+ case 3:
+ MBCR2 &= ~MSTA; /* STOP before reading the last value */
+ data_ready = true; /* Simplification - the last byte is a dummy. */
+ break;
+ }
+ adc_data[bytenum++] = MBDR2;
+ }
+
+}
+
+unsigned short adc_read(int channel)
+{
+ return adc_data[channel];
+}
+
+void adc_init(void)
+{
+ MFDR2 = 0x1f; /* I²C clock = SYSCLK / 3840 */
+ MBCR2 = IEN; /* Enable interface */
+ MBSR2 = 0; /* Clear flags */
+ MBCR2 = (IEN|IIEN); /* Enable interrupts */
+
+ and_l(~0x0f000000, &INTPRI8);
+ or_l( 0x04000000, &INTPRI8); /* INT62 - Priority 4 */
+
+ tick_add_task(adc_tick);
+
+ while (!data_ready)
+ sleep(1); /* Ensure valid readings when adc_init returns */
}
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 0000000..e5ff818
--- /dev/null
+++ b/firmware/target/coldfire/iaudio/m3/adc-target.h
@@ -0,0 +1,29 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Jens Arnold
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef _ADC_TARGET_H_
+#define _ADC_TARGET_H_
+
+#define NUM_ADC_CHANNELS 4
+
+#define ADC_BUTTONS 0
+#define ADC_BATTERY 1
+#define ADC_REMOTE 2
+
+#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 c7c5b2e..ecea221 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)
if (!hold_button)
{
- data = adc_scan(ADC_BUTTONS);
+ data = adc_read(ADC_BUTTONS);
if (data < 0xc0)
{
@@ -82,7 +82,7 @@ int button_read_device(void)
}
/* remote buttons */
- data = remote_detect() ? adc_scan(ADC_REMOTE) : 0xff;
+ data = remote_detect() ? adc_read(ADC_REMOTE) : 0xff;
remote_hold_button_old = remote_hold_button;
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 7b5af43..52a5de3 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)
/* Charger detect */
and_l(~0x00000020, &GPIO1_ENABLE);
or_l(0x00000020, &GPIO1_FUNCTION);
+
+ /* FIXME: Just disable the multi-colour LED for now. */
+ and_l(~0x00000210, &GPIO1_OUT);
+ and_l(~0x00008000, &GPIO_OUT);
}
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 0000000..8c94947
--- /dev/null
+++ b/firmware/target/coldfire/iaudio/m3/powermgmt-m3.c
@@ -0,0 +1,57 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 Jens Arnold
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "adc.h"
+#include "powermgmt.h"
+
+const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
+{
+ 3540
+};
+
+const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
+{
+ 3500
+};
+
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
+const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
+{
+ /* average measured values from X5 and M5L */
+ { 3500, 3650, 3720, 3740, 3760, 3790, 3840, 3900, 3950, 4040, 4120 }
+};
+
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
+const unsigned short percent_to_volt_charge[11] =
+{
+ /* TODO: This is identical to the discharge curve.
+ * Calibrate charging curve using a battery_bench log. */
+ 3500, 3650, 3720, 3740, 3760, 3790, 3840, 3900, 3950, 4040, 4120
+};
+
+#define BATTERY_SCALE_FACTOR 5720
+/* full-scale ADC readout (2^8) in millivolt */
+
+/* Returns battery voltage from ADC [millivolts] */
+unsigned int battery_adc_voltage(void)
+{
+ return (adc_read(ADC_BATTERY) * BATTERY_SCALE_FACTOR) >> 8;
+}
+
diff --git a/firmware/target/coldfire/iaudio/powermgmt-iaudio.c b/firmware/target/coldfire/iaudio/powermgmt-iaudio.c
index c4d64e6..6e2b19d 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] =
/* Returns battery voltage from ADC [millivolts] */
unsigned int battery_adc_voltage(void)
{
-#ifdef IAUDIO_M3
- return 4000; /* FIXME: fake value - no ADC yet */
-#else
return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10;
-#endif
}
diff --git a/firmware/target/coldfire/system-coldfire.c b/firmware/target/coldfire/system-coldfire.c
index eca5440..97e9d35 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 */
#define EXCP_BUTTON_MASK 0x0c000000
#define EXCP_BUTTON_VALUE 0x08000000 /* On button and !hold */
#define EXCP_PLLCR 0x10400000
+#elif defined(IAUDIO_M3)
+#define EXCP_BUTTON_GPIO_READ GPIO1_READ
+#define EXCP_BUTTON_MASK 0x00000202
+#define EXCP_BUTTON_VALUE 0x00000200 /* On button and !hold */
+#define EXCP_PLLCR 0x10800000
#else
#define EXCP_BUTTON_GPIO_READ GPIO1_READ
#define EXCP_BUTTON_MASK 0x00000022