Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: GlasgowEmbedded/glasgow
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: a450d1e1450d
Choose a base ref
...
head repository: GlasgowEmbedded/glasgow
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 02b15bac9d2d
Choose a head ref
  • 1 commit
  • 2 files changed
  • 1 contributor

Commits on Aug 17, 2020

  1. applet.interface.uart: allow to invert the UART line signals (=idle low)

    Adds the --invert-rx and --invert-tx cli arguments and the corresponding
    build-time parameters to the uart gateware.
    electroniceel authored and whitequark committed Aug 17, 2020
    Copy the full SHA
    02b15ba View commit details
Showing with 40 additions and 17 deletions.
  1. +21 −7 software/glasgow/applet/interface/uart/__init__.py
  2. +19 −10 software/glasgow/gateware/uart.py
28 changes: 21 additions & 7 deletions software/glasgow/applet/interface/uart/__init__.py
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@
import sys
import logging
import asyncio
import argparse
from nmigen.compat import *

from ....support.pyrepl import *
@@ -74,8 +75,9 @@ def __init__(self, uart, auto_cyc, seq_size=32):

class UARTSubtarget(Module):
def __init__(self, pads, out_fifo, in_fifo, parity, max_bit_cyc,
manual_cyc, auto_cyc, use_auto, bit_cyc, rx_errors):
self.submodules.uart = uart = UART(pads, bit_cyc=max_bit_cyc, parity=parity)
manual_cyc, auto_cyc, use_auto, bit_cyc, rx_errors, invert_rx, invert_tx):
self.submodules.uart = uart = UART(pads, bit_cyc=max_bit_cyc, parity=parity,
invert_rx=invert_rx, invert_tx=invert_tx)
self.submodules.auto_baud = auto_baud = UARTAutoBaud(uart, auto_cyc)

self.comb += uart.bit_cyc.eq(bit_cyc)
@@ -136,6 +138,12 @@ def add_build_arguments(cls, parser, access):
"--tolerance", metavar="PPM", type=int, default=50000,
help="verify that actual baud rate is within PPM parts per million of specified"
" (default: %(default)s)")
parser.add_argument(
"--invert-rx", default=False, action="store_true",
help="invert the line signal (=idle low) on RX")
parser.add_argument(
"--invert-tx", default=False, action="store_true",
help="invert the line signal (=idle low) on TX")

def build(self, target, args):
# We support any baud rates, even absurd ones like 60 baud, if you want, but the applet
@@ -166,6 +174,8 @@ def build(self, target, args):
use_auto=use_auto,
bit_cyc=bit_cyc,
rx_errors=rx_errors,
invert_rx=args.invert_rx,
invert_tx=args.invert_tx,
))

@classmethod
@@ -174,7 +184,7 @@ def add_run_arguments(cls, parser, access):

parser.add_argument(
"--pulls", default=False, action="store_true",
help="enable integrated pull-ups")
help="enable integrated pull-ups or pull-downs (when inverted)")
parser.add_argument(
"-a", "--auto-baud", default=False, action="store_true",
help="automatically estimate baud rate in response to RX errors")
@@ -191,14 +201,18 @@ async def run(self, device, args):
if args.auto_baud:
await device.write_register(self.__addr_use_auto, 1)

# Enable pull-ups, if requested.
# Enable pull-ups or pull-downs, if requested.
# This reduces the amount of noise received on tristated lines.
pulls = set()
pulls_high = set()
pulls_low = set()
if args.pulls:
pulls = {args.pin_rx}
if args.invert_rx:
pulls_low = {args.pin_rx}
else:
pulls_high = {args.pin_rx}

return await device.demultiplexer.claim_interface(self, self.mux_interface, args,
pull_high=pulls)
pull_high=pulls_high, pull_low=pulls_low)

@classmethod
def add_interact_arguments(cls, parser):
29 changes: 19 additions & 10 deletions software/glasgow/gateware/uart.py
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ class UARTBus(Module):
Provides synchronization.
"""
def __init__(self, pads):
def __init__(self, pads, invert_rx, invert_tx):
self.has_rx = hasattr(pads, "rx_t")
if self.has_rx:
self.rx_t = pads.rx_t
@@ -25,15 +25,17 @@ def __init__(self, pads):
###

if self.has_tx:
self.comb += [
self.tx_t.oe.eq(1),
self.tx_t.o.eq(self.tx_o)
]
self.comb += self.tx_t.oe.eq(1)
if invert_tx:
self.comb += self.tx_t.o.eq(~self.tx_o)
else:
self.comb += self.tx_t.o.eq(self.tx_o)

if self.has_rx:
self.specials += [
MultiReg(self.rx_t.i, self.rx_i, reset=1)
]
if invert_rx:
self.specials += MultiReg(~self.rx_t.i, self.rx_i, reset=1)
else:
self.specials += MultiReg(self.rx_t.i, self.rx_i, reset=1)


class UART(Module):
@@ -55,6 +57,12 @@ class UART(Module):
:type max_bit_cyc: int
:param max_bit_cyc:
Maximum possible value for ``bit_cyc`` that can be configured at runtime.
:type invert_rx: bool
:param invert_rx:
Invert the line signal (=idle low) for RX
:type invert_tx: bool
:param invert_tx:
Invert the line signal (=idle low) for TX
:attr bit_cyc:
Register with the current value for bit time, minus one.
@@ -86,7 +94,8 @@ class UART(Module):
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, pads, bit_cyc, data_bits=8, parity="none", max_bit_cyc=None):
def __init__(self, pads, bit_cyc, data_bits=8, parity="none", max_bit_cyc=None,
invert_rx=False, invert_tx=False):
if max_bit_cyc is None:
max_bit_cyc = bit_cyc
self.bit_cyc = Signal(reset=bit_cyc, max=max_bit_cyc + 1)
@@ -103,7 +112,7 @@ def __init__(self, pads, bit_cyc, data_bits=8, parity="none", max_bit_cyc=None):
self.tx_rdy = Signal()
self.tx_ack = Signal()

self.submodules.bus = bus = UARTBus(pads)
self.submodules.bus = bus = UARTBus(pads, invert_rx=invert_rx, invert_tx=invert_tx)

###