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

📄 usb_new_uc_handler_rtl.vhdl

📁 实现USB接口功能的VHDL和verilog完整源代码
💻 VHDL
📖 第 1 页 / 共 3 页
字号:
----------------------------------------------------------------------------------------
---- 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 + -