URL
https://opencores.org/ocsvn/usb_dongle_fpga/usb_dongle_fpga/trunk
Subversion Repositories usb_dongle_fpga
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 24 to Rev 25
- ↔ Reverse comparison
Rev 24 → Rev 25
/trunk/src/usb/usb2mem.vhd
37,7 → 37,10
port ( |
clk25 : in std_logic; |
reset_n : in std_logic; |
dongle_ver: in std_logic_vector(15 downto 0); |
-- mem Bus |
mem_busy_n : in std_logic; |
mem_idle : out std_logic; -- '1' if controller is idle (flash is safe for LPC reads) |
mem_addr : out std_logic_vector(23 downto 0); |
mem_do : out std_logic_vector(15 downto 0); |
mem_di : in std_logic_vector(15 downto 0); |
46,6 → 49,7
mem_ack : in std_logic; |
mem_cmd : out std_logic; |
-- USB port |
usb_mode_en: in std_logic; -- enable this block |
usb_rd_n : out std_logic; -- enables out data if low (next byte detected by edge / in usb chip) |
usb_wr : out std_logic; -- write performed on edge \ of signal |
usb_txe_n : in std_logic; -- tx fifo empty (redy for new data if low) |
60,7 → 64,7
|
|
|
type state_type is (RESETs,RXCMD0s,RXCMD1s,DECODEs,INTERNs,VCIRDs,VCIWRs,TXCMD0s,TXCMD1s); |
type state_type is (RESETs,RXCMD0s,RXCMD1s,DECODEs,INTERNs,VCIRDs,VCIWRs,TXCMD0s,TXCMD1s,STS_WAITs); |
signal CS : state_type; |
|
signal data_reg_i : std_logic_vector(15 downto 0); |
70,7 → 74,7
signal addr_reg: std_logic_vector(23 downto 0); |
|
--State machine |
signal cmd_cnt : std_logic_vector(7 downto 0); |
signal cmd_cnt : std_logic_vector(15 downto 0); |
signal state_cnt : std_logic_vector(3 downto 0); |
--shyncro to USB |
signal usb_txe_nd : std_logic; -- tx fifo empty (redy for new data if low) |
81,6 → 85,7
signal write_mode : std_logic; |
signal write_count : std_logic; |
signal first_word : std_logic; |
signal mem_busy_nd : std_logic; |
|
|
|
98,11 → 103,13
'0'; |
|
|
usb_wr <= usb_wr_d; |
usb_wr <= usb_wr_d when usb_mode_en='1' else |
'Z'; |
|
|
-- this goes to byte buffer for that reason send LSB first and MSB second |
usb_bd <=data_reg_o(7 downto 0)when data_oe='1' and CS=TXCMD0s else --LSB byte first |
data_reg_o(15 downto 8) when data_oe='1' and CS=TXCMD1s else --MSB byte second |
usb_bd <=data_reg_o(7 downto 0)when data_oe='1' and CS=TXCMD0s and usb_mode_en='1' else --LSB byte first |
data_reg_o(15 downto 8) when data_oe='1' and CS=TXCMD1s and usb_mode_en='1' else --MSB byte second |
(others=>'Z'); |
|
|
127,15 → 134,21
write_mode <='0'; |
write_count <='0'; |
first_word <='0'; |
mem_idle <='1'; --set idle |
mem_busy_nd <='1'; |
elsif clk25'event and clk25 = '1' then -- rising clock edge |
usb_txe_nd <= usb_txe_n; |
usb_rxf_nd <= usb_rxf_n; |
usb_txe_nd <= usb_txe_n; --syncronize |
usb_rxf_nd <= usb_rxf_n; --syncronize |
mem_busy_nd <=mem_busy_n; --syncronize |
case CS is |
when RESETs => |
if usb_rxf_nd='0' then |
if usb_rxf_nd='0' and usb_mode_en='1' and mem_busy_nd='1' then |
state_cnt <=(others=>'0'); --init command counter |
data_oe <='0'; --we will read command in |
mem_idle <='0'; --set busy untill return here |
CS <= RXCMD0s; |
elsif mem_busy_nd='1' then |
mem_idle <='1'; --set idle when here |
end if; |
when RXCMD0s => |
if state_cnt="0000" then |
184,7 → 197,7
CS <= INTERNs; |
end if; |
when INTERNs => |
if cmd_cnt=x"00" then |
if cmd_cnt=x"0000" then |
if data_reg_i(7 downto 0)=x"A0" then |
addr_reg(7 downto 0)<= data_reg_i(15 downto 8); |
CS <= RESETs; --go back to resets |
197,10 → 210,18
elsif data_reg_i(7 downto 0)=x"3F" then |
CS <= RESETs; --go back to resets --NOP command |
elsif data_reg_i(7 downto 0)=x"C5" then |
data_reg_o <=x"3210"; |
if (data_reg_i(15 downto 8))=x"00" then |
data_reg_o <=x"3210"; |
else |
data_reg_o <=dongle_ver; |
end if; |
CS <= TXCMD0s; |
elsif data_reg_i(7 downto 0)=x"CD" then |
cmd_cnt <= data_reg_i(15 downto 8) - 1; -- -1 as one read will be done right now |
if (data_reg_i(15 downto 8))=x"00" then --64K word read coming |
cmd_cnt <= (others=>'1'); --64K word count |
else |
cmd_cnt <= x"00"&data_reg_i(15 downto 8) - 1; -- -1 as one read will be done right now (cmd_cnt words) |
end if; |
CS <= VCIRDs; --go perform a read |
read_mode <='1'; |
elsif data_reg_i(7 downto 0)=x"E8" then |
207,7 → 228,7
--write_mode <='1'; |
write_count <='0'; |
first_word <='0'; |
cmd_cnt <= data_reg_i(15 downto 8) + 1; --+2 for direct count write +1 |
cmd_cnt <= x"00"&data_reg_i(15 downto 8) + 1; --+2 for direct count write +1 |
data_reg_i(15 downto 8)<=(others=>'0'); |
CS <= VCIWRs; --go perform a write |
else |
214,7 → 235,7
CS <= VCIWRs; |
end if; |
else |
if cmd_cnt>x"00" then |
if cmd_cnt>x"0000" then |
cmd_cnt<= cmd_cnt - 1; |
if write_count='0' then |
write_count<='1'; |
252,12 → 273,18
mem_wr <='0'; --this is VCI write_not_read |
mem_cmd <='0'; |
mem_val <= '0'; |
if write_mode='0' then |
CS <= RESETs; |
--if write_mode='0' then |
|
if cmd_cnt=x"0000" then --if flash command and not data |
state_cnt <=(others=>'0'); --init command counter |
CS <= STS_WAITs; |
else |
CS <= RESETs; |
end if; |
--else --else if was 0xE8 must read and return XSR |
-- write_mode <='0'; --XSR return will no follow clear this bit |
-- CS <= VCIRDs; |
end if; |
--end if; |
end if; |
when TXCMD0s => --transmit over USB what ever is in data_reg_o MSB first |
|
301,7 → 328,7
elsif state_cnt="0111" then --must stay low at least 50ns |
if read_mode='0' then |
CS <= RESETs; |
elsif cmd_cnt="00" then --last word sent |
elsif cmd_cnt="0000" then --last word sent |
addr_reg <= addr_reg + 1; --autoincrement address in read mode |
read_mode <='0'; |
CS <= RESETs; |
314,7 → 341,16
else |
state_cnt <= state_cnt + 1;-- if intermediate cnt then count |
end if; |
|
when STS_WAITs => |
if mem_busy_nd='0' then |
CS <= RESETs; --now it's ok to go here |
else |
state_cnt <= state_cnt + 1; |
if state_cnt="1111" then |
--sts cant take longer than 500 ns to go low |
CS <= RESETs; --time out go to resets anyway |
end if; |
end if; |
when others => null; |
end case; |
end if; |