Fix warning about unused functions
[kugel-rb.git] / firmware / drivers / serial.c
blob694ddef79d15a3ab215b5722fae3bed640ccbde5
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdarg.h>
24 #include "button.h"
25 #include "config.h"
26 #include "cpu.h"
27 #include "system.h"
28 #include "kernel.h"
29 #include "backlight.h"
30 #include "adc.h"
31 #include "lcd.h"
32 #include "serial.h"
33 #include "iap.h"
35 #if CONFIG_CPU == IMX31L
36 #include "serial-imx31.h"
37 #endif
39 #if CONFIG_CPU == SH7034
41 /* FIX: this doesn't work on iRiver or iPod yet */
42 /* iFP7xx has no remote */
44 /* Received byte identifiers */
45 #define PLAY 0xC1
46 #define STOP 0xC2
47 #define PREV 0xC4
48 #define NEXT 0xC8
49 #define VOLUP 0xD0
50 #define VOLDN 0xE0
52 void serial_setup (void)
54 /* Set PB10 function to serial Rx */
55 PBCR1 = (PBCR1 & 0xffcf) | 0x0020;
57 SMR1 = 0x00;
58 SCR1 = 0;
59 BRR1 = (FREQ/(32*9600))-1;
60 and_b(0, &SSR1); /* The status bits must be read before they are cleared,
61 so we do an AND operation */
63 /* Let the hardware settle. The serial port needs to wait "at least
64 the interval required to transmit or receive one bit" before it
65 can be used. */
66 sleep(1);
68 SCR1 = 0x10; /* Enable the receiver, no interrupt */
71 int tx_rdy(void)
73 /* a dummy */
74 return 1;
77 int rx_rdy(void)
79 if(SSR1 & SCI_RDRF)
80 return 1;
81 else
82 return 0;
85 void tx_writec(unsigned char c)
87 /* a dummy */
88 (void)c;
91 unsigned char rx_readc(void)
93 char tmp;
94 /* Read byte and clear the Rx Full bit */
95 tmp = RDR1;
96 and_b(~SCI_RDRF, &SSR1);
97 return tmp;
101 /* This function returns the received remote control code only if it is
102 received without errors before or after the reception.
103 It therefore returns the received code on the second call after the
104 code has been received. */
105 int remote_control_rx(void)
107 static int last_valid_button = BUTTON_NONE;
108 static int last_was_error = false;
109 int btn;
110 int ret = BUTTON_NONE;
112 /* Errors? Just clear'em. The receiver stops if we don't */
113 if(SSR1 & (SCI_ORER | SCI_FER | SCI_PER)) {
114 and_b(~(SCI_ORER | SCI_FER | SCI_PER), &SSR1);
115 last_valid_button = BUTTON_NONE;
116 last_was_error = true;
117 return BUTTON_NONE;
120 if(rx_rdy()) {
121 btn = rx_readc();
123 if(last_was_error)
125 last_valid_button = BUTTON_NONE;
126 ret = BUTTON_NONE;
128 else
130 switch (btn)
132 case STOP:
133 last_valid_button = BUTTON_RC_STOP;
134 break;
136 case PLAY:
137 last_valid_button = BUTTON_RC_PLAY;
138 break;
140 case VOLUP:
141 last_valid_button = BUTTON_RC_VOL_UP;
142 break;
144 case VOLDN:
145 last_valid_button = BUTTON_RC_VOL_DOWN;
146 break;
148 case PREV:
149 last_valid_button = BUTTON_RC_LEFT;
150 break;
152 case NEXT:
153 last_valid_button = BUTTON_RC_RIGHT;
154 break;
156 default:
157 last_valid_button = BUTTON_NONE;
158 break;
162 else
164 /* This means that a valid remote control character was received
165 the last time we were called, with no receiver errors either before
166 or after. Then we can assume that there really is a remote control
167 attached, and return the button code. */
168 ret = last_valid_button;
169 last_valid_button = BUTTON_NONE;
172 last_was_error = false;
174 return ret;
177 #elif defined(CPU_COLDFIRE)
179 void serial_setup (void)
181 UCR0 = 0x30; /* Reset transmitter */
182 UCSR0 = 0xdd; /* Timer mode */
184 UCR0 = 0x10; /* Reset pointer */
185 UMR0 = 0x13; /* No parity, 8 bits */
186 UMR0 = 0x07; /* 1 stop bit */
188 UCR0 = 0x04; /* Tx enable */
191 int tx_rdy(void)
193 if(USR0 & 0x04)
194 return 1;
195 else
196 return 0;
199 int rx_rdy(void)
201 /* a dummy */
202 return 0;
205 void tx_writec(unsigned char c)
207 UTB0 = c;
210 #elif (CONFIG_CPU == IMX31L)
212 void serial_setup(void)
214 #ifdef UART_INT /*enable UART Interrupts */
215 UCR1_1 |= (EUARTUCR1_TRDYEN | EUARTUCR1_RRDYEN | EUARTUCR1_TXMPTYEN);
216 UCR4_1 |= (EUARTUCR4_TCEN);
217 #else /*disable UART Interrupts*/
218 UCR1_1 &= ~(EUARTUCR1_TRDYEN | EUARTUCR1_RRDYEN | EUARTUCR1_TXMPTYEN);
219 UCR4_1 &= ~(EUARTUCR4_TCEN);
220 #endif
221 UCR1_1 |= EUARTUCR1_UARTEN;
222 UCR2_1 |= (EUARTUCR2_TXEN | EUARTUCR2_RXEN | EUARTUCR2_IRTS);
224 /* Tx,Rx Interrupt Trigger levels, Disable for now*/
225 /*UFCR1 |= (UFCR1_TXTL_32 | UFCR1_RXTL_32);*/
228 int tx_rdy(void)
230 if((UTS1 & EUARTUTS_TXEMPTY))
231 return 1;
232 else
233 return 0;
236 /*Not ready...After first Rx, UTS1 & UTS1_RXEMPTY
237 keeps returning true*/
238 int rx_rdy(void)
240 if(!(UTS1 & EUARTUTS_RXEMPTY))
241 return 1;
242 else
243 return 0;
246 void tx_writec(unsigned char c)
248 UTXD1=(int) c;
251 #elif defined(IPOD_ACCESSORY_PROTOCOL)
252 static int autobaud = 0;
253 void serial_setup (void)
255 int tmp;
257 #if (MODEL_NUMBER == 3) || (MODEL_NUMBER == 8)
259 /* Route the Tx/Rx pins. 4G Ipod??? */
260 outl(0x70000018, inl(0x70000018) & ~0xc00);
261 #elif (MODEL_NUMBER == 4) || (MODEL_NUMBER == 5)
263 /* Route the Tx/Rx pins. 5G Ipod */
264 (*(volatile unsigned long *)(0x7000008C)) &= ~0x0C;
265 GPO32_ENABLE &= ~0x0C;
266 #endif
268 DEV_EN = DEV_EN | DEV_SER0;
269 CPU_HI_INT_DIS = SER0_MASK;
271 DEV_RS |= DEV_SER0;
272 sleep(1);
273 DEV_RS &= ~DEV_SER0;
275 SER0_LCR = 0x80; /* Divisor latch enable */
276 SER0_DLM = 0x00;
277 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
278 SER0_IER = 0x01;
280 SER0_FCR = 0x07; /* Tx+Rx FIFO reset and FIFO enable */
282 CPU_INT_EN |= HI_MASK;
283 CPU_HI_INT_EN |= SER0_MASK;
284 tmp = SER0_RBR;
286 serial_bitrate(0);
289 void serial_bitrate(int rate)
291 if(rate == 0)
293 autobaud = 2;
294 SER0_LCR = 0x80; /* Divisor latch enable */
295 SER0_DLL = 0x0D; /* 24000000/13/16 = 115384 baud */
296 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
297 return;
300 autobaud = 0;
301 SER0_LCR = 0x80; /* Divisor latch enable */
302 SER0_DLL = 24000000L / rate / 16;
303 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
306 int tx_rdy(void)
308 if((SER0_LSR & 0x20))
309 return 1;
310 else
311 return 0;
314 int rx_rdy(void)
316 if((SER0_LSR & 0x1))
317 return 1;
318 else
319 return 0;
322 void tx_writec(unsigned char c)
324 SER0_THR =(int) c;
327 unsigned char rx_readc(void)
329 return (SER0_RBR & 0xFF);
332 void SERIAL0(void)
334 static int badbaud = 0;
335 static bool newpkt = true;
336 char temp;
338 while(rx_rdy())
340 temp = rx_readc();
341 if (newpkt && autobaud > 0)
343 if (autobaud == 1)
345 switch (temp)
347 case 0xFF:
348 case 0x55:
349 break;
350 case 0xFC:
351 SER0_LCR = 0x80; /* Divisor latch enable */
352 SER0_DLL = 0x4E; /* 24000000/78/16 = 19230 baud */
353 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
354 temp = 0xFF;
355 break;
356 case 0xE0:
357 SER0_LCR = 0x80; /* Divisor latch enable */
358 SER0_DLL = 0x9C; /* 24000000/156/16 = 9615 baud */
359 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
360 temp = 0xFF;
361 break;
362 default:
363 badbaud++;
364 if (badbaud >= 6) /* Switch baud detection mode */
366 autobaud = 2;
367 SER0_LCR = 0x80; /* Divisor latch enable */
368 SER0_DLL = 0x0D; /* 24000000/13/16 = 115384 baud */
369 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
370 badbaud = 0;
371 } else {
372 SER0_LCR = 0x80; /* Divisor latch enable */
373 SER0_DLL = 0x1A; /* 24000000/26/16 = 57692 baud */
374 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
376 continue;
378 } else {
379 switch (temp)
381 case 0xFF:
382 case 0x55:
383 break;
384 case 0xFE:
385 SER0_LCR = 0x80; /* Divisor latch enable */
386 SER0_DLL = 0x1A; /* 24000000/26/16 = 57692 baud */
387 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
388 temp = 0xFF;
389 break;
390 case 0xFC:
391 SER0_LCR = 0x80; /* Divisor latch enable */
392 SER0_DLL = 0x27; /* 24000000/39/16 = 38461 baud */
393 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
394 temp = 0xFF;
395 break;
396 case 0xE0:
397 SER0_LCR = 0x80; /* Divisor latch enable */
398 SER0_DLL = 0x4E; /* 24000000/78/16 = 19230 baud */
399 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
400 temp = 0xFF;
401 break;
402 default:
403 badbaud++;
404 if (badbaud >= 6) /* Switch baud detection */
406 autobaud = 1;
407 SER0_LCR = 0x80; /* Divisor latch enable */
408 SER0_DLL = 0x1A; /* 24000000/26/16 = 57692 baud */
409 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
410 badbaud = 0;
411 } else {
412 SER0_LCR = 0x80; /* Divisor latch enable */
413 SER0_DLL = 0x0D; /* 24000000/13/16 = 115384 baud */
414 SER0_LCR = 0x03; /* Divisor latch disable, 8-N-1 */
416 continue;
420 bool pkt = iap_getc(temp);
421 if(newpkt == true && pkt == false)
422 autobaud = 0; /* Found good baud */
423 newpkt = pkt;
427 #endif
429 void dprintf(const char * str, ... )
431 char dprintfbuff[256];
432 char * ptr;
434 va_list ap;
435 va_start(ap, str);
437 ptr = dprintfbuff;
438 vsnprintf(ptr,sizeof(dprintfbuff),str,ap);
439 va_end(ap);
441 serial_tx((unsigned char *)ptr);
444 void serial_tx(const unsigned char * buf)
446 /*Tx*/
447 for(;;) {
448 if(tx_rdy()) {
449 if(*buf == '\0')
450 return;
451 if(*buf == '\n')
452 tx_writec('\r');
453 tx_writec(*buf);
454 buf++;