summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorMichael Giacomelli <giac2000@hotmail.com>2008-12-25 01:46:16 +0000
committerMichael Giacomelli <giac2000@hotmail.com>2008-12-25 01:46:16 +0000
commit70e9c7aed361787a404c4856211ddf53127fca9a (patch)
tree3072967cf3ed2779acf939e150694ef437cbad2d /firmware
parentf921f74873a1439cf4e25b87192b31c079863924 (diff)
downloadrockbox-70e9c7aed361787a404c4856211ddf53127fca9a.tar.gz
rockbox-70e9c7aed361787a404c4856211ddf53127fca9a.zip
Commit FS#8624 by Linus Nielsen, Ryan Press, Craig Elliott, and Kenderes Tamas. Adds preliminary support for numerous accessories that use the ipod serial port on the dock connector. See IpodAccessories for a list of tested devices.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19585 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/drivers/serial.c283
-rw-r--r--firmware/export/config-ipod4g.h2
-rw-r--r--firmware/export/config-ipodcolor.h2
-rw-r--r--firmware/export/config-ipodnano.h2
-rw-r--r--firmware/export/config-ipodvideo.h2
-rw-r--r--firmware/export/iap.h31
-rw-r--r--firmware/export/kernel.h2
-rw-r--r--firmware/export/serial.h5
-rw-r--r--firmware/target/arm/ipod/button-clickwheel.c4
-rw-r--r--firmware/target/arm/ipod/button-target.h15
-rw-r--r--firmware/target/arm/system-pp502x.c6
11 files changed, 328 insertions, 26 deletions
diff --git a/firmware/drivers/serial.c b/firmware/drivers/serial.c
index 47fbf564ff..a496824261 100644
--- a/firmware/drivers/serial.c
+++ b/firmware/drivers/serial.c
@@ -18,7 +18,9 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#include <stdio.h>
21#include <stdlib.h> 22#include <stdlib.h>
23#include <stdarg.h>
22#include "button.h" 24#include "button.h"
23#include "config.h" 25#include "config.h"
24#include "cpu.h" 26#include "cpu.h"
@@ -28,6 +30,7 @@
28#include "adc.h" 30#include "adc.h"
29#include "lcd.h" 31#include "lcd.h"
30#include "serial.h" 32#include "serial.h"
33#include "iap.h"
31 34
32#if CONFIG_CPU == IMX31L 35#if CONFIG_CPU == IMX31L
33#include "serial-imx31.h" 36#include "serial-imx31.h"
@@ -68,6 +71,35 @@ void serial_setup (void)
68 SCR1 = 0x10; /* Enable the receiver, no interrupt */ 71 SCR1 = 0x10; /* Enable the receiver, no interrupt */
69} 72}
70 73
74int tx_rdy(void)
75{
76 /* a dummy */
77 return 1;
78}
79
80int rx_rdy(void)
81{
82 if(SSR1 & SCI_RDRF)
83 return 1;
84 else
85 return 0;
86}
87
88void tx_writec(unsigned char c)
89{
90 /* a dummy */
91}
92
93unsigned char rx_readc(void)
94{
95 char tmp;
96 /* Read byte and clear the Rx Full bit */
97 tmp = RDR1;
98 and_b(~SCI_RDRF, &SSR1);
99 return tmp;
100}
101
102
71/* This function returns the received remote control code only if it is 103/* This function returns the received remote control code only if it is
72 received without errors before or after the reception. 104 received without errors before or after the reception.
73 It therefore returns the received code on the second call after the 105 It therefore returns the received code on the second call after the
@@ -87,11 +119,9 @@ int remote_control_rx(void)
87 return BUTTON_NONE; 119 return BUTTON_NONE;
88 } 120 }
89 121
90 if(SSR1 & SCI_RDRF) { 122 if(rx_rdy()) {
91 /* Read byte and clear the Rx Full bit */ 123 btn = rx_readc();
92 btn = RDR1; 124
93 and_b(~SCI_RDRF, &SSR1);
94
95 if(last_was_error) 125 if(last_was_error)
96 { 126 {
97 last_valid_button = BUTTON_NONE; 127 last_valid_button = BUTTON_NONE;
@@ -149,16 +179,6 @@ int remote_control_rx(void)
149#endif /* !HAVE_FMADC && !STORAGE_MMC */ 179#endif /* !HAVE_FMADC && !STORAGE_MMC */
150#elif defined(CPU_COLDFIRE) && defined(HAVE_SERIAL) 180#elif defined(CPU_COLDFIRE) && defined(HAVE_SERIAL)
151 181
152void serial_tx(const unsigned char *buf)
153{
154 while(*buf) {
155 while(!(USR0 & 0x04))
156 {
157 };
158 UTB0 = *buf++;
159 }
160}
161
162void serial_setup (void) 182void serial_setup (void)
163{ 183{
164 UCR0 = 0x30; /* Reset transmitter */ 184 UCR0 = 0x30; /* Reset transmitter */
@@ -171,6 +191,25 @@ void serial_setup (void)
171 UCR0 = 0x04; /* Tx enable */ 191 UCR0 = 0x04; /* Tx enable */
172} 192}
173 193
194int tx_rdy(void)
195{
196 if(USR0 & 0x04)
197 return 1;
198 else
199 return 0;
200}
201
202int rx_rdy(void)
203{
204 /* a dummy */
205 return 0;
206}
207
208void tx_writec(unsigned char c)
209{
210 UTB0 = c;
211}
212
174#elif (CONFIG_CPU == IMX31L) 213#elif (CONFIG_CPU == IMX31L)
175 214
176void serial_setup(void) 215void serial_setup(void)
@@ -207,15 +246,216 @@ int rx_rdy(void)
207 return 0; 246 return 0;
208} 247}
209 248
210void tx_writec(char c) 249void tx_writec(unsigned char c)
211{ 250{
212 UTXD1=(int) c; 251 UTXD1=(int) c;
213} 252}
214 253
254#elif defined(IPOD_ACCESSORY_PROTOCOL)
255static int autobaud = 0;
256void serial_setup (void)
257{
258 int tmp;
259
260#if (MODEL_NUMBER == 3) || (MODEL_NUMBER == 8)
261
262 /* Route the Tx/Rx pins. 4G Ipod??? */
263 outl(0x70000018, inl(0x70000018) & ~0xc00);
264#elif (MODEL_NUMBER == 4) || (MODEL_NUMBER == 5)
265
266 /* Route the Tx/Rx pins. 5G Ipod */
267 (*(volatile unsigned long *)(0x7000008C)) &= ~0x0C;
268 GPO32_ENABLE &= ~0x0C;
269#endif
270
271 DEV_EN = DEV_EN | DEV_SER0;
272 CPU_HI_INT_DIS = SER0_MASK;
273
274 DEV_RS |= DEV_SER0;
275 sleep(1);
276 DEV_RS &= ~DEV_SER0;
277
278 SER0_LCR = 0x80; /* Divisor latch enable */
279 SER0_DLM = 0x00;
280 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
281 SER0_IER = 0x01;
282
283 SER0_FCR = 0x07; /* Tx+Rx FIFO reset and FIFO enable */
284
285 CPU_INT_EN |= HI_MASK;
286 CPU_HI_INT_EN |= SER0_MASK;
287 tmp = SER0_RBR;
288
289 serial_bitrate(0);
290}
291
292void serial_bitrate(int rate)
293{
294 if(rate == 0)
295 {
296 autobaud = 2;
297 SER0_LCR = 0x80; /* Divisor latch enable */
298 SER0_DLL = 0x0D; /* 24000000/13/16 = 115384 baud */
299 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
300 return;
301 }
302
303 autobaud = 0;
304 SER0_LCR = 0x80; /* Divisor latch enable */
305 SER0_DLL = 24000000L / rate / 16;
306 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
307}
308
309int tx_rdy(void)
310{
311 if((SER0_LSR & 0x20))
312 return 1;
313 else
314 return 0;
315}
316
317int rx_rdy(void)
318{
319 if((SER0_LSR & 0x1))
320 return 1;
321 else
322 return 0;
323}
324
325void tx_writec(unsigned char c)
326{
327 SER0_THR =(int) c;
328}
329
330unsigned char rx_readc(void)
331{
332 return (SER0_RBR & 0xFF);
333}
334
335void SERIAL0(void)
336{
337 static int badbaud = 0;
338 static bool newpkt = true;
339 char temp;
340
341 while(rx_rdy())
342 {
343 temp = rx_readc();
344 if (newpkt && autobaud > 0)
345 {
346 if (autobaud == 1)
347 {
348 switch (temp)
349 {
350 case 0xFF:
351 case 0x55:
352 break;
353 case 0xFC:
354 SER0_LCR = 0x80; /* Divisor latch enable */
355 SER0_DLL = 0x4E; /* 24000000/78/16 = 19230 baud */
356 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
357 temp = 0xFF;
358 break;
359 case 0xE0:
360 SER0_LCR = 0x80; /* Divisor latch enable */
361 SER0_DLL = 0x9C; /* 24000000/156/16 = 9615 baud */
362 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
363 temp = 0xFF;
364 break;
365 default:
366 badbaud++;
367 if (badbaud >= 6) /* Switch baud detection mode */
368 {
369 autobaud = 2;
370 SER0_LCR = 0x80; /* Divisor latch enable */
371 SER0_DLL = 0x0D; /* 24000000/13/16 = 115384 baud */
372 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
373 badbaud = 0;
374 } else {
375 SER0_LCR = 0x80; /* Divisor latch enable */
376 SER0_DLL = 0x1A; /* 24000000/26/16 = 57692 baud */
377 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
378 }
379 continue;
380 }
381 } else {
382 switch (temp)
383 {
384 case 0xFF:
385 case 0x55:
386 break;
387 case 0xFE:
388 SER0_LCR = 0x80; /* Divisor latch enable */
389 SER0_DLL = 0x1A; /* 24000000/26/16 = 57692 baud */
390 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
391 temp = 0xFF;
392 break;
393 case 0xFC:
394 SER0_LCR = 0x80; /* Divisor latch enable */
395 SER0_DLL = 0x27; /* 24000000/39/16 = 38461 baud */
396 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
397 temp = 0xFF;
398 break;
399 case 0xE0:
400 SER0_LCR = 0x80; /* Divisor latch enable */
401 SER0_DLL = 0x4E; /* 24000000/78/16 = 19230 baud */
402 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
403 temp = 0xFF;
404 break;
405 default:
406 badbaud++;
407 if (badbaud >= 6) /* Switch baud detection */
408 {
409 autobaud = 1;
410 SER0_LCR = 0x80; /* Divisor latch enable */
411 SER0_DLL = 0x1A; /* 24000000/26/16 = 57692 baud */
412 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
413 badbaud = 0;
414 } else {
415 SER0_LCR = 0x80; /* Divisor latch enable */
416 SER0_DLL = 0x0D; /* 24000000/13/16 = 115384 baud */
417 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
418 }
419 continue;
420 }
421 }
422 }
423 bool pkt = iap_getc(temp);
424 if(newpkt == true && pkt == false)
425 autobaud = 0; /* Found good baud */
426 newpkt = pkt;
427 }
428}
429
430#else /* Other targets */
431void serial_setup (void)
432{
433 /* a dummy */
434}
435
436int tx_rdy(void)
437{
438 /* a dummy */
439 return 1;
440}
441
442int rx_rdy(void)
443{
444 /* a dummy */
445 return 0;
446}
447
448void tx_writec(unsigned char c)
449{
450 /* a dummy */
451}
452
453#endif
454
215void dprintf(const char * str, ... ) 455void dprintf(const char * str, ... )
216{ 456{
217 char dprintfbuff[256]; 457 char dprintfbuff[256];
218 unsigned char * ptr; 458 char * ptr;
219 459
220 va_list ap; 460 va_list ap;
221 va_start(ap, str); 461 va_start(ap, str);
@@ -224,7 +464,7 @@ void dprintf(const char * str, ... )
224 vsnprintf(ptr,sizeof(dprintfbuff),str,ap); 464 vsnprintf(ptr,sizeof(dprintfbuff),str,ap);
225 va_end(ap); 465 va_end(ap);
226 466
227 serial_tx(ptr); 467 serial_tx((unsigned char *)ptr);
228} 468}
229 469
230void serial_tx(const unsigned char * buf) 470void serial_tx(const unsigned char * buf)
@@ -241,10 +481,3 @@ void serial_tx(const unsigned char * buf)
241 } 481 }
242 } 482 }
243} 483}
244
245#else /* Other targets */
246void serial_setup (void)
247{
248 /* a dummy */
249}
250#endif
diff --git a/firmware/export/config-ipod4g.h b/firmware/export/config-ipod4g.h
index 89b14f9907..f6c71f39d8 100644
--- a/firmware/export/config-ipod4g.h
+++ b/firmware/export/config-ipod4g.h
@@ -186,4 +186,6 @@
186 186
187#define ICODE_ATTR_TREMOR_NOT_MDCT 187#define ICODE_ATTR_TREMOR_NOT_MDCT
188 188
189#define IPOD_ACCESSORY_PROTOCOL
190
189#endif 191#endif
diff --git a/firmware/export/config-ipodcolor.h b/firmware/export/config-ipodcolor.h
index 47b7a4eacf..58a888a969 100644
--- a/firmware/export/config-ipodcolor.h
+++ b/firmware/export/config-ipodcolor.h
@@ -166,4 +166,6 @@
166 166
167#define ICODE_ATTR_TREMOR_NOT_MDCT 167#define ICODE_ATTR_TREMOR_NOT_MDCT
168 168
169#define IPOD_ACCESSORY_PROTOCOL
170
169#endif 171#endif
diff --git a/firmware/export/config-ipodnano.h b/firmware/export/config-ipodnano.h
index 6017d0a2e8..8752181bb9 100644
--- a/firmware/export/config-ipodnano.h
+++ b/firmware/export/config-ipodnano.h
@@ -177,4 +177,6 @@
177 177
178#define ICODE_ATTR_TREMOR_NOT_MDCT 178#define ICODE_ATTR_TREMOR_NOT_MDCT
179 179
180#define IPOD_ACCESSORY_PROTOCOL
181
180#endif 182#endif
diff --git a/firmware/export/config-ipodvideo.h b/firmware/export/config-ipodvideo.h
index d04e562086..ab974dc236 100644
--- a/firmware/export/config-ipodvideo.h
+++ b/firmware/export/config-ipodvideo.h
@@ -197,4 +197,6 @@
197 197
198#define ICODE_ATTR_TREMOR_NOT_MDCT 198#define ICODE_ATTR_TREMOR_NOT_MDCT
199 199
200#define IPOD_ACCESSORY_PROTOCOL
201
200#endif 202#endif
diff --git a/firmware/export/iap.h b/firmware/export/iap.h
new file mode 100644
index 0000000000..6c0b968ab0
--- /dev/null
+++ b/firmware/export/iap.h
@@ -0,0 +1,31 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: iap.h 17400 2008-05-07 20:22:16Z xxxxxx $
9 *
10 * Copyright (C) 2002 by Alan Korr
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#ifndef __IAP_H__
21#define __IAP_H__
22
23extern int iap_getc(unsigned char x);
24extern void iap_write_pkt(unsigned char data, int len);
25extern void iap_setup(int ratenum);
26extern void iap_bitrate_set(int ratenum);
27extern void iap_periodic(void);
28extern void iap_handlepkt(void);
29extern void iap_track_changed(void);
30
31#endif
diff --git a/firmware/export/kernel.h b/firmware/export/kernel.h
index ef65463e5d..29cf8f2eb9 100644
--- a/firmware/export/kernel.h
+++ b/firmware/export/kernel.h
@@ -78,6 +78,8 @@
78#define SYS_REMOTE_UNPLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 5) 78#define SYS_REMOTE_UNPLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 5)
79#define SYS_SCREENDUMP MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 0) 79#define SYS_SCREENDUMP MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 0)
80#define SYS_CAR_ADAPTER_RESUME MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 1) 80#define SYS_CAR_ADAPTER_RESUME MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 1)
81#define SYS_IAP_PERIODIC MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 2)
82#define SYS_IAP_HANDLEPKT MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 3)
81 83
82#define IS_SYSEVENT(ev) ((ev & SYS_EVENT) == SYS_EVENT) 84#define IS_SYSEVENT(ev) ((ev & SYS_EVENT) == SYS_EVENT)
83 85
diff --git a/firmware/export/serial.h b/firmware/export/serial.h
index 425fc66fc6..8a4780c3f1 100644
--- a/firmware/export/serial.h
+++ b/firmware/export/serial.h
@@ -22,8 +22,11 @@
22#ifndef __SERIAL_H__ 22#ifndef __SERIAL_H__
23#define __SERIAL_H__ 23#define __SERIAL_H__
24 24
25extern void serial_setup (void); 25extern void serial_setup(void);
26extern void serial_bitrate(int rate);
26extern int remote_control_rx(void); 27extern int remote_control_rx(void);
27extern void serial_tx(const unsigned char *buf); 28extern void serial_tx(const unsigned char *buf);
29extern void tx_writec(unsigned char c);
30extern int tx_rdy(void);
28 31
29#endif 32#endif
diff --git a/firmware/target/arm/ipod/button-clickwheel.c b/firmware/target/arm/ipod/button-clickwheel.c
index e36c928fb0..21bbca62f0 100644
--- a/firmware/target/arm/ipod/button-clickwheel.c
+++ b/firmware/target/arm/ipod/button-clickwheel.c
@@ -316,7 +316,11 @@ int button_read_device(void)
316 } 316 }
317 317
318 /* The int_btn variable is set in the button interrupt handler */ 318 /* The int_btn variable is set in the button interrupt handler */
319#ifdef IPOD_ACCESSORY_PROTOCOL
320 return int_btn | remote_control_rx();
321#else
319 return int_btn; 322 return int_btn;
323#endif
320} 324}
321 325
322bool button_hold(void) 326bool button_hold(void)
diff --git a/firmware/target/arm/ipod/button-target.h b/firmware/target/arm/ipod/button-target.h
index a0ac372839..67bdc72955 100644
--- a/firmware/target/arm/ipod/button-target.h
+++ b/firmware/target/arm/ipod/button-target.h
@@ -50,7 +50,22 @@ void ipod_4g_button_int(void);
50 |BUTTON_LEFT|BUTTON_RIGHT|BUTTON_SCROLL_FWD\ 50 |BUTTON_LEFT|BUTTON_RIGHT|BUTTON_SCROLL_FWD\
51 |BUTTON_SCROLL_BACK|BUTTON_PLAY) 51 |BUTTON_SCROLL_BACK|BUTTON_PLAY)
52 52
53 /* Remote control's buttons */
54#ifdef IPOD_ACCESSORY_PROTOCOL
55#define BUTTON_RC_PLAY 0x00100000
56#define BUTTON_RC_STOP 0x00080000
57
58#define BUTTON_RC_LEFT 0x00040000
59#define BUTTON_RC_RIGHT 0x00020000
60#define BUTTON_RC_VOL_UP 0x00010000
61#define BUTTON_RC_VOL_DOWN 0x00008000
62
63#define BUTTON_REMOTE (BUTTON_RC_PLAY|BUTTON_RC_STOP\
64 |BUTTON_RC_LEFT|BUTTON_RC_RIGHT\
65 |BUTTON_RC_VOL_UP|BUTTON_RC_VOL_DOWN)
66#else
53#define BUTTON_REMOTE 0 67#define BUTTON_REMOTE 0
68#endif
54 69
55/* This is for later 70/* This is for later
56#define BUTTON_SCROLL_TOUCH 0x00000200 71#define BUTTON_SCROLL_TOUCH 0x00000200
diff --git a/firmware/target/arm/system-pp502x.c b/firmware/target/arm/system-pp502x.c
index d683b3a561..b1f178c8d5 100644
--- a/firmware/target/arm/system-pp502x.c
+++ b/firmware/target/arm/system-pp502x.c
@@ -32,6 +32,7 @@
32#ifndef BOOTLOADER 32#ifndef BOOTLOADER
33extern void TIMER1(void); 33extern void TIMER1(void);
34extern void TIMER2(void); 34extern void TIMER2(void);
35extern void SERIAL0(void);
35extern void ipod_mini_button_int(void); /* iPod Mini 1st gen only */ 36extern void ipod_mini_button_int(void); /* iPod Mini 1st gen only */
36extern void ipod_4g_button_int(void); /* iPod 4th gen and higher only */ 37extern void ipod_4g_button_int(void); /* iPod 4th gen and higher only */
37 38
@@ -78,6 +79,11 @@ void irq(void)
78 button_int(); 79 button_int();
79 } 80 }
80#endif 81#endif
82#ifdef IPOD_ACCESSORY_PROTOCOL
83 else if (CPU_HI_INT_STAT & SER0_MASK) {
84 SERIAL0();
85 }
86#endif
81#ifdef HAVE_USBSTACK 87#ifdef HAVE_USBSTACK
82 else if (CPU_INT_STAT & USB_MASK) { 88 else if (CPU_INT_STAT & USB_MASK) {
83 usb_drv_int(); 89 usb_drv_int();