1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Alan Korr & Nick Robinson
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
33 #if CONFIG_CPU == IMX31L
34 #include "serial-imx31.h"
37 #if CONFIG_CPU == SH7034
39 /* FIX: this doesn't work on iRiver or iPod yet */
40 /* iFP7xx has no remote */
42 /* Received byte identifiers */
50 void serial_setup (void)
52 /* Set PB10 function to serial Rx */
53 PBCR1
= (PBCR1
& 0xffcf) | 0x0020;
57 BRR1
= (FREQ
/(32*9600))-1;
58 and_b(0, &SSR1
); /* The status bits must be read before they are cleared,
59 so we do an AND operation */
61 /* Let the hardware settle. The serial port needs to wait "at least
62 the interval required to transmit or receive one bit" before it
66 SCR1
= 0x10; /* Enable the receiver, no interrupt */
83 void tx_writec(unsigned char c
)
89 unsigned char rx_readc(void)
92 /* Read byte and clear the Rx Full bit */
94 and_b(~SCI_RDRF
, &SSR1
);
99 /* This function returns the received remote control code only if it is
100 received without errors before or after the reception.
101 It therefore returns the received code on the second call after the
102 code has been received. */
103 int remote_control_rx(void)
105 static int last_valid_button
= BUTTON_NONE
;
106 static int last_was_error
= false;
108 int ret
= BUTTON_NONE
;
110 /* Errors? Just clear'em. The receiver stops if we don't */
111 if(SSR1
& (SCI_ORER
| SCI_FER
| SCI_PER
)) {
112 and_b(~(SCI_ORER
| SCI_FER
| SCI_PER
), &SSR1
);
113 last_valid_button
= BUTTON_NONE
;
114 last_was_error
= true;
123 last_valid_button
= BUTTON_NONE
;
131 last_valid_button
= BUTTON_RC_STOP
;
135 last_valid_button
= BUTTON_RC_PLAY
;
139 last_valid_button
= BUTTON_RC_VOL_UP
;
143 last_valid_button
= BUTTON_RC_VOL_DOWN
;
147 last_valid_button
= BUTTON_RC_LEFT
;
151 last_valid_button
= BUTTON_RC_RIGHT
;
155 last_valid_button
= BUTTON_NONE
;
162 /* This means that a valid remote control character was received
163 the last time we were called, with no receiver errors either before
164 or after. Then we can assume that there really is a remote control
165 attached, and return the button code. */
166 ret
= last_valid_button
;
167 last_valid_button
= BUTTON_NONE
;
170 last_was_error
= false;
175 #elif defined(CPU_COLDFIRE)
177 void serial_setup (void)
179 UCR0
= 0x30; /* Reset transmitter */
180 UCSR0
= 0xdd; /* Timer mode */
182 UCR0
= 0x10; /* Reset pointer */
183 UMR0
= 0x13; /* No parity, 8 bits */
184 UMR0
= 0x07; /* 1 stop bit */
186 UCR0
= 0x04; /* Tx enable */
203 void tx_writec(unsigned char c
)
208 #elif (CONFIG_CPU == IMX31L)
210 void serial_setup(void)
212 #ifdef UART_INT /*enable UART Interrupts */
213 UCR1_1
|= (EUARTUCR1_TRDYEN
| EUARTUCR1_RRDYEN
| EUARTUCR1_TXMPTYEN
);
214 UCR4_1
|= (EUARTUCR4_TCEN
);
215 #else /*disable UART Interrupts*/
216 UCR1_1
&= ~(EUARTUCR1_TRDYEN
| EUARTUCR1_RRDYEN
| EUARTUCR1_TXMPTYEN
);
217 UCR4_1
&= ~(EUARTUCR4_TCEN
);
219 UCR1_1
|= EUARTUCR1_UARTEN
;
220 UCR2_1
|= (EUARTUCR2_TXEN
| EUARTUCR2_RXEN
| EUARTUCR2_IRTS
);
222 /* Tx,Rx Interrupt Trigger levels, Disable for now*/
223 /*UFCR1 |= (UFCR1_TXTL_32 | UFCR1_RXTL_32);*/
228 if((UTS1
& EUARTUTS_TXEMPTY
))
234 /*Not ready...After first Rx, UTS1 & UTS1_RXEMPTY
235 keeps returning true*/
238 if(!(UTS1
& EUARTUTS_RXEMPTY
))
244 void tx_writec(unsigned char c
)
249 #elif defined(IPOD_ACCESSORY_PROTOCOL)
250 static int autobaud
= 0;
251 void serial_setup (void)
255 #if defined(IPOD_COLOR) || defined(IPOD_4G)
256 /* Route the Tx/Rx pins. 4G Ipod??? */
257 outl(0x70000018, inl(0x70000018) & ~0xc00);
258 #elif defined(IPOD_NANO) || defined(IPOD_VIDEO)
259 /* Route the Tx/Rx pins. 5G Ipod */
260 (*(volatile unsigned long *)(0x7000008C)) &= ~0x0C;
261 GPO32_ENABLE
&= ~0x0C;
264 DEV_EN
= DEV_EN
| DEV_SER0
;
265 CPU_HI_INT_DIS
= SER0_MASK
;
271 SER0_LCR
= 0x80; /* Divisor latch enable */
273 SER0_LCR
= 0x03; /* Divisor latch disable, 8-N-1 */
276 SER0_FCR
= 0x07; /* Tx+Rx FIFO reset and FIFO enable */
278 CPU_INT_EN
|= HI_MASK
;
279 CPU_HI_INT_EN
|= SER0_MASK
;
285 void serial_bitrate(int rate
)
290 SER0_LCR
= 0x80; /* Divisor latch enable */
291 SER0_DLL
= 0x0D; /* 24000000/13/16 = 115384 baud */
292 SER0_LCR
= 0x03; /* Divisor latch disable, 8-N-1 */
297 SER0_LCR
= 0x80; /* Divisor latch enable */
298 SER0_DLL
= 24000000L / rate
/ 16;
299 SER0_LCR
= 0x03; /* Divisor latch disable, 8-N-1 */
304 if((SER0_LSR
& 0x20))
318 void tx_writec(unsigned char c
)
323 unsigned char rx_readc(void)
325 return (SER0_RBR
& 0xFF);
330 static int badbaud
= 0;
331 static bool newpkt
= true;
337 if (newpkt
&& autobaud
> 0)
347 SER0_LCR
= 0x80; /* Divisor latch enable */
348 SER0_DLL
= 0x4E; /* 24000000/78/16 = 19230 baud */
349 SER0_LCR
= 0x03; /* Divisor latch disable, 8-N-1 */
353 SER0_LCR
= 0x80; /* Divisor latch enable */
354 SER0_DLL
= 0x9C; /* 24000000/156/16 = 9615 baud */
355 SER0_LCR
= 0x03; /* Divisor latch disable, 8-N-1 */
360 if (badbaud
>= 6) /* Switch baud detection mode */
363 SER0_LCR
= 0x80; /* Divisor latch enable */
364 SER0_DLL
= 0x0D; /* 24000000/13/16 = 115384 baud */
365 SER0_LCR
= 0x03; /* Divisor latch disable, 8-N-1 */
368 SER0_LCR
= 0x80; /* Divisor latch enable */
369 SER0_DLL
= 0x1A; /* 24000000/26/16 = 57692 baud */
370 SER0_LCR
= 0x03; /* Divisor latch disable, 8-N-1 */
381 SER0_LCR
= 0x80; /* Divisor latch enable */
382 SER0_DLL
= 0x1A; /* 24000000/26/16 = 57692 baud */
383 SER0_LCR
= 0x03; /* Divisor latch disable, 8-N-1 */
387 SER0_LCR
= 0x80; /* Divisor latch enable */
388 SER0_DLL
= 0x27; /* 24000000/39/16 = 38461 baud */
389 SER0_LCR
= 0x03; /* Divisor latch disable, 8-N-1 */
393 SER0_LCR
= 0x80; /* Divisor latch enable */
394 SER0_DLL
= 0x4E; /* 24000000/78/16 = 19230 baud */
395 SER0_LCR
= 0x03; /* Divisor latch disable, 8-N-1 */
400 if (badbaud
>= 6) /* Switch baud detection */
403 SER0_LCR
= 0x80; /* Divisor latch enable */
404 SER0_DLL
= 0x1A; /* 24000000/26/16 = 57692 baud */
405 SER0_LCR
= 0x03; /* Divisor latch disable, 8-N-1 */
408 SER0_LCR
= 0x80; /* Divisor latch enable */
409 SER0_DLL
= 0x0D; /* 24000000/13/16 = 115384 baud */
410 SER0_LCR
= 0x03; /* Divisor latch disable, 8-N-1 */
416 bool pkt
= iap_getc(temp
);
418 autobaud
= 0; /* Found good baud */
425 void dprintf(const char * str
, ... )
427 char dprintfbuff
[256];
434 vsnprintf(ptr
,sizeof(dprintfbuff
),str
,ap
);
437 serial_tx((unsigned char *)ptr
);
440 void serial_tx(const unsigned char * buf
)