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 2

Go to most recent revision | 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
    -- mem Bus
41
    mem_addr  : out std_logic_vector(23 downto 0);
42
    mem_do    : out std_logic_vector(15 downto 0);
43
    mem_di    : in std_logic_vector(15 downto 0);
44
    mem_wr    : out std_logic;
45
    mem_val   : out std_logic;
46
    mem_ack   : in  std_logic;
47
    mem_cmd   : out std_logic;
48
    -- USB port
49
    usb_rd_n   : out  std_logic;  -- enables out data if low (next byte detected by edge / in usb chip)
50
    usb_wr     : out  std_logic;  -- write performed on edge \ of signal
51
    usb_txe_n  : in   std_logic;  -- tx fifo empty (redy for new data if low)
52
    usb_rxf_n  : in   std_logic;  -- rx fifo empty (data redy if low)
53
    usb_bd     : inout  std_logic_vector(7 downto 0) --bus data
54
    );
55
end usb2mem;
56
 
57
 
58
architecture RTL of usb2mem is
59
 
60
 
61
 
62
 
63
  type state_type is (RESETs,RXCMD0s,RXCMD1s,DECODEs,INTERNs,VCIRDs,VCIWRs,TXCMD0s,TXCMD1s);
64
  signal CS : state_type;
65
 
66
  signal data_reg_i : std_logic_vector(15 downto 0);
67
  signal data_reg_o : std_logic_vector(15 downto 0);
68
  signal data_oe    : std_logic;  -- rx fifo empty (data redy if low)
69
  signal usb_wr_d   : std_logic;  -- internal readable output state for write
70
  signal addr_reg: std_logic_vector(23 downto 0);
71
 
72
  --State machine
73
  signal cmd_cnt   : std_logic_vector(7 downto 0);
74
  signal state_cnt : std_logic_vector(3 downto 0);
75
  --shyncro to USB
76
  signal usb_txe_nd  :    std_logic;  -- tx fifo empty (redy for new data if low)
77
  signal usb_rxf_nd  :    std_logic;  -- rx fifo empty (data redy if low)
78
  signal internal_cmd  :    std_logic;  -- rx fifo empty (data redy if low)
79
 
80
  signal read_mode   : std_logic;
81
  signal write_mode  : std_logic;
82
  signal write_count : std_logic;
83
  signal first_word : std_logic;
84
 
85
 
86
 
87
begin
88
 
89
--define internal command codes
90
internal_cmd <='1' when data_reg_i(7 downto 0) = x"C5" else
91
                                        '1' when data_reg_i(7 downto 0) = x"CD" else
92
                                        '1' when data_reg_i(7 downto 0) = x"A0" else
93
                                        '1' when data_reg_i(7 downto 0) = x"A1" else
94
                                        '1' when data_reg_i(7 downto 0) = x"A2" else
95
                                        '1' when data_reg_i(7 downto 0) = x"3F" else
96
                                        --These are spechial attention Flash commands
97
                                        '1' when data_reg_i(7 downto 0) = x"E8" else
98
                                        '0';
99
 
100
 
101
usb_wr <= usb_wr_d;
102
 
103
-- this goes to byte buffer for that reason send LSB first and MSB second
104
usb_bd <=data_reg_o(7 downto 0)when data_oe='1' and CS=TXCMD0s else --LSB byte first
105
                        data_reg_o(15 downto 8) when data_oe='1' and CS=TXCMD1s else --MSB byte second
106
                        (others=>'Z');
107
 
108
 
109
process (clk25,reset_n)  --enable the scanning while in reset (simulation will be incorrect)
110
begin  -- process
111
  if reset_n='0' then
112
        CS <= RESETs;
113
        usb_rd_n <= '1';
114
        usb_wr_d <= '0';
115
        usb_txe_nd <= '1';
116
        usb_rxf_nd <= '1';
117
        data_oe <='0';
118
        state_cnt <=(others=>'0'); --init command counter
119
        mem_do <= (others=>'Z');
120
        mem_addr <= (others=>'Z');
121
        addr_reg <= (others=>'0');
122
        mem_val <= '0';
123
        mem_wr <='0';
124
        mem_cmd <='0';
125
        cmd_cnt <= (others=>'0');
126
        read_mode <='0';
127
        write_mode <='0';
128
        write_count <='0';
129
        first_word <='0';
130
  elsif clk25'event and clk25 = '1' then    -- rising clock edge
131
        usb_txe_nd <= usb_txe_n;
132
        usb_rxf_nd <= usb_rxf_n;
133
        case CS is
134
        when RESETs =>
135
                        if usb_rxf_nd='0' then
136
                                state_cnt <=(others=>'0'); --init command counter
137
                                data_oe <='0'; --we will read command in
138
                                CS <= RXCMD0s;
139
                        end if;
140
                when RXCMD0s =>
141
                        if state_cnt="0000" then
