From ecaa40166000e3d6b49542d42804127c0a6079e2 Mon Sep 17 00:00:00 2001 From: andypotter Date: Mon, 15 Apr 2013 20:09:39 +0100 Subject: 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 Tested-by: andypotter Reviewed-by: Marcin Bukat --- firmware/SOURCES | 8 +- firmware/drivers/serial.c | 172 --------------------- firmware/export/config/ipodmini2g.h | 13 +- firmware/target/arm/pp/system-pp502x.c | 20 ++- firmware/target/arm/pp/uart-pp.c | 265 +++++++++++++++++++++++++++++++++ 5 files changed, 292 insertions(+), 186 deletions(-) create mode 100644 firmware/target/arm/pp/uart-pp.c 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 #include #include -#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 +#include +#include +#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 -- cgit v1.2.3