Skip to content

Commit

Permalink
com/uart: add tx and rx fifos.
Browse files Browse the repository at this point in the history
Since ressource usage is low with default depth of 16 (implemented in RAM LUTs) we don't keep old behaviour.
Tested successfully with BIOS and flterm.
enjoy-digital committed May 1, 2015
1 parent a6f290a commit 8aa3fb3
Showing 2 changed files with 41 additions and 23 deletions.
49 changes: 32 additions & 17 deletions misoclib/com/uart/__init__.py
Original file line number Diff line number Diff line change
@@ -3,30 +3,45 @@
from migen.bank.eventmanager import *
from migen.genlib.record import Record
from migen.flow.actor import Sink, Source
from migen.actorlib.fifo import SyncFIFO


class UART(Module, AutoCSR):
def __init__(self, phy):
def __init__(self, phy,
tx_fifo_depth=16,
rx_fifo_depth=16):
self._rxtx = CSR(8)
self._txfull = CSRStatus()
self._rxempty = CSRStatus()

self.submodules.ev = EventManager()
self.ev.tx = EventSourcePulse()
self.ev.rx = EventSourcePulse()
self.ev.tx = EventSourceProcess()
self.ev.rx = EventSourceProcess()
self.ev.finalize()
###
self.sync += [
If(self._rxtx.re,
phy.sink.stb.eq(1),
phy.sink.data.eq(self._rxtx.r),
).Elif(phy.sink.ack,
phy.sink.stb.eq(0)
),
If(phy.source.stb,
self._rxtx.w.eq(phy.source.data)
)

# # #

tx_fifo = SyncFIFO([("data", 8)], tx_fifo_depth)
self.submodules += tx_fifo
self.comb += [
tx_fifo.sink.stb.eq(self._rxtx.re),
tx_fifo.sink.data.eq(self._rxtx.r),
self._txfull.status.eq(~tx_fifo.sink.ack),
Record.connect(tx_fifo.source, phy.sink)
]

rx_fifo = SyncFIFO([("data", 8)], rx_fifo_depth)
self.submodules += rx_fifo
self.comb += [
Record.connect(phy.source, rx_fifo.sink),
self._rxempty.status.eq(~rx_fifo.source.stb),
self._rxtx.w.eq(rx_fifo.source.data),
rx_fifo.source.ack.eq(self.ev.rx.clear)
]

self.comb += [
self.ev.tx.trigger.eq(phy.sink.stb & phy.sink.ack),
self.ev.rx.trigger.eq(phy.source.stb & phy.source.ack),
phy.source.ack.eq(~self.ev.rx.pending)
# Generate TX IRQ when tx_fifo becomes empty
self.ev.tx.trigger.eq(tx_fifo.source.stb),
# Generate RX IRQ when rx_fifo becomes non-empty
self.ev.rx.trigger.eq(~rx_fifo.source.stb),
]
15 changes: 9 additions & 6 deletions software/libbase/uart.c
Original file line number Diff line number Diff line change
@@ -31,19 +31,22 @@ void uart_isr(void)
stat = uart_ev_pending_read();

if(stat & UART_EV_RX) {
rx_buf[rx_produce] = uart_rxtx_read();
rx_produce = (rx_produce + 1) & UART_RINGBUFFER_MASK_RX;
uart_ev_pending_write(UART_EV_RX);
while(!uart_rxempty_read()) {
rx_buf[rx_produce] = uart_rxtx_read();
rx_produce = (rx_produce + 1) & UART_RINGBUFFER_MASK_RX;
uart_ev_pending_write(UART_EV_RX);
}
}

if(stat & UART_EV_TX) {
uart_ev_pending_write(UART_EV_TX);
if(tx_level > 0) {
if(tx_level == 0)
tx_cts = 1;
while(tx_level > 0 && !uart_txfull_read()) {
uart_rxtx_write(tx_buf[tx_consume]);
tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX;
tx_level--;
} else
tx_cts = 1;
}
}
}

0 comments on commit 8aa3fb3

Please sign in to comment.