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: b8f138fcfdc4
Choose a base ref
...
head repository: GlasgowEmbedded/glasgow
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 299ead2daf1b
Choose a head ref
  • 1 commit
  • 10 files changed
  • 1 contributor

Commits on Jan 13, 2020

  1. s/master/initiator/ s/slave/target/ in I2C-related code.

    I was going to do this for a while, given that even the specification
    itself has to explain that "master" is the device that is initiating
    a transaction, etc.
    whitequark committed Jan 13, 2020
    Copy the full SHA
    299ead2 View commit details
2 changes: 1 addition & 1 deletion software/glasgow/applet/all.py
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@

from .interface.uart import UARTApplet
from .interface.spi_master import SPIMasterApplet
from .interface.i2c_master import I2CMasterApplet
from .interface.i2c_initiator import I2CInitiatorApplet
from .interface.jtag_pinout import JTAGPinoutApplet
from .interface.jtag_probe import JTAGProbeApplet
from .interface.jtag_openocd import JTAGOpenOCDApplet
4 changes: 2 additions & 2 deletions software/glasgow/applet/control/tps6598x/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
import asyncio

from ...interface.i2c_master import I2CMasterApplet
from ...interface.i2c_initiator import I2CInitiatorApplet
from ... import *


@@ -41,7 +41,7 @@ async def write_reg(self, address, data):
self._check(await self.lower.write(self._i2c_addr, [address, len(data), *data], stop=True))


class ControlTPS6598xApplet(I2CMasterApplet, name="control-tps6598x"):
class ControlTPS6598xApplet(I2CInitiatorApplet, name="control-tps6598x"):
logger = logging.getLogger(__name__)
help = "configure TPS6598x USB PD controllers"
description = """
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
from nmigen.compat import *

from ....gateware.pads import *
from ....gateware.i2c import I2CMaster
from ....gateware.i2c import I2CInitiator
from ... import *


@@ -15,9 +15,9 @@
CMD_READ = 0x05


class I2CMasterSubtarget(Module):
class I2CInitiatorSubtarget(Module):
def __init__(self, pads, out_fifo, in_fifo, period_cyc):
self.submodules.i2c_master = I2CMaster(pads, period_cyc)
self.submodules.i2c_initiator = I2CInitiator(pads, period_cyc)

###

@@ -26,18 +26,18 @@ def __init__(self, pads, out_fifo, in_fifo, period_cyc):

self.submodules.fsm = FSM(reset_state="IDLE")
self.fsm.act("IDLE",
If(~self.i2c_master.busy & out_fifo.readable,
If(~self.i2c_initiator.busy & out_fifo.readable,
out_fifo.re.eq(1),
NextValue(cmd, out_fifo.dout),
NextState("COMMAND")
)
)
self.fsm.act("COMMAND",
If(cmd == CMD_START,
self.i2c_master.start.eq(1),
self.i2c_initiator.start.eq(1),
NextState("IDLE")
).Elif(cmd == CMD_STOP,
self.i2c_master.stop.eq(1),
self.i2c_initiator.stop.eq(1),
NextState("IDLE")
).Elif(cmd == CMD_COUNT,
NextState("COUNT-MSB")
@@ -74,22 +74,22 @@ def __init__(self, pads, out_fifo, in_fifo, period_cyc):
self.fsm.act("WRITE-FIRST",
If(out_fifo.readable,
out_fifo.re.eq(1),
self.i2c_master.data_i.eq(out_fifo.dout),
self.i2c_master.write.eq(1),
self.i2c_initiator.data_i.eq(out_fifo.dout),
self.i2c_initiator.write.eq(1),
NextState("WRITE")
)
)
self.fsm.act("WRITE",
If(~self.i2c_master.busy,
If(self.i2c_master.ack_o,
If(~self.i2c_initiator.busy,
If(self.i2c_initiator.ack_o,
NextValue(count, count - 1)
),
If((count == 1) | ~self.i2c_master.ack_o,
If((count == 1) | ~self.i2c_initiator.ack_o,
NextState("REPORT")
).Elif(out_fifo.readable,
out_fifo.re.eq(1),
self.i2c_master.data_i.eq(out_fifo.dout),
self.i2c_master.write.eq(1),
self.i2c_initiator.data_i.eq(out_fifo.dout),
self.i2c_initiator.write.eq(1),
)
)
)
@@ -102,29 +102,29 @@ def __init__(self, pads, out_fifo, in_fifo, period_cyc):
)
)
self.fsm.act("READ-FIRST",
self.i2c_master.ack_i.eq(~(count == 1)),
self.i2c_master.read.eq(1),
self.i2c_initiator.ack_i.eq(~(count == 1)),
self.i2c_initiator.read.eq(1),
NextValue(count, count - 1),
NextState("READ")
)
self.fsm.act("READ",
If(~self.i2c_master.busy,
If(~self.i2c_initiator.busy,
If(in_fifo.writable,
in_fifo.we.eq(1),
in_fifo.din.eq(self.i2c_master.data_o),
in_fifo.din.eq(self.i2c_initiator.data_o),
If(count == 0,
NextState("IDLE")
).Else(
self.i2c_master.ack_i.eq(~(count == 1)),
self.i2c_master.read.eq(1),
self.i2c_initiator.ack_i.eq(~(count == 1)),
self.i2c_initiator.read.eq(1),
NextValue(count, count - 1)
)
)
)
)


class I2CMasterInterface:
class I2CInitiatorInterface:
def __init__(self, interface, logger):
self.lower = interface
self._logger = logger
@@ -257,7 +257,7 @@ async def scan(self, addresses=range(0b0001_000, 0b1111_000), *, read=True, writ
return found


class I2CMasterApplet(GlasgowApplet, name="i2c-master"):
class I2CInitiatorApplet(GlasgowApplet, name="i2c-initiator"):
logger = logging.getLogger(__name__)
help = "initiate I2C transactions"
description = """
@@ -282,7 +282,7 @@ def add_build_arguments(cls, parser, access):

