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

📄 usb_new_device_handler_rtl.vhdl

📁 实现USB接口功能的VHDL和verilog完整源代码
💻 VHDL
📖 第 1 页 / 共 2 页
字号:
  elsif (FsClk'event and FsClk='1') then

    DataToSIE.RemoteWakeup <= FALSE;
    DataToUc.Ready <= TRUE;

    -- DOC_BEGIN: Command Write
    -- When a command is received from the external micro controller,
    -- the decoder compares the command code with the codes of the commands
    -- it can handle. If there is a match, the module selects itself to 
    -- get access to the microcontroller interface.
    if (DataFromUC.Write and DataFromUC.Address = 1) then
      DataToUc.Ready <= FALSE;
      Selected <= TRUE;
      ByteCounter := 0;
      if DataFromUC.Data = GET_INTERRUPT_CODE then
	Command := GET_INTERRUPT;
      elsif DataFromUC.Data = GET_FRAMENUMBER_CODE then
	Command := GET_FRAMENUMBER;
      elsif DataFromUC.Data = GETSET_MODE_CODE then
	Command := GETSET_MODE;
      elsif DataFromUC.Data = GET_ERROR_CODE then
	Command := GET_ERROR;
      elsif DataFromUC.Data = GETSET_DEVICE_STATUS_CODE then
	Command := GETSET_DEVICE_STATUS;
      elsif DataFromUC.Data = GET_CHIPID_CODE then
	Command := GET_CHIPID;
      else
        Command := INVALID;
	Selected <= FALSE;
      end if;

      -- Depending on the command, the appropriate data are sent
      -- to the micro-controller interface for a possible micro-controller
      -- data read access.


      case Command is
	when GET_FRAMENUMBER =>
	  DataToUC.Data <= GetByteSlice(FrameNumber, ByteCounter);
	when GET_INTERRUPT =>
	  DataToUC.Data <= GetByteSlice(
                             conv_active_high(DataToHandlers.Interrupts),
                             ByteCounter);
	when GETSET_MODE =>
	  DataToUC.Data <= GetByteSlice(
                             conv_active_high(PINConfigArray), ByteCounter);
	when GET_CHIPID =>
	  DataToUC.Data <= GetByteSlice(ChipID, ByteCounter);
	when GET_ERROR =>
	  DataToUC.Data <= "000" & conv_active_high(DataToHandlers.Error) &
			    EncodeError(DataToHandlers.LastError);
	when GETSET_DEVICE_STATUS =>
          DataToUC.Data <= GetDeviceStatus(Connect, ConnectChangeInterrupt, 
                                           TM_Suspend, SuspendChangeInterrupt, 
                                           BusResetInterrupt,
                                           RemoteWakeupEvent);
	  BusResetInterrupt := FALSE;
	  SuspendChangeInterrupt := FALSE;
	  ConnectChangeInterrupt := FALSE;
          RemoteWakeupEvent := FALSE;
	  DataToSIE.Interrupts(0) <= FALSE;
        when others =>
	  DataToUC.Ready <= True;
      end case;
    -- DOC_END



    -- DOC_BEGIN: Data Read Access
    -- On every read access, the next byte is fetched and sent to the
    -- micro-contoller interface. In the case of a Read Device Status
    -- command, the change bits and the interrupt are cleared.
    elsif (DataFromUC.Read and Selected) then

      ByteCounter := IncMod(ByteCounter, 8); 
      DataToUc.Ready <= FALSE;

      case Command is
	when GET_FRAMENUMBER =>
	  DataToUC.Data <= GetByteSlice(FrameNumber, ByteCounter);
	when GET_INTERRUPT =>
	  DataToUC.Data <= GetByteSlice(
                             conv_active_high(DataToHandlers.Interrupts),
                             ByteCounter);
	when GETSET_MODE =>
	  DataToUC.Data <= GetByteSlice(
                             conv_active_high(PINConfigArray), ByteCounter);
	when GET_CHIPID =>
	  DataToUC.Data <= GetByteSlice(ChipID, ByteCounter);
	when GET_ERROR =>
	  DataToUC.Data <= "000" & conv_active_high(DataToHandlers.Error) &
			    EncodeError(DataToHandlers.LastError);
	when GETSET_DEVICE_STATUS =>
	  DataToUC.Data <= GetDeviceStatus(Connect, ConnectChangeInterrupt,
					   TM_Suspend, SuspendChangeInterrupt, 
					   BusResetInterrupt,
                                           RemoteWakeupEvent);
--	  BusResetInterrupt := FALSE;
--	  SuspendChangeInterrupt := FALSE;
--	  ConnectChangeInterrupt := FALSE;
--          RemoteWakeupEvent := FALSE;
--	  DataToSIE.Interrupts(0) <= FALSE;
	when others =>
	  null;  
      end case;
    -- DOC_END

    -- DOC_BEGIN: Data Write Access
    -- For the commands that support data write access, the appropriate 
    -- registers are updated on every write access.
    elsif (DataFromUC.Write and DataFromUC.Address = 0 and Selected) then
      DataToUc.Ready <= FALSE;

      if Command = GETSET_MODE then
	UCConfigArray <= conv_active_high(
	  SetByteSlice(conv_active_high(UCConfigArray),
                       DataFromUC.Data, ByteCounter));
      end if;

      if Command = GETSET_DEVICE_STATUS then
	AllowConnect := conv_active_high(DataFromUC.Data(CONNECT_BIT_POS));
	if DataFromUC.Data(SUSPEND_BIT_POS) = '0' then
	  DataToSIE.RemoteWakeUp <= TRUE;
	end if;
      end if;

      -- Increment bytecounter, ready to receive possible next byte
      ByteCounter := IncMod(ByteCounter, 8);
    else
      DataToUC.READY <= TRUE;  
    end if;
    -- DOC_END

    --InterruptLevel := or_reduce(DataToHandlers.Interrupts);
    -- BULK OUT Interrupt is seperated from DH_Interrupt
    --InterruptLevel := or_reduce(DataToHandlers.Interrupts(N_INTR_BITS-1 downto 7)) 
    --                  OR or_reduce(DataToHandlers.Interrupts(5 downto 0));
    
    -- All interrupts are seperated from DH_Interrupt
    InterruptLevel := or_reduce(DataToHandlers.Interrupts(9 downto 8));
    
    
    InterruptEdge := FALSE;
    for i in Interrupt_Z'range loop
      InterruptEdge := InterruptEdge or 
	(DataToHandlers.Interrupts(i) and not Interrupt_Z(i));
    end loop;
    Interrupt_Z := DataToHandlers.Interrupts;

    if (EdgeInterrupt(ConfigArray_int)) then
      DH_Interrupt <= (EdgeTimer > 0);
    else
      DH_Interrupt <= InterruptLevel;
    end if;
    DH_Interrupt_Ep0 <= DataToHandlers.Interrupts(0);
    DH_Interrupt_Ep1 <= DataToHandlers.Interrupts(1);
    DH_Interrupt_Ep2 <= DataToHandlers.Interrupts(2);
    DH_Interrupt_Ep3 <= DataToHandlers.Interrupts(3);
    DH_Interrupt_Ep4 <= DataToHandlers.Interrupts(4);
    DH_Interrupt_Ep5 <= DataToHandlers.Interrupts(5);
    DH_Interrupt_Ep6 <= DataToHandlers.Interrupts(6);
    DH_Interrupt_Ep7 <= DataToHandlers.Interrupts(7);
    DH_Interrupt_Dev <= DataToHandlers.Interrupts(10);

    if EdgeTimer > 0 then
      EdgeTimer := EdgeTimer -1;
    end if;

    if InterruptEdge then
      EdgeTimer := INTERRUPT_PULSE_LENGTH-1;
    end if;

    -- DOC_BEGIN: Status Change bits generation
    -- On a bus reset, the bus reset change bit is set
    -- and an interrupt is generated.
    if RG_SetSE0Int and Connect then
      BusResetInterrupt := TRUE;
      DataToSIE.Interrupts(0) <= TRUE;
    end if;

    -- On a change in the devices suspend state, the suspend
    -- change bit is set and an interrupt is generated.
    if TM_Suspend /= TM_Suspend_Z then
      SuspendChangeInterrupt := TRUE;
      DataToSIE.Interrupts(0) <= TRUE;
      TM_Suspend_Z := TM_Suspend;
      -- Only check if device goes out of suspend
      RemoteWakeupEvent := TM_RemoteWakeupEvent and not TM_Suspend;
    end if;

    -- When the device is disconnected because Vbus dissapeared,
    -- the connect change bit is set and and interrupt is generated.
    if (Connect and not VBusDebounced) then
      ConnectChangeInterrupt := TRUE;
      DataToSIE.Interrupts(0) <= TRUE;
    end if;
    -- DOC_END

    Connect <= VBusDebounced and AllowConnect;

    -- DOC_BEGIN: Vbus Debouncing
    -- This circuit masks small low spikes on Vbus. This allows
    -- to share the Vbus pin with an other input pin, provided
    -- that it goes low only for a short time during normal
    -- operation.
    VBusDebounced <= VBusAvailable or (DebounceTimer > 0);

    if VBusAvailable or not SUPPORT_SOFTCONNECT then
      DebounceTimer := VBUS_DEBOUNCE_TIME;

    elsif (TM_1kHzPulse = '1') then
      if (DebounceTimer > 0) then
	DebounceTimer := DebounceTimer -1;
      end if;
    end if;
    -- DOC_END
  end if;

end process;

  -- since all request can be handled in 1 cycle, ready is
  -- always true;
  -- DataToUc.Ready <= TRUE;
  DataToSIE.IntMode <= FALSE;
  DataToSIE.NeedClock <= (VBusAvailable /= VBusDebounced);
  DH_Connect <= Connect;

end RTL;

⌨️ 快捷键说明

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