05-05-2010 06:05 PM
Hello;
I am trying to implement a SPI interface to read ADC values but I couldn't be succesful. I don't want to use picoblaze. If anybody have VHDL code for the ADC - SPI interface, I will be very glad. please help me...
thanks
05-05-2010 11:38 PM
Please mention the manufacturer and part number of your A/D chip?
On some parts the SPI clock idles high and on others it idles low; and the number of SPI clock pulses needed to get the data varies depending on the part.
Jim
05-06-2010 01:05 AM
I want to use spartan3e board's a/d. The board has Linear Tech LTC1407A-1 Dual A/D and Linear Tech LTC6912-1 Dual Amp.
Please help...
05-06-2010 11:27 PM
I wrote some code a while back to read the LTC1407A on the Spartan 3E Starter Kit. I had thought might help you, but I found it today and it still needs work. I just cleaned it up a little and made sure it compiled, and am attaching it to this post just in case it might help you as a starting point. It is in VHDL. See the readme about what's left to do.
As I remember ... the problem I ran into is that the LTC6912 amplifier powers up in the OFF state. This means that you will just read zero when reading the A/D. So you need a second SPI interface to configure the amplifier and set the gain before using the A/D.
Basically the approach to any SPI interface is to study the data sheet for the device, see how many clocks and what timing it needs, and write some code to produce it. The LTC1407A is a dual part and needs 36 SPI clocks to get the data out of it for both channels. I think you have the option of letting the clock run continuously, or just running it when you clock the data out.
Besides the data sheets for the devices, there is also some info in the user manual for the Starter Kit that explains the A/D converter and the amplifier.
Jim
05-09-2010 10:22 AM
hi i am doing the same task while i am to take data from ADC bt i am using microblaze processor for this purpose...
the same kit and the same ADC number u mentioned...
i am also using EDK 10.1 with SPI interface i can connect it to microblaze processor..
i suggest u to find out the SPI interface from the ip catelogue instead of writing VHDL code as its an easy way to implement it
thanks
08-27-2010 12:12 PM
hi kajulkumar
You use both the amplifier and the ADC??
i am trying to use also XPS SPI core and connect both amplifier and the ADC, but i have some doubts
- Can i use one XPS SPI core for ADC and amplifier?? or have to use one XPS SPI for each one??
- the amplifier has a chip enable signal but the ADC only has SCK and MISO signals, or the AD_CONV signal is considered has chip enable??
thanks for your answers
regards
08-30-2010 01:13 PM
hi.,
anyone that can help me please
08-30-2010 02:08 PM
The LTC ADC does not have a classic SPI interface, but you should have little trouble adapting a low-level SPI core to control the LTC device. You are correct that the CONV pin performs a function similar to the SELn signal of a classic SPI device, but some additional coordinated SPI clock control is required to convey 'start convert', 'nap', and 'sleep' commands.
Jim Brady's code is pretty small, have you looked at it for a starting point?
Coding up a higher-level state machine to control the low-level SPI controller, instead of using a PicoBlaze, should be pretty straightforward.
Driving the CONV pin HIGH while communicating with the amplifier will cause the ADC to stop converting, and this may not be what you want to happen. For this reason, a dedicated SPI_CLK and SPI_MOSI for the ADC may be prudent. If you are communicating with the SPI-connected amplifier while performing conversions, you should choose two separate SPI interfaces. If you don't communicate with the amplifier while banging on the ADC, using a single SPI interface should not be a problem.
- Bob Elkind
08-31-2010 08:44 AM
thanks for your response, i will try the VHDL code that you suggest.
I though i can use XPS_SPI core because kajulkumar posted that he made it with microblaze.
Another question, so XPS_DeltaSigma core when is used??, in what kind of "hardware"??
thanks again
09-21-2010 02:46 AM
First ,you should make sure you have sent the gain succesfully.Second , you'd better slow down the clk .
It's hard to capture the data from ad throuh spi because the timing is tight.Read the datasheet carefully,ad1407a outputs data at least 8 ns after rising edge of spi clk.you may implement constrains on some signals. good luck.
09-21-2010 03:44 AM
@pumaju1808 wrote:
Another question, so XPS_DeltaSigma core when is used??, in what kind of "hardware"??
This doc may be helpful. Post again if you don't find the answer inside.
- Bob
09-21-2010 10:44 AM
@zc20060102 wrote:
First ,you should make sure you have sent the gain succesfully.Second , you'd better slow down the clk .
It's hard to capture the data from ad throuh spi because the timing is tight.Read the datasheet carefully,ad1407a outputs data at least 8 ns after rising edge of spi clk.you may implement constrains on some signals. good luck.
Dunno what you're on about, but the usual thing one does with SPI or SPI-like interfaces is to realize that the device will output data on the falling edge of the clock and you capture it in on the rising edge of the clock. With typical SPI speeds you have plenty of set-up time here. If your FPGA has a much higher speed clock from which the SPI clock is derived, you can (and probably should) use a simple rising-edge detector to shift in each bit.
02-16-2011 11:36 AM
Not is necesary add 2 ipcores spi, only, configure in the ucf file. Dont forget that ss port are than a array of pins, and you can simply put Net ss<0> Pin=............ Net ss<1> Pin=..............
02-16-2011 11:49 AM - edited 02-16-2011 11:51 AM
@celojan wrote:
Not is necesary add 2 ipcores spi, only, configure in the ucf file. Dont forget that ss port are than a array of pins, and you can simply put Net ss<0> Pin=............ Net ss<1> Pin=..............
Even if this thread hadn't been dormant for 5 months, this entire thread - and especially this latest post, on its own merits - deserves an appropriate followup response.
- Bob Elkind
02-17-2011 08:10 PM
Dear Sir,
I am facing problems with the adc spi interface. I am seeing only 2FFF in my seven segment disply. But that too is blinking. I divided the 50M clock to a 1M clock and i am using that clock. I will post my codes here. Kindly let me know what is the problem in the code that is making it to give output as previosuly mentioned. Also, I do not get what celojan had posted earlier regarding the ucf file.The code I am using is a modifed version of a code I got from the forum. Thanks in advance. I have disabled the other devices like dac_Cs in the toplevel code. So I have commented it here.
!!
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 09:17:56 02/27/2008
-- Design Name:
-- Module Name: ADC_AMP - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ADC_AMP is
Port (
spi_AMP_SHDN : out std_logic;
amp_dout :in std_logic;
ce_amp : in std_logic;
gain : in std_logic_vector(7 downto 0);
clk50 : in STD_LOGIC;
start_conv : in STD_LOGIC;
SPI_MISO : in std_logic; --adc
-- sample: out std_logic;
CONV : out STD_LOGIC; --adc
ADC1 : out std_logic_vector(13 downto 0):= (others => '0');
ADC2 : out std_logic_vector(13 downto 0):= (others => '0');
AMP_CS : out STD_LOGIC;
MOSI : out STD_LOGIC; -- amp
SCK : out STD_LOGIC
);
end ADC_AMP;
architecture Behavioral of ADC_AMP is
type state_type is (IDLE1,IDLE, START,START2,HI,HI_DUMMY,LO,LO_DUMMY,FINE,IDLE_AD, START_AD,HI_AD,LO_AD,FINE_AD);
signal state : state_type;
signal counter : std_logic_vector (5 downto 0);
signal sample : std_logic;
-- signal ADC2 : std_logic_vector (13 downto 0);
signal bit_count: std_logic_vector (4 downto 0);
signal gain_temp: std_logic_vector (7 downto 0);
begin
-- strataflash_oe <= '1';
-- strataflash_we <= '1';
-- strataflash_ce <= '1';
-- platformflash_oe <= '0';
--DAC_CS <= '1';
--SPI_SS_B <= '0';
process(clk50)
begin
if clk50'event and clk50 ='1' then
case state is
when IDLE1 => if ce_amp = '1' then
state <= IDLE;
else
state <= IDLE1;
spi_AMP_SHDN <= '1';
AMP_CS <= '1';
end if;
when IDLE =>
spi_AMP_SHDN <= '0';
SCK <= '0';
AMP_CS <= '1';
MOSI <='0';
counter <= "000000";-- 0;
state <= START;
when START =>
state <= LO_DUMMY;
bit_count <= "00000"; --:=0;
AMP_CS <= '0';
gain_temp <= gain;
when START2 =>
state <= HI;
MOSI <= gain_temp(7);
when HI =>
if counter = "000010" then--2 then
state <= HI_DUMMY;
else
SCK <= '1';
counter <= counter +1;
state <= HI;
end if;
when HI_DUMMY =>
bit_count <= bit_count + 1; --:= bit_count + 1;
state <= LO;
counter <= "000000";--0;
SCK <= '1';
gain_temp(7 downto 1) <= gain_temp(6 downto 0);
-- mosi <= amp_dout;
when LO =>
if bit_count = "01000" then --8 then
state <= FINE;
elsif counter = "000010" then --2 then
MOSI <= gain_temp(7);
state <= LO_DUMMY;
else
SCK <= '0';
counter <= counter +1;
state <= LO;
end if;
when LO_DUMMY =>
counter <="000000";
SCK <= '0';
state <= HI;
when FINE =>
AMP_CS <='1';
SCK <= '0';
MOSI <= '0';
state <= IDLE_AD;
when IDLE_AD =>
AMP_CS <= '1';
SCK <= '0';
CONV <= '0';
sample <='0';
if CE_AMP = '0' then
state <= IDLE1;
elsif start_conv = '1' then
state <= START_AD;
else
state <= IDLE_AD;
end if;
when START_AD =>
SCK <= '0';
CONV <= '1';
counter <= "000000";--0;
sample <='0';
state <= HI_AD;
when HI_AD =>
SCK <= '1';
CONV <= '0';
counter <= counter +1;
sample <='0';
state <= LO_AD;
when LO_AD =>
SCK <= '0';
if counter = "010100" then
ADC1(13) <= SPI_MISO;
elsif counter = "010101" then
ADC1(12) <= SPI_MISO;
elsif counter = "010110" then
ADC1(11) <= SPI_MISO;
elsif counter = "010111" then
ADC1(10) <= SPI_MISO;
elsif counter = "011000" then
ADC1(9) <= SPI_MISO;
elsif counter = "011001" then
ADC1(8) <= SPI_MISO;
elsif counter = "011010" then
ADC1(7) <= SPI_MISO;
elsif counter = "011011" then
ADC1(6) <= SPI_MISO;
elsif counter = "011100" then
ADC1(5) <= SPI_MISO;
elsif counter = "011101" then
ADC1(4) <= SPI_MISO;
elsif counter = "011110" then
ADC1(3) <= SPI_MISO;
elsif counter = "011111" then
ADC1(2) <= SPI_MISO;
elsif counter = "100000" then
ADC1(1) <= SPI_MISO;
elsif counter = "100001" then
ADC1(0) <= SPI_MISO;
else
sample <='0';
end if;
if counter = "100010" then
state <= FINE_AD;
else
state <= HI_AD;
end if;
when FINE_AD =>
state <= IDLE_AD;
counter <= "000000";
SCK <= '0';
CONV <= '0';
sample <= '1';
when others =>
SCK <= '0';
CONV <= '0';
-- AMP_CS <= '1';
-- MOSI <='0';
state <= IDLE_AD;
end case;
end if;
end process;
end Behavioral;
03-01-2011 09:30 AM
03-15-2011 05:38 AM
I don't get a part of your vhdl-code, you're not initialising the gain-parameter. Shouldn't you be sending temp_gain to the gain-parameter in the end of the preamp part?
greetings
03-20-2011 04:34 AM
Thanks a lot for sharing the verilog code.......its very easy to understand and gives a good idea on how the sampling will be done.
i wanted to know did you tested it on the kit yet?.
07-07-2012 02:43 PM
please someone help me with some project using spi spartan 3e card 1600???
07-07-2012 06:55 PM
@latinotaty wrote:
please someone help me with some project using spi spartan 3e card 1600???
It might be an interesting project to see what happens when you put the board into the microwave over and set the oven on high for a few minutes.
02-21-2013 07:53 PM
you can refer the user guide of spartan 3an and i am also doing same thing ,if you found the information about spi in spartan3an please mail me
02-22-2013 10:52 AM
@rabil.310@gmail.com wrote:
,if you found the information about spi in spartan3an please mail me
SPI in an FPGA is little more than a shift register.