Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

ADC on SPARTAN 3E Starter Board

Status
Not open for further replies.

nickb1

Newbie level 4
Joined
May 19, 2011
Messages
6
Helped
2
Reputation
4
Reaction score
1
Trophy points
1,283
Activity points
1,328
Hello,

I am trying to interface with the ADC on my Spartan 3E starter board.
First I made a 1.5Mhz clock so the sample rate will be above 40kHz (i want to sample audio).
Then I made a state machine that, in the first state (set_amp), sets the preamp with a gain of -1.
Te next state is the idle state which sets de AD_CONV high for two clock periods so the ADC can take a sample.
The last state (read_adc) reads out the two channels in 34 cycles. I use a seperate state machine to turn the serial clock of during the AD_CONV time.

But it doesnt seem to work, the output (as I can see on the leds) is switching very fast between 0 and the maximum input, also when I connect the input to the 1.8V supply nothing happens.

Hope someone can point me in the right direction.
Many thanks!

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity AD is
    Port ( SPI_SCK : out  STD_LOGIC;
           AD_CONV : out  STD_LOGIC;
           SPI_MISO : in  STD_LOGIC;
           SPI_MOSI : out  STD_LOGIC;
           AMP_CS : out  STD_LOGIC;
           AMP_SHDN : out  STD_LOGIC;
           AMP_DOUT : in  STD_LOGIC;
			  mclk: in STD_LOGIC;
			  amplitude1: out STD_LOGIC_VECTOR(13 downto 0);
			  amplitude2: out STD_LOGIC_VECTOR(13 downto 0);
			  LED : out std_logic_vector(7 downto 0));
end AD;
architecture Behavioral of AD is
type state_type is (idle, set_amp, read_adc);
signal state : state_type := set_amp;
type state_type_clock is (clock_on, clock_off);
signal state_clock : state_type_clock := clock_off;
signal cnt : integer range 0 to 40 := 0;
signal clk_sample : STD_LOGIC;
signal gain_set : STD_LOGIC := '0';
signal amplitude1_buffer : STD_LOGIC_VECTOR(13 downto 0);
signal amplitude2_buffer : STD_LOGIC_VECTOR(13 downto 0);
signal gain1 : STD_LOGIC_VECTOR(3 downto 0) := "0001";
signal gain2 : STD_LOGIC_VECTOR(3 downto 0) := "0001";
begin

-- 1.5MHz clock
		clock_divider : process (mclk)
		variable counter : integer range 0 to 33000001;
		begin
		  if(rising_edge(mclk)) then
			  if counter = 33 then
					clk_sample <= not clk_sample;
					counter := 0;
				else
				counter := counter + 1;
			  end if;
		  end if;	  	  
		end process;
		
		sclk_clock : process(mclk)
		begin
			if(rising_edge(mclk)) then
			case state_clock is
				when clock_on =>
				SPI_SCK <= clk_sample;
				when clock_off =>
				SPI_SCK <= '0';
				end case;
			
				 LED(0) <= amplitude1_buffer(5);
				 LED(1) <= amplitude1_buffer(6);
				 LED(2) <= amplitude1_buffer(7);
				 LED(3) <= amplitude1_buffer(8);
				 LED(4) <= amplitude1_buffer(9);
				 LED(5) <= amplitude1_buffer(10);
				 LED(6) <= amplitude1_buffer(11);
				 LED(7) <= amplitude1_buffer(12);
		 
			end if;
		end process;
		
	main : process (clk_sample)
	begin
	if(rising_edge(clk_sample)) then
	-- Set gain at -1
	case state is
	when set_amp =>
	AMP_CS <= '0';
	AMP_SHDN <= '0';
		if (cnt < 4) then
		SPI_MOSI <= gain2(3 - cnt);
		cnt <= cnt + 1;
		state <= set_amp;
		state_clock <= clock_on;
		elsif (cnt > 3 and cnt < 8) then
		SPI_MOSI <= gain1(7 - cnt);
		cnt <= cnt + 1;
		state <= set_amp;
		elsif (cnt = 8) then
		cnt <= 0;
		AMP_CS <= '1';
		state <= idle;
		end if;
		
	when idle =>
	-- 13ns delay
		if (cnt < 2) then
		AD_CONV <= '1';
		cnt <= cnt + 1;
		state <= idle;
		elsif (cnt = 2) then
		AD_CONV <= '0';
		cnt <= 0;
		state <= read_adc;
		end if;
	
	when read_adc =>
	state_clock <= clock_on;
		if (cnt < 2) then
		cnt <= cnt + 1;
		state <= read_adc;
		elsif (cnt > 1 and cnt < 16) then
		amplitude1_buffer(15 - cnt) <= SPI_MISO;
		cnt <= cnt + 1;
		state <= read_adc;
		elsif (cnt > 15 and cnt < 18) then
		cnt <= cnt + 1;
		state <= read_adc;
		elsif (cnt > 17 and cnt < 32) then
		amplitude2_buffer(31 - cnt) <= SPI_MISO;
		cnt <= cnt + 1;
		state <= read_adc;
		elsif (cnt > 31 and cnt < 34) then
		cnt <= cnt + 1;
		state <= read_adc;
		elsif (cnt = 34) then
		cnt <= 0;
		amplitude1<=amplitude1_buffer;
		amplitude2<=amplitude2_buffer;
		state_clock <= clock_off;
		state <= idle;
		end if;
		end case;
		end if;
	end process;		
