From 6c5b80671cab9436195fc3fdde9544764a5ded34 Mon Sep 17 00:00:00 2001 From: Megan Wachs Date: Fri, 16 Feb 2018 15:49:09 -0800 Subject: [PATCH 1/2] i2c: Allow irq to be cleared --- src/main/scala/devices/i2c/I2C.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/devices/i2c/I2C.scala b/src/main/scala/devices/i2c/I2C.scala index aecf2dc..d767a26 100644 --- a/src/main/scala/devices/i2c/I2C.scala +++ b/src/main/scala/devices/i2c/I2C.scala @@ -488,16 +488,16 @@ trait HasI2CModuleContents extends MultiIOModule 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) { From ef8139f18c1f0392fe7f5b56953e059aca0a98c9 Mon Sep 17 00:00:00 2001 From: Alex Solomatnikov Date: Thu, 22 Feb 2018 18:43:39 -0800 Subject: [PATCH 2/2] Do not allow status read if status.transferInProgress is going to change next cycle --- src/main/scala/devices/i2c/I2C.scala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/scala/devices/i2c/I2C.scala b/src/main/scala/devices/i2c/I2C.scala index d767a26..be7ff4a 100644 --- a/src/main/scala/devices/i2c/I2C.scala +++ b/src/main/scala/devices/i2c/I2C.scala @@ -514,11 +514,14 @@ trait HasI2CModuleContents extends MultiIOModule with HasRegMap { status.arbLost := false.B } status.transferInProgress := cmd.read || cmd.write - status.irqFlag := (cmdAck || arbLost || status.irqFlag) && !cmd.irqAck + status.irqFlag := (cmdAck || arbLost || status.irqFlag) && !cmd.irqAck // interrupt request flag is always generated val statusReadReady = Reg(init = true.B) - when (!statusReadReady) { + when (cmdAck || arbLost) { // => cmd.read or cmd.write deassert 1 cycle later => transferInProgress deassert 2 cycles later + statusReadReady := false.B // do not allow status read if status.transferInProgress is going to change + } + .elsewhen (!statusReadReady) { statusReadReady := true.B }