summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandypotter <liveboxandy@gmail.com>2013-04-15 20:09:39 +0100
committerMarcin Bukat <marcin.bukat@gmail.com>2013-04-25 21:02:09 +0200
commitecaa40166000e3d6b49542d42804127c0a6079e2 (patch)
tree35ce073fb6d63f90fa3be39aa7433907327b8998
parent354c9894062886443e1c53cc4dc5669a1d72a5f4 (diff)
downloadrockbox-ecaa401.tar.gz
rockbox-ecaa401.tar.bz2
rockbox-ecaa401.zip
Add Serial Port 1 support for iPod Photo/Color/4G/Mini2G
Based on FS#9920 by Ryan Press with changes to selection logic so that it works on my iPod Photo. Should also work on iPod Color/4G and Mini2G. Moved all target specific code from firmware/drivers/serial.c into new file firmware/target/arm/pp/uart-pp.c in the same manner as other target specific uart code. Update to fix build error on ipodmini2g by adding defines in config file. Removed unwanted whitespace Tested on iPod Photo. Change-Id: Ia5539563966198e06372d70b5adf2ef78882f863 Reviewed-on: http://gerrit.rockbox.org/455 Reviewed-by: andypotter <liveboxandy@gmail.com> Tested-by: andypotter <liveboxandy@gmail.com> Reviewed-by: Marcin Bukat <marcin.bukat@gmail.com>
-rw-r--r--firmware/SOURCES8
-rw-r--r--firmware/drivers/serial.c172
-rw-r--r--firmware/export/config/ipodmini2g.h13
-rw-r--r--firmware/target/arm/pp/system-pp502x.c20
-rw-r--r--firmware/target/arm/pp/uart-pp.c265
5 files changed, 292 insertions, 186 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index e6c0b967d4..9c45808b66 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -595,10 +595,16 @@ target/arm/pp/wmcodec-pp.c
target/arm/pp/system-pp5002.c
target/arm/pp/usb-fw-pp5002.c
target/arm/pp/ata-pp5002.c
+# ifdef HAVE_SERIAL
+target/arm/pp/uart-pp.c
+# endif /* HAVE_SERIAL */
#elif defined CPU_PP502x
target/arm/pp/usb-fw-pp502x.c
target/arm/pp/system-pp502x.c
-#endif
+# ifdef HAVE_SERIAL
+target/arm/pp/uart-pp.c
+# endif /* HAVE_SERIAL */
+#endif /* (CONFIG_CPU==PP5002) || CPU_PP502x */
#ifdef BOOTLOADER
#ifdef HAVE_BOOTLOADER_USB_MODE
target/arm/pp/crt0-pp502x-bl-usb.S
diff --git a/firmware/drivers/serial.c b/firmware/drivers/serial.c
index a46342389d..0fab570fdc 100644
--- a/firmware/drivers/serial.c
+++ b/firmware/drivers/serial.c
@@ -21,179 +21,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
-#include "button.h"
-#include "config.h"
-#include "cpu.h"
-#include "system.h"
-#include "kernel.h"
-#include "lcd.h"
#include "serial.h"
-#include "iap.h"
-
-#if defined(IPOD_ACCESSORY_PROTOCOL)
-static int autobaud = 0;
-
-static void set_bitrate(unsigned int rate)
-{
- unsigned int divisor;
-
- divisor = 24000000L / rate / 16;
- SER0_LCR = 0x80; /* Divisor latch enable */
- SER0_DLL = (divisor >> 0) & 0xFF;
- SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
-}
-
-void serial_setup (void)
-{
- int tmp;
-
-#if defined(IPOD_COLOR) || defined(IPOD_4G)
- /* Route the Tx/Rx pins. 4G Ipod??? */
- outl(0x70000018, inl(0x70000018) & ~0xc00);
-#elif defined(IPOD_NANO) || defined(IPOD_VIDEO)
- /* Route the Tx/Rx pins. 5G Ipod */
- (*(volatile unsigned long *)(0x7000008C)) &= ~0x0C;
- GPO32_ENABLE &= ~0x0C;
-#endif
-
- DEV_EN = DEV_EN | DEV_SER0;
- CPU_HI_INT_DIS = SER0_MASK;
-
- DEV_RS |= DEV_SER0;
- sleep(1);
- DEV_RS &= ~DEV_SER0;
-
- SER0_LCR = 0x80; /* Divisor latch enable */
- SER0_DLM = 0x00;
- SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
- SER0_IER = 0x01;
-
- SER0_FCR = 0x07; /* Tx+Rx FIFO reset and FIFO enable */
-
- CPU_INT_EN |= HI_MASK;
- CPU_HI_INT_EN |= SER0_MASK;
- tmp = SER0_RBR;
-
- serial_bitrate(0);
-}
-
-void serial_bitrate(int rate)
-{
- if(rate == 0)
- {
- autobaud = 2;
- set_bitrate(115200);
- }
- else
- {
- autobaud = 0;
- set_bitrate(rate);
- }
-}
-
-int tx_rdy(void)
-{
- if((SER0_LSR & 0x20))
- return 1;
- else
- return 0;
-}
-
-static int rx_rdy(void)
-{
- if((SER0_LSR & 0x1))
- return 1;
- else
- return 0;
-}
-
-void tx_writec(unsigned char c)
-{
- SER0_THR =(int) c;
-}
-
-static unsigned char rx_readc(void)
-{
- return (SER0_RBR & 0xFF);
-}
-
-void SERIAL0(void)
-{
- static int badbaud = 0;
- static bool newpkt = true;
- char temp;
-
- while(rx_rdy())
- {
- temp = rx_readc();
- if (newpkt && autobaud > 0)
- {
- if (autobaud == 1)
- {
- switch (temp)
- {
- case 0xFF:
- case 0x55:
- break;
- case 0xFC:
- set_bitrate(19200);
- temp = 0xFF;
- break;
- case 0xE0:
- set_bitrate(9600);
- temp = 0xFF;
- break;
- default:
- badbaud++;
- if (badbaud >= 6) /* Switch baud detection mode */
- {
- autobaud = 2;
- set_bitrate(115200);
- badbaud = 0;
- } else {
- set_bitrate(57600);
- }
- continue;
- }
- } else {
- switch (temp)
- {
- case 0xFF:
- case 0x55:
- break;
- case 0xFE:
- set_bitrate(57600);
- temp = 0xFF;
- break;
- case 0xFC:
- set_bitrate(38400);
- temp = 0xFF;
- break;
- case 0xE0:
- set_bitrate(19200);
- temp = 0xFF;
- break;
- default:
- badbaud++;
- if (badbaud >= 6) /* Switch baud detection */
- {
- autobaud = 1;
- set_bitrate(57600);
- badbaud = 0;
- } else {
- set_bitrate(115200);
- }
- continue;
- }
- }
- }
- bool pkt = iap_getc(temp);
- if(newpkt && !pkt)
- autobaud = 0; /* Found good baud */
- newpkt = pkt;
- }
-}
-#endif
void dprintf(const char * str, ... )
{
diff --git a/firmware/export/config/ipodmini2g.h b/firmware/export/config/ipodmini2g.h
index 12f63f9e11..5e4731679f 100644
--- a/firmware/export/config/ipodmini2g.h
+++ b/firmware/export/config/ipodmini2g.h
@@ -18,6 +18,8 @@
/* define this if you have recording possibility */
/*#define HAVE_RECORDING*/
+#define INPUT_SRC_CAPS (SRC_CAP_FMRADIO)
+
/* define the bitmask of hardware sample rates */
#define HW_SAMPR_CAPS (SAMPR_CAP_96 | SAMPR_CAP_88 | SAMPR_CAP_48 | \
SAMPR_CAP_44 | SAMPR_CAP_32 | SAMPR_CAP_8)
@@ -156,6 +158,11 @@
* if USB/MAIN power is discernable and hardware doesn't compel charging */
#define HAVE_USB_CHARGING_ENABLE
+
+/* Define Apple remote tuner */
+#define CONFIG_TUNER IPOD_REMOTE_TUNER
+#define HAVE_RDS_CAP
+
/* Define this if you have a PortalPlayer PP5022 */
#define CONFIG_CPU PP5022
@@ -166,7 +173,7 @@
#define HAVE_ATA_POWER_OFF
/* define this if the hardware can be powered off while charging */
-//#define HAVE_POWEROFF_WHILE_CHARGING
+/*#define HAVE_POWEROFF_WHILE_CHARGING */
/* The start address index for ROM builds */
#define ROM_START 0x00000000
@@ -212,8 +219,10 @@
#define ICODE_ATTR_TREMOR_NOT_MDCT
-#define IRAM_LCDFRAMEBUFFER IBSS_ATTR /* put the lcd frame buffer in IRAM */
+#define IPOD_ACCESSORY_PROTOCOL
+#define HAVE_SERIAL
+#define IRAM_LCDFRAMEBUFFER IBSS_ATTR /* put the lcd frame buffer in IRAM */
/* DMA is used only for reading on PP502x because although reads are ~8x faster
* writes appear to be ~25% slower.
diff --git a/firmware/target/arm/pp/system-pp502x.c b/firmware/target/arm/pp/system-pp502x.c
index d3331bf9f4..af2e6d7761 100644
--- a/firmware/target/arm/pp/system-pp502x.c
+++ b/firmware/target/arm/pp/system-pp502x.c
@@ -32,7 +32,7 @@
#if !defined(BOOTLOADER) || defined(HAVE_BOOTLOADER_USB_MODE)
extern void TIMER1(void);
extern void TIMER2(void);
-extern void SERIAL0(void);
+extern void SERIAL_ISR(void);
#if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
static struct corelock cpufreq_cl SHAREDBSS_ATTR;
@@ -126,7 +126,6 @@ void __attribute__((interrupt("IRQ"))) irq_handler(void)
button_int();
if (GPIOD_INT_STAT & 0x80)
headphones_int();
-
}
else if (CPU_HI_INT_STAT & GPIO2_MASK) {
if (GPIOL_INT_STAT & 0x04)
@@ -169,8 +168,8 @@ void __attribute__((interrupt("IRQ"))) irq_handler(void)
/* end PBELL_VIBE500 */
#endif
#ifdef IPOD_ACCESSORY_PROTOCOL
- else if (CPU_HI_INT_STAT & SER0_MASK) {
- SERIAL0();
+ else if (CPU_HI_INT_STAT & (SER0_MASK | SER1_MASK)) {
+ SERIAL_ISR();
}
#endif
} else {
@@ -310,7 +309,7 @@ void set_cpu_frequency(long frequency)
#else
static void pp_set_cpu_frequency(long frequency)
#endif
-{
+{
#if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
corelock_lock(&cpufreq_cl);
#endif
@@ -334,7 +333,7 @@ static void pp_set_cpu_frequency(long frequency)
PLL_CONTROL &= ~0x80000000; /* disable PLL */
DEV_INIT2 &= ~INIT_PLL; /* disable PLL power */
break;
-
+
case CPUFREQ_MAX:
cpu_frequency = CPUFREQ_MAX;
DEV_INIT2 |= INIT_PLL; /* enable PLL power */
@@ -379,7 +378,7 @@ static void pp_set_cpu_frequency(long frequency)
DEV_INIT2 &= ~INIT_PLL; /* disable PLL power */
break;
#else /******** CPUFREQ_NORMAL = 30MHz with PLL ********/
- case CPUFREQ_NORMAL:
+ case CPUFREQ_NORMAL:
cpu_frequency = CPUFREQ_NORMAL;
DEV_INIT2 |= INIT_PLL; /* enable PLL power */
PLL_CONTROL |= 0x88000000; /* enable PLL */
@@ -421,7 +420,7 @@ static void pp_set_cpu_frequency(long frequency)
DEV_INIT2 &= ~INIT_PLL; /* disable PLL power */
break;
}
-
+
#if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
corelock_unlock(&cpufreq_cl);
#endif
@@ -447,7 +446,7 @@ void system_init(void)
DEV_RS2 = 0xffffdfff;
DEV_RS = 0x00000000;
DEV_RS2 = 0x00000000;
-#elif defined (IPOD_VIDEO)
+#elif defined (IPOD_VIDEO)
/* set minimum startup configuration */
DEV_EN = 0xc2000124;
DEV_EN2 = 0x00000000;
@@ -461,7 +460,7 @@ void system_init(void)
DEV_RS2 = 0xffffffff;
DEV_RS = 0x00000000;
DEV_RS2 = 0x00000000;
-#elif defined (IPOD_NANO)
+#elif defined (IPOD_NANO)
/* set minimum startup configuration */
DEV_EN = 0xc2000124;
DEV_EN2 = 0x00002000;
@@ -625,4 +624,3 @@ int system_memory_guard(int newmode)
(void)newmode;
return 0;
}
-
diff --git a/firmware/target/arm/pp/uart-pp.c b/firmware/target/arm/pp/uart-pp.c
new file mode 100644
index 0000000000..612ffdf77c
--- /dev/null
+++ b/firmware/target/arm/pp/uart-pp.c
@@ -0,0 +1,265 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Alan Korr & Nick Robinson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include "button.h"
+#include "config.h"
+#include "cpu.h"
+#include "system.h"
+#include "kernel.h"
+#include "lcd.h"
+#include "serial.h"
+#include "iap.h"
+
+#if defined(IPOD_ACCESSORY_PROTOCOL)
+static int autobaud = 0;
+volatile unsigned long * base_RBR, * base_THR, * base_LCR, * base_LSR, * base_DLL;
+
+static void set_bitrate(unsigned int rate)
+{
+ unsigned int divisor;
+
+ divisor = 24000000L / rate / 16;
+ *base_LCR = 0x80; /* Divisor latch enable */
+ *base_DLL = (divisor >> 0) & 0xFF;
+ *base_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
+}
+
+void serial_setup (void)
+{
+ int tmp;
+
+#if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI2G)
+
+ /* Route the Tx/Rx pins. 4G Ipod, ser1, dock connector */
+ GPIO_CLEAR_BITWISE(GPIOD_ENABLE, 0x6);
+ GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x6);
+
+ outl(0x70000018, inl(0x70000018) & ~0xc00);
+
+ base_RBR = &SER1_RBR;
+ base_THR = &SER1_THR;
+ base_LCR = &SER1_LCR;
+ base_LSR = &SER1_LSR;
+ base_DLL = &SER1_DLL;
+
+ DEV_EN |= DEV_SER1;
+ CPU_HI_INT_DIS = SER1_MASK;
+
+ DEV_RS |= DEV_SER1;
+ sleep(1);
+ DEV_RS &= ~DEV_SER1;
+
+ SER1_LCR = 0x80; /* Divisor latch enable */
+ SER1_DLM = 0x00;
+ SER1_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
+ SER1_IER = 0x01;
+
+ SER1_FCR = 0x07; /* Tx+Rx FIFO reset and FIFO enable */
+
+ CPU_INT_EN = HI_MASK;
+ CPU_HI_INT_EN = SER1_MASK;
+ tmp = SER1_RBR;
+
+#elif defined(IPOD_NANO) || defined(IPOD_VIDEO)
+ /* Route the Tx/Rx pins. 5G Ipod */
+ (*(volatile unsigned long *)(0x7000008C)) &= ~0x0C;
+ GPO32_ENABLE &= ~0x0C;
+
+ base_RBR = &SER0_RBR;
+ base_THR = &SER0_THR;
+ base_LCR = &SER0_LCR;
+ base_LSR = &SER0_LSR;
+ base_DLL = &SER0_DLL;
+
+ DEV_EN = DEV_EN | DEV_SER0;
+ CPU_HI_INT_DIS = SER0_MASK;
+
+ DEV_RS |= DEV_SER0;
+ sleep(1);
+ DEV_RS &= ~DEV_SER0;
+
+ SER0_LCR = 0x80; /* Divisor latch enable */
+ SER0_DLM = 0x00;
+ SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
+ SER0_IER = 0x01;
+
+ SER0_FCR = 0x07; /* Tx+Rx FIFO reset and FIFO enable */
+
+ CPU_INT_EN = HI_MASK;
+ CPU_HI_INT_EN = SER0_MASK;
+ tmp = SER0_RBR;
+
+#else
+
+ /* Default Route the Tx/Rx pins. 4G Ipod, ser0, top connector */
+
+ GPIO_CLEAR_BITWISE(GPIOC_INT_EN, 0x8);
+ GPIO_CLEAR_BITWISE(GPIOC_INT_LEV, 0x8);
+ GPIOC_INT_CLR = 0x8;
+
+ base_RBR = &SER0_RBR;
+ base_THR = &SER0_THR;
+ base_LCR = &SER0_LCR;
+ base_LSR = &SER0_LSR;
+ base_DLL = &SER0_DLL;
+
+ DEV_EN |= DEV_SER0;
+ CPU_HI_INT_DIS = SER0_MASK;
+
+ DEV_RS |= DEV_SER0;
+ sleep(1);
+ DEV_RS &= ~DEV_SER0;
+
+ SER0_LCR = 0x80; /* Divisor latch enable */
+ SER0_DLM = 0x00;
+ SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
+ SER0_IER = 0x01;
+
+ SER0_FCR = 0x07; /* Tx+Rx FIFO reset and FIFO enable */
+
+ CPU_INT_EN = HI_MASK;
+ CPU_HI_INT_EN = SER0_MASK;
+ tmp = SER0_RBR;
+
+#endif
+
+ serial_bitrate(0);
+}
+
+void serial_bitrate(int rate)
+{
+ if(rate == 0)
+ {
+ autobaud = 2;
+ set_bitrate(115200);
+ }
+ else
+ {
+ autobaud = 0;
+ set_bitrate(rate);
+ }
+}
+
+int tx_rdy(void)
+{
+ if((*base_LSR & 0x20))
+ return 1;
+ else
+ return 0;
+}
+
+static int rx_rdy(void)
+{
+ if((*base_LSR & 0x1))
+ return 1;
+ else
+ return 0;
+}
+
+void tx_writec(unsigned char c)
+{
+ *base_THR =(int) c;
+}
+
+static unsigned char rx_readc(void)
+{
+ return (*base_RBR & 0xFF);
+}
+
+void SERIAL_ISR(void)
+{
+ static int badbaud = 0;
+ static bool newpkt = true;
+ char temp;
+
+ while(rx_rdy())
+ {
+ temp = rx_readc();
+ if (newpkt && autobaud > 0)
+ {
+ if (autobaud == 1)
+ {
+ switch (temp)
+ {
+ case 0xFF:
+ case 0x55:
+ break;
+ case 0xFC:
+ set_bitrate(19200);
+ temp = 0xFF;
+ break;
+ case 0xE0:
+ set_bitrate(9600);
+ temp = 0xFF;
+ break;
+ default:
+ badbaud++;
+ if (badbaud >= 6) /* Switch baud detection mode */
+ {
+ autobaud = 2;
+ set_bitrate(115200);
+ badbaud = 0;
+ } else {
+ set_bitrate(57600);
+ }
+ continue;
+ }
+ } else {
+ switch (temp)
+ {
+ case 0xFF:
+ case 0x55:
+ break;
+ case 0xFE:
+ set_bitrate(57600);
+ temp = 0xFF;
+ break;
+ case 0xFC:
+ set_bitrate(38400);
+ temp = 0xFF;
+ break;
+ case 0xE0:
+ set_bitrate(19200);
+ temp = 0xFF;
+ break;
+ default:
+ badbaud++;
+ if (badbaud >= 6) /* Switch baud detection */
+ {
+ autobaud = 1;
+ set_bitrate(57600);
+ badbaud = 0;
+ } else {
+ set_bitrate(115200);
+ }
+ continue;
+ }
+ }
+ }
+ bool pkt = iap_getc(temp);
+ if(newpkt && !pkt)
+ autobaud = 0; /* Found good baud */
+ newpkt = pkt;
+ }
+}
+#endif