1 |
2 |
nuubik |
--COMMAND STRUCTURE OF SERAL USB PROTOCOL
|
2 |
|
|
|
3 |
|
|
-- MSBYTE LSBYTE
|
4 |
|
|
|
5 |
|
|
-- DATA CODE
|
6 |
|
|
|
7 |
|
|
--Dongle internal command codes
|
8 |
|
|
-- 0x00 0xC5 --Get Status data is don't care (must return) 0x3210 (3 is the MSNibble)
|
9 |
|
|
-- 0x01 0xC5 --Get Dongle version code
|
10 |
|
|
-- 0x02 0xC5 --PCB version code
|
11 |
|
|
-- 0x03 0xC5 --Get Mode switch setting
|
12 |
|
|
|
13 |
|
|
-- 0xC1 0xC5 --Release memeory interface to LPC
|
14 |
|
|
-- 0xC2 0xC5 --Put the device in USB programming mode (pulldown buf_en)
|
15 |
|
|
-- 0xC3 0xC5 --Force the dongle to indicate it's disconnected
|
16 |
|
|
-- 0xC4 0xC5 --Force the dongle to indicate it's connected
|
17 |
|
|
|
18 |
|
|
-- 0xC5 0xC5 --Force the dongle to lock memory interface
|
19 |
|
|
-- 0xC6 0xC5 --Force the dongle to unlock memory interface
|
20 |
|
|
|
21 |
|
|
-- 0x-- 0xC5 --Get Status data is don't care (must return) 0x3210 (3 is the MSNibble)
|
22 |
|
|
|
23 |
|
|
|
24 |
|
|
-- 0xNN 0xCD --Get Data from flash (performs read from current address) NN count of words auto increment address
|
25 |
|
|
-- 0xAA 0xA0 --Addr LSByte write
|
26 |
|
|
-- 0xAA 0xA1 --Addr Byte write
|
27 |
|
|
-- 0xAA 0xA2 --Addr MSByte write
|
28 |
|
|
-- 0x-- 0x3F --NOP
|
29 |
|
|
|
30 |
|
|
--Flash operations codes
|
31 |
|
|
-- 0xNN 0xE8 --Write to buffer returns extended satus NN is word count for USB machine
|
32 |
|
|
-- 0x-- 0xD0 -- 0xD0 is flash confirm command
|
33 |
|
|
|
34 |
|
|
--PSRAM operations codes
|
35 |
|
|
-- 0xNN 0xE9 --Write to buffer returns extended satus NN is word count for USB machine
|
36 |
|
|
-- 0xDD 0xDD --N+1 times data expected 0xF + 1 is the maximum
|
37 |
|
|
|
38 |
|
|
|
39 |
|
|
--write flash buffer sequence
|
40 |
|
|
-- ??? -- set address if needed
|
41 |
|
|
-- 0xNN 0xE8 --Write to buffer returns extended satus NN is word count for USB machine
|
42 |
|
|
-- 0x-- 0xNN --0xNN is word count for flash ges directly to flash and is wordCount - 1
|
43 |
|
|
-- 0xDD 0xDD --N+1 times data expected 0xF + 1 is the maximum
|
44 |
|
|
-- ...
|
45 |
|
|
-- 0x-- 0xD0 -- 0xD0 is flash confirm command
|
46 |
|
|
|
47 |
|
|
|
48 |
|
|
|
49 |
|
|
library IEEE;
|
50 |
|
|
use IEEE.std_logic_1164.all;
|
51 |
|
|
use IEEE.std_logic_unsigned.all;
|
52 |
|
|
use IEEE.std_logic_arith.all;
|
53 |
|
|
|
54 |
|
|
entity usb2mem is
|
55 |
|
|
port (
|
56 |
|
|
clk25 : in std_logic;
|
57 |
|
|
reset_n : in std_logic;
|
58 |
|
|
dongle_ver: in std_logic_vector(15 downto 0);
|
59 |
|
|
pcb_ver : in std_logic_vector(15 downto 0);
|
60 |
|
|
mode : in std_logic_vector(2 downto 0); --sel upper addr bits
|
61 |
|
|
usb_buf_en : out std_logic;
|
62 |
|
|
dev_present_n : out std_logic;
|
63 |
|
|
-- mem Bus
|
64 |
|
|
mem_busy_n: in std_logic;
|
65 |
|
|
mem_idle : out std_logic; -- '1' if controller is idle (flash is safe for LPC reads)
|
66 |
|
|
mem_addr : out std_logic_vector(23 downto 0);
|
67 |
|
|
mem_do : out std_logic_vector(15 downto 0);
|
68 |
|
|
mem_di : in std_logic_vector(15 downto 0);
|
69 |
|
|
mem_wr : out std_logic;
|
70 |
|
|
mem_val : out std_logic;
|
71 |
|
|
mem_ack : in std_logic;
|
72 |
|
|
mem_cmd : out std_logic;
|
73 |
|
|
-- USB port
|
74 |
|
|
usb_mode_en: in std_logic; -- enable this block
|
75 |
|
|
usb_rd_n : out std_logic; -- enables out data if low (next byte detected by edge / in usb chip)
|
76 |
|
|
usb_wr : out std_logic; -- write performed on edge \ of signal
|
77 |
|
|
usb_txe_n : in std_logic; -- tx fifo empty (redy for new data if low)
|
78 |
|
|
usb_rxf_n : in std_logic; -- rx fifo empty (data redy if low)
|
79 |
|
|
usb_bd : inout std_logic_vector(7 downto 0) --bus data
|
80 |
|
|
);
|
81 |
|
|
end usb2mem;
|
82 |
|
|
|
83 |
|
|
|
84 |
|
|
architecture RTL of usb2mem is
|
85 |
|
|
|
86 |
|
|
|
87 |
|
|
|
88 |
|
|
|
89 |
|
|
type state_type is (RESETs,RXCMD0s,RXCMD1s,DECODEs,INTERNs,VCIRDs,VCIWRs,TXCMD0s,TXCMD1s,STS_WAITs);
|
90 |
|
|
signal CS : state_type;
|
91 |
|
|
|
92 |
|
|
signal data_reg_i : std_logic_vector(15 downto 0);
|
93 |
|
|
signal data_reg_o : std_logic_vector(15 downto 0);
|
94 |
|
|
signal data_oe : std_logic; -- rx fifo empty (data redy if low)
|
95 |
|
|
signal usb_wr_d : std_logic; -- internal readable output state for write
|
96 |
|
|
signal addr_reg: std_logic_vector(23 downto 0);
|
97 |
|
|
|
98 |
|
|
--State machine
|
99 |
|
|
signal cmd_cnt : std_logic_vector(15 downto 0);
|
100 |
|
|
signal state_cnt : std_logic_vector(3 downto 0);
|
101 |
|
|
--shyncro to USB
|
102 |
|
|
signal usb_txe_nd : std_logic; -- tx fifo empty (redy for new data if low)
|
103 |
|
|
signal usb_rxf_nd : std_logic; -- rx fifo empty (data redy if low)
|
104 |
|
|
signal internal_cmd : std_logic; -- rx fifo empty (data redy if low)
|
105 |
|
|
|
106 |
|
|
signal read_mode : std_logic;
|
107 |
|
|
signal write_mode : std_logic;
|
108 |
|
|
signal write_count : std_logic;
|
109 |
|
|
signal first_word : std_logic;
|
110 |
|
|
signal mem_busy_nd : std_logic;
|
111 |
|
|
|
112 |
|
|
|
113 |
|
|
|
114 |
|
|
begin
|
115 |
|
|
|
116 |
|
|
--define internal command codes
|
117 |
|
|
internal_cmd <='1' when data_reg_i(7 downto 0) = x"C5" else
|
118 |
|
|
'1' when data_reg_i(7 downto 0) = x"CD" else
|
119 |
|
|
'1' when data_reg_i(7 downto 0) = x"A0" else
|
120 |
|
|
'1' when data_reg_i(7 downto 0) = x"A1" else
|
121 |
|
|
'1' when data_reg_i(7 downto 0) = x"A2" else
|
122 |
|
|
'1' when data_reg_i(7 downto 0) = x"3F" else
|
123 |
|
|
--These are spechial attention Flash commands
|
124 |
|
|
'1' when data_reg_i(7 downto 0) = x"E8" else
|
125 |
|
|
'1' when data_reg_i(7 downto 0) = x"E9" else
|
126 |
|
|
'0';
|
127 |
|
|
|
128 |
|
|
|
129 |
|
|
usb_wr <= usb_wr_d when usb_mode_en='1' else
|
130 |
|
|
'Z';
|
131 |
|
|
|
132 |
|
|
|
133 |
|
|
-- this goes to byte buffer for that reason send LSB first and MSB second
|
134 |
|
|
usb_bd <=data_reg_o(7 downto 0)when data_oe='1' and CS=TXCMD0s and usb_mode_en='1' else --LSB byte first
|
135 |
|
|
data_reg_o(15 downto 8) when data_oe='1' and CS=TXCMD1s and usb_mode_en='1' else --MSB byte second
|
136 |
|
|
(others=>'Z');
|
137 |
|
|
|
138 |
|
|
|
139 |
|
|
process (clk25,reset_n) --enable the scanning while in reset (simulation will be incorrect)
|
140 |
|
|
begin -- process
|
141 |
|
|
if reset_n='0' then
|
142 |
|
|
CS <= RESETs;
|
143 |
|
|
usb_rd_n <= '1';
|
144 |
|
|
usb_wr_d <= '0';
|
145 |
|
|
usb_txe_nd <= '1';
|
146 |
|
|
usb_rxf_nd <= '1';
|
147 |
|
|
data_oe <='0';
|
148 |
|
|
state_cnt <=(others=>'0'); --init command counter
|
149 |
|
|
mem_do <= (others=>'Z');
|
150 |
|
|
mem_addr <= (others=>'Z');
|
151 |
|
|
addr_reg <= (others=>'0');
|
152 |
|
|
mem_val <= '0';
|
153 |
|
|
mem_wr <='0';
|
154 |
|
|
mem_cmd <='0';
|
155 |
|
|
cmd_cnt <= (others=>'0');
|
156 |
|
|
read_mode <='0';
|
157 |
|
|
write_mode <='0';
|
158 |
|
|
write_count <='0';
|
159 |
|
|
first_word <='0';
|
160 |
|
|
mem_idle <='1'; --set idle
|
161 |
|
|
mem_busy_nd <='1';
|
162 |
|
|
usb_buf_en <='1'; -- default mode (USB prog disabled, buffer with HiZ outputs)
|
163 |
|
|
dev_present_n <='0'; --indicate that device is present on LPC bus for thincans
|
164 |
|
|
elsif clk25'event and clk25 = '1' then -- rising clock edge
|
165 |
|
|
usb_txe_nd <= usb_txe_n; --syncronize
|
166 |
|
|
usb_rxf_nd <= usb_rxf_n; --syncronize
|
167 |
|
|
mem_busy_nd <=mem_busy_n; --syncronize
|
168 |
|
|
case CS is
|
169 |
|
|
when RESETs =>
|
170 |
|
|
if usb_rxf_nd='0' and usb_mode_en='1' and mem_busy_nd='1' then
|
171 |
|
|
state_cnt <=(others=>'0'); --init command counter
|
172 |
|
|
data_oe <='0'; --we will read command in
|
173 |
|
|
--mem_idle <='0'; --set busy untill return here
|
174 |
|
|
CS <= RXCMD0s;
|
175 |
|
|
end if;
|
176 |
|
|
when RXCMD0s =>
|
177 |
|
|
if state_cnt="0000" then
|
178 |
|
|
usb_rd_n <='0'; -- set read low
|
179 |
|
|
state_cnt <= state_cnt + 1;-- must be min 50ns long (two cycles)
|
180 |
|
|
elsif state_cnt="0001" then
|
181 |
|
|
state_cnt <= state_cnt + 1;-- one wait cycle
|
182 |
|
|
elsif state_cnt="0010" then
|
183 |
|
|
state_cnt <= state_cnt + 1;-- now is ok
|
184 |
|
|
data_reg_i(15 downto 8) <= usb_bd; --get data form bus MSByte must come first
|
185 |
|
|
elsif state_cnt="0011" then
|
186 |
|
|
usb_rd_n <='1'; -- set read back to high
|
187 |
|
|
state_cnt <= state_cnt + 1;-- start wait
|
188 |
|
|
elsif state_cnt="0100" then
|
189 |
|
|
state_cnt <= state_cnt + 1;-- wait (the usb_rxf_n toggles after each read and next data is not ready)
|
190 |
|
|
elsif state_cnt="0101" then
|
191 |
|
|
state_cnt <= state_cnt + 1;-- wait
|
192 |
|
|
elsif state_cnt="0110" then
|
193 |
|
|
state_cnt <= state_cnt + 1;-- now is ok prob.
|
194 |
|
|
else
|
195 |
|
|
if usb_rxf_nd='0' then --wait untill next byte is available
|
196 |
|
|
state_cnt <=(others=>'0'); --init command counter
|
197 |
|
|
CS <= RXCMD1s;
|
198 |
|
|
end if;
|
199 |
|
|
end if;
|
200 |
|
|
when RXCMD1s =>
|
201 |
|
|
if state_cnt="0000" then
|
202 |
|
|
usb_rd_n <='0'; -- set read low
|
203 |
|
|
state_cnt <= state_cnt + 1;-- must be min 50ns long (two cycles)
|
204 |
|
|
elsif state_cnt="0001" then
|
205 |
|
|
state_cnt <= state_cnt + 1;-- one wait cycle
|
206 |
|
|
elsif state_cnt="0010" then
|
207 |
|
|
state_cnt <= state_cnt + 1;-- now is ok
|
208 |
|
|
data_reg_i(7 downto 0) <= usb_bd; --get data form bus LSByte must come last
|
209 |
|
|
elsif state_cnt="0011" then
|
210 |
|
|
state_cnt <= state_cnt + 1;-- now is ok
|
211 |
|
|
usb_rd_n <='1'; -- set read back to high
|
212 |
|
|
elsif state_cnt="0100" then
|
213 |
|
|
state_cnt <= state_cnt + 1;-- wait (the usb_rxf_n toggles after each read and next data is not ready)
|
214 |
|
|
elsif state_cnt="0101" then
|
215 |
|
|
state_cnt <= state_cnt + 1;-- wait
|
216 |
|
|
elsif state_cnt="0110" then
|
217 |
|
|
state_cnt <= state_cnt + 1;-- now is ok prob.
|
218 |
|
|
else
|
219 |
|
|
state_cnt <=(others=>'0'); --init command counter
|
220 |
|
|
CS <= INTERNs;
|
221 |
|
|
end if;
|
222 |
|
|
when INTERNs =>
|
223 |
|
|
if cmd_cnt=x"0000" then
|
224 |
|
|
if data_reg_i(7 downto 0)=x"A0" then
|
225 |
|
|
addr_reg(7 downto 0)<= data_reg_i(15 downto 8);
|
226 |
|
|
CS <= RESETs; --go back to resets
|
227 |
|
|
elsif data_reg_i(7 downto 0)=x"A1" then
|
228 |
|
|
addr_reg(15 downto 8)<= data_reg_i(15 downto 8);
|
229 |
|
|
CS <= RESETs; --go back to resets
|
230 |
|
|
elsif data_reg_i(7 downto 0)=x"A2" then
|
231 |
|
|
addr_reg(23 downto 16)<= data_reg_i(15 downto 8);
|
232 |
|
|
CS <= RESETs; --go back to resets
|
233 |
|
|
elsif data_reg_i(7 downto 0)=x"3F" then
|
234 |
|
|
CS <= RESETs; --go back to resets --NOP command
|
235 |
|
|
elsif data_reg_i(7 downto 0)=x"C5" then
|
236 |
|
|
if (data_reg_i(15 downto 8))=x"00" then
|
237 |
|
|
data_reg_o <=x"3210";
|
238 |
|
|
elsif(data_reg_i(15 downto 8))=x"01" then
|
239 |
|
|
data_reg_o <=dongle_ver;
|
240 |
|
|
elsif(data_reg_i(15 downto 8))=x"02" then
|
241 |
|
|
data_reg_o <=pcb_ver;
|
242 |
|
|
elsif(data_reg_i(15 downto 8))=x"03" then
|
243 |
|
|
data_reg_o <="0000000000000"&mode;
|
244 |
|
|
elsif(data_reg_i(15 downto 8))=x"C1" then --release flash to LPC interface
|
245 |
|
|
data_reg_o <=x"C1C5";
|
246 |
|
|
mem_idle <='1'; --set idle
|
247 |
|
|
elsif(data_reg_i(15 downto 8))=x"C2" then --force USB prog mode
|
248 |
|
|
usb_buf_en <='0';
|
249 |
|
|
data_reg_o <=x"C2C5";
|
250 |
|
|
elsif(data_reg_i(15 downto 8))=x"C3" then --fake dongle disconnect
|
251 |
|
|
data_reg_o <=x"C3C5";
|
252 |
|
|
dev_present_n <='0';
|
253 |
|
|
elsif(data_reg_i(15 downto 8))=x"C4" then --fake dongle connect
|
254 |
|
|
data_reg_o <=x"C4C5";
|
255 |
|
|
dev_present_n <='1';
|
256 |
|
|
elsif(data_reg_i(15 downto 8))=x"C5" then --fake dongle connect
|
257 |
|
|
data_reg_o <=x"C5C5";
|
258 |
|
|
mem_idle <='0'; --lock LPC out from memory interface
|
259 |
|
|
elsif(data_reg_i(15 downto 8))=x"C6" then --fake dongle connect
|
260 |
|
|
data_reg_o <=x"C6C5";
|
261 |
|
|
mem_idle <='1'; --unlock memory interface
|
262 |
|
|
else
|
263 |
|
|
data_reg_o <=x"3210"; --always return even on unknown commands
|
264 |
|
|
end if;
|
265 |
|
|
CS <= TXCMD0s;
|
266 |
|
|
elsif data_reg_i(7 downto 0)=x"CD" then
|
267 |
|
|
if (data_reg_i(15 downto 8))=x"00" then --64K word read coming
|
268 |
|
|
cmd_cnt <= (others=>'1'); --64K word count
|
269 |
|
|
else
|
270 |
|
|
cmd_cnt <= x"00"&data_reg_i(15 downto 8) - 1; -- -1 as one read will be done right now (cmd_cnt words)
|
271 |
|
|
end if;
|
272 |
|
|
CS <= VCIRDs; --go perform a read
|
273 |
|
|
read_mode <='1';
|
274 |
|
|
elsif data_reg_i(7 downto 0)=x"E8" then
|
275 |
|
|
--write_mode <='1';
|
276 |
|
|
write_count <='0';
|
277 |
|
|
first_word <='0';
|
278 |
|
|
cmd_cnt <= x"00"&data_reg_i(15 downto 8) + 1; --+2 for direct count write +1
|
279 |
|
|
data_reg_i(15 downto 8)<=(others=>'0');
|
280 |
|
|
CS <= VCIWRs; --go perform a write
|
281 |
|
|
elsif data_reg_i(7 downto 0)=x"E9" then
|
282 |
|
|
write_count <='1'; --no initial command write
|
283 |
|
|
first_word <='0';
|
284 |
|
|
if (data_reg_i(15 downto 8))=x"00" then --64K word write coming
|
285 |
|
|
cmd_cnt <= (others=>'1'); --64K word count
|
286 |
|
|
else
|
287 |
|
|
cmd_cnt <= x"00"&data_reg_i(15 downto 8);
|
288 |
|
|
end if;
|
289 |
|
|
data_reg_i(15 downto 8)<=(others=>'0');
|
290 |
|
|
CS <= RESETs; --PSRAM does not need command
|
291 |
|
|
else
|
292 |
|
|
CS <= VCIWRs;
|
293 |
|
|
end if;
|
294 |
|
|
else
|
295 |
|
|
if cmd_cnt>x"0000" then
|
296 |
|
|
cmd_cnt<= cmd_cnt - 1;
|
297 |
|
|
if write_count='0' then
|
298 |
|
|
write_count<='1';
|
299 |
|
|
elsif write_count='1' and first_word ='0' then
|
300 |
|
|
first_word <='1';
|
301 |
|
|
elsif write_count='1' and first_word ='1' then
|
302 |
|
|
addr_reg <= addr_reg + 1; --autoincrement address in in block mode
|
303 |
|
|
end if;
|
304 |
|
|
--if cmd_cnt>x"02" then --so not to increase too many times on write buffer
|
305 |
|
|
-- addr_reg <= addr_reg + 1; --autoincrement address in in block mode
|
306 |
|
|
--end if;
|
307 |
|
|
end if;
|
308 |
|
|
CS <= VCIWRs;
|
309 |
|
|
end if;
|
310 |
|
|
when VCIRDs => --flash read
|
311 |
|
|
mem_wr <='0'; --this is VCI write_not_read
|
312 |
|
|
mem_cmd <='0';
|
313 |
|
|
mem_addr <= addr_reg(22 downto 0)&'0'; --translate byte address to word address
|
314 |
|
|
mem_val <= '1';
|
315 |
|
|
if mem_ack='1' then
|
316 |
|
|
data_reg_o <= mem_di;
|
317 |
|
|
mem_wr <='0'; --this is VCI write_not_read
|
318 |
|
|
mem_cmd <='0';
|
319 |
|
|
mem_val <= '0';
|
320 |
|
|
CS <= TXCMD0s;
|
321 |
|
|
end if;
|
322 |
|
|
when VCIWRs => --flash write
|
323 |
|
|
mem_addr <= addr_reg(22 downto 0)&'0'; --translate byte address to word address
|
324 |
|
|
if mode(2)='1' then
|
325 |
|
|
--this HW swap removes the need to swap bytes in python for PSRAM region
|
326 |
|
|
mem_do <= data_reg_i(7 downto 0)&data_reg_i(15 downto 8); --SWAP data for PSRAM region
|
327 |
|
|
else
|
328 |
|
|
mem_do <= data_reg_i; --USB data in will go to mem_out
|
329 |
|
|
end if;
|
330 |
|
|
mem_wr <='1'; --this is VCI write_not_read
|
331 |
|
|
mem_cmd <='1';
|
332 |
|
|
mem_val <= '1';
|
333 |
|
|
if mem_ack='1' then
|
334 |
|
|
mem_do <= (others=>'Z');
|
335 |
|
|
mem_wr <='0'; --this is VCI write_not_read
|
336 |
|
|
mem_cmd <='0';
|
337 |
|
|
mem_val <= '0';
|
338 |
|
|
--if write_mode='0' then
|
339 |
|
|
|
340 |
|
|
if cmd_cnt=x"0000" then --if flash command and not data
|
341 |
|
|
state_cnt <=(others=>'0'); --init command counter
|
342 |
|
|
CS <= STS_WAITs;
|
343 |
|
|
else
|
344 |
|
|
CS <= RESETs;
|
345 |
|
|
end if;
|
346 |
|
|
--else --else if was 0xE8 must read and return XSR
|
347 |
|
|
-- write_mode <='0'; --XSR return will no follow clear this bit
|
348 |
|
|
-- CS <= VCIRDs;
|
349 |
|
|
--end if;
|
350 |
|
|
end if;
|
351 |
|
|
when TXCMD0s => --transmit over USB what ever is in data_reg_o MSB first
|
352 |
|
|
|
353 |
|
|
if state_cnt="0000" then
|
354 |
|
|
if usb_txe_nd='0' then
|
355 |
|
|
usb_wr_d<='1'; -- data is mux'ed by state and data_oe in the beginning of arch
|
356 |
|
|
state_cnt <= state_cnt + 1;-- now is ok
|
357 |
|
|
end if;
|
358 |
|
|
elsif state_cnt="0010" then
|
359 |
|
|
data_oe<='1'; --this is to put data on bus befora falling edge of wr (max 20ns before)
|
360 |
|
|
state_cnt <= state_cnt + 1;-- now is ok
|
361 |
|
|
elsif state_cnt="0011" then
|
362 |
|
|
usb_wr_d<='0'; --falling edge performs write must be high for atleast 50ns
|
363 |
|
|
state_cnt <= state_cnt + 1;-- now is ok
|
364 |
|
|
elsif state_cnt="0100" then
|
365 |
|
|
state_cnt <= state_cnt + 1;-- now is ok
|
366 |
|
|
data_oe<='0';
|
367 |
|
|
elsif state_cnt="0111" then --must stay low at least 50ns
|
368 |
|
|
CS <= TXCMD1s;
|
369 |
|
|
state_cnt <= (others=>'0');
|
370 |
|
|
else
|
371 |
|
|
state_cnt <= state_cnt + 1;-- if intermediate cnt then count
|
372 |
|
|
end if;
|
373 |
|
|
|
374 |
|
|
when TXCMD1s =>
|
375 |
|
|
|
376 |
|
|
if state_cnt="0000" then
|
377 |
|
|
if usb_txe_nd='0' then
|
378 |
|
|
usb_wr_d<='1'; -- data is mux'ed by state and data_oe in the beginning of arch
|
379 |
|
|
state_cnt <= state_cnt + 1;-- now is ok
|
380 |
|
|
end if;
|
381 |
|
|
elsif state_cnt="0010" then
|
382 |
|
|
data_oe<='1'; --this is to put data on bus befora falling edge of wr (max 20ns before)
|
383 |
|
|
state_cnt <= state_cnt + 1;-- now is ok
|
384 |
|
|
elsif state_cnt="0011" then
|
385 |
|
|
usb_wr_d<='0'; --falling edge performs write must be high for atleast 50ns
|
386 |
|
|
state_cnt <= state_cnt + 1;-- now is ok
|
387 |
|
|
elsif state_cnt="0100" then
|
388 |
|
|
state_cnt <= state_cnt + 1;-- now is ok
|
389 |
|
|
data_oe<='0';
|
390 |
|
|
elsif state_cnt="0111" then --must stay low at least 50ns
|
391 |
|
|
if read_mode='0' then
|
392 |
|
|
CS <= RESETs;
|
393 |
|
|
elsif cmd_cnt="0000" then --last word sent
|
394 |
|
|
addr_reg <= addr_reg + 1; --autoincrement address in read mode
|
395 |
|
|
read_mode <='0';
|
396 |
|
|
CS <= RESETs;
|
397 |
|
|
else
|
398 |
|
|
cmd_cnt<= cmd_cnt - 1;
|
399 |
|
|
addr_reg <= addr_reg + 1; --autoincrement address in read mode
|
400 |
|
|
CS <= VCIRDs; --more data to be read
|
401 |
|
|
end if;
|
402 |
|
|
state_cnt <= (others=>'0');
|
403 |
|
|
else
|
404 |
|
|
state_cnt <= state_cnt + 1;-- if intermediate cnt then count
|
405 |
|
|
end if;
|
406 |
|
|
when STS_WAITs =>
|
407 |
|
|
if mem_busy_nd='0' or mode(2)='1' then --go to RESETs if PSRAM mode is selected
|
408 |
|
|
CS <= RESETs; --now it's ok to go here
|
409 |
|
|
else
|
410 |
|
|
state_cnt <= state_cnt + 1;
|
411 |
|
|
if state_cnt="1111" then
|
412 |
|
|
--sts cant take longer than 500 ns to go low
|
413 |
|
|
CS <= RESETs; --time out go to resets anyway
|
414 |
|
|
end if;
|
415 |
|
|
end if;
|
416 |
|
|
when others => null;
|
417 |
|
|
end case;
|
418 |
|
|
end if;
|
419 |
|
|
end process;
|
420 |
|
|
|
421 |
|
|
|
422 |
|
|
|
423 |
|
|
end RTL;
|
424 |
|
|
|