Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
21615 Discussions

Any idea why this SPI code didn't work?

Altera_Forum
Honored Contributor II
1,260 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
492 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