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: 7c7ded1a8bb0
Choose a base ref
...
head repository: GlasgowEmbedded/glasgow
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 6516cb8d6f02
Choose a head ref
  • 2 commits
  • 1 file changed
  • 1 contributor

Commits on Apr 3, 2019

  1. gateware.i2c: load new data after each byte is read.

    Also, fix testbench to release SDA after writing a bit.
    whitequark committed Apr 3, 2019
    Copy the full SHA
    6e44cfb View commit details

Commits on Apr 4, 2019

  1. gateware.i2c: fix fencepost error in reads.

    The ACK period would be interpreted as starting one bit time too
    early, and SDA would be released. Not only that is a fencepost error,
    but releasing SDA during the sample half-period is illegal; it would
    be correctly detected as a stop condition, terminating trasnaction.
    
    This commit reworks the read part of the FSM to only change SDA level
    during setup half-period, and fixes the fencepost error.
    whitequark committed Apr 4, 2019
    Copy the full SHA
    6516cb8 View commit details
Showing with 22 additions and 8 deletions.
  1. +22 −8 software/glasgow/gateware/i2c.py
30 changes: 22 additions & 8 deletions software/glasgow/gateware/i2c.py
Original file line number Diff line number Diff line change
@@ -330,8 +330,8 @@ def __init__(self, pads):
).Elif(bus.sample,
If(shreg_i[0],
self.start.eq(1),
NextState("READ-SHIFT"),
NextValue(shreg_o, self.data_o)
NextValue(shreg_o, self.data_o),
NextState("READ-SHIFT")
)
)
)
@@ -370,12 +370,11 @@ def __init__(self, pads):
).Elif(bus.start,
NextState("START")
).Elif(bus.setup,
NextValue(bitno, bitno + 1),
NextValue(bus.sda_o, shreg_o[7]),
NextValue(shreg_o, shreg_o << 1),
).Elif(bus.sample,
If(bitno == 0,
NextValue(bus.sda_o, 1),
NextValue(shreg_o, shreg_o << 1),
NextValue(bitno, bitno + 1),
If(bitno == 7,
NextState("READ-ACK")
)
)
@@ -385,8 +384,11 @@ def __init__(self, pads):
NextState("IDLE")
).Elif(bus.start,
NextState("START")
).Elif(bus.setup,
NextValue(bus.sda_o, 1),
).Elif(bus.sample,
If(~bus.sda_i,
NextValue(shreg_o, self.data_o),
NextState("READ-SHIFT")
).Else(
NextState("IDLE")
@@ -651,6 +653,7 @@ def write_bit(self, bit):
yield from self.half_period()
yield self.scl_o.eq(1)
yield from self.half_period()
yield self.sda_o.eq(1)

def write_octet(self, octet):
for bit in range(8)[::-1]:
@@ -824,9 +827,9 @@ def test_write_ack_stop(self, tb):

@simulation_test
def test_read_ack(self, tb):
yield tb.dut.data_o.eq(0b10100101)
yield tb.dut.data_o.eq(0b10101010)
yield from self.start_addr(tb, read=True)
self.assertEqual((yield from tb.read_octet()), 0b10100101)
self.assertEqual((yield from tb.read_octet()), 0b10101010)
yield from tb.write_bit(0)
yield from self.assertState(tb, "READ-SHIFT")

@@ -851,6 +854,17 @@ def test_read_nak_stop(self, tb):
yield
yield from self.assertState(tb, "IDLE")

@simulation_test
def test_read_ack_read(self, tb):
yield tb.dut.data_o.eq(0b10100101)
yield from self.start_addr(tb, read=True)
self.assertEqual((yield from tb.read_octet()), 0b10100101)
yield tb.dut.data_o.eq(0b00110011)
yield from tb.write_bit(0)
self.assertEqual((yield from tb.read_octet()), 0b00110011)
yield from tb.write_bit(0)
yield from self.assertState(tb, "READ-SHIFT")


class _DummyPads(Module):
def __init__(self):