aboutsummaryrefslogtreecommitdiff
path: root/fpga/src
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/src')
-rw-r--r--fpga/src/I2C.bs26
1 files changed, 16 insertions, 10 deletions
diff --git a/fpga/src/I2C.bs b/fpga/src/I2C.bs
index 4a302dd..292691b 100644
--- a/fpga/src/I2C.bs
+++ b/fpga/src/I2C.bs
@@ -5,15 +5,21 @@ import Clocks
import GetPut
struct I2CStatus =
- { -- | Whether a read or write is not in progress, so a new command can be
- -- performed. Writing this bit to move it from high to low begins a
- -- command.
- notBusy :: Bool
- ; -- | Whether the bus is idle. Usually, software will want to use the
- -- `notBusy` bit instead to determine when to send new commands; the
- -- `busIdle` bit is only set to `True` after the STOP condition (i.e.,
- -- after the transaction ends). Writing to this bit does not affect the
- -- internal state of the I²C controller.
+ { -- | This bit is low when a message is being sent, and gets raised after:
+ --
+ -- - We finished sending an address, but a NACK was received.
+ -- - We finished reading a byte, including sending an ACK or NACK bit.
+ -- - We finished writing a byte, including reading an ACK or NACK bit.
+ --
+ -- When this bit is `True`, writing to it will cause a new read or write,
+ -- either in the current transaction (if this happened before `busIdle` was
+ -- lowered) or in a new one.
+ ready :: Bool
+ ; -- | Whether the bus is idle. Usually, software will want to enable
+ -- interrupts on the `ready` bit instead to determine when to send new
+ -- commands; the `busIdle` bit is only set to `True` after the STOP
+ -- condition (i.e., after the transaction ends). Writing to this bit does
+ -- not affect the internal state of the I²C controller.
busIdle :: Bool
; -- | The last ACK bit we received from sending an address. Writing to this
-- bit does not affect the internal state of the I²C controller.
@@ -107,7 +113,7 @@ mkI2C' rxSCL rxSDA txSCL txSDA addrReg dataReg statusReg = module
txSDA := 1
"triggered from Idle": when Idle <- state, not statusReg.notBusy ==>
if rxSDA == 0 then do
- statusReg := statusReg { arbitrationLost = True }
+ statusReg := statusReg { ready = True; busIdle = True; arbitrationLost = True }
state := Idle
txSCL := 1
txSDA := 1