⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 devicetranseiver.vhd

📁 < FPGA数字电子系统设计与开发实例导航> 一书的代码
💻 VHD
📖 第 1 页 / 共 2 页
字号:
					if read_count = read_in then
						handle_step := 6;		  
						-- send command: clear endpoint buffer	
					else
						a0 <= D12_DATA;
						rd_n_var := '0';
					end if;	
				when 6 => 
					a0 <= D12_COMMAND;
					data_out <= D12_COMMAND_CLEAR_EP_BUFFER;
					wr_n_var := '0';  
					handle_step := 7;		 
				when others => 
					handle_step := 0;
					-- restore to the origin state
					ts_state <= last_ts_state;			
				end case;
			
			-- state is 'end receive', means finishing receiving all data
			when TS_END_RECEIVE =>	
				recv_n <= '0';
				req_type <= ts_data(ADDRESS_DEVICE_REQUEST);	
				ts_state <= TS_IDLE;
			
			-- state is 'write endpoint 0', means writing data to endpoint 0 buffer
			when TS_WRITE_ENDPOINT =>
				case handle_step is
				when 0 =>						  
					-- send command: select end point
					a0 <= D12_COMMAND;
					data_out <= active_ep;
					wr_n_var := '0';
					handle_step := handle_step+1;
				when 1 =>
					-- i don't know what this does
					a0 <= D12_DATA;
					rd_n_var := '0';
					handle_step := handle_step+1;
				when 2 =>
					-- send command: read/write endpoint buffer
					a0 <= D12_COMMAND;
					data_out <= D12_COMMAND_RW_BUFFER;
					wr_n_var := '0';				 
					handle_step := handle_step+1;
				when 3 =>
					-- write first byte which is reserved
					a0 <= D12_DATA;
					data_out <= X"00";
					wr_n_var := '0';				 
					handle_step := handle_step+1;
				when 4 =>
					-- write data length
					a0 <= D12_DATA;
					data_out <= conv_std_logic_vector(to_write, 8);
					wr_n_var := '0';
					write_count := 0;
					handle_step := handle_step+1;  
				when 5 =>	
					if to_write = 0 then 
						-- send comnand: enable buffer
						a0 <= D12_COMMAND;
						data_out <= D12_COMMAND_ENABLE_BUFFER; 			   
						wr_n_var := '0';			 
						handle_step := 7;
					else
						handle_step := handle_step+1;
					end if;
				when 6 =>
					if write_count = to_write then 
						-- send comnand: enable buffer
						a0 <= D12_COMMAND;
						data_out <= D12_COMMAND_ENABLE_BUFFER; 			   
						wr_n_var := '0';
						handle_step := 7;
					else
						-- write data to buffer
						a0 <= D12_DATA;
						data_out <= ts_data(ram_address);  
						ram_address := ram_address+1;
						wr_n_var := '0';
						write_count := write_count+1;
					end if;
				when 7 =>   
					-- restore to the origin state
					handle_step := 0;
					ts_state <= last_ts_state;						
				when others =>				  
					NULL;
				end case;	 
			
			-- state is 'endpoint 0 transmit', means endpoint 0 need transmit data
			when TS_EP0_TRANSMIT =>		   			
				-- state is 'start', means starting processing
				case ih_state is 															   
				when IH_START =>	   	   	
					-- send command: read last transaction status register of endpoint 0
					a0 <= D12_COMMAND;
					data_out <= D12_COMMAND_READ_LTS_EP0_IN;
					wr_n_var := '0';
					handle_step := 0;
					ih_state <= IH_READ_LTS;
				-- state is 'read lts', means reading last transaction status
				when IH_READ_LTS =>
					if handle_step = 0 then
						-- try to retrieve last transaction status register of endpoint 0
						a0 <= D12_DATA;
						rd_n_var := '0';
						handle_step := handle_step+1;
					else
						-- check whether is in TRANSMIT state
						if is_transmit = '0' then
							ts_state <= TS_IDLE;
						else
							-- calculate base address
							handle_step := 0;
							active_ep := X"01";
							-- calculate write data count
							to_write := data_length - data_count; 
							ts_state <= TS_WRITE_ENDPOINT;
							last_ts_state := TS_IDLE;
							if to_write >= LENGTH_ENDPOINT0_BUFFER then
								to_write := LENGTH_ENDPOINT0_BUFFER;
							else
								is_transmit := '0';
							end if;									
							data_count := data_count+to_write;
						end if;
					end if;					
				-- unknown state, do nothing
				when others =>
					NULL;
				end case;

			-- 'get descriptor' request (1st step)
			when TS_SEND_DESCRIPTOR_1ST =>	
				if ts_data(ADDRESS_DESCRIPTOR_TYPE) = TYPE_DEVICE_DESCRIPTOR then 
					step(0) <= '0';
					to_write :=	LENGTH_ENDPOINT0_BUFFER;
					active_ep := X"01";
					ram_address := ADDRESS_DEVICE_DESCRIPTOR;	
					ts_state <= TS_WRITE_ENDPOINT;
					last_ts_state := TS_END_REQUESTHANDLER;			
					handle_step := 0;
				else
					ts_state <= TS_IDLE;
				end if;				
				
			-- 'get descriptor' request
			when TS_SEND_DESCRIPTOR =>												 
				handle_step := 0;
				active_ep := X"01";
				if ts_data(ADDRESS_DESCRIPTOR_TYPE) = TYPE_DEVICE_DESCRIPTOR then  
					step(0) <= '0';
					-- check data length
					if data_length > LENGTH_DEVICE_DESCRIPTOR then
						data_length := LENGTH_DEVICE_DESCRIPTOR;
					end if;	
					if data_length > LENGTH_ENDPOINT0_BUFFER then
						to_write := LENGTH_ENDPOINT0_BUFFER; 
						is_transmit := '1';	   
					else
						to_write := data_length; 
					end if;
					data_count := to_write; 
					ram_address := ADDRESS_DEVICE_DESCRIPTOR;
					ts_state <= TS_WRITE_ENDPOINT;
				elsif ts_data(ADDRESS_DESCRIPTOR_TYPE) = TYPE_CONFIGURATION_DESCRIPTOR then
					-- check data length  
					if data_length > LENGTH_CONFIGURATION_DESCRIPTOR then
						data_length := LENGTH_CONFIGURATION_DESCRIPTOR;	
						step(2) <= '0';
					else	 
						step(1) <= '0';
					end if;	
					if data_length > LENGTH_ENDPOINT0_BUFFER then
						to_write := LENGTH_ENDPOINT0_BUFFER; 
						is_transmit := '1';	   
					else
						to_write := data_length; 
					end if;						
					data_count := to_write; 
					ram_address := ADDRESS_CONFIGURATION_DESCRIPTOR; 
					ts_state <= TS_WRITE_ENDPOINT;	
				else
					ts_state <= TS_IDLE;
				end if;
				last_ts_state := TS_END_REQUESTHANDLER; 					
				
			-- 'set address' request
			when TS_SET_ADDRESS => 	
				step(3) <= '0';
				if handle_step = 0 then
					a0 <= D12_COMMAND;
					data_out <= D12_COMMAND_ENABLE_ADDRESS;
					wr_n_var := '0';
					handle_step := handle_step+1;
				elsif handle_step = 1 then
					a0 <= D12_DATA;
					data_out <= X"80" or ts_data(ADDRESS_SET_ADDRESS);
					wr_n_var := '0';
					handle_step := handle_step+1;
				else
					to_write :=	0;
					handle_step := 0;
					active_ep := X"01";
					ts_state <= TS_WRITE_ENDPOINT;
					last_ts_state := TS_END_REQUESTHANDLER;
				end if;
				
			-- 'set configuration' request
			when TS_SET_CONFIGURATION => 
				case ih_state is
				-- state is 'start', means start of handling
				when IH_START=>	 		  
					to_write := 0;
					active_ep := X"01";
					handle_step := 0;  
					last_ts_state := TS_SET_CONFIGURATION;
					ts_state <= TS_WRITE_ENDPOINT;
					ih_state <= IH_ENABLE_EP;--IH_DISABLE_EP;
				-- disable all endpoints
