2 * Copyright © 2009 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20 #define SERIAL_FIFO 32
25 char fifo[SERIAL_FIFO];
28 volatile __xdata struct ao_fifo ao_usart1_rx_fifo;
29 volatile __xdata struct ao_fifo ao_usart1_tx_fifo;
31 #define ao_fifo_insert(f,c) do { \
32 (f).fifo[(f).insert] = (c); \
33 (f).insert = ((f).insert + 1) & (SERIAL_FIFO-1); \
36 #define ao_fifo_remove(f,c) do {\
37 c = (f).fifo[(f).remove]; \
38 (f).remove = ((f).remove + 1) & (SERIAL_FIFO-1); \
41 #define ao_fifo_full(f) ((((f).insert + 1) & (SERIAL_FIFO-1)) == (f).remove)
42 #define ao_fifo_empty(f) ((f).insert == (f).remove)
45 ao_serial_rx1_isr(void) interrupt 3
47 if (!ao_fifo_full(ao_usart1_rx_fifo))
48 ao_fifo_insert(ao_usart1_rx_fifo, U1DBUF);
49 ao_wakeup(&ao_usart1_rx_fifo);
52 static __xdata uint8_t ao_serial_tx1_started;
55 ao_serial_tx1_start(void)
57 if (!ao_fifo_empty(ao_usart1_tx_fifo) &&
58 !ao_serial_tx1_started)
60 ao_serial_tx1_started = 1;
61 ao_fifo_remove(ao_usart1_tx_fifo, U1DBUF);
66 ao_serial_tx1_isr(void) interrupt 14
69 ao_serial_tx1_started = 0;
70 ao_serial_tx1_start();
71 ao_wakeup(&ao_usart1_tx_fifo);
75 ao_serial_getchar(void) __critical
78 while (ao_fifo_empty(ao_usart1_rx_fifo))
79 ao_sleep(&ao_usart1_rx_fifo);
80 ao_fifo_remove(ao_usart1_rx_fifo, c);
85 ao_serial_putchar(char c) __critical
87 while (ao_fifo_full(ao_usart1_tx_fifo))
88 ao_sleep(&ao_usart1_tx_fifo);
89 ao_fifo_insert(ao_usart1_tx_fifo, c);
90 ao_serial_tx1_start();
97 while (ao_cmd_lex_c != '\n') {
98 ao_serial_putchar(ao_cmd_lex_c);
103 __code struct ao_cmds ao_serial_cmds[] = {
104 { 'S', send_serial, "S <data> Send data to serial line" },
105 { 0, send_serial, NULL },
111 /* Set up the USART pin assignment */
112 PERCFG = (PERCFG & ~PERCFG_U1CFG_ALT_MASK) | PERCFG_U1CFG_ALT_2;
114 /* ee has already set the P2SEL bits */
116 /* Make the USART pins be controlled by the USART */
117 P1SEL |= (1 << 6) | (1 << 7);
119 /* UART mode with receiver enabled */
120 U1CSR = (UxCSR_MODE_UART | UxCSR_RE);
122 /* Pick a 4800 baud rate */
123 U1BAUD = 163; /* 4800 */
124 U1GCR = 7 << UxGCR_BAUD_E_SHIFT; /* 4800 */
126 /* Reasonable serial parameters */
127 U1UCR = (UxUCR_FLUSH |
129 UxUCR_D9_ODD_PARITY |
131 UxUCR_PARITY_DISABLE |
132 UxUCR_SPB_1_STOP_BIT |
139 ao_cmd_register(&ao_serial_cmds[0]);