add ASIC version of I2C Master
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 30 Sep 2020 21:30:44 +0000 (22:30 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 30 Sep 2020 21:30:44 +0000 (22:30 +0100)
src/soc/litex/florent/libresoc/ls180.py
src/soc/litex/florent/ls180soc.py

index dc91c4e9e5c21b2b063a596858f844631812d664..5331cd7f12d764e3501a83a142b6bed6585c4d74 100644 (file)
@@ -42,7 +42,9 @@ _io = [
     # I2C0: 2 pins
     ("i2c", 0,
         Subsignal("scl", Pins("L4"), IOStandard("LVCMOS33")),
-        Subsignal("sda", Pins("M1"), IOStandard("LVCMOS33"))
+        Subsignal("sda_i", Pins("M1"), IOStandard("LVCMOS33")),
+        Subsignal("sda_o", Pins("M1"), IOStandard("LVCMOS33")),
+        Subsignal("sda_oe", Pins("M1"), IOStandard("LVCMOS33")),
     ),
 
     # SPI0: 4 pins
index cd8119ebba7ce080cf17a6c147db92edbedd27f5..fd6c84b95f20b05bcdf1876c440ae84652d2afd0 100755 (executable)
@@ -26,7 +26,7 @@ from litedram.common import PHYPadsCombiner, PhySettings
 from litedram.phy.dfi import Interface as DFIInterface
 from litex.soc.cores.spi import SPIMaster
 from litex.soc.cores.pwm import PWM
-from litex.soc.cores.bitbang import I2CMaster
+#from litex.soc.cores.bitbang import I2CMaster
 from litex.soc.cores import uart
 
 from litex.tools.litex_sim import sdram_module_nphases, get_sdram_phy_settings
@@ -61,6 +61,43 @@ from litesdcard.frontend.dma import SDBlock2MemDMA, SDMem2BlockDMA
 from litex.build.io import SDROutput, SDRInput
 
 
+# I2C Master Bit-Banging --------------------------------------------------
+
+class I2CMaster(Module, AutoCSR):
+    """I2C Master Bit-Banging
+
+    Provides the minimal hardware to do software I2C Master bit banging.
+
+    On the same write CSRStorage (_w), software can control SCL (I2C_SCL),
+    SDA direction and value (I2C_OE, I2C_W). Software get back SDA value
+    with the read CSRStatus (_r).
+    """
+    pads_layout = [("scl", 1), ("sda", 1)]
+    def __init__(self, pads):
+        self.pads = pads
+        self._w = CSRStorage(fields=[
+            CSRField("scl", size=1, offset=0),
+            CSRField("oe",  size=1, offset=1),
+            CSRField("sda", size=1, offset=2)],
+            name="w")
+        self._r = CSRStatus(fields=[
+            CSRField("sda", size=1, offset=0)],
+            name="r")
+
+        self.connect(pads)
+
+    def connect(self, pads):
+        _sda_w  = Signal()
+        _sda_oe = Signal()
+        _sda_r  = Signal()
+        self.comb += [
+            pads.scl.eq(self._w.fields.scl),
+            pads.sda_oe.eq( self._w.fields.oe),
+            pads.sda_o.eq(  self._w.fields.sda),
+            self._r.fields.sda.eq(pads.sda_i),
+        ]
+
+
 class GPIOTristateASIC(Module, AutoCSR):
     def __init__(self, pads):
         nbits     = len(pads.oe) # hack