142
                                usb_rd_n <='0'; -- set read low
143
                                state_cnt <= state_cnt + 1;-- must be min 50ns long (two cycles)
144
                        elsif state_cnt="0001" then
145
                                state_cnt <= state_cnt + 1;-- one wait cycle
146
                        elsif state_cnt="0010" then
147
                                state_cnt <= state_cnt + 1;-- now is ok
148
                                data_reg_i(15 downto 8) <= usb_bd; --get data form bus MSByte must come first
149
                        elsif state_cnt="0011" then
150
                                usb_rd_n <='1'; -- set read back to high
151
                                state_cnt <= state_cnt + 1;-- start wait        
152
                        elsif state_cnt="0100" then
153
                                state_cnt <= state_cnt + 1;-- wait      (the usb_rxf_n toggles after each read and next data is not ready)
154
                        elsif state_cnt="0101" then
155
                                state_cnt <= state_cnt + 1;-- wait      
156
                        elsif state_cnt="0110" then
157
                                state_cnt <= state_cnt + 1;-- now is ok prob.                                                                                                           
158
                        else
159
                                if usb_rxf_nd='0' then   --wait untill next byte is available
160
                                        state_cnt <=(others=>'0'); --init command counter
161
                                        CS <= RXCMD1s;
162
                                end if;
163
                        end if;
164
                when RXCMD1s =>
165
                        if state_cnt="0000" then
166
                                usb_rd_n <='0'; -- set read low
167
                                state_cnt <= state_cnt + 1;-- must be min 50ns long (two cycles)
168
                        elsif state_cnt="0001" then
169
                                state_cnt <= state_cnt + 1;-- one wait cycle
170
                        elsif state_cnt="0010" then
171
                                state_cnt <= state_cnt + 1;-- now is ok
172
                                data_reg_i(7 downto 0) <= usb_bd; --get data form bus LSByte must come last
173
                        elsif state_cnt="0011" then
174
                                state_cnt <= state_cnt + 1;-- now is ok
175
                                usb_rd_n <='1'; -- set read back to high        
176
                        elsif state_cnt="0100" then
177
                                state_cnt <= state_cnt + 1;-- wait (the usb_rxf_n toggles after each read and next data is not ready)
178
                        elsif state_cnt="0101" then
179
                                state_cnt <= state_cnt + 1;-- wait
180
                        elsif state_cnt="0110" then
181
                                state_cnt <= state_cnt + 1;-- now is ok prob.                                                                                           
182
                        else
183
                                state_cnt <=(others=>'0'); --init command counter
184
                                CS <= INTERNs;
185
                        end if;
186
                when INTERNs =>
187
                if      cmd_cnt=x"00" then
188
                        if data_reg_i(7 downto 0)=x"A0" then
189
                                addr_reg(7 downto 0)<= data_reg_i(15 downto 8);
190
                                CS <= RESETs; --go back to resets
191
                        elsif data_reg_i(7 downto 0)=x"A1" then
192
                                addr_reg(15 downto 8)<= data_reg_i(15 downto 8);
193
                                CS <= RESETs; --go back to resets
194
                        elsif data_reg_i(7 downto 0)=x"A2" then
195
                                addr_reg(23 downto 16)<= data_reg_i(15 downto 8);
196
                                CS <= RESETs; --go back to resets
197
                        elsif data_reg_i(7 downto 0)=x"3F" then
198
                                CS <= RESETs; --go back to resets               --NOP command           
199
                        elsif data_reg_i(7 downto 0)=x"C5" then
200
                                data_reg_o <=x"3210";
201
                                CS <= TXCMD0s;
202
                        elsif data_reg_i(7 downto 0)=x"CD" then
203
                                cmd_cnt <= data_reg_i(15 downto 8) - 1; -- -1 as one read will be done right now
204
                                CS <= VCIRDs; --go perform a read
205
                                read_mode <='1';
206
                        elsif data_reg_i(7 downto 0)=x"E8" then
207
                            --write_mode <='1';
208
                                write_count <='0';
209
                                first_word <='0';
210
                                cmd_cnt <= data_reg_i(15 downto 8) + 1;  --+2 for direct count write +1
211
                                data_reg_i(15 downto 8)<=(others=>'0');
212
                                CS <= VCIWRs; --go perform a write
213
                        else
214
                                CS <= VCIWRs;
215
                        end if;
216
                else
217
                        if cmd_cnt>x"00" then
218
                                cmd_cnt<= cmd_cnt - 1;
219
                                if write_count='0' then
220
                                        write_count<='1';
221
                                elsif write_count='1' and  first_word ='0' then
222
                                        first_word <='1';
223
                                elsif write_count='1' and  first_word ='1' then
224
                                        addr_reg <= addr_reg + 1; --autoincrement address in in block mode
225
                                end if;
