i2c: Allow irq to be cleared
[sifive-blocks.git] / src / main / scala / devices / i2c / I2C.scala
index 147a739b6041c01f361eb208bd6ce37345fedf07..d767a265f05c5add29c63ef0e53e70bc96ba08c7 100644 (file)
@@ -42,6 +42,7 @@
 package sifive.blocks.devices.i2c
 
 import Chisel._
+import chisel3.experimental.MultiIOModule
 import freechips.rocketchip.config._
 import freechips.rocketchip.regmapper._
 import freechips.rocketchip.tilelink._
@@ -64,7 +65,7 @@ trait HasI2CBundleContents extends Bundle {
   val port = new I2CPort
 }
 
-trait HasI2CModuleContents extends Module with HasRegMap {
+trait HasI2CModuleContents extends MultiIOModule with HasRegMap {
   val io: HasI2CBundleContents
   val params: I2CParams
 
@@ -487,16 +488,16 @@ trait HasI2CModuleContents extends Module with HasRegMap {
 
   // hack: b/c the same register offset is used to write cmd and read status
   val nextCmd = Wire(UInt(8.W))
-  nextCmd := cmd.asUInt
   cmd := (new CommandBundle).fromBits(nextCmd)
+  nextCmd := cmd.asUInt & 0xFE.U  // clear IRQ_ACK bit (essentially 1 cycle pulse b/c it is overwritten by regmap below)
 
+  // Note: This wins over the regmap update of nextCmd (even if something tries to write them to 1, these values take priority).
   when (cmdAck || arbLost) {
     cmd.start := false.B    // clear command bits when done
     cmd.stop  := false.B    // or when aribitration lost
     cmd.read  := false.B
     cmd.write := false.B
   }
-  cmd.irqAck  := false.B    // clear IRQ_ACK bit (essentially 1 cycle pulse b/c it is overwritten by regmap below)
 
   status.receivedAck := receivedAck
   when (stopCond) {