Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+65 -76
+2
firmware/target/arm/pp/system-pp502x.c
··· 190 190 else if (CPU_HI_INT_STAT & SER0_MASK) { 191 191 SERIAL_ISR(0); 192 192 } 193 + #if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) || defined(IPOD_MINI2G) 193 194 else if (CPU_HI_INT_STAT & SER1_MASK) { 194 195 SERIAL_ISR(1); 195 196 } 197 + #endif 196 198 #endif 197 199 } else { 198 200 if (COP_INT_STAT & TIMER2_MASK)
+63 -76
firmware/target/arm/pp/uart-pp.c
··· 31 31 #include "iap.h" 32 32 33 33 #if defined(IPOD_ACCESSORY_PROTOCOL) 34 - static int autobaud = 0; 35 - volatile unsigned long * base_RBR, * base_THR, * base_LCR, * base_LSR, * base_DLL; 34 + struct ppuart { 35 + volatile unsigned long *RBR_THR_DLL; 36 + volatile unsigned long *LCR; 37 + volatile unsigned long *LSR; 38 + int autobaud; 39 + }; 36 40 37 - static void set_bitrate(unsigned int rate) 41 + static struct ppuart SER0 = { &SER0_RBR, &SER0_LCR, &SER0_LSR, 0 }; 42 + #if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) || defined(IPOD_MINI2G) 43 + static struct ppuart SER1 = { &SER1_RBR, &SER1_LCR, &SER1_LSR, 0 }; 44 + static volatile struct ppuart *SERn = &SER1; // ie dock connector 45 + #else 46 + static volatile struct ppuart *SERn = &SER0; 47 + #endif 48 + 49 + static void set_bitrate(volatile struct ppuart *port, unsigned int rate) 38 50 { 39 51 unsigned int divisor; 40 52 41 53 divisor = 24000000L / rate / 16; 42 - *base_LCR = 0x80; /* Divisor latch enable */ 43 - *base_DLL = (divisor >> 0) & 0xFF; 44 - *base_LCR = 0x03; /* Divisor latch disable, 8-N-1 */ 54 + *port->LCR = 0x80; /* Divisor latch enable */ 55 + *port->RBR_THR_DLL = (divisor >> 0) & 0xFF; 56 + *port->LCR = 0x03; /* Divisor latch disable, 8-N-1 */ 45 57 } 46 58 47 59 void serial_setup (void) ··· 53 65 (*(volatile unsigned long *)(0x7000008C)) &= ~0x0C; 54 66 GPO32_ENABLE &= ~0x0C; 55 67 56 - base_RBR = &SER0_RBR; 57 - base_THR = &SER0_THR; 58 - base_LCR = &SER0_LCR; 59 - base_LSR = &SER0_LSR; 60 - base_DLL = &SER0_DLL; 61 - 62 68 DEV_EN = DEV_EN | DEV_SER0; 63 69 CPU_HI_INT_DIS = SER0_MASK; 64 70 ··· 77 83 CPU_HI_INT_EN = SER0_MASK; 78 84 tmp = SER0_RBR; 79 85 80 - serial_bitrate(0); 86 + SER0.autobaud = 2; 87 + set_bitrate(&SER0, 115200); 81 88 82 89 #elif defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) || defined(IPOD_MINI2G) 83 90 84 91 /* Route the Tx/Rx pins. 4G Ipods, MINI & MINI2G. ser1, dock connector */ 85 92 GPIO_CLEAR_BITWISE(GPIOD_ENABLE, 0x6); 86 93 GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x6); 94 + GPIOD_INT_CLR = 0x6; 87 95 88 96 outl(0x70000018, inl(0x70000018) & ~0xc00); 89 97 90 - base_RBR = &SER1_RBR; 91 - base_THR = &SER1_THR; 92 - base_LCR = &SER1_LCR; 93 - base_LSR = &SER1_LSR; 94 - base_DLL = &SER1_DLL; 95 - 96 98 DEV_EN |= DEV_SER1; 97 99 CPU_HI_INT_DIS = SER1_MASK; 98 100 ··· 111 113 CPU_HI_INT_EN = SER1_MASK; 112 114 tmp = SER1_RBR; 113 115 114 - serial_bitrate(0); 115 - 116 116 /* Route the Tx/Rx pins. 4G Ipod, ser0, top connector */ 117 117 GPIO_CLEAR_BITWISE(GPIOC_INT_EN, 0x8); 118 118 GPIO_CLEAR_BITWISE(GPIOC_INT_LEV, 0x8); 119 119 GPIOC_INT_CLR = 0x8; 120 120 121 - base_RBR = &SER0_RBR; 122 - base_THR = &SER0_THR; 123 - base_LCR = &SER0_LCR; 124 - base_LSR = &SER0_LSR; 125 - base_DLL = &SER0_DLL; 126 - 127 121 DEV_EN |= DEV_SER0; 128 122 CPU_HI_INT_DIS = SER0_MASK; 129 123 ··· 142 136 CPU_HI_INT_EN = SER0_MASK; 143 137 tmp = SER0_RBR; 144 138 145 - serial_bitrate(0); 139 + SER1.autobaud = 2; 140 + set_bitrate(&SER1, 115200); 141 + SER0.autobaud = 2; 142 + set_bitrate(&SER0, 115200); 146 143 147 144 #endif 148 145 ··· 154 151 { 155 152 if(rate == 0) 156 153 { 157 - autobaud = 2; 158 - set_bitrate(115200); 154 + SER0.autobaud = 2; 155 + set_bitrate(&SER0, 115200); 156 + #if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) || defined(IPOD_MINI2G) 157 + SER1.autobaud = 2; 158 + set_bitrate(&SER1, 115200); 159 + #endif 159 160 } 160 161 else 161 162 { 162 - autobaud = 0; 163 - set_bitrate(rate); 163 + SER0.autobaud = 0; 164 + set_bitrate(&SER0, rate); 165 + #if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) || defined(IPOD_MINI2G) 166 + SER1.autobaud = 0; 167 + set_bitrate(&SER1, rate); 168 + #endif 164 169 } 165 170 } 166 171 167 172 int tx_rdy(void) 168 173 { 169 - if((*base_LSR & 0x20)) 170 - return 1; 171 - else 172 - return 0; 173 - } 174 - 175 - static int rx_rdy(void) 176 - { 177 - if((*base_LSR & 0x1)) 174 + if((*SERn->LSR & 0x20)) 178 175 return 1; 179 176 else 180 177 return 0; ··· 182 179 183 180 void tx_writec(unsigned char c) 184 181 { 185 - *base_THR =(int) c; 186 - } 187 - 188 - static unsigned char rx_readc(void) 189 - { 190 - return (*base_RBR & 0xFF); 182 + *SERn->RBR_THR_DLL = (int)c; 191 183 } 192 184 193 185 void SERIAL_ISR(int port) ··· 196 188 static bool newpkt = true; 197 189 char temp; 198 190 199 - if (port && base_RBR != &SER1_RBR) { 200 - base_RBR = &SER1_RBR; 201 - base_THR = &SER1_THR; 202 - base_LCR = &SER1_LCR; 203 - base_LSR = &SER1_LSR; 204 - base_DLL = &SER1_DLL; 205 - } else if (!port && base_RBR != &SER0_RBR) { 206 - base_RBR = &SER0_RBR; 207 - base_THR = &SER0_THR; 208 - base_LCR = &SER0_LCR; 209 - base_LSR = &SER0_LSR; 210 - base_DLL = &SER0_DLL; 211 - } 191 + #if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) || defined(IPOD_MINI2G) 192 + if (port && SERn != &SER1) 193 + SERn = &SER1; 194 + else if (!port && SERn != &SER0) 195 + SERn = &SER0; 196 + #else 197 + (void)port; 198 + #endif 212 199 213 - while(rx_rdy()) 200 + while((*SERn->LSR & 0x1)) 214 201 { 215 - temp = rx_readc(); 216 - if (newpkt && autobaud > 0) 202 + temp = (*SERn->RBR_THR_DLL & 0xFF); 203 + if (newpkt && SERn->autobaud > 0) 217 204 { 218 - if (autobaud == 1) 205 + if (SERn->autobaud == 1) 219 206 { 220 207 switch (temp) 221 208 { ··· 223 210 case 0x55: 224 211 break; 225 212 case 0xFC: 226 - set_bitrate(19200); 213 + set_bitrate(SERn, 19200); 227 214 temp = 0xFF; 228 215 break; 229 216 case 0xE0: 230 - set_bitrate(9600); 217 + set_bitrate(SERn, 9600); 231 218 temp = 0xFF; 232 219 break; 233 220 default: 234 221 badbaud++; 235 222 if (badbaud >= 6) /* Switch baud detection mode */ 236 223 { 237 - autobaud = 2; 238 - set_bitrate(115200); 224 + SERn->autobaud = 2; 225 + set_bitrate(SERn, 115200); 239 226 badbaud = 0; 240 227 } else { 241 - set_bitrate(57600); 228 + set_bitrate(SERn, 57600); 242 229 } 243 230 continue; 244 231 } ··· 249 236 case 0x55: 250 237 break; 251 238 case 0xFE: 252 - set_bitrate(57600); 239 + set_bitrate(SERn, 57600); 253 240 temp = 0xFF; 254 241 break; 255 242 case 0xFC: 256 - set_bitrate(38400); 243 + set_bitrate(SERn, 38400); 257 244 temp = 0xFF; 258 245 break; 259 246 case 0xE0: 260 - set_bitrate(19200); 247 + set_bitrate(SERn, 19200); 261 248 temp = 0xFF; 262 249 break; 263 250 default: 264 251 badbaud++; 265 252 if (badbaud >= 6) /* Switch baud detection */ 266 253 { 267 - autobaud = 1; 268 - set_bitrate(57600); 254 + SERn->autobaud = 1; 255 + set_bitrate(SERn, 57600); 269 256 badbaud = 0; 270 257 } else { 271 - set_bitrate(115200); 258 + set_bitrate(SERn, 115200); 272 259 } 273 260 continue; 274 261 } ··· 276 263 } 277 264 bool pkt = iap_getc(temp); 278 265 if(newpkt && !pkt) 279 - autobaud = 0; /* Found good baud */ 266 + SERn->autobaud = 0; /* Found good baud */ 280 267 newpkt = pkt; 281 268 } 282 269 }