📄 usb_new_uc_handler_rtl.vhdl
字号:
----------------------------------------------------------------------------------------
---- File >>> usb_new_uc_handler_rtl.vhdl
---- Iden >>> 980317-11:42:38
----
---- Project: USB Developement
---- Customer: Philips_ITCL
----
---- VHDL Design Unit: architecture RTL of UC_HANDLER
---- Written by: Usb User
---- Easics nv
---- http://www.easics.com
---- mailto: vhdl@easics.be
----
---- Creation Date: Tue, 17 Mar 1998
----
---- Purpose:
----
---- Revision history:
----
----------------------------------------------------------------------------------------
-- DESCRIPTION_BEGIN
-- This module takes care of the communication between the external controller
-- and the endpoint handling part of the USB device. The external controller can
-- write commands and data and read data.
-- DESCRIPTION_END
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
library work;
use work.PCK_GENERAL.all;
use work.PCK_USB.all;
use work.PCK_CONFIGURATION.all;
use work.PCK_SETUP.all;
architecture RTL of UC_HANDLER is
type T_Priority_enum is (SIE,DSP);
subtype S_endpoint_range is integer range 0 to N_ENDPOINTS-1;
constant EndpointInfo: T_UC_HANDLER_Info := UC_HANDLER_Info;
--constant EndpointRAMInfo: T_UC_HANDLER_RAMInfo := UC_HANDLER_RAMInfo;
-- Not used any more, comented out 99/06/08 by fma
constant C_STALL: integer := 0;
constant C_PID: integer := 1;
constant C_FULL: integer := 2;
constant C_SETUP: integer := 3;
constant C_OVERWRITING: integer := 4;
constant C_DISABLED:integer := 5;
constant C_INTMODE:integer := 6;
constant C_FORCE_UPDATE:integer := 7;
constant C_CONDSTALL:integer := 7;
constant SEL_FULL: integer := 0;
constant SEL_STALL: integer := 1;
constant SEL_SETUP: integer := 2;
constant SEL_OVERWRITTEN: integer := 3;
constant SEL_NAKED: integer := 4;
constant CLB_OVERWRITTEN: integer := 0;
-- device address table
type T_DevAddrTable is array(integer range 0 to N_HANDLER_DEVICES(ID)-1) of byte;
subtype S_Index is integer range 0 to 1;
subtype S_NData is unsigned(log2(HANDLERS_MAX_BUFFER_SIZE(ID)+1)-1 downto 0);
signal Selected: boolean;
signal DataToUC: T_Handlers_to_UC;
signal EmbPortChange: booleans(N_HANDLER_DEVICES(ID)-1 downto 0);
signal DataValid: boolean;
signal SIEDataValid: boolean;
signal NeedClock: boolean;
signal DevAddrTable: T_DevAddrTable;
signal Stalled : boolean;
signal Disabled : boolean;
signal Accepted : boolean;
signal EndpointEnables: unsigned(N_HANDLER_DEVICES(ID)-1 downto 0);
signal DataToSie: T_Handlers_To_Sie;
signal Selected_by_SIE: boolean;
signal PID: integer range 0 to 1;
signal IntMode: boolean;
signal Sie_read_i: one_bit;
signal PreventInt_N_I: std_logic;
constant ConfigResetValue: S_UCConfigArray := CONFIG_RESET;
begin
-- DOC_BEGIN: Ring of Handlers, uC side
-- The UC_Handler is together with the other handlers connected
-- to the UCInterface by a ring structure. This structure enables a clean
-- communication between the handlers and the microcontroller.
UCConnector(DataToUC_Out, DataToUC_In,
DataToUC, Selected);
-- DOC_END
-- DOC_BEGIN: Ring of Handlers, SIE side
-- The UC_Handler is together with the other handlers connected
-- to the SIEInterface by a ring structure. This structure enables a clean
-- communication between the handlers and the SIEInterface.
SIEConnector(ID, DataFromHandlers_Out, DataFromHandlers_In,
DataToHandlers, DataToSIE, Selected_by_SIE);
-- DOC_END
To_SIE:for I in 0 to N_HANDLER_DEVICES(ID)-1 generate
DataToSIE.USBAddress(I) <= DevAddrTable(I)(6 downto 0);
DataToSIE.DeviceEnabled(I)
<= conv_active_high(DevAddrTable(I)(7));
end generate To_SIE;
DataToSIE.Accepted <= Accepted;
DataToSIE.Stalled <= Stalled;
DataToSIE.Disabled <= Disabled;
DataToSIE.NeedClock <= NeedClock;
DataToSIE.RemoteWakeUp <= FALSE;
DataToSIE.DeviceConfigured(N_HANDLER_DEVICES(ID)-1 downto 0) <=
conv_active_high(EndpointEnables);
DataToSIE.DataPID <= PID;
DataToSIE.IntMode <= IntMode;
DataToSIE.TxData <= Pi_To_UC.Rx_Data;
SIE_EndTransfer <= '1' when (DataToHandlers.endoftransfer = true) else '0';
SIE_N_Data <= DataToHandlers.N_Data;
RxError_SIE <= DataToHandlers.Error;
Sie_Read <= Sie_read_i;
--PreventInt_N <= PreventInt_N_I;
--------------------------------------------------------------------
-- process MAIN
-------------------------------------------------------------------
MAIN: process(FsClk, PUReset_N)
type T_Command_enum is (
--RW_DATA,
SET_BUFFER_FE,
SET_EP_ENABLE,
SET_ADDRESS,
SELECT_EP,
SET_EP_STATUS,
INVALID
);
-- DOC_END
-- DOC_BEGIN: Commands and Arguments
-- A command can have an endpoint number or a device number
-- as an argument. Therefore the range of the arguments in general
-- is the maximum of the number of endpoints and the number of
-- devices of the UC_Handler.
constant MAX_CMDARG: integer := Maximum(NUM_ENDPOINTS(ID),
Maximum(N_HANDLER_DEVICES(ID),1));
subtype S_CmdArg_range is integer range 0 to MAX_CMDARG - 1;
subtype S_Index is integer range 0 to 1;
-- DOC_BEGIN: Procedures
-- DOC_BEGIN: DecodeCommand Procedure
-- This procedure converts the CommandCode sent over
-- by the controller to a constant of the type T_Command_enum
-- and an argument in the range S_CmdArg_range. The variables
-- Command and CmdArgument are assigned to these constants.
-- A reference table of all the commands follows.
-- _______________________________________________________________
-- | Command Code | Function |
-- | 0 | 0 | Endpoint Number | Select Endpoint |
-- | 0 | 1 | Endpoint Number | Set Endpoint Status |
-- | 1 | 1 | 0 | 1 | Device Number | Set Address |
-- | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | Set Endpoint Enable |
-- | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | Read/Write Data |
-- | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | Clear Buffer |
-- | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | Validate Buffer |
-- |_______________________________________________________________|
-- The procedure is just the implementation of this table.
-- DOC_END
-- DOC_END
procedure DecodeCommand(CommandCode: in byte;
Command: inout T_Command_enum;
CmdArgument: out S_CmdArg_range;
Selected: out boolean
) is
--begin
-- Selected := TRUE;
-- if CommandCode= byte'("11110000") then
-- Command := INVALID;
-- elsif CommandCode= byte'("11110010") then
-- Command := SET_BUFFER_FE;
-- CmdArgument := to_integer(CommandCode(3));
-- elsif CommandCode= byte'("11111010") then
-- Command := SET_BUFFER_FE;
-- CmdArgument := to_integer(CommandCode(3));
-- elsif CommandCode(7 downto 4) = four_bits'("1101") then
-- case CommandCode(3 downto 0) is
-- when "1000" =>
-- Command := SET_EP_ENABLE;
-- when others =>
-- Command := SET_ADDRESS;
-- CmdArgument := to_integer(CommandCode(3 downto 0));
-- end case;
-- else
-- case CommandCode(7 downto 6) is
-- when "00" =>
-- Command := SELECT_EP;
-- if (to_integer(CommandCode(5 downto 0)) < NUM_ENDPOINTS(ID)) then
-- CmdArgument := to_integer(CommandCode(5 downto 0));
-- else
-- Selected := FALSE;
-- Command := INVALID;
-- end if;
-- when "01" =>
-- Command := SET_EP_STATUS;
-- if (to_integer(CommandCode(5 downto 0)) < NUM_ENDPOINTS(ID)) then
-- CmdArgument := to_integer(CommandCode(5 downto 0));
-- else
-- Selected := FALSE;
-- Command := INVALID;
-- end if;
-- when others =>
-- Command := INVALID;
-- Selected := FALSE;
-- end case;
-- end if;
--end;
begin
Selected := TRUE;
case CommandCode (7 downto 4) is
when "1111" =>
case Commandcode (3 downto 0) is
when "0010" =>
Command := SET_BUFFER_FE;
CmdArgument := to_integer(CommandCode(3));
when "1010" =>
Command := SET_BUFFER_FE;
CmdArgument := to_integer(CommandCode(3));
when others =>
Selected := FALSE;
Command := INVALID;
end case;
when "1101" =>
case CommandCode(3 downto 0) is
when "1000" =>
Command := SET_EP_ENABLE;
when others =>
Command := SET_ADDRESS;
CmdArgument := to_integer(CommandCode(3 downto 0));
end case;
when "0000" =>
Command := SELECT_EP;
if (to_integer(CommandCode(5 downto 0)) < NUM_ENDPOINTS(ID)) then
CmdArgument := to_integer(CommandCode(5 downto 0));
else
Selected := FALSE;
Command := INVALID;
end if;
when "0100" =>
Command := SET_EP_STATUS;
if (to_integer(CommandCode(5 downto 0)) < NUM_ENDPOINTS(ID)) then
CmdArgument := to_integer(CommandCode(5 downto 0));
else
Selected := FALSE;
Command := INVALID;
end if;
when others =>
Selected := FALSE;
Command := INVALID;
end case;
end;
variable Command: T_Command_enum;
variable CmdArgument: S_CmdArg_range;
variable Data: byte;
variable ByteToSend: byte;
variable CorrespEP: integer;
variable Selected_int: boolean;
variable ConfigNr: S_ConfigurationRange;
variable InterruptByte: booleans(7 downto 0);
variable EndpointNr: S_Endpoint_range;
variable EndpointNr_tmp: S_Endpoint_range;
variable CommandSwitch: one_bit;
variable Loaded: booleans(N_HANDLER_DEVICES(ID)-1 downto 0);
type T_TempAddrTable is array(0 to N_HANDLER_DEVICES(ID)-1) of seven_bits;
variable DevAddrTable_tmp: T_TempAddrTable;
variable FrameNr_bits: unsigned (10 downto 0);
variable Device_In_UC: integer range 0 to (N_HANDLER_DEVICES(ID));
variable DataPID: T_ToggleArray;
variable UCToggle: T_ToggleArray;
variable USBToggle: T_ToggleArray;
variable Stall: booleans(0 to N_ENDPOINTS-1);
variable Setup: booleans(0 to N_ENDPOINTS-1);
variable Naked: booleans(0 to N_ENDPOINTS-1);
variable Overwritten: booleans(0 to N_ENDPOINTS-1);
variable Disable: booleans(0 to N_ENDPOINTS-1);
variable RateFeedback: booleans(0 to N_ENDPOINTS-1);
variable Full: T_Full;
variable CommandDisabled: boolean;
variable RFB : boolean;
variable SendEmptyPacket : boolean;
variable PreventInt_Count: integer range 0 to 2;
function IsFull(Endpoint: S_Endpoint_Range;
Toggle: T_ToggleArray;
Full: T_Full;
Config: S_ConfigurationRange) return boolean is
begin
-- if EndpointInfo(Config)(Endpoint).EndpointType = ISOCHRONOUS THEN
-- return EndpointInfo(Config)(Endpoint).USBDirection = DIR_IN;
if EndpointInfo(Config)(Endpoint).N_Buffers > 1 then
return
Full(Endpoint)(Toggle(Endpoint));
else
return Full(Endpoint)(0);
end if;
end;
begin
if (PUReset_N = ACTIVE_LOW) then
uc_to_pi.rx_data <= "00000000";
uc_to_pi.endpoint <= 0;
uc_to_pi.setuppacket <= FALSE;
SendEmptyPacket := FALSE;
EPBufferInfo.UCToggle <= (others => 0);
EPBufferInfo.USBToggle <= (others => 0);
EPBufferInfo.Full <= (others =>(others => FALSE));
-- uc_to_pi.end_of_transfer <= FALSE;
PreventInt_N_I <= '0';
PreventInt_Count := 0;
DataToUC <= HandlersToUCDefault;
DataToSIE.Interrupts <= (others => FALSE);
-- DataToSIE.TxData <= (others => '0');
DataToSIE.TxDataValid <= FALSE;
Command := INVALID;
CmdArgument := 0;
Data := (others => '0');
EndpointNr := 0;
EmbPortChange <= (others => FALSE);
CommandSwitch := '0';
DataValid <= FALSE;
SIEDataValid <= FALSE;
NeedClock <= FALSE;
EndpointEnables <= (others => '0');
DevAddrTable <= (others => (others => '0'));
DevAddrTable_tmp := (others => (others => '0'));
Loaded := (others => FALSE);
Accepted <= FALSE;
Stalled <= FALSE;
Disabled <= FALSE;
PID <= 0;
Selected_int := FALSE;
Selected <= FALSE;
IntMode <= FALSE;
ConfigNr := 0;
DataPID := (others => 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -