soc/cores/i2c: only change SDA when SCL is stable

Avoid changing SDA immediately in states WRITE0 and READ0 to guarantee SDA hold is > 0
This commit is contained in:
Andrew Dennison 2023-08-25 15:24:03 +10:00
parent aef6cb3103
commit c867d5647b
1 changed files with 9 additions and 1 deletions

View File

@ -232,11 +232,19 @@ class I2CMaster(Module, AutoCSR):
self.sda_t = TSTriple() self.sda_t = TSTriple()
self.specials += self.sda_t.get_tristate(pads.sda) self.specials += self.sda_t.get_tristate(pads.sda)
self.comb += [ self.comb += [
self.sda_t.oe.eq(~i2c.sda_o),
self.sda_t.o.eq(0), self.sda_t.o.eq(0),
i2c.sda_i.eq(self.sda_t.i), i2c.sda_i.eq(self.sda_t.i),
] ]
# only change SDA when SCL is stable
self.scl_i_n = Signal() # previous scl_i
self.sync += [
self.scl_i_n.eq(self.scl_t.i),
If(self.scl_i_n == i2c.scl_o,
self.sda_t.oe.eq(~i2c.sda_o),
),
]
# Event Manager. # Event Manager.
self.submodules.ev = EventManager() self.submodules.ev = EventManager()
self.ev.idle = EventSourceProcess(edge="rising") self.ev.idle = EventSourceProcess(edge="rising")