226
                                --if cmd_cnt>x"02" then --so not to increase too many times on write buffer
227
                                --      addr_reg <= addr_reg + 1; --autoincrement address in in block mode
228
                                --end if;
229
                        end if;
230
                        CS <= VCIWRs;
231
                end if;
232
                when VCIRDs =>          --flash read
233
                        mem_wr <='0';                    --this is VCI write_not_read
234
                        mem_cmd <='0';
235
                        mem_addr <= addr_reg(22 downto 0)&'0'; --translate byte address to word address
236
                        mem_val <= '1';
237
                        if mem_ack='1' then
238
                                data_reg_o <= mem_di;
239
                                mem_wr <='0';                    --this is VCI write_not_read
240
                                mem_cmd <='0';
241
                                mem_val <= '0';
242
                                CS <= TXCMD0s;
243
                        end if;
244
                when VCIWRs =>          --flash write
245
                        mem_addr <= addr_reg(22 downto 0)&'0'; --translate byte address to word address
246
                        mem_do <= data_reg_i;   --USB data in will go to mem_out
247
                        mem_wr <='1';                   --this is VCI write_not_read
248
                        mem_cmd <='1';
249
                        mem_val <= '1';
250
                        if mem_ack='1' then
251
                                mem_do <= (others=>'Z');
252
                                mem_wr <='0';                    --this is VCI write_not_read
253
                                mem_cmd <='0';
254
                                mem_val <= '0';
255
                                if write_mode='0' then
256
                                        CS <= RESETs;
257
                                --else  --else if was 0xE8 must read and return XSR
258
                                --      write_mode <='0'; --XSR return will no follow clear this bit
259
                                --      CS <= VCIRDs;
260
                                end if;
261
                        end if;
262
                when TXCMD0s =>  --transmit over USB what ever is in data_reg_o MSB first
263
 
264
                                if state_cnt="0000" then
265
                                        if usb_txe_nd='0' then
266
                                                usb_wr_d<='1'; -- data is mux'ed by state and data_oe in the beginning of arch
267
                                                state_cnt <= state_cnt + 1;-- now is ok
268
                                        end if;
269
                                elsif state_cnt="0010" then
270
                                    data_oe<='1'; --this is to put data on bus befora falling edge of wr (max 20ns before)
271
                                        state_cnt <= state_cnt + 1;-- now is ok
272
                                elsif state_cnt="0011" then
273
                                    usb_wr_d<='0'; --falling edge performs write  must be high for atleast 50ns
274
                                        state_cnt <= state_cnt + 1;-- now is ok
275
                                elsif state_cnt="0100" then
276
                                        state_cnt <= state_cnt + 1;-- now is ok         
277
                                        data_oe<='0';
278
                                elsif state_cnt="0111" then       --must stay low at least 50ns
279
                                        CS <= TXCMD1s;
280
                                        state_cnt <= (others=>'0');
281
                                else
282
                                        state_cnt <= state_cnt + 1;-- if intermediate cnt then count
283
                                end if;
284
 
285
                when TXCMD1s =>
286
 
287
                                if state_cnt="0000" then
288
                                    if usb_txe_nd='0' then
289
                                                usb_wr_d<='1'; -- data is mux'ed by state and data_oe in the beginning of arch
290
                                                state_cnt <= state_cnt + 1;-- now is ok
291
                                        end if;
292
                                elsif state_cnt="0010" then
293
                                    data_oe<='1'; --this is to put data on bus befora falling edge of wr (max 20ns before)
294
                                        state_cnt <= state_cnt + 1;-- now is ok
295
                                elsif state_cnt="0011" then
296
                                    usb_wr_d<='0'; --falling edge performs write  must be high for atleast 50ns
297
                                        state_cnt <= state_cnt + 1;-- now is ok
298
                                elsif state_cnt="0100" then
299
                                        state_cnt <= state_cnt + 1;-- now is ok         
300
                                        data_oe<='0';
301
                                elsif state_cnt="0111" then       --must stay low at least 50ns
302
                                        if read_mode='0' then
303
                                                CS <= RESETs;
304
                                        elsif cmd_cnt="00" then --last word sent
305
                                                addr_reg <= addr_reg + 1; --autoincrement address in read mode
306
                                                read_mode <='0';
307
                                                CS <= RESETs;
308
                                        else
309
                                                cmd_cnt<= cmd_cnt - 1;
310
                                                addr_reg <= addr_reg + 1; --autoincrement address in read mode
311
                                                CS <= VCIRDs;   --more data to be read
312
                                        end if;
313
                                        state_cnt <= (others=>'0');
314
                                else
315
                                        state_cnt <= state_cnt + 1;-- if intermediate cnt then count
316
                                end if;
317
 
318
        when others => null;
319
        end case;
320
  end if;
321
end process;
322
 
323
 
324
 
325
end RTL;
326
 

powered by: WebSVN 2.1.0

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