@@ -42,7 +42,7 @@ end entity;
42
42
43
43
architecture rtl of i2c_core is
44
44
45
- type state_t is (IDLE, START, WAIT_START, WAIT_ADDR, ADDR_ACK , READ , WRITE , WAIT_WRITE_ACK, STOP , WAIT_STOP);
45
+ type state_t is (IDLE, START, WAIT_START, WAIT_ADDR_ACK , READ , WRITE , WAIT_WRITE_ACK, STOP , WAIT_STOP);
46
46
47
47
type sm_reg_t is record
48
48
state : state_t;
@@ -108,8 +108,6 @@ begin
108
108
is_read := '0' when sm_reg.cmd.op = WRITE else '1' ;
109
109
110
110
-- defaults
111
- v.do_start := '0' ;
112
- v.do_stop := '0' ;
113
111
v.tx_byte_valid := '0' ;
114
112
115
113
case sm_reg.state is
@@ -124,25 +122,18 @@ begin
124
122
-- single cycle state to initiate a START
125
123
when START =>
126
124
v.state := WAIT_START;
127
- v.do_start := '1' ;
128
125
129
126
-- wait for link layer to finish START sequence and load up the address byte
130
127
when WAIT_START =>
128
+ v.tx_byte := sm_reg.cmd.addr & is_read;
129
+ v.tx_byte_valid := '1' ;
131
130
if ll_ready then
132
- v.state := WAIT_ADDR;
133
- v.tx_byte := sm_reg.cmd.addr & is_read;
134
- v.tx_byte_valid := '1' ;
135
- end if ;
136
-
137
- -- wait for address byte to have been sent
138
- when WAIT_ADDR =>
139
- if ll_ready then
140
- v.state := ADDR_ACK;
131
+ v.state := WAIT_ADDR_ACK;
141
132
end if ;
142
133
143
- -- take action based off the operation type and the ACK
144
- when ADDR_ACK =>
145
- if ll_ackd_valid then
134
+ -- wait for address byte to have been sent and for the peripheral to ACK
135
+ when WAIT_ADDR_ACK =>
136
+ if ll_ready = '1' and ll_ackd_valid = '1' then
146
137
if ll_ackd then
147
138
if sm_reg.cmd.op = Read or sm_reg.in_random_read then
148
139
v.state := READ ;
@@ -160,7 +151,6 @@ begin
160
151
-- TODO: address nack error
161
152
v.state := STOP ;
162
153
end if ;
163
-
164
154
end if ;
165
155
166
156
-- read as many bytes as requested
@@ -207,7 +197,6 @@ begin
207
197
-- initiate a STOP and clear state
208
198
when STOP =>
209
199
v.state := WAIT_STOP;
210
- v.do_stop := '1' ;
211
200
v.bytes_done := (others => '0' );
212
201
v.in_random_read := false ;
213
202
@@ -218,6 +207,10 @@ begin
218
207
end if ;
219
208
end case ;
220
209
210
+ -- next state logic
211
+ v.do_start := '1' when v.state = START else '0' ;
212
+ v.do_stop := '1' when v.state = STOP else '0' ;
213
+
221
214
sm_reg_next <= v;
222
215
end process ;
223
216
0 commit comments