def build(self, target, args):
self.mux_interface = iface = target.multiplexer.claim_interface(self, args)
iface.add_subtarget(I2CMasterSubtarget(
iface.add_subtarget(I2CInitiatorSubtarget(
pads=iface.get_pads(args, pins=self.__pins),
out_fifo=iface.get_out_fifo(),
in_fifo=iface.get_in_fifo(),
@@ -303,7 +303,7 @@ async def run(self, device, args):
pulls = {args.pin_scl, args.pin_sda}
iface = await device.demultiplexer.claim_interface(self, self.mux_interface, args,
pull_high=pulls)
i2c_iface = I2CMasterInterface(iface, self.logger)
i2c_iface = I2CInitiatorInterface(iface, self.logger)
return i2c_iface

@classmethod
@@ -351,7 +351,7 @@ async def interact(self, device, args, i2c_iface):

# -------------------------------------------------------------------------------------------------

class I2CMasterAppletTestCase(GlasgowAppletTestCase, applet=I2CMasterApplet):
class I2CInitiatorAppletTestCase(GlasgowAppletTestCase, applet=I2CInitiatorApplet):
@synthesis_test
def test_build(self):
self.assertBuilds()
4 changes: 2 additions & 2 deletions software/glasgow/applet/memory/_24x/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
import argparse

from ...interface.i2c_master import I2CMasterApplet
from ...interface.i2c_initiator import I2CInitiatorApplet
from ... import *


@@ -80,7 +80,7 @@ async def write(self, addr, data):
return True


class Memory24xApplet(I2CMasterApplet, name="memory-24x"):
class Memory24xApplet(I2CInitiatorApplet, name="memory-24x"):
logger = logging.getLogger(__name__)
help = "read and write 24-series I²C EEPROM memories"
default_page_size = 8
4 changes: 2 additions & 2 deletions software/glasgow/applet/sensor/bmp280/__init__.py
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@

from ....support.data_logger import DataLogger
from ... import *
from ...interface.i2c_master import I2CMasterApplet
from ...interface.i2c_initiator import I2CInitiatorApplet


REG_CAL_T1 = 0x88 # 16-bit unsigned
@@ -267,7 +267,7 @@ async def write(self, addr, data):
.format(self._i2c_addr))


class SensorBMP280Applet(I2CMasterApplet, name="sensor-bmp280"):
class SensorBMP280Applet(I2CInitiatorApplet, name="sensor-bmp280"):
logger = logging.getLogger(__name__)
help = "measure temperature and pressure with Bosch BMP280 sensors"
description = """
4 changes: 2 additions & 2 deletions software/glasgow/applet/sensor/ina260/__init__.py
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@

from ....support.data_logger import DataLogger
from ... import *
from ...interface.i2c_master import I2CMasterApplet
from ...interface.i2c_initiator import I2CInitiatorApplet


REG_CONFIG = 0x00 # 16-bit rw
@@ -90,7 +90,7 @@ async def get_power(self):
return watts


class SensorINA260Applet(I2CMasterApplet, name="sensor-ina260"):
class SensorINA260Applet(I2CInitiatorApplet, name="sensor-ina260"):
logger = logging.getLogger(__name__)
help = "measure voltage, current and power with TI INA260 sensors"
description = """
4 changes: 2 additions & 2 deletions software/glasgow/applet/sensor/scd30/__init__.py
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@

from ....support.logging import dump_hex
from ....support.data_logger import DataLogger
from ...interface.i2c_master import I2CMasterApplet
from ...interface.i2c_initiator import I2CInitiatorApplet
from ... import *


@@ -167,7 +167,7 @@ async def set_altitude_compensation(self, altitude_m):
await self._write(CMD_ALTITUDE_COMP, ">H", altitude_m)


class SensorSCD30Applet(I2CMasterApplet, name="sensor-scd30"):
class SensorSCD30Applet(I2CInitiatorApplet, name="sensor-scd30"):
logger = logging.getLogger(__name__)
help = "measure CO₂, humidity, and temperature with Sensirion SCD30 sensors"
description = """
30 changes: 15 additions & 15 deletions software/glasgow/gateware/i2c.py
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
from nmigen.compat.genlib.cdc import MultiReg


__all__ = ['I2CSlave']
__all__ = ["I2CInitiator", "I2CTarget"]


class I2CBus(Module):
@@ -53,9 +53,9 @@ def __init__(self, pads):
]


class I2CMaster(Module):
class I2CInitiator(Module):
"""
Simple I2C master.
Simple I2C transaction initiator.
Generates start and stop conditions, and transmits and receives octets.
Clock stretching is supported.
@@ -69,7 +69,7 @@ class I2CMaster(Module):
:type clk_stretch: bool
:attr busy:
Busy flag. Low if the master state machine is idle, high otherwise.
Busy flag. Low if the state machine is idle, high otherwise.
:attr start:
Start strobe. When ``busy`` is low, asserting ``start`` for one cycle generates
a start or repeated start condition on the bus. Ignored when ``busy`` is high.
@@ -250,7 +250,7 @@ def stb_x(state, next_state, *exprs):
stb_x("READ-ACK-SDA-N", "IDLE")


class I2CSlave(Module):
class I2CTarget(Module):
"""
Simple I2C slave.
@@ -267,15 +267,15 @@ class I2CSlave(Module):
:attr write:
Write strobe. Active for one cycle immediately after receiving a data octet.
:attr data_i:
Data octet received from the master. Valid when ``write`` is high.
Data octet received from the initiator. Valid when ``write`` is high.
:attr ack_o:
Acknowledge strobe. If active for at least one cycle during the acknowledge bit
setup period (one half-period after write strobe is asserted), acknowledge is asserted.
Otherwise, no acknowledge is asserted. May use combinatorial feedback from ``write``.
:attr read:
Read strobe. Active for one cycle immediately before latching ``data_o``.
:attr data_o:
Data octet to be transmitted to the master. Latched immedately after receiving
Data octet to be transmitted to the initiator. Latched immedately after receiving
a read command.
"""
def __init__(self, pads):
@@ -465,11 +465,11 @@ def assertCondition(self, tb, fn):
self.assertTrue((yield from self.tb.wait_for(fn)))


class I2CMasterTestbench(I2CTestbench):
class I2CInitiatorTestbench(I2CTestbench):
def __init__(self):
super().__init__()

self.submodules.dut = I2CMaster(pads=self, period_cyc=self.period_cyc)
self.submodules.dut = I2CInitiator(pads=self, period_cyc=self.period_cyc)
self.wait_cyc = self.period_cyc * 3

def strobe(self, signal):
@@ -493,9 +493,9 @@ def write(self, data):
yield from self.strobe(self.dut.write)


class I2CMasterTestCase(I2CTestCase):
class I2CInitiatorTestCase(I2CTestCase):
def setUp(self):
self.tb = I2CMasterTestbench()
self.tb = I2CInitiatorTestbench()

@simulation_test
def test_start(self, tb):
@@ -641,11 +641,11 @@ def test_read_tx(self, tb):
self.assertEqual((yield tb.scl_i), 1)


class I2CSlaveTestbench(I2CTestbench):
class I2CTargetTestbench(I2CTestbench):
def __init__(self):
super().__init__()

self.submodules.dut = I2CSlave(pads=self)
self.submodules.dut = I2CTarget(pads=self)
self.wait_cyc = self.period_cyc // 4

def start(self):
@@ -704,9 +704,9 @@ def read_octet(self):
return octet


class I2CSlaveTestCase(I2CTestCase):
class I2CTargetTestCase(I2CTestCase):
def setUp(self):
self.tb = I2CSlaveTestbench()
self.tb = I2CTargetTestbench()

def simulationSetUp(self, tb):
yield tb.dut.address.eq(0b0101000)
Loading