diplomacy: update to new API (#40)
[sifive-blocks.git] / src / main / scala / devices / i2c / I2C.scala
index da555496a8297f1a1d69a9d7cbeb90a67b5b3b20..aecf2dca476cde9bb5bfb94adbb650ed988b0959 100644 (file)
 package sifive.blocks.devices.i2c
 
 import Chisel._
-import config._
-import util._
-import regmapper._
-import uncore.tilelink2._
-import rocketchip.PeripheryBusConfig
-import util.AsyncResetRegVec
-import sifive.blocks.devices.gpio.{GPIOPinCtrl}
-
-case class I2CConfig(address: BigInt)
-
-trait HasI2CParameters {
-  implicit val p: Parameters
-  val params: I2CConfig
-  val c = params
-}
+import chisel3.experimental.MultiIOModule
+import freechips.rocketchip.config._
+import freechips.rocketchip.regmapper._
+import freechips.rocketchip.tilelink._
+import freechips.rocketchip.util.{AsyncResetRegVec, Majority}
+
+case class I2CParams(address: BigInt)
 
 class I2CPin extends Bundle {
   val in  = Bool(INPUT)
@@ -69,12 +61,13 @@ class I2CPort extends Bundle {
   val sda = new I2CPin
 }
 
-trait I2CBundle extends Bundle with HasI2CParameters {
+trait HasI2CBundleContents extends Bundle {
   val port = new I2CPort
 }
 
-trait I2CModule extends Module with HasI2CParameters with HasRegMap {
-  val io: I2CBundle
+trait HasI2CModuleContents extends MultiIOModule with HasRegMap {
+  val io: HasI2CBundleContents
+  val params: I2CParams
 
   val I2C_CMD_NOP   = UInt(0x00)
   val I2C_CMD_START = UInt(0x01)
@@ -143,8 +136,8 @@ trait I2CModule extends Module with HasI2CParameters with HasRegMap {
     fSDA := Cat(fSDA, io.port.sda.in)
   }
 
-  val sSCL      = Reg(init = true.B, next = (new Majority(fSCL.toBools.toSet)).out)
-  val sSDA      = Reg(init = true.B, next = (new Majority(fSDA.toBools.toSet)).out)
+  val sSCL      = Reg(init = true.B, next = Majority(fSCL))
+  val sSDA      = Reg(init = true.B, next = Majority(fSDA))
 
   val dSCL      = Reg(init = true.B, next = sSCL)
   val dSDA      = Reg(init = true.B, next = sSDA)
@@ -182,10 +175,10 @@ trait I2CModule extends Module with HasI2CParameters with HasRegMap {
   }
 
   val sclOen     = Reg(init = true.B)
-  io.port.scl.oe := sclOen
+  io.port.scl.oe := !sclOen
 
   val sdaOen     = Reg(init = true.B)
-  io.port.sda.oe := sdaOen
+  io.port.sda.oe := !sdaOen
 
   val sdaChk     = Reg(init = false.B)       // check SDA output (Multi-master arbitration)
 
@@ -524,12 +517,28 @@ trait I2CModule extends Module with HasI2CParameters with HasRegMap {
   status.irqFlag            := (cmdAck || arbLost || status.irqFlag) && !cmd.irqAck
 
 
+  val statusReadReady = Reg(init = true.B)
+  when (!statusReadReady) {
+    statusReadReady := true.B
+  }
+
+  // statusReadReady,
   regmap(
     I2CCtrlRegs.prescaler_lo -> Seq(RegField(8, prescaler.lo)),
     I2CCtrlRegs.prescaler_hi -> Seq(RegField(8, prescaler.hi)),
     I2CCtrlRegs.control      -> control.elements.map{ case(name, e) => RegField(e.getWidth, e.asInstanceOf[UInt]) }.toSeq,
     I2CCtrlRegs.data         -> Seq(RegField(8, r = RegReadFn(receivedData),  w = RegWriteFn(transmitData))),
-    I2CCtrlRegs.cmd_status   -> Seq(RegField(8, r = RegReadFn(status.asUInt), w = RegWriteFn(nextCmd)))
+    I2CCtrlRegs.cmd_status   -> Seq(RegField(8, r = RegReadFn{ ready =>
+                                                               (statusReadReady, status.asUInt)
+                                                             },
+                                                w = RegWriteFn((valid, data) => {
+                                                               when (valid) {
+                                                                 statusReadReady := false.B
+                                                                 nextCmd := data
+                                                             }
+                                                             true.B
+                                                }
+                                                )))
   )
 
   // tie off unused bits
@@ -540,16 +549,8 @@ trait I2CModule extends Module with HasI2CParameters with HasRegMap {
   interrupts(0) := status.irqFlag & control.intEn
 }
 
-// Copied from UART.scala
-class Majority(in: Set[Bool]) {
-  private val n = (in.size >> 1) + 1
-  private val clauses = in.subsets(n).map(_.reduce(_ && _))
-  val out = clauses.reduce(_ || _)
-}
-
-
 // Magic TL2 Incantation to create a TL2 Slave
-class TLI2C(c: I2CConfig)(implicit p: Parameters)
-  extends TLRegisterRouter(c.address, interrupts = 1, beatBytes = p(PeripheryBusConfig).beatBytes)(
-  new TLRegBundle(c, _)    with I2CBundle)(
-  new TLRegModule(c, _, _) with I2CModule)
+class TLI2C(w: Int, c: I2CParams)(implicit p: Parameters)
+  extends TLRegisterRouter(c.address, "i2c", Seq("sifive,i2c0"), interrupts = 1, beatBytes = w)(
+  new TLRegBundle(c, _)    with HasI2CBundleContents)(
+  new TLRegModule(c, _, _) with HasI2CModuleContents)