end Behavioral;
 
Last edited:

Checkout these excellent tutorials using the Spartan 3E Starter and Nexys 2 Boards. The are free and include the project files and PDFs; tutorial 15 covers ADC and DAC.

SPARTAN 3E TUTORIALS
 

    V

    Points: 2
    Helpful Answer Positive Rating
Thanks for the reply
I already found that tutorial, i based my code on it.
But I think their board has another ADC without the extra preamp.
 

Are you using the Digilent Spartan 3E Starter 500K Board? If so have you tried the tutorial code without modifying it?

If not what is the model of your board?

I seem to remember running the tutorial a couple of years ago without a problem.
 

Its up and running now!
I used the process for making the sample clock from the tutorial and it started to work :)
Many thanks!
 

Hi\. i am working on my thesis and i have to use adc on spartan 3an which is the same with spartan 3e.
could u please explain me why that :
" if(rising_edge(mclk)) then
case state_clock is
when clock_on =>
SPI_SCK <= clk_sample;
when clock_off =>
SPI_SCK <= '0';
end case;

LED(0) <= amplitude1_buffer(5);
LED(1) <= amplitude1_buffer(6);
LED(2) <= amplitude1_buffer(7);
LED(3) <= amplitude1_buffer(8);
LED(4) <= amplitude1_buffer(9);
LED(5) <= amplitude1_buffer(10);
LED(6) <= amplitude1_buffer(11);
LED(7) <= amplitude1_buffer(12);

end if;
"
What are u doing with SPI_SCK?
isn 't the same clk_sample?

Thanks in advance
 

It's for turning the serial clock on and of. The datasheet says that the clock needs to be turned of when the ADC takes a sample when AD_CONV is high.

---------- Post added at 22:38 ---------- Previous post was at 22:36 ----------

Here is the working code
Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity AD is
    Port ( SPI_SCK : out  STD_LOGIC;
           AD_CONV : out  STD_LOGIC;
           SPI_MISO : in  STD_LOGIC;
           SPI_MOSI : out  STD_LOGIC;
           AMP_CS : out  STD_LOGIC;
           AMP_SHDN : out  STD_LOGIC;
           AMP_DOUT : in  STD_LOGIC;
			  mclk: in STD_LOGIC;
			  amplitude1: out STD_LOGIC_VECTOR(13 downto 0);
			  amplitude2: out STD_LOGIC_VECTOR(13 downto 0);
			  LED : out std_logic_vector(7 downto 0);
			  trigger : out std_logic);
end AD;
architecture Behavioral of AD is
type state_type is (idle, set_amp, read_adc);
signal state : state_type := set_amp;
type state_type_clock is (clock_on, clock_off);
signal state_clock : state_type_clock := clock_off;
signal cnt : integer range 0 to 40 := 0;
signal clk_sample : STD_LOGIC := '0';
signal gain_set : STD_LOGIC := '0';
signal amplitude1_buffer : STD_LOGIC_VECTOR(13 downto 0);
signal amplitude1_buffer_n : STD_LOGIC_VECTOR(13 downto 0);
signal amplitude2_buffer : STD_LOGIC_VECTOR(13 downto 0);
signal gain1 : STD_LOGIC_VECTOR(3 downto 0) := "0001";
signal gain2 : STD_LOGIC_VECTOR(3 downto 0) := "0001";
signal risingedge : std_logic := '1';
signal counter : integer range 0 to 34;
begin

-- 1.5MHz clock
		clock_divider : process (mclk)
		begin
		  if(rising_edge(mclk)) then
			if(counter = 33) then
				risingedge <= risingedge xor '1';
				clk_sample <= clk_sample xor '1';
				counter <= 0;
			else
				counter <= counter + 1;
			end if;
		end if; 
		end process;
		
		sclk_clock : process(mclk)
		begin
			if(rising_edge(mclk)) then
			case state_clock is
				when clock_on =>
				SPI_SCK <= clk_sample;
				when clock_off =>
				SPI_SCK <= '0';
				end case;
			
				 
		 
			end if;
		end process;
		
	main : process (mclk)
	begin
	if(rising_edge(mclk)) then
		if(counter = 33 and risingedge = '1') then
	-- Set gain at -1
	case state is
	when set_amp =>
	AMP_CS <= '0';
	AMP_SHDN <= '0';
		if (cnt < 4) then
		SPI_MOSI <= gain2(3 - cnt);
		cnt <= cnt + 1;
		state <= set_amp;
		state_clock <= clock_on;
		elsif (cnt > 3 and cnt < 8) then
		SPI_MOSI <= gain1(7 - cnt);
		cnt <= cnt + 1;
		state <= set_amp;
		elsif (cnt = 8) then
		cnt <= 0;
		AMP_CS <= '1';
		state <= idle;
		end if;
		
	when idle =>
	-- 13ns delay
		if (cnt < 2) then
		AD_CONV <= '1';
		cnt <= cnt + 1;
		state <= idle;
		elsif (cnt = 2) then
		AD_CONV <= '0';
		cnt <= 0;
		state <= read_adc;
		trigger <= '0';
		end if;
	
	when read_adc =>
		if (cnt < 2) then
		cnt <= cnt + 1;
		state <= read_adc;
		state_clock <= clock_on;
		elsif (cnt > 1 and cnt < 16) then
		amplitude1_buffer(15 - cnt) <= SPI_MISO;
		cnt <= cnt + 1;
		state <= read_adc;
		elsif (cnt > 15 and cnt < 18) then
		cnt <= cnt + 1;
		state <= read_adc;
		elsif (cnt > 17 and cnt < 32) then
		amplitude2_buffer(31 - cnt) <= SPI_MISO;
		cnt <= cnt + 1;
		state <= read_adc;
		elsif (cnt > 31 and cnt < 34) then
		cnt <= cnt + 1;
		state <= read_adc;
		elsif (cnt = 34) then
		cnt <= 0;
		
		if(amplitude1_buffer(12) = '1') then
		amplitude1_buffer_n(13) <= amplitude1_buffer(13);
		amplitude1_buffer_n(12) <= amplitude1_buffer(12);
		amplitude1_buffer_n(11) <= not(amplitude1_buffer(11));
		amplitude1_buffer_n(10) <= not(amplitude1_buffer(10));
		amplitude1_buffer_n(9) <= not(amplitude1_buffer(9));
		amplitude1_buffer_n(8) <= not(amplitude1_buffer(8));
		amplitude1_buffer_n(7) <= not(amplitude1_buffer(7));
		amplitude1_buffer_n(6) <= not(amplitude1_buffer(6));
		amplitude1_buffer_n(5) <= not(amplitude1_buffer(5));
		amplitude1_buffer_n(4) <= not(amplitude1_buffer(4));
		amplitude1_buffer_n(3) <= not(amplitude1_buffer(3));
		amplitude1_buffer_n(2) <= not(amplitude1_buffer(2));
		amplitude1_buffer_n(1) <= not(amplitude1_buffer(1));
		amplitude1_buffer_n(0) <= not(amplitude1_buffer(0));
		amplitude1<=amplitude1_buffer_n;
		LED(0) <= amplitude1_buffer(4);
				 LED(1) <= amplitude1_buffer_n(5);
				 LED(2) <= amplitude1_buffer_n(6);
				 LED(3) <= amplitude1_buffer_n(7);
				 LED(4) <= amplitude1_buffer_n(8);
				 LED(5) <= amplitude1_buffer_n(9);
				 LED(6) <= amplitude1_buffer_n(10);
				 LED(7) <= amplitude1_buffer_n(11);
		else
		amplitude1<=amplitude1_buffer;
		amplitude2<=amplitude2_buffer;
		LED(0) <= amplitude1_buffer(4);
				 LED(1) <= amplitude1_buffer(5);
				 LED(2) <= amplitude1_buffer(6);
				 LED(3) <= amplitude1_buffer(7);
				 LED(4) <= amplitude1_buffer(8);
				 LED(5) <= amplitude1_buffer(9);
				 LED(6) <= amplitude1_buffer(10);
				 LED(7) <= amplitude1_buffer(11);
		end if;
		state_clock <= clock_off;
		state <= idle;
		trigger <= '1';
		end if;
		end case;
		end if;
		end if;
	end process;		
