2 * Copyright © 2012 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 __xdata struct ao_fifo ao_usart1_rx_fifo;
21 __xdata struct ao_fifo ao_usart1_tx_fifo;
28 while (!(STM_USART1->usart_sr & (1 << STM_USART_SR_TXE)));
29 STM_USART1->usart_dr = c;
33 static __xdata uint8_t ao_serial_tx1_started;
36 ao_serial_tx1_start(void)
38 if (!ao_fifo_empty(ao_usart1_tx_fifo) &&
39 !ao_serial_tx1_started)
41 ao_serial_tx1_started = 1;
42 ao_fifo_remove(ao_usart1_tx_fifo, STM_USART1->usart_dr);
48 if (STM_USART1->usart_sr & (1 << STM_USART_SR_RXNE)) {
49 if (!ao_fifo_full(ao_usart1_rx_fifo))
50 ao_fifo_insert(ao_usart1_rx_fifo, STM_USART1->usart_dr);
51 ao_wakeup(&ao_usart1_rx_fifo);
53 ao_wakeup(&ao_stdin_ready);
56 if (STM_USART1->usart_sr & (1 << STM_USART_SR_TXE)) {
57 ao_serial_tx1_started = 0;
58 ao_serial_tx1_start();
59 ao_wakeup(&ao_usart1_tx_fifo);
64 ao_serial_getchar(void) __critical
68 while (ao_fifo_empty(ao_usart1_rx_fifo))
69 ao_sleep(&ao_usart1_rx_fifo);
70 ao_fifo_remove(ao_usart1_rx_fifo, c);
77 ao_serial_pollchar(void) __critical
81 if (ao_fifo_empty(ao_usart1_rx_fifo)) {
85 ao_fifo_remove(ao_usart1_rx_fifo,c);
92 ao_serial_putchar(char c) __critical
95 while (ao_fifo_full(ao_usart1_tx_fifo))
96 ao_sleep(&ao_usart1_tx_fifo);
97 ao_fifo_insert(ao_usart1_tx_fifo, c);
98 ao_serial_tx1_start();
103 ao_serial_drain(void) __critical
106 while (!ao_fifo_empty(ao_usart1_tx_fifo))
107 ao_sleep(&ao_usart1_tx_fifo);
113 int _write(int file, char *ptr, int len)
117 ao_debug_out(*ptr++);
121 #define F_CPU 24000000
123 static const struct {
125 } ao_serial_speeds[] = {
126 [AO_SERIAL_SPEED_4800] = {
127 (F_CPU * 16) / (16 * 4800)
129 [AO_SERIAL_SPEED_9600] = {
130 (F_CPU * 16) / (16 * 9600)
132 [AO_SERIAL_SPEED_19200] = {
133 (F_CPU * 16) / (16 * 19200)
135 [AO_SERIAL_SPEED_57600] = {
136 (F_CPU * 16) / (16 * 57600)
141 ao_serial_set_speed(uint8_t speed)
146 if (speed > AO_SERIAL_SPEED_57600)
148 STM_USART1->usart_brr = ao_serial_speeds[speed].usart_brr;
154 STM_USART1->usart_cr1 = ((0 << STM_USART_CR1_OVER8) |
155 (1 << STM_USART_CR1_UE) |
156 (0 << STM_USART_CR1_M) |
157 (0 << STM_USART_CR1_WAKE) |
158 (0 << STM_USART_CR1_PCE) |
159 (0 << STM_USART_CR1_PS) |
160 (0 << STM_USART_CR1_PEIE) |
161 (0 << STM_USART_CR1_TXEIE) | /* XXX enable */
162 (0 << STM_USART_CR1_TCIE) |
163 (0 << STM_USART_CR1_RXNEIE) | /* XXX enable */
164 (0 << STM_USART_CR1_IDLEIE) |
165 (1 << STM_USART_CR1_TE) |
166 (1 << STM_USART_CR1_RE) |
167 (0 << STM_USART_CR1_RWU) |
168 (0 << STM_USART_CR1_SBK));
170 STM_USART1->usart_cr2 = 0;
171 STM_USART1->usart_cr3 = 0;
173 /* Pick a 9600 baud rate */
174 ao_serial_set_speed(AO_SERIAL_SPEED_9600);
176 printf ("serial initialized\n");
179 ao_add_stdio(ao_serial_pollchar,