Prevent file descriptor leakage or overuse
[Rockbox.git] / firmware / drivers / serial.c
blob6ed539b780f2e5e813dd988f4d21c45f742c2128
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Alan Korr & Nick Robinson
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.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include <stdlib.h>
20 #include "button.h"
21 #include "config.h"
22 #include "cpu.h"
23 #include "system.h"
24 #include "kernel.h"
25 #include "backlight.h"
26 #include "adc.h"
27 #include "lcd.h"
28 #include "serial.h"
30 #if CONFIG_CPU == IMX31L
31 #include "serial-imx31.h"
32 #endif
34 #if CONFIG_CPU == SH7034
36 /* FIX: this doesn't work on iRiver or iPod yet */
37 /* iFP7xx has no remote */
39 #if !defined(HAVE_FMADC) /* Recorder FM/V2 has no remote control pin */ \
40 && !defined(HAVE_MMC) /* MMC takes serial port 1, so don't mess with it */
42 /* Received byte identifiers */
43 #define PLAY 0xC1
44 #define STOP 0xC2
45 #define PREV 0xC4
46 #define NEXT 0xC8
47 #define VOLUP 0xD0
48 #define VOLDN 0xE0
50 void serial_setup (void)
52 /* Set PB10 function to serial Rx */
53 PBCR1 = (PBCR1 & 0xffcf) | 0x0020;
55 SMR1 = 0x00;
56 SCR1 = 0;
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
63 can be used. */
64 sleep(1);
66 SCR1 = 0x10; /* Enable the receiver, no interrupt */
69 /* This function returns the received remote control code only if it is
70 received without errors before or after the reception.
71 It therefore returns the received code on the second call after the
72 code has been received. */
73 int remote_control_rx(void)
75 static int last_valid_button = BUTTON_NONE;
76 static int last_was_error = false;
77 int btn;
78 int ret = BUTTON_NONE;
80 /* Errors? Just clear'em. The receiver stops if we don't */
81 if(SSR1 & (SCI_ORER | SCI_FER | SCI_PER)) {
82 and_b(~(SCI_ORER | SCI_FER | SCI_PER), &SSR1);
83 last_valid_button = BUTTON_NONE;
84 last_was_error = true;
85 return BUTTON_NONE;
88 if(SSR1 & SCI_RDRF) {
89 /* Read byte and clear the Rx Full bit */
90 btn = RDR1;
91 and_b(~SCI_RDRF, &SSR1);
93 if(last_was_error)
95 last_valid_button = BUTTON_NONE;
96 ret = BUTTON_NONE;
98 else
100 switch (btn)
102 case STOP:
103 last_valid_button = BUTTON_RC_STOP;
104 break;
106 case PLAY:
107 last_valid_button = BUTTON_RC_PLAY;
108 break;
110 case VOLUP:
111 last_valid_button = BUTTON_RC_VOL_UP;
112 break;
114 case VOLDN:
115 last_valid_button = BUTTON_RC_VOL_DOWN;
116 break;
118 case PREV:
119 last_valid_button = BUTTON_RC_LEFT;
120 break;
122 case NEXT:
123 last_valid_button = BUTTON_RC_RIGHT;
124 break;
126 default:
127 last_valid_button = BUTTON_NONE;
128 break;
132 else
134 /* This means that a valid remote control character was received
135 the last time we were called, with no receiver errors either before
136 or after. Then we can assume that there really is a remote control
137 attached, and return the button code. */
138 ret = last_valid_button;
139 last_valid_button = BUTTON_NONE;
142 last_was_error = false;
144 return ret;
147 #endif /* !HAVE_FMADC && !HAVE_MMC */
148 #elif defined(CPU_COLDFIRE) && defined(HAVE_SERIAL)
150 void serial_tx(const unsigned char *buf)
152 while(*buf) {
153 while(!(USR0 & 0x04))
156 UTB0 = *buf++;
160 void serial_setup (void)
162 UCR0 = 0x30; /* Reset transmitter */
163 UCSR0 = 0xdd; /* Timer mode */
165 UCR0 = 0x10; /* Reset pointer */
166 UMR0 = 0x13; /* No parity, 8 bits */
167 UMR0 = 0x07; /* 1 stop bit */
169 UCR0 = 0x04; /* Tx enable */
172 #elif (CONFIG_CPU == IMX31L)
174 void serial_setup(void)
176 #ifdef UART_INT /*enable UART Interrupts */
177 UCR1_1 |= (EUartUCR1_TRDYEN | EUartUCR1_RRDYEN | EUartUCR1_TXMPTYEN);
178 UCR4_1 |= (EUartUCR4_TCEN);
179 #else /*disable UART Interrupts*/
180 UCR1_1 &= ~(EUartUCR1_TRDYEN | EUartUCR1_RRDYEN | EUartUCR1_TXMPTYEN);
181 UCR4_1 &= ~(EUartUCR4_TCEN);
182 #endif
183 UCR1_1 |= EUartUCR1_UARTEN;
184 UCR2_1 |= (EUartUCR2_TXEN | EUartUCR2_RXEN | EUartUCR2_IRTS);
186 /* Tx,Rx Interrupt Trigger levels, Disable for now*/
187 /*UFCR1 |= (UFCR1_TXTL_32 | UFCR1_RXTL_32);*/
190 int Tx_Rdy(void)
192 if((UTS1 & EUartUTS_TXEMPTY))
193 return 1;
194 else return 0;
197 /*Not ready...After first Rx, UTS1 & UTS1_RXEMPTY
198 keeps returning true*/
199 int Rx_Rdy(void)
201 if(!(UTS1 & EUartUTS_RXEMPTY))
202 return 1;
203 else return 0;
206 void Tx_Writec(char c)
208 UTXD1=(int) c;
211 void dprintf(const char * str, ... )
213 char dprintfbuff[256];
214 unsigned char * ptr;
216 va_list ap;
217 va_start(ap, str);
219 ptr = dprintfbuff;
220 vsnprintf(ptr,sizeof(dprintfbuff),str,ap);
221 va_end(ap);
223 serial_tx(ptr);
226 void serial_tx(const unsigned char * buf)
228 /*Tx*/
229 for(;;) {
230 if(Tx_Rdy()) {
231 if(*buf == '\0')
232 return;
233 if(*buf == '\n')
234 Tx_Writec('\r');
235 Tx_Writec(*buf);
236 buf++;
241 #else /* Other targets */
242 void serial_setup (void)
244 /* a dummy */
246 #endif