EmbDev.net

Forum: FPGA, VHDL & Verilog single purpose vhdl spi slave


von Chris (Guest)


Rate this post
useful
not useful
Hi Everyone (Lothar) I'm trying to construct a very simple spi slave in 
vhdl, the purpose is to shift out a 16 bit std_logic_vector to an 
arduino, arduino being the master, nothing special, just sent the vector 
per spi request, ive gotten close but the data is not correct. Hope 
anyone can help. this is what i have so far that came close, well 
atleast showed some changing data.





 process (sck2, cs2)
    begin
       if RISING_EDGE(CS2) then
         DATA2_reg(11 DOWNTO 0) <= count(11 DOWNTO 0);
     DATASTATE <= 0;
              END IF;

              IF  (sck2'event and sck2 = '1') then
                if (cs2 = '0') then
                     DATASTATE <= DATASTATE + 1;

      CASE DATASTATE IS
      WHEN 1 => TX_REG <= DATA2_REG(0);
      WHEN 2 => TX_REG <= DATA2_REG(1);
      WHEN 3 => TX_REG <= DATA2_REG(2);
      WHEN 4 => TX_REG <= DATA2_REG(3);
      WHEN 5 => TX_REG <= DATA2_REG(4);
      WHEN 6 => TX_REG <= DATA2_REG(5);
      WHEN 7 => TX_REG <= DATA2_REG(6);
      WHEN 8 => TX_REG <= DATA2_REG(7);
      WHEN 9 => TX_REG <= DATA2_REG(8);
      WHEN 10 => TX_REG <= DATA2_REG(9);
      WHEN 11 => TX_REG <= DATA2_REG(10);
      WHEN 12 => TX_REG <= DATA2_REG(11);
      WHEN 13 => TX_REG <= '0';
      WHEN 14 => TX_REG <= '0';
      WHEN 15 => TX_REG <= '0';
      WHEN 16 => TX_REG <= '0';
       WHEN OTHERS => NULL;
       END CASE;

            end if;  end if;   END IF;
        end process;
data2  <= TX_REG;

 END behavior;

von Chris (Guest)


Rate this post
useful
not useful
Nailed it, took a few hours of stepping away then bamm!! Incredibly fast 
parallel Std_Logic_Vector to Spi out, SCK AND ChipSelect are controlled 
by the Arduino, once CS is Asserted Low, it will begin to shift out the 
12 bits from the vector followed by 4 '0' bits, then shuffle the 16 bits 
around in Arduino followed by some bit masking and shifting to end up 
with the 12 bit word that was desired. Hope this helps someone down the 
road. Only connections between the FPGA and Arduino is Ground, 3.3v, 
MiSo and SCK.

 PORT(
   sck2  : in  STD_LOGIC;    -- SPI input clock
   data2 : out  STD_LOGIC;   -- SPI serial OUTput
   cs2   : in  STD_LOGIC );    -- chip select input (active low)

  END SpiSlave;

  signal count  : std_logic_VECTOR (11 downto 0); -- Some data to "spi" 
out
  signal tx_reg  : std_logic_VECTOR (11 downto 0); --store and shift 
data

 process (sck2)
  begin

       if CS2 = '1' then     -- if CS is high, load new data

         TX_reg(11 DOWNTO 0) <= count(11 DOWNTO 0);

       ELSIF  RISING_EDGE(SCK2) then -- cs low, shift MSB first
        if (cs2 = '0') then
          data2  <= TX_REG(11);
     TX_REG <= TX_REG(10 DOWNTO 0) & '0';

      end if;  end if;
    end process;

Code on Arduino Zero board


#include <SPI.h>
word result;
unsigned int HighByte = 0;
unsigned int LowByte = 0;
void setup() {

 SerialUSB.begin(115200);

  pinMode(8,OUTPUT);
  digitalWrite(8,HIGH);
  SPI.begin();
  SPI.setClockDivider( 2 );
  SPI.setDataMode( SPI_MODE1);

}

void loop() {

digitalWrite(8,LOW);
 HighByte = SPI.transfer( 0x00);
 LowByte = SPI.transfer( 0x00);
digitalWrite(8,HIGH);

LowByte &= 0b11110000;

//  SerialUSB.print("HighByte = ");
//  SerialUSB.println(HighByte,BIN);
//  SerialUSB.print("LowByte  = ");
//  SerialUSB.println(LowByte,BIN);

 result = word(HighByte,LowByte);
 result = result>>4;
SerialUSB.println(result, DEC);
//delay(100);

}

von Chris (Guest)


Rate this post
useful
not useful
EDIT- Chip Select is also connected to fpga from Arduino Digital Pin 8.

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.