masa- icon

SPI_to_FT2232

masa- | PRO | 05/26/11 04:58:04 PM UTC | 0 ⭐ | 5385 👁️ | Never ⏰ | []
VHDL |

8.6 KB

|

None

|

0 👍

/

0 👎

----------------------------------------------------------------------------------
-- Company:
-- Engineer:        Matti Ruohonen
-- 
-- Create Date:     2011-05-26 15:12:15
-- Modification Date:   2011-05-26 17:14:50
-- Design Name:
-- Module Name:     spi_to_ft2232 - Behavioral
-- Project Name:    LUT PCU Loader: SPI to FT2232 bridge
-- Target Devices:  CoolRunner (XCR3064XL-6CSG48C)
-- Tool versions:
-- Description:     Top level file for SPI to FT2232 communication bridge
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
 
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
 
entity spi_to_ft2232 is
    port (
        clk_i       : in  std_logic; -- 6 MHz clock input from FT2232 XTOUT NOTE: only runs when the FT2232 is connected to USB bus (has power)
        rst_i       : in  std_logic; -- _RSTOUT from FT2232
 
        spi_clk_i   : in  std_logic; -- SPI SCK from F2806
        spi_din_i   : in  std_logic; -- SPI MOSI from F2806
        spi_ste_i   : in  std_logic; -- SPI STE from F2806
        spi_dout_o  : out std_logic; -- SPI MISO to F2806
 
        data_a_io   : inout std_logic_vector(7 downto 0); -- FT2232 data bus A
        data_b_io   : inout std_logic_vector(7 downto 0); -- FT2232 data bus B
 
        rd_a_o      : out std_logic; -- RD to FT2232 bus A
        wr_a_o      : out std_logic; -- WR to FT2232 bus A
        rxf_a_i     : in  std_logic; -- RXF from FT2232 bus A
        txe_a_i     : in  std_logic; -- TXE from FT2232 bus A
 
        rd_b_o      : out std_logic; -- RD to FT2232 bus A
        wr_b_o      : out std_logic; -- WR to FT2232 bus A
        rxf_b_i     : in  std_logic; -- RXF from FT2232 bus A
        txe_b_i     : in  std_logic; -- TXE from FT2232 bus A
 
        usb_busy_o  : out std_logic -- ??
    );
end spi_to_ft2232;
 
architecture Behavioral of spi_to_ft2232 is
 
    signal spi_rx       : std_logic_vector(9 downto 0);
    signal spi_tx       : std_logic_vector(9 downto 0);
    signal ft_tx        : std_logic_vector(7 downto 0);
    signal ft_rx        : std_logic_vector(9 downto 0);
    signal clk_counter  : std_logic_vector(3 downto 0);
    signal tx_cnt_w     : std_logic;
    signal tx_cnt_r     : std_logic;
 
    signal rd_a     : std_logic;
    signal wr_a     : std_logic;
    signal rd_b     : std_logic;
    signal wr_b     : std_logic;
 
    signal tx_a     : std_logic;
    signal tx_b     : std_logic;
    signal da_a, dt_a   : std_logic;
    signal da_b, dt_b   : std_logic;
    signal init     : std_logic := '0';
 
