mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-13 10:07:38 -04:00
pp502x: Restructure UART code
* Move to a structure instead of pointers to registers * Autobaud operates per-uart * When explitily setting uart speed, it applies to all uarts This allows both UARTs to be enabled and serviced simultaneously, allowing either accessory port to be used. Note that the last port to receive something is where subsequent transmits are directed, and only one set of IAP state is maintained. To change this, we will need to revamp IAP to support more than one state machine, and then extend the serial API to allow for both UARTs to be used independently. Probably not worth the effort. Change-Id: I0142f0906706fc0c4ee6d6d7aa6b0515e1a749dd
This commit is contained in:
parent
921abc7beb
commit
16a6ad032f
2 changed files with 65 additions and 76 deletions
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue