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;
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); }
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
Log in with Google account
No account? Register here.