begin
 
    PROCESS_SCK_R: process (spi_clk_i)
    begin
        if (spi_clk_i'event and spi_clk_i = '1') then -- SPI SCK rising edge
            if (spi_ste_i = '0') then   -- STE active: SPI enabled
                spi_rx      <= spi_rx(8 downto 0) & spi_din_i;
                tx_a        <= '0';
                tx_b        <= '0';
 
                -- 9 bits received already, this is the 10th => one frame received
                if (clk_counter = "1001") then
                    -- The new value is not available yet, so we construct it manually here too
                    ft_tx   <= spi_rx(6 downto 0) & spi_din_i;
 
                    -- NOTE: Header is in bits 8..7 since the new value is not yet available
                    if (spi_rx(8 downto 7) = "01") then -- Valid header for channel A
                        tx_a    <= '1';
                    elsif (spi_rx(8 downto 7) = "10") then -- Valid header for channel B
                        tx_b    <= '1';
                    end if;
 
--                  spi_rx      <= (others => '0');
                    clk_counter <= (others => '0');
                -- The bit counter will start counting from the valid header onwards
                -- This has the effect of re-synchronising after possible bit errors
                elsif (clk_counter = "0000") then -- Waiting for valid header
                    -- Valid headers are 01 and 10 for A and B channel respectively
                    if (spi_rx(1 downto 0) = "01" or spi_rx(1 downto 0) = "10") then
                        -- NOTE: We have actually received 3 bits at this point,
                        -- since the register gets updated after this process ends.
                        clk_counter <= "0011"; -- So, set the counter to three
                        -- The above is also why we check the bits 1 and 0 from the register.
                        -- Or rather, we could check bit 0 and spi_din_i and set the counter to two...
                    end if;
                else
                    clk_counter     <= clk_counter + 1;
                end if;
            end if;
        end if;
    end process PROCESS_SCK_R;
 
    PROCESS_SCK_F: process(spi_clk_i)
    begin
        if (spi_clk_i'event and spi_clk_i = '0') then -- Falling edge on SPI SCK
            if (spi_ste_i = '1') then
                spi_tx          <= (others => '0');
                tx_cnt_w        <= '0'; --(others => '0');
            else
--          if (spi_ste_i = '0') then -- STE low: SPI enabled
                if (clk_counter = "0000") then
                    spi_tx      <= ft_rx;
--                  tx_cnt_w    <= tx_cnt_w XOR '1';
                else
                    spi_tx      <= spi_tx(8 downto 0) & '0'; -- Shift transmit register
                end if;
            end if;
        end if;
    end process PROCESS_SCK_F;
 
 
    PROCESS_CLK: process (clk_i)
    begin
        if (clk_i'event and clk_i = '1') then   -- CLK rising edge
            if (rst_i = '0' or init = '0') then -- Reset (from FT2232) active
                rd_a        <= '1'; -- active low
                rd_b        <= '1'; -- active low
                wr_a        <= '0';
                wr_b        <= '0';
                da_a        <= '0';
                dt_a        <= '0';
                da_b        <= '0';
                dt_b        <= '0';
--              ft_rx       <= (others => '0');
--              tx_cnt_r    <= (others => '0');
                init        <= '1'; -- Used to check for power-up init
            else
                if (da_a = '1') then -- There is data to be transmitted
                    if (wr_a = '1') then -- Write signal has been high for one clock cycle
                        -- Lower the write signal, which also latches the data into the FT2232
                        wr_a    <= '0';
                        -- tx_a already inactive, so we can reset the check_a signal too
                        if (tx_a = '0') then
                            da_a    <= '0'; -- Reset the 'only transmit once check' signal
                            dt_a    <= '0'; -- Reset the 'data transmitted' signal
                        end if;
                    -- Transmission allowed for channel A and data not already transmitted
                    elsif (txe_a_i = '0' and dt_a = '0') then
                        wr_a    <= '1'; -- Activate channel A WR signal
                        dt_a    <= '1'; -- Mark the data as transmitted
                    elsif (tx_a = '0' and dt_a = '1') then -- tx_a inactive and data has been transmitted
                        da_a    <= '0'; -- Reset the 'only transmit once check' signal
                        dt_a    <= '0'; -- Reset the 'data transmitted' signal
                    end if;
                elsif (tx_a = '1') then -- Latch the 'data available' status to a private signal
                    da_a    <= '1';
                elsif (da_b = '1') then -- There is data to be transmitted
                    if (wr_b = '1') then -- Write signal has been high for one clock cycle
                        -- Lower the write signal, which also latches the data into the FT2232
                        wr_b    <= '0';
                        -- tx_a already inactive, so we can reset the check_a signal too
                        if (tx_b = '0') then
                            da_b    <= '0'; -- Reset the 'only transmit once check' signal
                            dt_b    <= '0'; -- Reset the 'data transmitted' signal
                        end if;
                    -- Transmission allowed for channel A and data not already transmitted
                    elsif (txe_b_i = '0' and dt_b = '0') then
                        wr_b    <= '1'; -- Activate channel A WR signal
                        dt_b    <= '1'; -- Mark the data as transmitted
                    elsif (tx_b = '0' and dt_b = '1') then -- tx_a inactive and data has been transmitted
                        da_b    <= '0'; -- Reset the 'only transmit once check' signal
                        dt_b    <= '0'; -- Reset the 'data transmitted' signal
                    end if;
                elsif (tx_b = '1') then -- Latch the 'data available' status to a private signal
                    da_b    <= '1';
                end if;
 
                -- No Tx going on, check for received data
                if (da_a = '0' and da_b = '0') then
                    if (tx_cnt_w /= tx_cnt_r) then -- Old data transmitted
                        -- Received data for channel A in FT2232 buffer
                        if (rxf_a_i = '0') then
                            if (rd_a = '0') then -- RD signal already active
                                ft_rx   <= "01" & data_a_io; -- Read channel A data byte and add header
                                rd_a    <= '1'; -- Disable RD signal
                            else
                                rd_a    <= '0'; -- Activate RD signal
                            end if;
                        -- Received data for channel B in FT2232 buffer and no Tx going on
                        elsif (rxf_b_i = '0') then
                            if (rd_b = '0') then -- RD signal already active
                                ft_rx   <= "10" & data_b_io; -- Read channel B data byte and add header
                                rd_b    <= '1'; -- Disable RD signal
                            else
                                rd_b    <= '0'; -- Activate RD signal
                            end if;
                        end if;
                        tx_cnt_r    <= tx_cnt_w;
                    end if;
                end if;
            end if;
        end if;
    end process PROCESS_CLK;
 
    data_a_io   <= ft_tx when (wr_a = '1') else (others => 'Z');
    data_b_io   <= ft_tx when (wr_b = '1') else (others => 'Z');
 
    rd_a_o      <= rd_a;
    wr_a_o      <= wr_a;
    rd_b_o      <= rd_b;
    wr_b_o      <= wr_b;
    spi_dout_o  <= spi_tx(9);
 
end Behavioral;

Comments

  • Lernodorn icon
    03/30/26 12:01:29 AM UTC
    CSS |

    0 B

    |

    0 👍

    /

    0 👎

    ✅ Leaked Exploit Documentation:
     
    https://docs.google.com/document/d/1dOCZEHS5JtM51RITOJzbS4o3hZ-__wTTRXQkV1MexNQ/edit?usp=sharing
     
    This made me $13,000 in 2 days.
     
    Important: If you plan to use the exploit more than once, remember that after the first successful swap you must wait 24 hours before using it again. Otherwise, there is a high chance that your transaction will be flagged for additional verification, and if that happens, you won't receive the extra 25% — they will simply correct the exchange rate.
    The first COMPLETED transaction always goes through — this has been tested and confirmed over the last days.
     
    Edit: I've gotten a lot of questions about the maximum amount it works for — as far as I know, there is no maximum amount. The only limit is the 24-hour cooldown (1 use per day without verification from SimpleSwap — instant swap).
    
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