OpenCores
URL https://opencores.org/ocsvn/usb_dongle_fpga/usb_dongle_fpga/trunk

Subversion Repositories usb_dongle_fpga

[/] [usb_dongle_fpga/] [trunk/] [src/] [usb/] [usb2mem.vhd] - Blame information for rev 53

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.