Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions software/glasgow/applet/interface/uart/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from glasgow.support.arepl import AsyncInteractiveConsole
from glasgow.support.logging import dump_hex
from glasgow.support.endpoint import ServerEndpoint
from glasgow.gateware.uart import UART
from glasgow.gateware.uart import ExternalUART
from glasgow.abstract import AbstractAssembly, GlasgowPin
from glasgow.applet import GlasgowAppletV2

Expand Down Expand Up @@ -117,7 +117,8 @@ def elaborate(self, platform):
# TODO: `uart.bit_cyc` is only used to set the width of the register; the actual initial
# value is zero (same as `self.bit_cyc`); this is a footgun and should be fixed by rewriting
# the UART to use lib.wiring
m.submodules.uart = uart = UART(self.ports,
m.submodules.uart = uart = ExternalUART(
self.ports,
bit_cyc=(1 << len(self.manual_cyc)) - 1,
parity=self.parity)
m.submodules.auto_baud = auto_baud = UARTAutoBaud()
Expand Down
8 changes: 5 additions & 3 deletions software/glasgow/applet/interface/uart_analyzer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from amaranth.lib.wiring import In, Out

from glasgow.gateware.ports import PortGroup
from glasgow.gateware.uart import UART
from glasgow.gateware.uart import ExternalUART
from glasgow.gateware.stream import Queue
from glasgow.abstract import AbstractAssembly, GlasgowPin, ClockDivisor
from glasgow.applet import GlasgowAppletV2, GlasgowAppletError
Expand Down Expand Up @@ -51,8 +51,10 @@ def elaborate(self, platform):

channels = []
for index, pin in enumerate(self._port):
m.submodules[f"ch{index}"] = uart = UART(PortGroup(rx=pin),
bit_cyc=(1 << len(self.periods[index])) - 1, parity=self._parity)
m.submodules[f"ch{index}"] = uart = ExternalUART(
PortGroup(rx=pin),
bit_cyc=(1 << len(self.periods[index])) - 1,
parity=self._parity)
m.d.comb += uart.bit_cyc.eq(self.periods[index] + 1)
channels.append(uart)

Expand Down
2 changes: 1 addition & 1 deletion software/glasgow/applet/program/m16c/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def __init__(self, ports, out_fifo, in_fifo, bit_cyc, reset, mode, max_bit_cyc):
self.reset = reset
self.mode = mode

self.uart = UART(ports, bit_cyc=max_bit_cyc)
self.uart = ExternalUART(ports, bit_cyc=max_bit_cyc)

def elaborate(self, platform):
m = Module()
Expand Down
3 changes: 2 additions & 1 deletion software/glasgow/applet/sensor/pmsx003/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ def __init__(self, ports, in_fifo, out_fifo):

def elaborate(self, platform):
m = Module()
m.submodules.uart = uart = UART(self.ports,
m.submodules.uart = uart = ExternalUART(
self.ports,
bit_cyc=int(platform.default_clk_frequency // 9600))
m.d.comb += [
self.in_fifo.w_data.eq(uart.rx_data),
Expand Down
48 changes: 29 additions & 19 deletions software/glasgow/gateware/uart.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from amaranth.lib.cdc import FFSynchronizer


__all__ = ["UART"]
__all__ = ["UART", "ExternalUART"]


class UARTBus(Elaboratable):
Expand All @@ -12,6 +12,7 @@ class UARTBus(Elaboratable):

Provides synchronization.
"""

def __init__(self, ports):
self.ports = ports

Expand Down Expand Up @@ -90,7 +91,8 @@ class UART(Elaboratable):
Transmit acknowledgement. If active when ``tx_rdy`` is active, ``tx_rdy`` is reset,
``tx_data`` is sampled, and the transmit state machine starts transmitting a frame.
"""
def __init__(self, ports, bit_cyc, data_bits=8, parity="none", max_bit_cyc=None):

def __init__(self, bus, bit_cyc, data_bits=8, parity="none", max_bit_cyc=None):
if max_bit_cyc is not None:
self.max_bit_cyc = max_bit_cyc
else:
Expand All @@ -102,18 +104,18 @@ def __init__(self, ports, bit_cyc, data_bits=8, parity="none", max_bit_cyc=None)
self.bit_cyc = Signal(range(self.max_bit_cyc + 1), init=bit_cyc)

self.rx_data = Signal(data_bits)
self.rx_rdy = Signal()
self.rx_ack = Signal()
self.rx_rdy = Signal()
self.rx_ack = Signal()
self.rx_ferr = Signal()
self.rx_perr = Signal()
self.rx_ovf = Signal()
self.rx_err = Signal()
self.rx_ovf = Signal()
self.rx_err = Signal()

self.tx_data = Signal(data_bits)
self.tx_rdy = Signal()
self.tx_ack = Signal()
self.tx_rdy = Signal()
self.tx_ack = Signal()

self.bus = UARTBus(ports)
self.bus = bus

def elaborate(self, platform):
m = Module()
Expand All @@ -139,7 +141,7 @@ def calc_parity(sig, kind):
if self.bus.has_rx:
rx_start = Signal()
rx_timer = Signal(range(self.max_bit_cyc))
rx_stb = Signal()
rx_stb = Signal()
rx_shreg = Signal(self.data_bits)
rx_bitno = Signal(range(len(rx_shreg)))

Expand Down Expand Up @@ -199,11 +201,11 @@ def calc_parity(sig, kind):
###

if self.bus.has_tx:
tx_start = Signal()
tx_timer = Signal(range(self.max_bit_cyc))
tx_stb = Signal()
tx_shreg = Signal(self.data_bits)
tx_bitno = Signal(range(len(tx_shreg)))
tx_start = Signal()
tx_timer = Signal(range(self.max_bit_cyc))
tx_stb = Signal()
tx_shreg = Signal(self.data_bits)
tx_bitno = Signal(range(len(tx_shreg)))
tx_parity = Signal()

with m.If(tx_start | (tx_timer == 0)):
Expand All @@ -222,15 +224,17 @@ def calc_parity(sig, kind):
self.bus.tx_o.eq(0),
]
if self.parity != "none":
m.d.sync += tx_parity.eq(calc_parity(self.tx_data, self.parity))
m.d.sync += tx_parity.eq(
calc_parity(self.tx_data, self.parity)
)
m.next = "START"
with m.Else():
m.d.sync += self.bus.tx_o.eq(1)
with m.State("START"):
with m.If(tx_stb):
m.d.sync += [
self.bus.tx_o.eq(tx_shreg[0]),
tx_shreg.eq(Cat(tx_shreg[1:], C(0,1))),
tx_shreg.eq(Cat(tx_shreg[1:], C(0, 1))),
]
m.next = "DATA"
with m.State("DATA"):
Expand All @@ -239,7 +243,7 @@ def calc_parity(sig, kind):
with m.If(tx_bitno != len(tx_shreg) - 1):
m.d.sync += [
self.bus.tx_o.eq(tx_shreg[0]),
tx_shreg.eq(Cat(tx_shreg[1:], C(0,1))),
tx_shreg.eq(Cat(tx_shreg[1:], C(0, 1))),
]
with m.Else():
if self.parity == "none":
Expand All @@ -250,10 +254,16 @@ def calc_parity(sig, kind):
m.next = "PARITY"
with m.State("PARITY"):
with m.If(tx_stb):
m.d.sync += self.bus.tx_o.eq(1),
m.d.sync += (self.bus.tx_o.eq(1),)
m.next = "STOP"
with m.State("STOP"):
with m.If(tx_stb):
m.next = "IDLE"

return m


class ExternalUART(UART):
def __init__(self, ports, *args, **kwargs):
bus = UARTBus(ports)
super().__init__(bus, *args, **kwargs)
Loading