@@ -14,7 +14,7 @@ import Clash.Cores.I2C.Types
14
14
import Data.Maybe (fromJust )
15
15
16
16
data ByteStateMachine = Idle | Active | Start | Read | Write | Ack | Stop
17
- deriving (Show , Generic , NFDataX )
17
+ deriving (Show , Generic , NFDataX , Eq )
18
18
19
19
data I2COperation = ReadData | WriteData (BitVector 8 )
20
20
deriving (Generic , NFDataX )
@@ -29,10 +29,8 @@ data ByteMasterS
29
29
, _coreTxd :: Bit -- coreTxd register
30
30
, _shiftsr :: Bool -- shift sr
31
31
, _ld :: Bool -- load values in to sr
32
- , _i2cOpAck :: Bool -- host cmd acknowlegde register
33
- , _slaveAck :: Bool -- slave ack register
34
32
}
35
- deriving (Generic , NFDataX )
33
+ deriving (Generic , NFDataX , Eq )
36
34
37
35
makeLenses ''ByteMasterS
38
36
@@ -78,45 +76,46 @@ byteMasterInit
78
76
, _coreTxd = low
79
77
, _shiftsr = False
80
78
, _ld = False
81
- , _i2cOpAck = False
82
- , _slaveAck = True
83
79
}
84
80
85
81
byteMasterT :: ByteMasterS -> ByteMasterI -> (ByteMasterS , ByteMasterO )
86
82
byteMasterT s@ (ByteS {_srState = ShiftRegister {.. }, .. })
87
- (rst,claimBus,maybeI2COp,ackIn ,~ (coreAck,al,coreRxd)) = swap $ flip runState s $ do
83
+ (rst,claimBus,maybeI2COp,ackRead ,~ (coreAck,al,coreRxd)) = swap $ flip runState s $ do
88
84
89
85
-- assign dOut the output of the shift-register
90
86
let dout = _sr
91
87
92
88
cntDone <- zoom srState (shiftRegister rst _ld _shiftsr (bv2v (getWriteData $ fromJust maybeI2COp )) coreRxd)
93
89
94
90
-- state machine
95
- coreTxd .= head dout
96
- shiftsr .= False
97
- ld .= False
98
- i2cOpAck .= False
91
+ coreTxd .= head dout
92
+ shiftsr .= False
93
+ ld .= False
99
94
100
95
if rst || al then do
101
96
coreCmd .= I2Cnop
102
97
coreTxd .= low
103
98
byteStateM .= Idle
104
- slaveAck .= True
105
99
else case (_byteStateM, maybeI2COp) of
106
100
(Idle , _) -> when claimBus $ do
107
101
ld .= True
108
102
byteStateM .= Start
109
103
coreCmd .= I2Cstart
110
104
(Active , Just ReadData ) -> do
105
+ ld .= True
111
106
byteStateM .= Read
112
107
coreCmd .= I2Cread
113
108
(Active , Just (WriteData _)) -> do
114
109
ld .= True
115
110
byteStateM .= Write
116
111
coreCmd .= I2Cwrite
117
- (Active ,Nothing ) -> do
118
- byteStateM .= Active
119
- coreCmd .= I2Cnop
112
+ (Active ,Nothing ) ->
113
+ if claimBus then do
114
+ byteStateM .= Active
115
+ coreCmd .= I2Cnop
116
+ else do
117
+ byteStateM .= Stop
118
+ coreCmd .= I2Cstop
120
119
(Start , Nothing ) -> when coreAck $ do
121
120
byteStateM .= Active
122
121
coreCmd .= I2Cnop
@@ -137,7 +136,7 @@ byteMasterT s@(ByteS {_srState = ShiftRegister {..}, ..})
137
136
138
137
(Read , _) -> when coreAck $ do
139
138
shiftsr .= True
140
- coreTxd .= bitCoerce ackIn
139
+ coreTxd .= ( bitCoerce $ not ackRead)
141
140
if cntDone then do
142
141
byteStateM .= Ack
143
142
coreCmd .= I2Cwrite
@@ -146,26 +145,25 @@ byteMasterT s@(ByteS {_srState = ShiftRegister {..}, ..})
146
145
147
146
(Ack , _) ->
148
147
if coreAck then do
149
- slaveAck .= bitCoerce coreRxd
150
- coreTxd .= high
148
+ coreTxd .= high
151
149
-- check for stop; Should a STOP command be generated?
152
150
if claimBus then do
153
151
byteStateM .= Active
154
152
coreCmd .= I2Cnop
155
- -- generate command acknowledge signal
156
- i2cOpAck .= True
157
153
else do
158
154
byteStateM .= Stop
159
155
coreCmd .= I2Cstop
160
156
else
161
- coreTxd .= bitCoerce ackIn
157
+ coreTxd .= ( bitCoerce $ not ackRead)
162
158
163
159
(Stop , _) -> when coreAck $ do
164
160
byteStateM .= Idle
165
161
coreCmd .= I2Cnop
166
- i2cOpAck .= True
167
162
168
- let bitCtrl = (_coreCmd,_coreTxd)
169
- outp = (_i2cOpAck,_slaveAck,v2bv dout,bitCtrl)
163
+ let
164
+ bitCtrl = (_coreCmd,_coreTxd)
165
+ i2cOpAck = (_byteStateM == Ack ) && coreAck
166
+ ackWrite = i2cOpAck && not (bitCoerce coreRxd)
167
+ outp = (i2cOpAck,ackWrite,v2bv dout,bitCtrl)
170
168
171
169
return outp
0 commit comments