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

📄 usb_new_sieinterface_rtl.vhdl

📁 实现USB接口功能的VHDL和verilog完整源代码
💻 VHDL
📖 第 1 页 / 共 2 页
字号:
    HandlerNumber <= 0;


    USBAddressTable <= (others => (others => '0'));
    DeviceEnabled <= (others => FALSE);
    StopReceiving <= FALSE;


  elsif (FsClk'event and FsClk = '1') then

    DataToHandlers.StartOfTransfer <= FALSE;
    DataToHandlers.EndOfTransfer <= FALSE;
    --DataToHandlers.Success <= FALSE;
    DataToHandlers.TxDataFetched <= SIE_TxDataAck;
    DataToHandlers.NAKed <= FALSE;

    SH_Succes <= FALSE;


    -- DOC_BEGIN: Error Handling
    -- When there is no error generated in the SIEINTERFACE module, the error
    -- code coming from the SIE is copied.
    --
    if (SIE_RxError) then
      if not(DataFromHandlers_In.IntMode and SIE_RxErrorType = ERROR_PACKET_UNEXPECTED) then
        SetError(SIE_RxErrorType);
      end if;
    end if;
    -- DOC_END

    if N_DEVICES = 1 then 
      DevNr := 0;
    end if;


    DataToHandlers.Endpoint <= GetPhysEndpNr(DevNr,
                                             EndpNr,
                                             HandlingINBuffer,
                                             ConfigArray);
    HandlerNumber <= GetHandlerNr(DevNr,
                                  EndpNr,
                                  HandlingINBuffer,
                                  ConfigArray);
    IsIsoEndpoint := SUPPORT_ISO and IsoEnabled(DevNr,
                                                EndpNr,
                                                HandlingINBuffer,
                                                ConfigArray);

    -- DOC_BEGIN: Main State Machine
    case SH_State is 

      -- In this state, the SIEINTERFACE waits to be triggered to do
      -- an address lookup when a token comes in.
      --
      when DEVADDR_SEARCH =>
      --  EndpNr := 0;
	MM_EndpSearchReady <= TRUE;
	TokenReceived := FALSE;
	DataSentReceived := FALSE;
	HandshakeSentReceived := FALSE;
     	StopReceiving <= TRUE;
      -- DOC_END
      

    -------------------------------------------------------------------
    --                        Receiving a SOF                        --
    -------------------------------------------------------------------

        -- DOC_BEGIN
	-- When a Start of Frame (SOF) comes in, the frame number
	-- is updated.
	if SIE_SOFByte1 then
	  SOFByte1 := SIE_RxData;
	elsif SIE_SOFByte2 and (not SIE_RxError) then
	  DataToHandlers.FrameNumber <= SIE_RxData(2 downto 0) & SOFByte1;
	end if;
	-- DOC_END


    -------------------------------------------------------------------
    --                  Receiving an IN/OUT/SETUP Token              --
    -------------------------------------------------------------------


        -- DOC_BEGIN
	-- When the SIEINTERFACE is triggered on the arrival of a token, 
	-- all protocol signals to the SIE are initialized and a device
	-- address lookup is done. If the address in the token is the address
	-- of an enabled device, the state machine jumps to the 
	-- WAIT_FOR_ENDPOINT state, where it waits for the endpoint number
	-- to come in. Otherwise, it stays in the DEV_ADDR_SEARCH and waits
	-- for the next token.

        if (SIE_StartEndpSearch) then

          MM_EndpSearchReady <= FALSE;
          EndpSearchReady := FALSE;
          MM_EndpSearchSelected <= FALSE;
	  MM_Accepted <= FALSE;
	  MM_Stalled <= FALSE;
	  MM_EmbeddedBabbled <= FALSE;
	  DataToHandlers.Success <= FALSE;
	  DataToHandlers.Error <= FALSE;

          -- loop through device address table (content search);
          DevAddrEnabled := FALSE;
          for i in DataFromHandlers_In.USBAddress'range loop
	    if DataFromHandlers_In.USBAddress(i)=SIE_RxData(6 downto 0) and 
	      DataFromHandlers_In.DeviceEnabled(i) then
	      DevNr := i;
	      DevAddrEnabled := TRUE;
	      exit;
	    end if;
	  end loop;
	  if N_DEVICES = 1 then 
	    DevNr := 0;
	  end if;

          -- if device enabled, proceed to check endpoint
	  if DevAddrEnabled then
            SH_State := WAIT_FOR_ENDPOINT;
          else 
            SetNoEndpointSelected;
	  end if;

	end if;


      -- When the endpoint number arrives, a check is done whether
      -- the endpoint exists, is enabled and can handle the current
      -- data direction. If there is a match, more endpoint data are
      -- retrieved in the WAIT_FOR_ENDOFTOKEN state. Otherwise the SIEINTERFACE
      -- waits for the next token.
      when WAIT_FOR_ENDPOINT =>
	-- wait until endpoint number is available
	if SIE_RxDataRdy then
	  EndpNr := to_integer(SIE_RxData);
	  HandlingINBuffer := (SIE_RxPid = PID_IN);  
	  -- pid must have right direction and EP must be enabled
	  if (SIE_RxPid = PID_IN and 
              not InEndpointEnabled(DevNr, EndpNr, ConfigArray)) or

	     ((SIE_RxPid = PID_OUT or SIE_RxPid = PID_SETUP) and 
              not OutEndpointEnabled(DevNr, EndpNr, ConfigArray)) or

	     ((SIE_RxPid = PID_SETUP) and 
              not OutSetupEnabled(DevNr, EndpNr, ConfigArray)) or

	     (EndpNr /= 0 and not DataFromHandlers_In.DeviceConfigured(DevNr))
	      then
            SetNoEndpointSelected;
	    SH_State := DEVADDR_SEARCH;
	  else
	    SH_State:=WAIT_FOR_ENDOFTOKEN;
	  end if;
	end if;
	  
      -- In this state, the SIEINTERFACE waits for the end of the token
      -- packet. At that moment, all flags for the SIE are set to 
      -- generate the right answer.
      when WAIT_FOR_ENDOFTOKEN =>
	SetupPacket <= (SIE_RxPid = PID_SETUP);
	DataPid <= DataFromHandlers_In.DataPID;
	N_Data:=0; 
	if SIE_RxEOP and DataFromHandlers_In.Disabled then
          SetNoEndpointSelected;
          SH_State := DEVADDR_SEARCH;
        elsif SIE_RxEOP then  
   --       DataToHandlers.StartOfTransfer <= TRUE;
          StopReceiving <= FALSE;
          SetEndpointSelected;
          MM_ISO <= FALSE;
          if IsIsoEndpoint then
            MM_ISO <= TRUE;
            DataPid <= 0; -- always send DATA0
          end if;
          if SIE_RxPid = PID_SETUP then
            -- always accept a setup packet
            DataToHandlers.StartOfTransfer <= TRUE;
            DataPid <= 0; -- Always DATA0 PID
            MM_Stalled <= FALSE;
            SH_State := WAIT_FOR_DATA;
          elsif SIE_RxPid = PID_OUT then
            MM_Stalled <= DataFromHandlers_In.Stalled;
            -- Decide how to handle OUT token
            if DataFromHandlers_In.Stalled then
              -- Endpoint Stalled -> Send STALL
              SetError(ERROR_SENT_STALL);
            else
              -- Otherwise Receive Data
              DataToHandlers.StartOfTransfer <= TRUE;
              SH_State := WAIT_FOR_DATA;
            end if;
          else  -- PID_IN
            MM_Stalled <= DataFromHandlers_In.Stalled;
            -- Decide how to handle IN token
            if DataFromHandlers_In.Stalled  then
              -- Endpoint Stalled -> send stall
              SetError(ERROR_SENT_STALL);
            elsif not DataFromHandlers_In.Accepted and IsIsoEndpoint then
              -- Otherwise No data and ISO -> send empty packet
              DataToHandlers.StartOfTransfer <= TRUE;
              MM_Accepted <= TRUE;
              SetError(ERROR_SENT_EMPTYPACK);
            elsif not DataFromHandlers_In.Accepted then
              -- Otherwise No data  -> send nak
              SetError(ERROR_SENT_RECEIVED_NAK);
            else
              -- Otherwise send data
              DataToHandlers.StartOfTransfer <= TRUE;
              MM_Accepted <= TRUE;
              SH_State := SEND_IN_PACKET;
              if DataFromHandlers_In.IntMode then
                MM_ISO <= TRUE;
              end if;  
            end if;
	  end if;
	end if;


      -- In this state, the SIEINTERFACE waits for the data packet to 
      -- arrive. When the PID comes in, a decision is taken whether
      -- the packet must be accepted or ignored, depending on the
      -- DATA0/1 sequence.
      when WAIT_FOR_DATA =>
	if SIE_RxPidRdy then   
	  RxData1Pid := (SIE_RxPid = PID_DATA1);
	  IgnoreData <= ((DataPid=1) and (not RxData1Pid)) or
			((DataPid=0) and RxData1Pid);
          if RxData1Pid then
	    DataPid <= 1;
	  else
	    DataPid <= 0;
	  end if;
	  if IsIsoEndpoint then
	    IgnoreData <= FALSE;
	  end if;
	  N_Data:=0; 
	  SH_State := RECEIVE_OUT_PACKET;
	end if;
      
      -- In the RECEIVE_OUT_PACKET state, the data part of the data packet
      -- is received, and all incoming data are stored into the endpoint's
      -- buffer. An error is generated on buffer overflow.
      -- At the end of the packet, the endpoint's setup information is
      -- updated.
      when RECEIVE_OUT_PACKET =>
	BufferSize := GetBufferSize(DevNr,EndpNr,HandlingINBuffer,ConfigArray);
	OverRunSize := BufferSize +2;

	if SIE_RxDataRdy and not IgnoreData then
	  if N_Data < OverRunSize then
	    N_Data := N_Data +1;
	  else
	    SetError(ERROR_OVERRUN);
	    MM_ISO <= TRUE; -- no ack
	  end if;
	  if N_Data >= BufferSize then
	      StopReceiving <= TRUE;
	  end if;
	elsif DataSentReceived then
	  MM_Accepted <= DataFromHandlers_In.Accepted or SetupPacket
                         or IgnoreData;
          if not(DataFromHandlers_In.Accepted or DataFromHandlers_In.stalled or
                 SetupPacket or IgnoreData) then
	    SetError(ERROR_SENT_RECEIVED_NAK);
	  elsif IgnoreData then
	    SetError(ERROR_DATA_IGNORED_WRONG_DATA01);
	  else
	    N_Data := N_Data -2;
	    SetSuccess;
	    --DataToHandlers.EndOfTransfer <= TRUE;
	    --EndOfTransfer <= FALSE;
	  end if;
	end if;

      -- In this state, the SIEINTERFACE sends a data packet to the host.
      -- First the number of data is read from the RAM. After that,
      -- that amount of data is read from the endpoint's buffer and
      -- is sent to the SIE.
      -- At the end, the endpoint's setup information is updated.
      when SEND_IN_PACKET =>
        if DataFromHandlers_In.Disabled then
          DataToHandlers.EndOfTransfer <= TRUE;
          DataToHandlers.Success <= FALSE;
          SH_State := DEVADDR_SEARCH;
        else   
	  if SIE_TxDataAck then
	    N_Data := N_Data+1;
	  end if;
	  if DataSentReceived then
	    if IsIsoEndpoint or DataFromHandlers_In.IntMode then
	      SetSuccess;
	      --DataToHandlers.EndOfTransfer <= TRUE;
	    end if;
	  end if;
	  if SIE_RxPidRdy then
	    if SIE_RxPid = PID_ACK then
	      SetSuccessAtEOP;
	    else 
	      SetError(ERROR_SENT_RECEIVED_NAK);
	    end if;
	  end if;
	  if TM_EOF1 then
	    SetError(ERROR_BABBLE);
	    MM_EmbeddedBabbled <= TRUE;
	  end if;
        end if;
    end case; -- SH_STATE;
    -- DOC_END

    -------------------------------------------------------------------
    --                        Error Handling                         --
    -------------------------------------------------------------------

    --  Check for DataSentReceived and TokenReceived after errors
    --  are handled, to be sure that no errors are missed.


    if SIE_RxEOP and DataSentReceived then
      HandshakeSentReceived := TRUE;
    end if;


    if SIE_RxEOP and TokenReceived then
      DataSentReceived := TRUE;
    end if;

    if SIE_RxEOP then
      TokenReceived := TRUE;
    end if;


    if TokenReceived then
      MM_EndpSearchReady <= EndpSearchReady;
    end if;

    DataToHandlers.N_Data <= N_Data;
    if EndOfTransfer and SIE_RxEOP then
      DataToHandlers.EndOfTransfer <= TRUE;
      EndOfTransfer <= FALSE;
    end if;

  end if;

end process MAIN;

DataToHandlers.RxData <= SIE_RxData;
DataToHandlers.RxDataValid <= SIE_RxDataRdy and not StopReceiving and not IgnoreData;
DataToHandlers.Interrupts <= DataFromHandlers_In.Interrupts;
DataToHandlers.SetupPacket <= SetupPacket;
DataToHandlers.Handler <= HandlerNumber;

end RTL;

⌨️ 快捷键说明

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