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

📄 usb_new_uc_handler_rtl.vhdl

📁 实现USB接口功能的VHDL和verilog完整源代码
💻 VHDL
📖 第 1 页 / 共 3 页
字号:
    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);
    Naked := (others => FALSE);
    Overwritten := (others => FALSE);
    Disable := (others => FALSE);
    RateFeedback := (others => FALSE);
    Full:= (others => (others => FALSE));
    Sie_Write <= '0';
    Sie_Read_i  <= '0';
    start_in_transfer <= '0';
  elsif (FsClk'event and FsClk = '1') then

-- rama
    -- Doublebuffered endpoints are allways toggled on the frameclock
    for i in 0 to (N_ENDPOINTS-1) loop
      if EndpointInfo(ConfigNr)(i).EndpointType = ISOCHRONOUS then     
        UCToggle(i) := TM_IsoToggle;
        USBToggle(i) := 1 - TM_IsoToggle;
      end if;
    end loop;

    -- Send bufferinfo to PI_Handler
    EPBufferInfo.UCToggle <= UCToggle;
    EPBufferInfo.USBToggle <= USBToggle;
    EPBufferInfo.Full <= Full;
    
    Selected_int := Selected;
    ConfigNr := GetConfiguration(ConfigArray);
     
    -- DOC_BEGIN: Device Address Table
    -- Bit 7 in the Device Address Table
    -- indicates whether a function is active (1) or not (0).
    -- Rows with addresses 0 to 7 are contained in DevAddrTable()().
    -- The row with address equal to 8 is the EndpointEnables register.
    -- Each device has its own bit. If the bit is set, all endpoints
    -- of that device are enabled. If the bit is reset, only the default
    -- endpoint is enabled. (USB Control Endpoint 0)
    --  __________________________________________________________________
    -- |Addr.|   bit 7   | bit 6| bit 5| bit 4| bit 3| bit 2| bit 1| bit 0|
    -- |__________________________________________________________________|
    -- |  0  | F0 enable |             Function 0 Address                 |
    -- |  1  | F1 enable |             Function 1 Address                 |
    -- |  2  | F2 enable |             Function 2 Address                 |
    -- |  3  | F3 enable |             Function 3 Address                 |
    -- |  4  | F4 enable |             Function 4 Address                 |
    -- |  5  | F5 enable |             Function 5 Address                 |
    -- |  6  | F6 enable |             Function 6 Address                 |
    -- |  7  | F7 enable |             Function 7 Address                 |
    -- |__________________________________________________________________|
    -- |  8  | F7 En.    |F6 En.|F5 En.|F4 En.|F3 En.|F2 En.|F1 En.|F0 En.|  
    -- |__________________________________________________________________|
    -- DOC_END

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

    if EndpointInfo(ConfigNr)(DataToHandlers.Endpoint).EndpointType =
      ISOCHRONOUS then 
      PID <= 0;
      Stalled <= FALSE;
    else
      PID <= DataPID(DataToHandlers.Endpoint);
      Stalled <= Stall(DataToHandlers.Endpoint);
    end if;
   
    if EndpointInfo(ConfigNr)(DataToHandlers.Endpoint).EndpointType /=
      CONTROL then 
      Disabled <= Disable(DataToHandlers.Endpoint);
    else
      Disabled <= FALSE;
    end if;
   
    -- default assignments
    NeedClock <= FALSE;
    
    -- DOC_BEGIN: uC Commands processing     
    -- GIF clears or validates buffers: 
    -- (note: if this is also implemented for other endpoints: take care of
    -- command_disabled)
        
    --if (ValidateEP1 = '1') then 
    --  if not overwritten(0)then
    --    Full(1)(0) := TRUE;
    --  end if;
    --end if;    
        
    --if (ValidateEP3 = '1') then 
    --  Full(3)(0) := TRUE;
    --end if;    
            
    --if (ValidateEP5 = '1') then 
    --  Full(5)(0) := TRUE;
    --end if;    

    --if (ClearEP6 = '1') then 
    --  if EndpointInfo(ConfigNr)(6).N_Buffers > 1 then
    --    Full(6)(UCToggle(6)) := FALSE;
     --   UCToggle(6) := 1-UCToggle(6);
    --  else  
     --   Full(6)(0) := FALSE;
     -- end if;
    --end if;
    
    --if (ValidateEP7 = '1') then 
    --  if EndpointInfo(ConfigNr)(7).N_Buffers > 1 then
     --   Full(7)(UCToggle(7)) := TRUE;
     --   UCToggle(7) := 1-UCToggle(7);
     -- else  
     --   Full(7)(0) := TRUE;
     -- end if;
   -- end if;    
    
   -- if (ClearEP8 = '1') then 
   --   if EndpointInfo(ConfigNr)(8).N_Buffers > 1 then
    --    Full(8)(UCToggle(8)) := FALSE;
   --   else  
    --    Full(8)(0) := FALSE;
   --   end if;
   -- end if;
    
   -- if (ValidateEP9 = '1') then 
   --   if EndpointInfo(ConfigNr)(9).N_Buffers > 1 then
   --     Full(9)(UCToggle(9)) := TRUE;
   --   else  
   --     Full(9)(0) := TRUE;
   --   end if;
   -- end if;    
    
    
    -- External controller writes a command :
    if (DataFromUC.Write and DataFromUC.Address = 1) then
      NeedClock <= TRUE;
      -- Split input DataFromUC.Data in Command and argument
      DecodeCommand(DataFromUC.Data, Command, CmdArgument, Selected_int);
      DataToUC.Ready <= FALSE;
      case command is

        -- The Select Endpoint command initializes an internal
        -- pointer to the start of the Selected buffer.
        -- It also returns a byte with bit 2 indicating that the
        -- packet in the buffer was preceeded by a Setup token,
        -- bit 1 indicates a stall state and bit 0 indicates if
        -- the buffer is full.

        when SELECT_EP | SET_EP_STATUS =>
          -- in case of SET_EP_STATUS, the selecting of the 
          -- of the endpoint and the resetting of the buffer are
          -- done when reading a byte
          if command = SELECT_EP then	
            EndpointNr := CmdArgument;     
          end if;
          EndpointNr_tmp := CmdArgument;
          DataToUC.Data <= "00000000";

          if EndpointInfo(ConfigNr)(CmdArgument).N_Buffers > 1 then
            DataToUC.Data(SEL_FULL) <=
              conv_active_high(Full(CmdArgument)(UCToggle(CmdArgument)));
          else
            DataToUC.Data(SEL_FULL) <= conv_active_high(Full(CmdArgument)(0));
          end if;

          if EndpointInfo(ConfigNr)(EndpointNr_tmp).EndpointType /= CONTROL or
             EndpointInfo(ConfigNr)(EndpointNr_tmp).USBDirection /= DIR_OUT then 
            DataToUC.Data(SEL_SETUP) <= '0';
            DataToUC.data(SEL_OVERWRITTEN) <= '0';
          else
            DataToUC.Data(SEL_SETUP) <= conv_active_high(Setup(EndpointNr_tmp));
            DataToUC.Data(SEL_OVERWRITTEN) <=
              conv_active_high(Overwritten(EndpointNr_tmp));
          end if;

          if EndpointInfo(ConfigNr)(EndpointNr_tmp).EndpointType /= CONTROL then
            DataToUC.Data(SEL_NAKED) <= '0';
          elsif EndpointInfo(ConfigNr)(EndpointNr_tmp).EndpointType = CONTROL then
            DataToUC.Data(SEL_NAKED) <= conv_active_high(Naked(EndpointNr_tmp));
          end if;

          if EndpointInfo(ConfigNr)(EndpointNr_tmp).EndpointType =
              ISOCHRONOUS then 
            DataToUC.Data(SEL_STALL) <= '0';
          else
             DataToUC.Data(SEL_STALL) <= conv_active_high(Stall(EndpointNr_tmp));
          end if;       
                            
        -- The following  command implements both the 'Clear Buffer' and
        -- the 'Validate Buffer' commands of the uC. It controls
        -- the Buffer Full bit in the endpoint status register.
        -- CmdArgument = 1 sets the Buffer Full bit.
        -- CmdArgument = 0 resets the Buffer Full bit.

        when SET_BUFFER_FE =>
          if CmdArgument = 0 then 
            DataToUC.Data <= "00000000";
            if EndpointInfo(ConfigNr)(EndpointNr).EndpointType /= CONTROL or
               EndpointInfo(ConfigNr)(EndpointNr).USBDirection /= DIR_OUT then 
              DataToUC.data(CLB_OVERWRITTEN) <= '0';
            else
              DataToUC.Data(CLB_OVERWRITTEN) <=
                conv_active_high(Overwritten(EndpointNr));
            end if;

            -- UCClearBuffer
            
            CommandDisabled := FALSE;
            if EndpointInfo(ConfigNr)(EndpointNr).EndpointType = CONTROL then
              CorrespEP := EndpointInfo(ConfigNr)(EndpointNr).CorrespondingEP;
              if EndpointInfo(ConfigNr)(EndpointNr).USBDirection =DIR_OUT then 
                CommandDisabled := Overwritten(EndpointNr);
              else
                CommandDisabled := Overwritten(CorrespEP);
              end if;
            end if;
            if not CommandDisabled then
              if EndpointInfo(ConfigNr)(EndpointNr).N_Buffers > 1 then
                Full(EndpointNr)(UCToggle(EndpointNr)) := FALSE;
                if EndpointInfo(ConfigNr)(EndpointNr).EndpointType /= ISOCHRONOUS then
                  UCToggle(EndpointNr) := 1-UCToggle(EndpointNr);
                end if;
              else  
                Full(EndpointNr)(0) := FALSE;
              end if;
            end if; 

            -- end UCClearBuffer
            if IsFull(EndpointNr, UCToggle, Full, ConfigNr) then
              DataToSIE.Interrupts(EndpointNr) <= TRUE;
            end if;  

          else  

           -- UCValidateBuffer
            CommandDisabled := FALSE;
            if EndpointInfo(ConfigNr)(EndpointNr).EndpointType = CONTROL then
              CorrespEP := EndpointInfo(ConfigNr)(EndpointNr).CorrespondingEP;
              if EndpointInfo(ConfigNr)(EndpointNr).USBDirection = DIR_OUT then 
                CommandDisabled := Overwritten(EndpointNr);
              else
                CommandDisabled := Overwritten(CorrespEP);
              end if;
            end if;
            if not CommandDisabled then
              if EndpointInfo(ConfigNr)(EndpointNr).N_Buffers > 1 then
                Full(EndpointNr)(UCToggle(EndpointNr)) := TRUE;
                if EndpointInfo(ConfigNr)(EndpointNr).EndpointType /= ISOCHRONOUS then
                  UCToggle(EndpointNr) := 1-UCToggle(EndpointNr);
                end if;
              else  
                Full(EndpointNr)(0) := TRUE;
              end if;
           end if;

            -- end UCValidateBuffer

          end if;

        -- The command Read data reads data from the Endpoint Data Buffer 
        -- Each read pulse, the data is red from the buffer.
        -- The pointer is incremented to the next position in the
        -- buffer.

        -- The first byte in the buffer is the most significant byte of
        -- the number of bytes in the buffer. Only bits 1 and 0 are used
        -- for the number of bytes. Bit 7 in this byte indicates that
        -- the last transaction was successfull.
        -- Bit 6 indicates that it was a setup packet.
        -- This byte is cleared when it has been sent to the the external
        -- controller.
          

        when SET_ADDRESS | SET_EP_ENABLE =>
          null;
      

        -- Invalid States
        when others =>
          DataToUC.Ready <= TRUE;

      end case;

    -- External controller writes data
    elsif (DataFromUC.Write and Selected_int)then
      Data := DataFromUC.Data;
      NeedClock <= TRUE;
      DataToUC.Ready <= FALSE;
      case command is
        
        -- The Set Address command sets the address and the enable bit
        -- of a function
        when SET_ADDRESS =>
          Data := DataFromUC.Data;
          DevAddrTable(CmdArgument)(7) <= Data(7);
          if loaded(CmdArgument) then
            DevAddrTable(CmdArgument) <= Data;
            Loaded(CmdArgument) := FALSE;
          else
            DevAddrTable_tmp(CmdArgument):= Data(6 downto 0);
            Loaded(CmdArgument) := TRUE;
          end if;

        -- Enables/disables endpoints
        when SET_EP_ENABLE =>
          EndpointEnables <= Data(N_HANDLER_DEVICES(ID)-1 downto 0);

        -- The command Set Endpoint Status followed by writing one byte
        -- will stall or unstall the selected endpoint, set or reset the
        -- DataPID, mark the buffer full or empty, indicate if the buffer
        -- contains a setup packet and set the status of the buffer to
        -- overwritten or not.
        -- Writing 01h will stall the endpoint, writing 00h will unstall
        -- the endpoint. Stalling the endpoint will also reset the
        -- endpoint status.
        when SET_EP_STATUS =>  
         -- InitializeEndpoint
          CommandDisabled := FALSE;
          if EndpointInfo(ConfigNr)(CmdArgument).EndpointType = CONTROL then 
            CorrespEP := EndpointInfo(ConfigNr)(CmdArgument).CorrespondingEP;
            if EndpointInfo(ConfigNr)(CmdArgument).USBDirection = DIR_OUT then 
              CommandDisabled :=  Overwritten(CmdArgument);
              if conv_active_high(DataFromUC.Data(C_CONDSTALL))
              and (Setup(CmdArgument) = TRUE) then
                CommandDisabled := TRUE;
              end if;
            else
              CommandDisabled := Overwritten(CorrespEP);
            end if;
          end if;
        
          if not CommandDisabled THEN
              -- only clear buffers etc when unstalling
              IF DataFromUC.Data(C_STALL)='0' THEN
                  if (EndpointInfo(ConfigNr)(CmdArgument).N_Buffers > 1)  then
                      Full(CmdArgument) := 
                      (others => FALSE);
                      UCToggle(CmdArgument) := 0;
                      USBToggle(CmdArgument) := 0;
                  else  
                      Full(CmdArgument)(0) := FALSE;
                  end if;
              END IF;
              if EndpointInfo(ConfigNr)(CmdArgument).EndpointType /=
                  ISOCHRONOUS then 
                  Stall(CmdArgument) := conv_active_high(DataFromUC.Data(C_STALL));
                  DataPID(CmdArgument) := 0;
              end if;
              if EndpointInfo(ConfigNr)(CmdArgument).EndpointType = CONTROL
                 and EndpointInfo(ConfigNr)(CmdArgument).USBDirection =
                   DIR_OUT then 
                   if conv_active_high(DataFromUC.Data(C_CONDSTALL)) then
                     CorrespEP := EndpointInfo(ConfigNr)(CmdArgument).CorrespondingEP;
                     Stall(CmdArgument) := TRUE;
                     Stall(CorrespEP) := TRUE;

⌨️ 快捷键说明

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