summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCástor Muñoz <cmvidal@gmail.com>2016-05-25 23:18:33 +0200
committerCástor Muñoz <cmvidal@gmail.com>2016-05-26 09:05:44 +0200
commitf6ed4f830666b7281308cca4bf90e0000dcfaef4 (patch)
tree5cdcbf641268ec6f9ad551d6c274bd2db384dca1
parentd8989b15b79b4732df147b35bbf0beb39be06065 (diff)
downloadrockbox-f6ed4f830666b7281308cca4bf90e0000dcfaef4.zip
rockbox-f6ed4f830666b7281308cca4bf90e0000dcfaef4.tar.gz
rockbox-f6ed4f830666b7281308cca4bf90e0000dcfaef4.tar.bz2
rockbox-f6ed4f830666b7281308cca4bf90e0000dcfaef4.tar.xz
iPod Classic: use PMU interrupts to detect accessories
- Speed auto detection is launched when an accessory is inserted, so the user doesn't need to modify settings to use accessories that operates at different speeds (or when the same accessory is unplugged and plugged again). - UART controller is disabled when no accessory is inserted, not much powersave but everything counts. Change-Id: If20c3617c2a87b6277fd7e0270031030c44fa953
-rw-r--r--firmware/target/arm/s5l8702/debug-s5l8702.c38
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/serial-ipod6g.c67
2 files changed, 75 insertions, 30 deletions
diff --git a/firmware/target/arm/s5l8702/debug-s5l8702.c b/firmware/target/arm/s5l8702/debug-s5l8702.c
index 48a20a9..b274b5f 100644
--- a/firmware/target/arm/s5l8702/debug-s5l8702.c
+++ b/firmware/target/arm/s5l8702/debug-s5l8702.c
@@ -138,22 +138,26 @@ bool dbg_hw_info(void)
else if(state==2)
{
extern struct uartc_port ser_port;
- int tx_stat, rx_stat, tx_speed, rx_speed;
- char line_cfg[4];
- int abr_stat;
- uint32_t abr_cnt;
- char *abrstatus[] = {"Idle", "Launched", "Counting", "Abnormal"};
-
- uartc_port_get_line_info(&ser_port,
- &tx_stat, &rx_stat, &tx_speed, &rx_speed, line_cfg);
- abr_stat = uartc_port_get_abr_info(&ser_port, &abr_cnt);
-
- _DEBUG_PRINTF("UART %d:", ser_port.id);
- line++;
- _DEBUG_PRINTF("line: %s", line_cfg);
- _DEBUG_PRINTF("Tx: %s, speed: %d", tx_stat ? "On":"Off", tx_speed);
- _DEBUG_PRINTF("Rx: %s, speed: %d", rx_stat ? "On":"Off", rx_speed);
- _DEBUG_PRINTF("ABR: %s, cnt: %u", abrstatus[abr_stat], abr_cnt);
+ bool opened = !!ser_port.uartc->port_l[ser_port.id];
+ _DEBUG_PRINTF("UART %d: %s", ser_port.id, opened ? "opened":"closed");
+ if (opened)
+ {
+ int tx_stat, rx_stat, tx_speed, rx_speed;
+ char line_cfg[4];
+ int abr_stat;
+ uint32_t abr_cnt;
+ char *abrstatus[] = {"Idle", "Launched", "Counting", "Abnormal"};
+
+ uartc_port_get_line_info(&ser_port,
+ &tx_stat, &rx_stat, &tx_speed, &rx_speed, line_cfg);
+ abr_stat = uartc_port_get_abr_info(&ser_port, &abr_cnt);
+
+ line++;
+ _DEBUG_PRINTF("line: %s", line_cfg);
+ _DEBUG_PRINTF("Tx: %s, speed: %d", tx_stat ? "On":"Off", tx_speed);
+ _DEBUG_PRINTF("Rx: %s, speed: %d", rx_stat ? "On":"Off", rx_speed);
+ _DEBUG_PRINTF("ABR: %s, cnt: %u", abrstatus[abr_stat], abr_cnt);
+ }
line++;
_DEBUG_PRINTF("n_tx_bytes: %u", ser_port.n_tx_bytes);
_DEBUG_PRINTF("n_rx_bytes: %u", ser_port.n_rx_bytes);
@@ -162,7 +166,7 @@ bool dbg_hw_info(void)
_DEBUG_PRINTF("n_frame_err: %u", ser_port.n_frame_err);
_DEBUG_PRINTF("n_break_detect: %u", ser_port.n_break_detect);
_DEBUG_PRINTF("ABR n_abnormal: %u %u",
- ser_port.n_abnormal0, ser_port.n_abnormal1);
+ ser_port.n_abnormal0, ser_port.n_abnormal1);
}
#endif
else
diff --git a/firmware/target/arm/s5l8702/ipod6g/serial-ipod6g.c b/firmware/target/arm/s5l8702/ipod6g/serial-ipod6g.c
index c77b5d0..f1f0698 100644
--- a/firmware/target/arm/s5l8702/ipod6g/serial-ipod6g.c
+++ b/firmware/target/arm/s5l8702/ipod6g/serial-ipod6g.c
@@ -48,7 +48,7 @@
extern const struct uartc s5l8702_uartc;
#ifdef IPOD_ACCESSORY_PROTOCOL
-void iap_rx_isr(int, char*, char*, uint32_t);
+static void iap_rx_isr(int, char*, char*, uint32_t);
#endif
struct uartc_port ser_port IDATA_ATTR =
@@ -75,6 +75,17 @@ struct uartc_port ser_port IDATA_ATTR =
/*
* serial driver API
*/
+int tx_rdy(void)
+{
+ return uartc_port_tx_ready(&ser_port) ? 1 : 0;
+}
+
+void tx_writec(unsigned char c)
+{
+ uartc_port_tx_byte(&ser_port, c);
+}
+
+#ifndef IPOD_ACCESSORY_PROTOCOL
void serial_setup(void)
{
uartc_port_open(&ser_port);
@@ -91,18 +102,10 @@ void serial_setup(void)
logf("[%lu] "MODEL_NAME" port %d ready!", USEC_TIMER, ser_port.id);
}
-int tx_rdy(void)
-{
- return uartc_port_tx_ready(&ser_port) ? 1 : 0;
-}
-
-void tx_writec(unsigned char c)
-{
- uartc_port_tx_byte(&ser_port, c);
-}
-
-#ifdef IPOD_ACCESSORY_PROTOCOL
+#else /* IPOD_ACCESSORY_PROTOCOL */
+#include "kernel.h"
+#include "pmu-target.h"
#include "iap.h"
static enum {
@@ -111,8 +114,46 @@ static enum {
ABR_STATUS_DONE
} abr_status;
+static int bitrate = 0;
+static bool acc_plugged = false;
+
+static void serial_acc_tick(void)
+{
+ bool plugged = pmu_accessory_present();
+ if (acc_plugged != plugged)
+ {
+ acc_plugged = plugged;
+ if (acc_plugged)
+ {
+ uartc_open(ser_port.uartc);
+ uartc_port_open(&ser_port);
+ /* set a default configuration, Tx and Rx modes are
+ disabled when the port is initialized */
+ uartc_port_config(&ser_port, ULCON_DATA_BITS_8,
+ ULCON_PARITY_NONE, ULCON_STOP_BITS_1);
+ uartc_port_set_tx_mode(&ser_port, UCON_MODE_INTREQ);
+ serial_bitrate(bitrate);
+ }
+ else
+ {
+ uartc_port_close(&ser_port);
+ uartc_close(ser_port.uartc);
+ }
+ }
+}
+
+void serial_setup(void)
+{
+ uartc_close(ser_port.uartc);
+ tick_add_task(serial_acc_tick);
+}
+
void serial_bitrate(int rate)
{
+ bitrate = rate;
+ if (!acc_plugged)
+ return;
+
logf("[%lu] serial_bitrate(%d)", USEC_TIMER, rate);
if (rate == 0) {
@@ -150,7 +191,7 @@ void serial_bitrate(int rate)
}
}
-void iap_rx_isr(int len, char *data, char *err, uint32_t abr_cnt)
+static void iap_rx_isr(int len, char *data, char *err, uint32_t abr_cnt)
{
/* ignore Rx errors, upper layer will discard bad packets */
(void) err;