-static __code struct {
- uint8_t baud;
- uint8_t gcr;
-} ao_serial_speeds[] = {
- /* [AO_SERIAL_SPEED_4800] = */ {
- /* .baud = */ 163,
- /* .gcr = */ (7 << UxGCR_BAUD_E_SHIFT) | UxGCR_ORDER_LSB
- },
- /* [AO_SERIAL_SPEED_9600] = */ {
- /* .baud = */ 163,
- /* .gcr = */ (8 << UxGCR_BAUD_E_SHIFT) | UxGCR_ORDER_LSB
- },
- /* [AO_SERIAL_SPEED_19200] = */ {
- /* .baud = */ 163,
- /* .gcr = */ (9 << UxGCR_BAUD_E_SHIFT) | UxGCR_ORDER_LSB
- },
- /* [AO_SERIAL_SPEED_57600] = */ {
- /* .baud = */ 59,
- /* .gcr = */ (11 << UxGCR_BAUD_E_SHIFT) | UxGCR_ORDER_LSB
- },
-};
+void
+ao_serial0_set_speed(uint8_t speed)
+{
+ ao_serial0_drain();
+ if (speed > AO_SERIAL_SPEED_57600)
+ return;
+ U0UCR |= UxUCR_FLUSH;
+ U0BAUD = ao_serial_speeds[speed].baud;
+ U0GCR = ao_serial_speeds[speed].gcr;
+}
+#endif /* HAS_SERIAL_0 */
+
+#if HAS_SERIAL_1
+
+volatile __xdata struct ao_fifo ao_serial1_rx_fifo;
+volatile __xdata struct ao_fifo ao_serial1_tx_fifo;
+
+void
+ao_serial1_rx_isr(void) __interrupt 3
+{
+ if (!ao_fifo_full(ao_serial1_rx_fifo))
+ ao_fifo_insert(ao_serial1_rx_fifo, U1DBUF);
+ ao_wakeup(&ao_serial1_rx_fifo);
+#if USE_SERIAL_1_STDIN
+ ao_wakeup(&ao_stdin_ready);
+#endif
+}
+
+static __xdata uint8_t ao_serial1_tx_started;
+
+static void
+ao_serial1_tx_start(void)
+{
+ if (!ao_fifo_empty(ao_serial1_tx_fifo) &&
+ !ao_serial1_tx_started)
+ {
+ ao_serial1_tx_started = 1;
+ ao_fifo_remove(ao_serial1_tx_fifo, U1DBUF);
+ }
+}
+
+void
+ao_serial1_tx_isr(void) __interrupt 14
+{
+ UTX1IF = 0;
+ ao_serial1_tx_started = 0;
+ ao_serial1_tx_start();
+ ao_wakeup(&ao_serial1_tx_fifo);
+}
+
+char
+ao_serial1_getchar(void) __critical
+{
+ char c;
+ while (ao_fifo_empty(ao_serial1_rx_fifo))
+ ao_sleep(&ao_serial1_rx_fifo);
+ ao_fifo_remove(ao_serial1_rx_fifo, c);
+ return c;
+}
+
+#if USE_SERIAL_1_STDIN
+char
+ao_serial1_pollchar(void) __critical
+{
+ char c;
+ if (ao_fifo_empty(ao_serial1_rx_fifo))
+ return AO_READ_AGAIN;
+ ao_fifo_remove(ao_serial1_rx_fifo,c);
+ return c;
+}
+#endif
+
+void
+ao_serial1_putchar(char c) __critical
+{
+ while (ao_fifo_full(ao_serial1_tx_fifo))
+ ao_sleep(&ao_serial1_tx_fifo);
+ ao_fifo_insert(ao_serial1_tx_fifo, c);
+ ao_serial1_tx_start();
+}