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

📄 usb_new_uc_handler_rtl.vhdl

📁 实现USB接口功能的VHDL和verilog完整源代码
💻 VHDL
📖 第 1 页 / 共 3 页
字号:
                   end if;
                   Setup(CmdArgument) := FALSE;
                   Overwritten(CmdArgument) := FALSE;
              end if;
          end if;
          
        -- end InitializeEndpoint
          
          if EndpointInfo(ConfigNr)(CmdArgument).EndpointType /= CONTROL then 
            Disable(CmdArgument) :=
              conv_active_high(DataFromUC.Data(C_DISABLED));
          end if;
          if (EndpointInfo(ConfigNr)(CmdArgument).EndpointType =
               BULK_OR_INTERRUPT and
               EndpointInfo(ConfigNr)(CmdArgument).USBDirection = DIR_IN) then
            RateFeedback(CmdArgument) :=
              conv_active_high(DataFromUC.Data(C_INTMODE));
          else
            RateFeedback(CmdArgument) := FALSE;
          end if;

        when others =>
          DataToUC.Ready <= TRUE;
          
      end case;
          
    -- External controller reads data
    elsif (DataFromUC.Read and Selected_int) then
      NeedClock <= TRUE;
      DataToUC.Ready <= FALSE;
      case Command is

        when SELECT_EP  | SET_BUFFER_FE =>

          null;
          
        -- The Select Endpoint/Clear interrupt Command is the same as 
        -- the Select Endpoint command, but clears the interrupt and 
        -- setup and overwritten bits.
        when SET_EP_STATUS =>
          EndpointNr := CmdArgument;
          DataToSie.Interrupts(EndpointNr) <= FALSE;
          if ((EndpointInfo(ConfigNr)(EndpointNr).EndpointType = CONTROL) and 
             (EndpointInfo(ConfigNr)(EndpointNr).USBDirection  = DIR_OUT ))then
            Setup(EndpointNr) := FALSE;
            Overwritten(EndpointNr) := FALSE;
          end if;

        -- The command Read data reads an Endpoint Data Buffer.
        -- Each read pulse the contents of the buffer is returned
        -- and the pointer is incremented to the next position in the
        -- buffer.


        when others =>
          DataToUC.Ready <= TRUE;

      end case;

    else
      DataToUC.Ready <= TRUE;
    end if;
    -- DOC_END

    -- DOC_BEGIN
    -- On bus reset, reset the complete Device Address Table
    -- disable all functions and their endpoints
    -- but enable function 0.

    if RG_SetSE0Int and (DH_CONNECT or not SUPPORT_SOFTCONNECT) then 
      PreventInt_N_I <= '0';
      PreventInt_Count := 0;
      Device_In_UC := 0;
      DevAddrTable <= (others => (others => '0'));
      EndpointEnables <= (others => '0');
      DataPID := (others => 0);
      for i in 0 to (N_ENDPOINTS-1) loop
        if EndpointInfo(ConfigNr)(i).EndpointType /= ISOCHRONOUS then     
          UCToggle(i) := 0;
          USBToggle(i) := 0;
        end if;
      end loop;
      Stall := (others => FALSE);
      Setup := (others => FALSE);
      Overwritten := (others => FALSE);
      Disable := (others => FALSE);
      RateFeedback := (others => FALSE);
      Full:= (others => (others => FALSE));
        -- disable all endpoints and set all function addresses to zero.
      for i in 0 to N_DEVICES -1 loop
        if (ADDRESS_HANDLER(i) = ID) then
          if ENABLE_RESET_ON(GetConfiguration(ConfigArray)) = i then
            DevAddrTable(Device_In_UC)(7) <= '1';
          end if;
          Device_In_UC := Device_In_UC + 1;
        end if;
      end loop;  
    end if;
    -- DOC_END

    -- DOC_BEGIN: Delayed Set Address
    -- The addresses given by the Write Configuration Array command are
    -- first stored in a temporary register. The SieHandler indicates
    -- when the address can be stored in the Device Address Table. (After
    -- a successfull IN token for endpoint 0)

    -- This is after the status stage of the control transfer. (Host
    -- sends Set Address command, using a SETUP token. Status stage
    -- is an IN token).
    
    if (DataToHandlers.EndofTransfer and DataToHandlers.success) then
      for i in 0 to N_HANDLER_DEVICES(ID)-1 loop
        if (DataToHandlers.Endpoint =
            DEFAULT_IN_EP(GetConfiguration(ConfigArray))(i)
            and Loaded(i)) then
          DevAddrTable(i)(6 downto 0) <=
            DevAddrTable_tmp(i);
          Loaded(i) := FALSE;
        elsif (DataToHandlers.Endpoint =
               DEFAULT_OUT_EP(GetConfiguration(ConfigArray))(i)) then
          Loaded(i) := FALSE;
        end if;
      end loop;  
    end if;
    -- DOC_END

    -- DOC_BEGIN: Interface with the SIE-side of the design
    -- This part consists of :
    --      * logic that handles the control signals and
    --        the passing/reading of the data to/from the GIF
    -- This code only comes in effect when the SIEInterface has selected the
    -- UCHandler.
    if Selected_by_SIE then
      -- A new packet is arriving and can/must be accepted
      if (DataToHandlers.RxDataValid and
         (not IsFull(DataToHandlers.Endpoint, USBToggle, Full, ConfigNr) or
          DataToHandlers.SetupPacket or
          EndpointInfo(ConfigNr)(DataToHandlers.Endpoint).EndpointType =
          ISOCHRONOUS )) then
          uc_to_pi.Rx_Data  <= DataToHandlers.RxData;
          uc_to_pi.Endpoint <= DataToHandlers.Endpoint;
          uc_to_pi.SetupPacket <= DataToHandlers.SetupPacket;
          sie_write <= '1';
        -- if the buffer is still full while receiving a packet, set
        -- the overwrite bit (this can only happen in the case of a
        -- setup packet, since this has to be accepted.)
        if IsFull(DataToHandlers.Endpoint, USBToggle, Full, ConfigNr) then
          if EndpointInfo(ConfigNr)(DataToHandlers.Endpoint).EndpointType =
               CONTROL and EndpointInfo(ConfigNr)
               (DataToHandlers.Endpoint).USBDirection = DIR_OUT then 
            Overwritten(DataToHandlers.Endpoint) := TRUE;
          end if;
        end if;
      else
          sie_write <= '0';
      end if;


      -- Generate an interrupt on a NAKed transfer if this 
      -- feature is on.
      if Selected_by_SIE and InterruptOnNAK(ConfigArray) and
         DataToHandlers.EndOfTransfer and DataToHandlers.NAKed then
        DataToSIE.Interrupts(DataToHandlers.Endpoint) <= TRUE;
        if (EndpointInfo(ConfigNr)(DataToHandlers.Endpoint).EndpointType
            = CONTROL) then
          Naked(DataToHandlers.Endpoint) := TRUE;
        end if;  
      end if;

      if (EndpointInfo(ConfigNr)(DataToHandlers.Endpoint).EndpointType
            = BULK_OR_INTERRUPT and EndpointInfo(ConfigNr)
            (DataToHandlers.Endpoint).USBDirection = DIR_IN) then
        RFB := RateFeedback(DataToHandlers.Endpoint);
      else
        RFB := FALSE;
      end if;

      -- When an IN command is handled succesfully, clear the
      -- buffer and generate an interrupt
      if (EndpointInfo(ConfigNr)(DataToHandlers.Endpoint).USBDirection
          = DIR_IN) then
        Accepted <= IsFull(DataToHandlers.Endpoint, USBToggle, Full, ConfigNr);
        if EndpointInfo(ConfigNr)(DataToHandlers.Endpoint).EndpointType =
        ISOCHRONOUS then
          Accepted <= TRUE;
        end if;
        if (DataToHandlers.EndOfTransfer and
           (DataToHandlers.Success or (EndpointInfo(ConfigNr)
           (DataToHandlers.Endpoint).EndpointType = BULK_OR_INTERRUPT and RFB)) and 
           (IsFull(DataToHandlers.Endpoint, USBToggle, Full, ConfigNr) or 
           EndpointInfo(ConfigNr)(DataToHandlers.Endpoint).Endpointtype = ISOCHRONOUS)) then

          -- USBClearBuffer/USBToggleBuffer        
          if EndpointInfo(ConfigNr)(DataToHandlers.Endpoint).N_Buffers > 1 then
            Full(DataToHandlers.Endpoint)
              (USBToggle(DataToHandlers.Endpoint)) := FALSE;
            USBToggle(DataToHandlers.Endpoint) :=
              1-USBToggle(DataToHandlers.Endpoint);
          else  
            Full(DataToHandlers.Endpoint)(0) := FALSE;
          end if;
        
          -- Toggle PID and set interrupt
          if EndpointInfo(ConfigNr)
            (DataToHandlers.Endpoint).EndpointType /= ISOCHRONOUS then
            DataPID(DataToHandlers.Endpoint) :=
              1-DataPID(DataToHandlers.Endpoint);
            DataToSIE.Interrupts(DataToHandlers.Endpoint) <= TRUE;
          end if;

          -- Clear Nak-bit
          if (EndpointInfo(ConfigNr)(DataToHandlers.Endpoint).EndpointType
            = CONTROL) then
            Naked(DataToHandlers.Endpoint) := FALSE;
          end if;          
        end if;
 
      -- When an OUT or SETUP command is handled succesfully,
      -- the endpoints statusbits are updated...
      elsif ((EndpointInfo(ConfigNr)(DataToHandlers.Endpoint).USBDirection
              = DIR_OUT) and
          (DataToHandlers.EndOfTransfer) and
          (DataToHandlers.Success and Accepted)) then
            if (EndpointInfo(ConfigNr)(DataToHandlers.Endpoint).EndpointType
                = CONTROL) then
              Naked(DataToHandlers.Endpoint) := FALSE;
            end if;

            -- Declare buffer full / Toggle buffer for non ISO
            if EndpointInfo(ConfigNr)(DataToHandlers.Endpoint).N_Buffers
              > 1 then
              Full(DataToHandlers.Endpoint)
                (USBToggle(DataToHandlers.Endpoint)) := TRUE;
              if EndpointInfo(ConfigNr)
                 (DataToHandlers.Endpoint).EndpointType /= ISOCHRONOUS then
                USBToggle(DataToHandlers.Endpoint) :=
                  1-USBToggle(DataToHandlers.Endpoint);
              end if;
            else
              Full(DataToHandlers.Endpoint)(0) := TRUE;
            end if;

            -- Toggle PID and set Interrupt
            if EndpointInfo(ConfigNr)
              (DataToHandlers.Endpoint).EndpointType /= ISOCHRONOUS then
              DataPID(DataToHandlers.Endpoint) :=
                1-DataPID(DataToHandlers.Endpoint);
              DataToSIE.Interrupts(DataToHandlers.Endpoint) <= TRUE;
            end if;

            -- Initialize on SetupPacket
            if (EndpointInfo(ConfigNr)
                (DataToHandlers.Endpoint).EndpointType = CONTROL) then
              Setup(DataToHandlers.Endpoint) := DataToHandlers.SetupPacket;
              if DataToHandlers.SetupPacket then
                CorrespEP := EndpointInfo(ConfigNr)
                             (DataToHandlers.Endpoint).CorrespondingEP;
                Setup(DataToHandlers.Endpoint) := TRUE;
                Stall(DataToHandlers.Endpoint) := FALSE;
                DataPID(DataToHandlers.Endpoint) := 1;
                PreventInt_N_I <= '0';
                PreventInt_count := 0;
                Full(CorrespEP)(0) := FALSE;
                Stall(CorrespEP) := FALSE;
                DataPID(CorrespEP) := 1;
              end if;
            end if;
      end if;

      start_in_transfer <= '0';  
      if (DataToHandlers.StartOfTransfer) then
        SendEmptyPacket := FALSE;
        -- Start of IN-transfer: if buffer full: transfer data
        -- For ISO-endpoints, if buffer empty, send empty packet
        if (EndpointInfo(ConfigNr)(DataToHandlers.Endpoint).USBDirection
            = DIR_IN) then
          if (EndpointInfo(ConfigNr)
             (DataToHandlers.Endpoint).EndpointType = ISOCHRONOUS and 
             not IsFull(DataToHandlers.Endpoint, USBToggle, Full, ConfigNr)) then

            SendEmptyPacket := TRUE;
          elsif IsFull(DataToHandlers.Endpoint, USBToggle, Full, ConfigNr) then
            uc_to_pi.endpoint <= DataToHandlers.Endpoint;
            start_in_transfer <= '1';
            sie_read_i <= '1';
          end if;
        --Start of OUT transfer
        else 
          -- Allways accept ISO and Setup-packets
          if DataToHandlers.SetupPacket or 
             EndpointInfo(ConfigNr)
             (DataToHandlers.Endpoint).EndpointType = ISOCHRONOUS then
            Accepted <= TRUE;
          -- Accept other packets when buffer empty
          else
            Accepted <= not IsFull(DataToHandlers.Endpoint, USBToggle,
                                   Full, ConfigNr);
          end if;  
        end if;
      end if;
  
      if sie_read_i = '1' and N_Data_EP = "0000" then
        sie_read_i <= '0';
      end if;

      -- if the SIEInterface received his data and the transfer is not
      -- over yet, read the next byte from the RAM
      if ((DataToHandlers.N_Data < N_Data_EP) and
          (not DataToHandlers.EndOfTransfer) and
          (not SendEmptyPacket)) then
        if (DataToHandlers.TXDataFetched) then
            uc_to_pi.Endpoint <= DataToHandlers.Endpoint;
            sie_read_i <= '1';
        else 
            sie_read_i <= '0';
        end if;