end Behavioral;
 
  • Like
Reactions: johannesBTH

    V

    Points: 2
    Helpful Answer Positive Rating

    johannesBTH

    Points: 2
    Helpful Answer Positive Rating
Thank u very much nickb1! what is "amplitude1_buffer(12) = '1'" for? Why do u check that bit?
Something else . how do u check the other bits to see if the value is right? sorry to disturb and thanks...
 

Sorry to disturb again...But i can't make it work.Your code is the greatest i have found and i have understood it. i tried to set the gain to amplifier and see it on leds without using the adc but leds go high.Don't i have to disable the other spi devices? Which spi flash prom programming option have u used?Direct or indirect?
thanks
 

You indeed have to disable all the other SPI devices. These are explained in the manual. But if you want I can send you my UCF file.
 
Last edited:

i use spartan 3an and its manual is ug334 .There are a lot of things missing. If u could send me ucf , it would be really helpful . thanks for replying .
 

Attached is the UCF from the installation CDROM.

Hope it helps with your endeavors.
 

Attachments

  • s3anstarter.zip
    4.5 KB · Views: 130

Thanks for your past reply . i've also been using the same ucf, which is general for all the devices. I just wanted to check which devices to disable, because they are not mentioned clearly in the manual. Also, if possible, send me the ucf you are using, if it is different from the one you have just uploaded. thanks
 

But this code has no error, the output (as I can see on the leds) can not see, also when I connect the input from the board jp9 pin, give 3.3 volt supply nothing happens.
please help me how i see the o/p in led..........its very urgent................
 

You indeed have to disable all the other SPI devices. These are explained in the manual. But if you want I can send you my UCF file.

sir, can you send me that UCF file for ADC. I am not able understand how to use ADC and DAC in spartan 3e kit because I am very new to spartan 3e kit. Can you please explain how to use ADC and DAC using spartan 3e kit?

- - - Updated - - -

You indeed have to disable all the other SPI devices. These are explained in the manual. But if you want I can send you my UCF file.

sir, can you send me that UCF file for ADC. I am not able understand how to use ADC and DAC in spartan 3e kit because I am very new to spartan 3e kit. Can you please explain how to use ADC and DAC using spartan 3e kit?
 

Hi,
thank you very much for a useful information.
I am a student and doing school project of FPGA based DC-to-DC convertor, where the use of ADC is required.
I am new in vhdl, could you explain why do we need to use led's ?
and why we need to an amplitude buffers in code ?
 

hi thank you for your great code
could you please send me the ucf file of SPARTAN 3E Starter Board and DAC code just if you have :)
 

hi nickb1,u have a very gr8 code..but when i give 1.5 v supply to the adc at channel ai.e VINA the out is not as expected.Expected value as per data sheet is 3D7 but i am getting 8A. is it because as per datasheet we should get data after minimu 8 ns delay from rising edge of 3rd SPI_SCK cycle...pls help if you knw abt it...
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top