diff --git a/firmware/target/arm/pp/system-pp502x.c b/firmware/target/arm/pp/system-pp502x.c index 860e17957c..8b9c2b15a1 100644 --- a/firmware/target/arm/pp/system-pp502x.c +++ b/firmware/target/arm/pp/system-pp502x.c @@ -190,9 +190,11 @@ void __attribute__((interrupt("IRQ"))) irq_handler(void) else if (CPU_HI_INT_STAT & SER0_MASK) { SERIAL_ISR(0); } +#if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) || defined(IPOD_MINI2G) else if (CPU_HI_INT_STAT & SER1_MASK) { SERIAL_ISR(1); } +#endif #endif } else { if (COP_INT_STAT & TIMER2_MASK) diff --git a/firmware/target/arm/pp/uart-pp.c b/firmware/target/arm/pp/uart-pp.c index f7d5aacb11..e51c680053 100644 --- a/firmware/target/arm/pp/uart-pp.c +++ b/firmware/target/arm/pp/uart-pp.c @@ -31,17 +31,29 @@ #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; +struct ppuart { + volatile unsigned long *RBR_THR_DLL; + volatile unsigned long *LCR; + volatile unsigned long *LSR; + int autobaud; +}; -static void set_bitrate(unsigned int rate) +static struct ppuart SER0 = { &SER0_RBR, &SER0_LCR, &SER0_LSR, 0 }; +#if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) || defined(IPOD_MINI2G) +static struct ppuart SER1 = { &SER1_RBR, &SER1_LCR, &SER1_LSR, 0 }; +static volatile struct ppuart *SERn = &SER1; // ie dock connector +#else +static volatile struct ppuart *SERn = &SER0; +#endif + +static void set_bitrate(volatile struct ppuart *port, 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 */ + *port->LCR = 0x80; /* Divisor latch enable */ + *port->RBR_THR_DLL = (divisor >> 0) & 0xFF; + *port->LCR = 0x03; /* Divisor latch disable, 8-N-1 */ } void serial_setup (void) @@ -53,12 +65,6 @@ void serial_setup (void) (*(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; @@ -77,22 +83,18 @@ void serial_setup (void) CPU_HI_INT_EN = SER0_MASK; tmp = SER0_RBR; - serial_bitrate(0); + SER0.autobaud = 2; + set_bitrate(&SER0, 115200); #elif defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) || defined(IPOD_MINI2G) /* Route the Tx/Rx pins. 4G Ipods, MINI & MINI2G. ser1, dock connector */ GPIO_CLEAR_BITWISE(GPIOD_ENABLE, 0x6); GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x6); + GPIOD_INT_CLR = 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; @@ -111,19 +113,11 @@ void serial_setup (void) CPU_HI_INT_EN = SER1_MASK; tmp = SER1_RBR; - serial_bitrate(0); - /* 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; @@ -142,7 +136,10 @@ void serial_setup (void) CPU_HI_INT_EN = SER0_MASK; tmp = SER0_RBR; - serial_bitrate(0); + SER1.autobaud = 2; + set_bitrate(&SER1, 115200); + SER0.autobaud = 2; + set_bitrate(&SER0, 115200); #endif @@ -154,27 +151,27 @@ void serial_bitrate(int rate) { if(rate == 0) { - autobaud = 2; - set_bitrate(115200); + SER0.autobaud = 2; + set_bitrate(&SER0, 115200); +#if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) || defined(IPOD_MINI2G) + SER1.autobaud = 2; + set_bitrate(&SER1, 115200); +#endif } else { - autobaud = 0; - set_bitrate(rate); + SER0.autobaud = 0; + set_bitrate(&SER0, rate); +#if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) || defined(IPOD_MINI2G) + SER1.autobaud = 0; + set_bitrate(&SER1, rate); +#endif } } int tx_rdy(void) { - if((*base_LSR & 0x20)) - return 1; - else - return 0; -} - -static int rx_rdy(void) -{ - if((*base_LSR & 0x1)) + if((*SERn->LSR & 0x20)) return 1; else return 0; @@ -182,12 +179,7 @@ static int rx_rdy(void) void tx_writec(unsigned char c) { - *base_THR =(int) c; -} - -static unsigned char rx_readc(void) -{ - return (*base_RBR & 0xFF); + *SERn->RBR_THR_DLL = (int)c; } void SERIAL_ISR(int port) @@ -196,26 +188,21 @@ void SERIAL_ISR(int port) static bool newpkt = true; char temp; - if (port && base_RBR != &SER1_RBR) { - base_RBR = &SER1_RBR; - base_THR = &SER1_THR; - base_LCR = &SER1_LCR; - base_LSR = &SER1_LSR; - base_DLL = &SER1_DLL; - } else if (!port && base_RBR != &SER0_RBR) { - base_RBR = &SER0_RBR; - base_THR = &SER0_THR; - base_LCR = &SER0_LCR; - base_LSR = &SER0_LSR; - base_DLL = &SER0_DLL; - } +#if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) || defined(IPOD_MINI2G) + if (port && SERn != &SER1) + SERn = &SER1; + else if (!port && SERn != &SER0) + SERn = &SER0; +#else + (void)port; +#endif - while(rx_rdy()) + while((*SERn->LSR & 0x1)) { - temp = rx_readc(); - if (newpkt && autobaud > 0) + temp = (*SERn->RBR_THR_DLL & 0xFF); + if (newpkt && SERn->autobaud > 0) { - if (autobaud == 1) + if (SERn->autobaud == 1) { switch (temp) { @@ -223,22 +210,22 @@ void SERIAL_ISR(int port) case 0x55: break; case 0xFC: - set_bitrate(19200); + set_bitrate(SERn, 19200); temp = 0xFF; break; case 0xE0: - set_bitrate(9600); + set_bitrate(SERn, 9600); temp = 0xFF; break; default: badbaud++; if (badbaud >= 6) /* Switch baud detection mode */ { - autobaud = 2; - set_bitrate(115200); + SERn->autobaud = 2; + set_bitrate(SERn, 115200); badbaud = 0; } else { - set_bitrate(57600); + set_bitrate(SERn, 57600); } continue; } @@ -249,26 +236,26 @@ void SERIAL_ISR(int port) case 0x55: break; case 0xFE: - set_bitrate(57600); + set_bitrate(SERn, 57600); temp = 0xFF; break; case 0xFC: - set_bitrate(38400); + set_bitrate(SERn, 38400); temp = 0xFF; break; case 0xE0: - set_bitrate(19200); + set_bitrate(SERn, 19200); temp = 0xFF; break; default: badbaud++; if (badbaud >= 6) /* Switch baud detection */ { - autobaud = 1; - set_bitrate(57600); + SERn->autobaud = 1; + set_bitrate(SERn, 57600); badbaud = 0; } else { - set_bitrate(115200); + set_bitrate(SERn, 115200); } continue; } @@ -276,7 +263,7 @@ void SERIAL_ISR(int port) } bool pkt = iap_getc(temp); if(newpkt && !pkt) - autobaud = 0; /* Found good baud */ + SERn->autobaud = 0; /* Found good baud */ newpkt = pkt; } }