--        if (Pi_To_Uc.Data_Ready) then
--          DataToSIE.TxData <= Pi_To_UC.Rx_Data;
--        end if;

        DataToSIE.TxDataValid <= TRUE;
      else
        DataToSIE.TxDataValid <= FALSE;
      end if;

    end if;
    -- DOC_END;

    -- DOC_BEGIN: HUB wants a downstream port to be reset

    Device_In_UC := 0;
    for i in 0 to N_DEVICES -1 loop
      if (ADDRESS_HANDLER(i) = ID) then
        if HC_ResetDevice(Device_In_UC) then
          DevAddrTable(Device_In_UC) <= (others => '0');
          DevAddrTable(Device_In_UC)(7) <= '1';
          EndpointEnables(Device_In_UC) <= '0';
        end if;
        Device_In_UC := Device_In_UC + 1;
      end if;
    end loop;
    -- DOC_END;

    --Prevent interrupt on IN-endpoints on arrival of Setuppacket, Busreset or
    --Reset. PreventInt should stay low for three cycles.
    --if PreventInt_N_I = '0' then
    --  if PreventInt_Count = 2 then
    --    PreventInt_Count := 0;
    --    PreventInt_N_I <= '1';
    --  else
    --    PreventInt_Count := PreventInt_Count + 1;
    --  end if;
    --end if;
            

    Selected <= Selected_int;      

  end if;
end process MAIN;


end RTL;

⌨️ 快捷键说明

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