Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
21336 Discussions

Any idea why this SPI code didn't work?

Altera_Forum
Honored Contributor II
1,164 Views

Hi, i am a beginner in designing using VHDL. I need to construct interconnection between ADC(ADS7861 from Texas) and FPGA DE2 board. I have been told to use a SPI --- a serial to parallel SPi interface between ADC and FPGA. I have constructed the VHDL code for master(FPGA) and slave (ADC).  

 

I understand that SPI only consists of 4 wires but my ADC having more than that. Therefore, i used Data_out( for MISO in slave), modeselect_A0 or convst (for MOSI in slave).  

The total cycle needed for conversion is 32cycles but i only obtain the data till 16 cycles as the A0(I use mode 2 which is( M0=0,M1=1,A0=1)==>CHA1). After 16 cycle the A0 =0 so it convert for CHA0,so i stop then.  

I put the CS always to low so that it is always ready to sent data.  

 

 

I hope that someone please help me in this case. Thank you in advanced  

 

master  

LIBRARY ieee;  

use IEEE.std_logic_1164.all;  

use IEEE.std_logic_arith.all;  

use IEEE.std_logic_unsigned.all;  

LIBRARY work;  

 

ENTITY ADC_MASTER IS  

PORT( serial_data_clock : IN STD_LOGIC;  

serial_convst : IN STD_LOGIC;  

serial_modeselect_A0 : IN STD_LOGIC;  

serial_slaveselect : IN STD_LOGIC;  

Data_in : IN STD_LOGIC_vector(15 downto 0)  

); 

END ENTITY;  

 

 

ARCHITECTURE main OF ADC_MASTER IS  

shared variable data_register : BIT_VECTOR(15 downto 0);  

shared variable data_counter : integer range 0 to 15 := 0;  

 

 

BEGIN  

recv_data: PROCESS(serial_data_clock,serial_slaveselect)  

BEGIN  

if serial_slaveselect ='1' then  

data_counter := 0;  

 

else(serial_data_clock'event = '1' and serial_data_clock ='1') then  

if serial_convst = '1' and serial_modeselect_A0 = '1' then  

if data_counter < 15 then  

data_register(0) := to_stdlogicvector(Data_in);  

data_register := data_register sll 1;  

data_counter := data_counter +1;  

else data_register(0) := to_bit(Data_in);  

data_register := to_bit(data_register);  

end if;  

end if;  

end if;  

END PROCESS;  

 

PROCESS(data_register)  

BEGIN  

if serial_convst = '0' then  

data_counter := 0;  

data_register <=(other=>'0');  

elsif rising_edge (data_register) and data_counter < 15 then  

data_counter <= data_counter + 1;  

if (counter>"000000000000010") then  

data_register(15 downto 1) <= data_register(14 downto 0);  

data_register(0) <= Data_in;  

end if;  

end if;  

END PROCESS;  

 

END main;  

 

slave  

LIBRARY ieee;  

use IEEE.std_logic_1164.all;  

use IEEE.std_logic_arith.all;  

use IEEE.std_logic_unsigned.all;  

LIBRARY work;  

 

ENTITY ADC_SLAVE_SPI IS  

PORT( serial_data_clock : IN STD_LOGIC;  

serial_convst : IN STD_LOGIC;  

serial_modeselect_A0 : IN STD_LOGIC;  

serial_slaveselect : IN STD_LOGIC;  

Data_out : OUT STD_LOGIC_vector(15 downto 0)  

); 

END ENTITY;  

 

ARCHITECTURE main OF ADC_SLAVE_SPI IS  

shared variable data_register: STD_LOGIC_VECTOR(15 downto 0);  

shared variable data_counter : integer range 0 to 15 := 0;  

 

BEGIN  

 

PROCESS(serial_slaveselect)  

BEGIN  

if serial_convst = '0' then  

Dataout<="0000000000000000";  

elsif serial_modeselect_A0='1' and rising_edge(serial_slaveselect) then  

Data_out<=data_register;  

end if;  

END PROCESS;  

 

 

PROCESS(serial_slaveselect,serial_data_clock)  

BEGIN  

if serial_slaveselect='0' then  

if rising_edge(serial_data_clock) then  

data_register<=data_register(15 downto 0);  

end if;  

end if;  

END PROCESS;  

END main;
0 Kudos
1 Reply
Altera_Forum
Honored Contributor II
396 Views

I stopped reading the post at the port definition, that shows only inputs. Can't work as a SPI master interface.

0 Kudos
Reply