--				when IH_DISABLE_EP => 
--					if handle_step = 0 then
--						a0 <= D12_COMMAND;
--						data_out <= D12_COMMAND_ENABLE_ENDPOINT;
--						wr_n_var := '0';
--						handle_step := handle_step+1;
--					elsif handle_step = 1 then
--						a0 <= D12_DATA;
--						wr_n_var := '0';								  
--						data_out <= X"00"; 
--						if ts_data(ADDRESS_SET_CONFIGURATION) = X"00" then
--							config <= '0';	
--							ts_state <= TS_END_REQUESTHANDLER;
--						else
--							config <= '1';	
--							ih_state <= IH_ENABLE_EP;
--							handle_step := 0;
--						end if;
--					end if;
				-- enable all endpoints
				when IH_ENABLE_EP =>     
					step(4) <= '0';
					if handle_step = 0 then
						a0 <= D12_COMMAND;
						data_out <= D12_COMMAND_ENABLE_ENDPOINT;
						wr_n_var := '0';
						handle_step := handle_step+1;
					elsif handle_step = 1 then
						a0 <= D12_DATA;		  
						data_out <= X"01";	
						wr_n_var := '0';    		
						ts_state <= TS_END_REQUESTHANDLER;
					end if;	
				-- unknown state, do nothing
				when others =>
					NULL;
				end case;

			-- 'get status' request
			when TS_SEND_STATUS =>
				case ts_data(ADDRESS_DEVICE_REQUEST_TYPE)(1 downto 0) is 
				when "00" =>
					if remote_wakeup = '0' then
						ts_data(ADDRESS_TEMP_DATA) <= X"03";
					else
						ts_data(ADDRESS_TEMP_DATA) <= X"00";
					end if;
					ts_data(ADDRESS_TEMP_DATA+1) <= X"00";
				when "01" =>							  
					ts_data(ADDRESS_TEMP_DATA) <= X"00";
					ts_data(ADDRESS_TEMP_DATA+1) <= X"00";
				when "10" =>							  
					ts_data(ADDRESS_TEMP_DATA) <= X"00";
					ts_data(ADDRESS_TEMP_DATA+1) <= X"00";
				when others =>
					NULL;
				end case;
				ram_address := ADDRESS_TEMP_DATA;
				handle_step := 0;
				active_ep := X"01";
				to_write := 2;
				ts_state <= TS_WRITE_ENDPOINT;
				last_ts_state := TS_END_REQUESTHANDLER;	

			-- 'clear feature' request
			when TS_CLEAR_FEATURE =>
				case ts_data(ADDRESS_DEVICE_REQUEST_TYPE)(1 downto 0) is 
				when "00" =>
					if ts_data(ADDRESS_REQUEST_VALUE_LOW) = X"01" then
						remote_wakeup <= '0';
					end if;
				when others =>
					NULL;
				end case;
				handle_step := 0;
				active_ep := X"01";
				to_write := 0;
				ts_state <= TS_WRITE_ENDPOINT;
				last_ts_state := TS_END_REQUESTHANDLER;	
		  
			-- 'set feature' request	
			when TS_SET_FEATURE =>
				case ts_data(ADDRESS_DEVICE_REQUEST_TYPE)(1 downto 0) is 
				when "00" =>
					if ts_data(ADDRESS_REQUEST_VALUE_LOW) = X"01" then
						remote_wakeup <= '1';
					end if;
				when others =>
					NULL;
				end case;
				handle_step := 0;
				active_ep := X"01";
				to_write := 0;
				ts_state <= TS_WRITE_ENDPOINT;
				last_ts_state := TS_END_REQUESTHANDLER;

			-- 'get configuration' request
			when TS_GET_CONFIGURATION => 
				step(5) <= '0';
				handle_step := 0;
				active_ep := X"01";
				to_write := 1;
				if config = '1' then
					ts_data(ADDRESS_TEMP_DATA) <= X"01";
				else									
					ts_data(ADDRESS_TEMP_DATA) <= X"00";
				end if;
				ram_address := ADDRESS_TEMP_DATA;
				ts_state <= TS_WRITE_ENDPOINT;
				last_ts_state := TS_END_REQUESTHANDLER;
				
			-- 'get interface' request
			when TS_GET_INTERFACE =>   
				step(6) <= '0';
				handle_step := 0;
				active_ep := X"01";
				to_write := 1; 
				ts_data(ADDRESS_TEMP_DATA) <= X"00";
				ram_address := ADDRESS_TEMP_DATA;
				ts_state <= TS_WRITE_ENDPOINT;
				last_ts_state := TS_END_REQUESTHANDLER;

			-- 'set interface' request
			when TS_SET_INTERFACE =>
				handle_step := 0;
				active_ep := X"01";
				to_write := 0; 
				ts_state <= TS_WRITE_ENDPOINT;
				last_ts_state := TS_END_REQUESTHANDLER;
				
			-- state is unknows, do nothing
			when others =>
				NULL;
			
			end case;  
			-- set signal values
			wr_n <= wr_n_var;
			rd_n <= rd_n_var;
		end if;
	end process; 

end DeviceTranseiver;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -