/* Blackfin Universal Asynchronous Receiver/Transmitter (UART) model.
For "old style" UARTs on BF53x/etc... parts.
- Copyright (C) 2010-2011 Free Software Foundation, Inc.
+ Copyright (C) 2010-2013 Free Software Foundation, Inc.
Contributed by Analog Devices, Inc.
This file is part of simulators.
}
bu16
-bfin_uart_write_byte (struct hw *me, bu16 thr)
+bfin_uart_write_byte (struct hw *me, bu16 thr, bu16 mcr)
{
+ struct bfin_uart *uart = hw_data (me);
unsigned char ch = thr;
+
+ if (mcr & LOOP_ENA)
+ {
+ /* XXX: This probably doesn't work exactly right with
+ external FIFOs ... */
+ uart->saved_byte = thr;
+ uart->saved_count = 1;
+ }
+
bfin_uart_write_buffer (me, &ch, 1);
+
return thr;
}
uart->dll = value;
else
{
- uart->thr = bfin_uart_write_byte (me, value);
+ uart->thr = bfin_uart_write_byte (me, value, uart->mcr);
if (uart->ier & ETBEI)
hw_port_event (me, DV_PORT_TX, 1);
/* Switch between socket and stdin on the fly. */
bu16
-bfin_uart_get_next_byte (struct hw *me, bu16 rbr, bool *fresh)
+bfin_uart_get_next_byte (struct hw *me, bu16 rbr, bu16 mcr, bool *fresh)
{
SIM_DESC sd = hw_system (me);
struct bfin_uart *uart = hw_data (me);
fresh = &_fresh;
*fresh = false;
- if (status & DV_SOCKSER_DISCONNECTED)
+
+ if (uart->saved_count > 0)
+ {
+ *fresh = true;
+ rbr = uart->saved_byte;
+ --uart->saved_count;
+ }
+ else if (mcr & LOOP_ENA)
{
- if (uart->saved_count > 0)
+ /* RX is disconnected, so only return local data. */
+ }
+ else if (status & DV_SOCKSER_DISCONNECTED)
+ {
+ char byte;
+ int ret = sim_io_poll_read (sd, 0/*STDIN*/, &byte, 1);
+
+ if (ret > 0)
{
*fresh = true;
- rbr = uart->saved_byte;
- --uart->saved_count;
- }
- else
- {
- char byte;
- int ret = sim_io_poll_read (sd, 0/*STDIN*/, &byte, 1);
- if (ret > 0)
- {
- *fresh = true;
- rbr = byte;
- }
+ rbr = byte;
}
}
else
}
else
lsr |= (status & DV_SOCKSER_INPUT_EMPTY ? 0 : DR) |
- (status & DV_SOCKSER_OUTPUT_EMPTY ? TEMT | THRE : 0);
+ (status & DV_SOCKSER_OUTPUT_EMPTY ? TEMT | THRE : 0);
return lsr;
}
dv_store_2 (dest, uart->dll);
else
{
- uart->rbr = bfin_uart_get_next_byte (me, uart->rbr, NULL);
+ uart->rbr = bfin_uart_get_next_byte (me, uart->rbr, uart->mcr, NULL);
dv_store_2 (dest, uart->rbr);
}
break;
uart->lsr = 0x0060;
}
-const struct hw_descriptor dv_bfin_uart_descriptor[] = {
+const struct hw_descriptor dv_bfin_uart_descriptor[] =
+{
{"bfin_uart", bfin_uart_finish,},
{NULL, NULL},
};