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.