Merge pull request #48 from sifive/i2c_int
i2c interrupt: allow irq to be cleared
This commit is contained in:
commit
462976a070
@ -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
|
// hack: b/c the same register offset is used to write cmd and read status
|
||||||
val nextCmd = Wire(UInt(8.W))
|
val nextCmd = Wire(UInt(8.W))
|
||||||
nextCmd := cmd.asUInt
|
|
||||||
cmd := (new CommandBundle).fromBits(nextCmd)
|
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) {
|
when (cmdAck || arbLost) {
|
||||||
cmd.start := false.B // clear command bits when done
|
cmd.start := false.B // clear command bits when done
|
||||||
cmd.stop := false.B // or when aribitration lost
|
cmd.stop := false.B // or when aribitration lost
|
||||||
cmd.read := false.B
|
cmd.read := false.B
|
||||||
cmd.write := 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
|
status.receivedAck := receivedAck
|
||||||
when (stopCond) {
|
when (stopCond) {
|
||||||
@ -514,11 +514,14 @@ trait HasI2CModuleContents extends MultiIOModule with HasRegMap {
|
|||||||
status.arbLost := false.B
|
status.arbLost := false.B
|
||||||
}
|
}
|
||||||
status.transferInProgress := cmd.read || cmd.write
|
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)
|
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
|
statusReadReady := true.B
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user