UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Observer tryhard
Observer
6,601 Views
Registered: ‎02-21-2011

Help ADC SPI

Hi,

I have gone through the forum regarding the spartan 3e adc programming but I have not found any soluation to my problem yet. I am using a spartgan 3e xc3s500e fg320 development board with ltc1407-a adc and ltc6912 prog pre amplifier.

I am trying to take help of the data sheet and make the code for the adc along with the amp. I created a testbench to see if the timing is correct and it seems ok. But the output, when I display on the seven segment LEDs is alwasys high i.e.F's. I checked the MOSI signal with the oscilloscope and it seems.

I have disbled the other devices which share the interface as per the datasheet. Still the problem persists.I will provide the code below so that some one can go through and give me a good reply. Im really in need of ideas  at this stage. So please help.

 

--------------------------------------------------

--------------------------------
-- 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;

Tags (3)
0 Kudos
5 Replies
Historian
Historian
6,578 Views
Registered: ‎02-25-2008

Re: Help ADC SPI

I'm too lazy/busy/tired/disinterested to actually help you with your problem, but I noticed that your state:

 

when LO_AD =>

 

is ugly.

 

Consider implementing a simple shift register and not decoding the count value and stuffing the incoming bits into the proper place in the ADC1 vector. Your code, with the priority encoder and all, synthesizes to something huge and slow.

----------------------------Yes, I do this for a living.
0 Kudos
Teacher eteam00
Teacher
6,576 Views
Registered: ‎07-21-2009

Re: Help ADC SPI

I'm too lazy/busy/tired/disinterested to actually help you with your problem, but I noticed that your state:

when LO_AD =>

is ugly.

Apparently this routine was coded in 2008.  I guess back in 2008 the only code available was ugly code ... and code comments were quite expensive as well.

 

Basic principle for newbie designers who think they can string together chunks of code which have been grabbed, and piece together a working design:  If you grab someone else's code instead of writing it yourself, you still need to understand the code and its functions well enough to debug it and customise it to your application.

 

- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
0 Kudos
Observer tryhard
Observer
6,491 Views
Registered: ‎02-21-2011

Re: Help ADC SPI

I have tried to modify the above code slightly. I changed the counter to be a variable integer and also modified the state lo_ad. The timing seems correct as specified in the datasheet. But the implementation still is not working. If anyone has any correct codes please let me know.

0 Kudos
Teacher eteam00
Teacher
6,480 Views
Registered: ‎07-21-2009

Re: Help ADC SPI

Tryhard...

 

1.  This code is "dated" sometime in 2008.  Did you folks copy this code in 2008, or did you write this code in 2008?  Where did this code come from?

 

2.  In its "original" form, did this code work?

 

Suggestions:

  • You revert to the last working version of this design
  • Verify that the "working version" of the design still works
  • Make incremental (small and localised) changes and debug the small changes.
  • Keep making incremental changes until your new design requirements are realised.

Does this make sense?

 

The only problem you describe with any detail is that the 7-segment LED display is always "FF".  Is this because the 7-segment interface is broken, or because the data value displayed is always "FF" ?

 

Your code has no comments, and you haven't described your problem with sufficient detail.  Have you ever debugged a design before?  Do you have an oscilloscope at hand?

 

Seriously, even if we pored through your un-commented code and reverse-engineered it, if we could come up with a useful bug it would only be the result of a combination of extraordinary luck and considerable amounts of effort.

 

It is always easier to debug a new design if you started out with working code in a working design, and you then made changes to it.  You can always point to the changes as the likely causes of errors.

 

If this is a totally unknown set of code to you, then perhaps you are better off re-writing the code from scratch, yourself.   By re-writing the code yourself you will understand the code design much better -- and this is very important when you are debugging code.

 

Debugging someone else's code without understanding how it works or what it is trying to do is very very difficult.  This is difficult for you, and it is difficult for us, and this is what you are asking us to do for you.

 

- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
0 Kudos
Historian
Historian
6,449 Views
Registered: ‎02-25-2008

Re: Help ADC SPI

 


@tryhard wrote:

I have tried to modify the above code slightly. I changed the counter to be a variable integer and also modified the state lo_ad. The timing seems correct as specified in the datasheet. But the implementation still is not working. If anyone has any correct codes please let me know.


You copied crappy code that you don't understand, and you want us to debug it. Do you realize that there are some folks out there who just love to post crappy code and snag cheaters and the lazy in their web of crap? You got pwned, dude.

 

----------------------------Yes, I do this for a living.
0 Kudos