Jump to content
  • 0

Pmod Ad5


1116345

Question

Hello

I am using the Pmod AD5 to convert my analog signals from light sensor to be able to feed it into the fpga. Any one has an idea of how can i proceed? I tried by testing the AD5 by inputting an analog input but i cannot get to the digital output...any help would be highly appreciated..Thanks

Link to comment
Share on other sites

Recommended Posts

Hi @roman3017,

I have requested of our content team to add this IP; it will be a little while before it is there though since we will want to make sure it is formatted like all of our other IPs and make sure it gets verified by a second set of eyes before pushing it onto that platform.

Thanks,
JColvin

Link to comment
Share on other sites

Hi,

 

There are a few things that could potentially be the source of your problem, but I'm not sure quite yet what they might be. So, I have three questions.

 

Did you change/write to any of the registers of the Analog Devices ADC that is on the Pmod?

Did you use any external reference voltage?

Is it just a single analog signal that you are measuring?

 

Thanks,

JColvin

Link to comment
Share on other sites

Hi i1116345,

 

From a quick read of the datasheet, it seems that you need to send a few register writes to switch ADC into continuous sample mode, and then you can just clock the data in every time DRDY is asserted.

 

You can take either the high road (with lots of levels of abstractions in your design) or the often-muddy low road (where you do all the work on paper, and then just make a design that achieves the desired result).

 

The high road most likely involves a soft CPU, with a SPI peripheral interface, and software that talks SPI that will configure the device and retrieve the samples.

 

The low road involves a long shift register to send out the SPI signals needed to configure the eight registers in the device, and then a simple FSM that clocks in the samples when they are available, storing the values into a flip-flops connected to the LEDs. So to me the low road looks to be something like two or three 128-bit shift registers (as it has to program up to eight 8-bit registers), a counter to act as a clock divider, and a small FSM that clocks in the samples . 

 

I know which road I would take - but that is just me.

 

Mike

Link to comment
Share on other sites

To Mr JColvin,

I don't know how to write to the registers on the Pmod :/

I am just using a supply to feed my adc ( 5V) and to act as an input ( 1 V) and i wish to see the digital output of the input ?( I dnt know if am on the right track)

I am using an oscilloscope to view the output considering the fact that the output is a serial one. For the time being its just a single analog input but for the project i require 6 analog inputs to be converted to digital so that i can use the fpga to compare and drive my motors.

I am a little confused about the SYNC and the JP1 ( I think i am wronly connecting them).

Thanks.

 

Link to comment
Share on other sites

Hi 1116345,

 

So here is a quick hack at it, without any reference to the datasheet.

 

First off you need an idea of what the interface design for the AD5 will look like - here's my stab at it:

-    COMPONENT pmod_ad5
    PORT(
         clk50MHz  : IN  std_logic;
         pmod_sclk : OUT  std_logic;
         pmod_mosi : OUT  std_logic;
         pmod_miso : IN  std_logic;
         pmod_cs   : OUT  std_logic;
         samples   : OUT  std_logic_vector(23 downto 0)
        );
    END COMPONENT;

The 50 MHz system clock, the PMOD signals, and something to hold the sample.

 

And now here's the first file of VHDL - it does nothing but divide the system clock from 50 MHz down to 1 MHz, for use as the SPI clock:

 

----------------------------------------------------------------------------------
-- PMOD_AD5 - an attempt at configuring the Digilent PMOD_AD5 over SPI
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
 
entity pmod_ad5 is
    Port ( clk50MHz  : in  STD_LOGIC;
           pmod_sclk : out STD_LOGIC := '1';
           pmod_mosi : out STD_LOGIC := '1';
           pmod_miso : in  STD_LOGIC;
           pmod_cs   : out STD_LOGIC := '1';
           samples   : OUT  std_logic_vector(23 downto 0)
);
end pmod_ad5;
 
architecture Behavioral of pmod_ad5 is
   signal counter : unsigned(5 downto 0) := (others => '0');
begin
 
p: process(clk50Mhz)
   begin
      if rising_edge(clk50MHz) then
         -- First off, generate a 1MHz square wave for SCLK;
         -- I haven't checked how fast the SPI interface works, so check this on the datasheet.
         if counter = 49 then
            pmod_sclk <= '1';
            counter <= (others => '0');
         else
           if counter = 24 then
              pmod_sclk <= '0';
           end if;
           counter <= counter + 1;
         end if;
      end if;
   end process;
 
end Behavioral;

 

You will also need to add a constraints file (.UCF file) to attach the external signals to the correct pins. For testing you might want to connect the highest 8 bits of 'samples' to the LEDs.
 
You will also need a test bench to allow you to simulate the design:
 

--------------------------------------------------------------------------------
-- TB_PMOD_AD5 - test bench for my attempt at using the PMODAD5
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
 
ENTITY tb_pmod_ad5 IS
END tb_pmod_ad5;
 
ARCHITECTURE behavior OF tb_pmod_ad5 IS 
    COMPONENT pmod_ad5
    PORT(
         clk50MHz  : IN  std_logic;
         pmod_sclk : OUT  std_logic;
         pmod_mosi : OUT  std_logic;
         pmod_miso : IN  std_logic;
         pmod_cs   : OUT  std_logic;
         samples   : OUT  std_logic_vector(23 downto 0)
        );
    END COMPONENT;
 
   signal clk50MHz : std_logic := '0';
   signal pmod_miso : std_logic := '0';
   signal pmod_sclk : std_logic;
   signal pmod_mosi : std_logic;
   signal pmod_cs   : std_logic;
   signal samples   : std_logic_vector(23 downto 0);
 
   -- Clock period definitions
   constant clk50MHz_period : time := 20 ns;
 
BEGIN
 
uut: pmod_ad5 PORT MAP (
          clk50MHz => clk50MHz,
          pmod_sclk => pmod_sclk,
          pmod_mosi => pmod_mosi,
          pmod_miso => pmod_miso,
          pmod_cs => pmod_cs
        );
 
clk50MHz_process :process
   begin
      clk50MHz <= '0';
      wait for clk50MHz_period/2;
      clk50MHz <= '1';
      wait for clk50MHz_period/2;
   end process;
 
END;

Link to comment
Share on other sites

Great - if you get this far, you should be able to fire up the simulator and get a trace which shows CLK50MHz running at 50Mhz, and PMOD_SCLK running at 1MHz.

 

However, I've run out of space to upload images, so can't show you :-(.

 

So trust me - you now have a 1MHz SCK.

 

Next is to start sending data out. I2S send in MSB first. so source reads best if we send bits from high to low. To do this we need a shift register, and to output the highest bit from it at the correct time:

----------------------------------------------------------------------------------
-- PMOD_AD5 - an attempt at configuring the Digilent PMOD_AD5 over SPI
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
 
entity pmod_ad5 is
    Port ( clk50MHz  : in  STD_LOGIC;
           pmod_sclk : out STD_LOGIC := '1';
           pmod_mosi : out STD_LOGIC := '1';
           pmod_miso : in  STD_LOGIC;
           pmod_cs   : out STD_LOGIC := '1';
           samples   : OUT  std_logic_vector(23 downto 0)
);
end pmod_ad5;
 
architecture Behavioral of pmod_ad5 is
   signal counter : unsigned(5 downto 0) := (others => '0');
   signal cs_shift_reg : std_logic_vector(63 downto 0) := x"FF007FFFFFFFFFFF";
   
begin
 
p: process(clk50Mhz)
   begin
      if rising_edge(clk50MHz) then
         -- First off, generate a 1MHz square wave for SCLK;
         -- I haven't checked how fast the SPI interface works, so check this on the datasheet.
         if counter = 49 then
            pmod_sclk <= '1';
            counter <= (others => '0');
         else
           -- change the CS signal when SCLK is high
           if counter = 12 then
              -- Output the highest bit and advance the shift register
              pmod_cs <= cs_shift_reg(cs_shift_reg'high);
              cs_shift_reg <= cs_shift_reg(cs_shift_reg'high-1 downto 0) & '1';
           end if;
           if counter = 24 then
              pmod_sclk <= '0';
           end if;
           counter <= counter + 1;
         end if;
      end if;
   end process;
 
end Behavioral;
 

In simulation  I now get a PMOD_CS that drops when the SCLK signal is high, and stays low for 9us (or 9 clock cycles) due to the data in the cs_shift_reg. Now to the the same to the data line, but this time the data has to change in the middle of the low part of the clock cycle

----------------------------------------------------------------------------------
-- PMOD_AD5 - an attempt at configuring the Digilent PMOD_AD5 over SPI
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
 
entity pmod_ad5 is
    Port ( clk50MHz  : in  STD_LOGIC;
           pmod_sclk : out STD_LOGIC := '1';
           pmod_mosi : out STD_LOGIC := '1';
           pmod_miso : in  STD_LOGIC;
           pmod_cs   : out STD_LOGIC := '1';
           samples   : OUT  std_logic_vector(23 downto 0)
);
end pmod_ad5;
 
architecture Behavioral of pmod_ad5 is
   signal counter : unsigned(5 downto 0) := (others => '0');
   signal cs_shift_reg   : std_logic_vector(63 downto 0) := x"FF00FFFFFFFFFFFF";
   signal mosi_shift_reg : std_logic_vector(63 downto 0) := x"00A5000000000000";
begin
 
p: process(clk50Mhz)
   begin
      if rising_edge(clk50MHz) then
         -- First off, generate a 1MHz square wave for SCLK;
         -- I haven't checked how fast the SPI interface works, so check this on the datasheet.
         if counter = 49 then
            pmod_sclk <= '1';
            counter <= (others => '0');
         else
           -- change the CS signal when SCLK is high
           if counter = 12 then
              -- Output the highest bit and advance the shift register
              pmod_cs <= cs_shift_reg(cs_shift_reg'high);
              cs_shift_reg <= cs_shift_reg(cs_shift_reg'high-1 downto 0) & '1';
           end if;
           if counter = 24 then
              pmod_sclk <= '0';
           end if;
 
           if counter = 37 then
              -- Output the highest bit and advance the shift register
              pmod_mosi <= mosi_shift_reg(mosi_shift_reg_shift_reg'high);
              mosi_shift_reg_shift_reg <= mosi_shift_reg_shift_reg(mosi_shift_reg_shift_reg'high-1 downto 0) & '1';
           end if;
           counter <= counter + 1;
         end if;
      end if;
   end process;
 
end Behavioral;

When you simulate that you should get something that looks like the SPI transfer on page 9 of the datasheet.

 

(I just picked 'A5' as a pleasing bit pattern to send out, so I can see where the transitions are relative to the other signals)

 

Time for me to read some more of the data sheet....

Link to comment
Share on other sites

So here's my first error, readying page 34, SCLK should be high when idle, as this lowers the noise and power. So here are some minor tweaks to get it all looking correct in the simulation

 

----------------------------------------------------------------------------------
-- PMOD_AD5 - an attempt at configuring the Digilent PMOD_AD5 over SPI
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
 
entity pmod_ad5 is
    Port ( clk50MHz  : in  STD_LOGIC;
           pmod_sclk : out STD_LOGIC := '1';
           pmod_mosi : out STD_LOGIC := '1';
           pmod_miso : in  STD_LOGIC;
           pmod_cs   : out STD_LOGIC := '1';
           samples   : OUT  std_logic_vector(23 downto 0)
);
end pmod_ad5;
 
architecture Behavioral of pmod_ad5 is
   signal counter : unsigned(5 downto 0) := (others => '0');
   signal cs_shift_reg   : std_logic_vector(63 downto 0) := x"FF007FFFFFFFFFFF";
   signal mosi_shift_reg : std_logic_vector(63 downto 0) := x"00A5000000000000";
begin
 
p: process(clk50Mhz)
   begin
      if rising_edge(clk50MHz) then
         -- First off, generate a 1MHz square wave for SCLK;
         -- I haven't checked how fast the SPI interface works, so check this on the datasheet.
         if counter = 49 then
            pmod_sclk <= '1';
            counter <= (others => '0');
         else
           -- change the CS signal when SCLK is high
           if counter = 12 then
              -- Output the highest bit and advance the shift register
              pmod_cs <= cs_shift_reg(cs_shift_reg'high-1);
              cs_shift_reg <= cs_shift_reg(cs_shift_reg'high-1 downto 0) & '1';
           end if;
           if counter = 24 then
              pmod_sclk <= cs_shift_reg(cs_shift_reg'high);
           end if;
           if counter = 37 then
              -- Output the highest bit and advance the shift register
              pmod_mosi <= mosi_shift_reg(mosi_shift_reg'high-1);
              mosi_shift_reg <= mosi_shift_reg(mosi_shift_reg'high-1 downto 0) & '1';
           end if;
 
           counter <= counter + 1;
         end if;
      end if;
   end process;
 
end Behavioral;
Link to comment
Share on other sites

Next minor detail - the AD7193 needs to have 40 '1's written to it to trigger a reset, then wait 500us after reset to become active. It needs a bit of a major refactor of the code, into "startup" and the normal function. It also requires simulating now for 700us.

 

As a bonus I've also implemented the first half of the transaction in figure 35.

 

 

----------------------------------------------------------------------------------
-- PMOD_AD5 - an attempt at configuring the Digilent PMOD_AD5 over SPI
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
 
entity pmod_ad5 is
    Port ( clk50MHz  : in  STD_LOGIC;
           pmod_sclk : out STD_LOGIC := '1';
           pmod_mosi : out STD_LOGIC := '1';
           pmod_miso : in  STD_LOGIC;
           pmod_cs   : out STD_LOGIC := '1';
           samples   : OUT  std_logic_vector(23 downto 0)
);
end pmod_ad5;
 
architecture Behavioral of pmod_ad5 is
   signal counter : unsigned(5 downto 0) := (others => '0');
   signal cs_shift_reg   : std_logic_vector(63 downto 0) := x"FF000000007FFFFF";
   signal mosi_shift_reg : std_logic_vector(63 downto 0) := x"0008280060000000";
   signal startup_timer  : unsigned(9 downto 0) := to_unsigned(600,10); -- 500us at 50Mhz;
begin
 
p: process(clk50Mhz)
   begin
      if rising_edge(clk50MHz) then
         if startup_timer = 0 then
            case counter is 
               when to_unsigned(0,6) =>
                  pmod_sclk <= '1';
               when to_unsigned(12,6) => 
                  -- change the CS signal when SCLK is high
                  -- Output the highest bit and advance the shift register
                  pmod_cs <= cs_shift_reg(cs_shift_reg'high-1);
                  cs_shift_reg <= cs_shift_reg(cs_shift_reg'high-1 downto 0) & '1';
               when to_unsigned(24,6) =>
                  pmod_sclk <= cs_shift_reg(cs_shift_reg'high);
               when to_unsigned(37,6) =>
                  -- Output the highest bit and advance the shift register
                  pmod_mosi <= mosi_shift_reg(mosi_shift_reg'high-1);
                  mosi_shift_reg <= mosi_shift_reg(mosi_shift_reg'high-1 downto 0) & '1';
               when others =>
                  NULL;
            end case;
         else
            -- Just during startup, output > 40 '1' bits to reset the ADC, then wait for at least 500us.
            pmod_mosi <= '1';
            case counter is 
               when to_unsigned(0,6) =>
                  pmod_sclk <= '1';
               when to_unsigned(12,6) => 
                  if startup_timer >= 512 then
                     pmod_cs <= '0';
                  end if;
               when to_unsigned(24,6) =>
                  if startup_timer >= 512 then
                     pmod_sclk <= '0';
                  end if;
               when to_unsigned(49,6) =>
                  startup_timer <= startup_timer - 1;
               when others =>
                  NULL;
            end case;
         end if;
         
         -- Generate the 1MHz for the SPI interface
         -- I haven't checked how fast the SPI interface works, so check this on the datasheet.
         if counter = 49 then
             counter <= (others => '0');
         else   
            counter <= counter + 1;
         end if;      
            
 
      end if;
   end process;
 
end Behavioral;
Link to comment
Share on other sites

So, almost there. 

 

Now we need the second half of the transaction.

 

When cs_shift_reg is all ones, we know we have sent the request for data to the DAC. MOSI should be high until the data is ready. When MOSI drops, we need to send a "read" command (0x58) to the ADC, and then capture the output...

 

Humm... first things first - make it flip between requesting a conversion, and then request data: 

 

----------------------------------------------------------------------------------
-- PMOD_AD5 - an attempt at configuring the Digilent PMOD_AD5 over SPI
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
 
entity pmod_ad5 is
    Port ( clk50MHz  : in  STD_LOGIC;
           pmod_sclk : out STD_LOGIC := '1';
           pmod_mosi : out STD_LOGIC := '1';
           pmod_miso : in  STD_LOGIC;
           pmod_cs   : out STD_LOGIC := '1';
           samples   : OUT  std_logic_vector(23 downto 0)
);
end pmod_ad5;
 
architecture Behavioral of pmod_ad5 is
   signal counter : unsigned(5 downto 0) := (others => '0');
   signal cs_shift_reg   : std_logic_vector(63 downto 0) := (others => '1'); -- You can put init commands here if you want
   signal mosi_shift_reg : std_logic_vector(63 downto 0) := (others => '1'); -- You can put init commands here if you want
   signal startup_timer  : unsigned(9 downto 0) := to_unsigned(600,10); -- 500us at 50Mhz;
   signal sent_command    : std_logic := '0';
begin
 
p: process(clk50Mhz)
   begin
      if rising_edge(clk50MHz) then
         if startup_timer = 0 then
            case counter is 
               when to_unsigned(0,6) =>
                  pmod_sclk <= '1';
               when to_unsigned(12,6) => 
                  -- change the CS signal when SCLK is high
                  -- Output the highest bit and advance the shift register
                  pmod_cs <= cs_shift_reg(cs_shift_reg'high-1);
                  cs_shift_reg <= cs_shift_reg(cs_shift_reg'high-1 downto 0) & '1';
               when to_unsigned(24,6) =>
                  pmod_sclk <= cs_shift_reg(cs_shift_reg'high);
               when to_unsigned(37,6) =>
                  -- Output the highest bit and advance the shift register
                  pmod_mosi <= mosi_shift_reg(mosi_shift_reg'high-1);
                  mosi_shift_reg <= mosi_shift_reg(mosi_shift_reg'high-1 downto 0) & '0';
               when to_unsigned(49,6) =>
                  if cs_shift_reg = x"FFFFFFFFFFFFFFFF" then
                     if sent_command = '0' then
                        -- send the start conversion command
                        cs_shift_reg   <= x"FF000000007FFFFF";
                        mosi_shift_reg <= x"0008280060000000";
                        sent_command  <= '1';
                     elsif pmod_miso = '0' then     
                        -- Send the read data command
                        cs_shift_reg   <= x"FF000000007FFFFF";
                        mosi_shift_reg <= x"0058000000000000";
                        sent_command  <= '0';
                     end if;
                  end if;
               when others =>
                  NULL;
            end case;
         else
            -- Just during startup, output > 40 '1' bits to reset the ADC, then wait for at least 500us.
            pmod_mosi <= '1';
            case counter is 
               when to_unsigned(0,6) =>
                  pmod_sclk <= '1';
               when to_unsigned(12,6) => 
                  if startup_timer >= 512 then
                     pmod_cs <= '0';
                  end if;
               when to_unsigned(24,6) =>
                  if startup_timer >= 512 then
                     pmod_sclk <= '0';
                  end if;
               when to_unsigned(49,6) =>
                  startup_timer <= startup_timer - 1;
               when others =>
                  NULL;
            end case;
         end if;
         
         -- Generate the 1MHz for the SPI interface
         -- I haven't checked how fast the SPI interface works, so check this on the datasheet.
         if counter = 49 then
             counter <= (others => '0');
         else   
            counter <= counter + 1;
         end if;      
            
 
      end if;
   end process;
 
end Behavioral;

 

Next step is to capture the bits from the ADC, and move them to 'sample' at the correct time....

Link to comment
Share on other sites

The easy way is to capture the MISO signal when the sclk signal is raised, and then sample the caputured bits in this register when we start the next conversion. And that should be it - now would be the time to re-read the datasheet closely, paying special attention to the registers, timing and clock speeds, verifying everything against the simulation traces, and then hit boards & logic analyzer to debug it.

----------------------------------------------------------------------------------
-- PMOD_AD5 - an attempt at configuring the Digilent PMOD_AD5 over SPI
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
 
entity pmod_ad5 is
    Port ( clk50MHz  : in  STD_LOGIC;
           pmod_sclk : out STD_LOGIC := '1';
           pmod_mosi : out STD_LOGIC := '1';
           pmod_miso : in  STD_LOGIC;
           pmod_cs   : out STD_LOGIC := '1';
           samples   : OUT  std_logic_vector(23 downto 0)
);
end pmod_ad5;
 
architecture Behavioral of pmod_ad5 is
   signal counter : unsigned(5 downto 0) := (others => '0');
   signal cs_shift_reg   : std_logic_vector(63 downto 0) := (others => '1'); -- You can put init commands here if you want
   signal mosi_shift_reg : std_logic_vector(63 downto 0) := (others => '1'); -- You can put init commands here if you want
   signal miso_shift_reg : std_logic_vector(63 downto 0) := (others => '0'); 
   signal startup_timer  : unsigned(9 downto 0) := to_unsigned(600,10); -- 500us at 50Mhz;
   signal sent_command    : std_logic := '0';
begin
 
p: process(clk50Mhz)
   begin
      if rising_edge(clk50MHz) then
         if startup_timer = 0 then
            case counter is 
               when to_unsigned(0,6) =>
                  pmod_sclk <= '1';
                  -- Correct time to capture data ison the rising edge.
                   miso_shift_reg <= miso_shift_reg(miso_shift_reg'high-1 downto 0) & pmod_miso;
               when to_unsigned(12,6) => 
                  -- change the CS signal when SCLK is high
                  -- Output the highest bit and advance the shift register
                  pmod_cs <= cs_shift_reg(cs_shift_reg'high-1);
                  cs_shift_reg <= cs_shift_reg(cs_shift_reg'high-1 downto 0) & '1';
               when to_unsigned(24,6) =>
                  pmod_sclk <= cs_shift_reg(cs_shift_reg'high);
               when to_unsigned(37,6) =>
                  -- Output the highest bit and advance the shift register
                  pmod_mosi <= mosi_shift_reg(mosi_shift_reg'high-1);
                  mosi_shift_reg <= mosi_shift_reg(mosi_shift_reg'high-1 downto 0) & '0';
               when to_unsigned(49,6) =>
                  if cs_shift_reg = x"FFFFFFFFFFFFFFFF" then
                     if sent_command = '0' then
                        -- we should have all the data bits in mosi_shift_reg, so latch it
                        samples <= mosi_shift_reg(23 downto 0);
                        -- send the start conversion command
                        cs_shift_reg   <= x"FF000000007FFFFF";
                        mosi_shift_reg <= x"0008280060000000";
                        sent_command  <= '1';
                     elsif pmod_miso = '0' then     
                        -- Send the read data command
                        cs_shift_reg   <= x"FF000000007FFFFF";
                        mosi_shift_reg <= x"0058000000000000";
                        sent_command  <= '0';
                     end if;
                  end if;
               when others =>
                  NULL;
            end case;
         else
            -- Just during startup, output > 40 '1' bits to reset the ADC, then wait for at least 500us.
            pmod_mosi <= '1';
            case counter is 
               when to_unsigned(0,6) =>
                  pmod_sclk <= '1';
               when to_unsigned(12,6) => 
                  if startup_timer >= 512 then
                     pmod_cs <= '0';
                  end if;
               when to_unsigned(24,6) =>
                  if startup_timer >= 512 then
                     pmod_sclk <= '0';
                  end if;
               when to_unsigned(49,6) =>
                  startup_timer <= startup_timer - 1;
               when others =>
                  NULL;
            end case;
         end if;
         
         -- Generate the 1MHz for the SPI interface
         -- I haven't checked how fast the SPI interface works, so check this on the datasheet.
         if counter = 49 then
             counter <= (others => '0');
         else   
            counter <= counter + 1;
         end if;      
 
      end if;
   end process;
 
end Behavioral;
Link to comment
Share on other sites

Hi Mr Mike,

Thanks a lot for this explanation..Since I am just a beginner most of the codes pass over my head though i understood what you intended to do..So basically I need to activate the clock of the ADC using the clock divider ( from datasheet 2.4KHz)...then the ADC converts the input analog data at this rate...then how will I know conversion is over?? am still confused :/

Link to comment
Share on other sites

Hi 123244423, 

The Analog Devices chip on the PmodAD5 does not have the capability to perform non-differential measurements. The closest you can get is by using a pseudo differential measurement where you are comparing the input to a common reference voltage-- either the default reference voltage of 2.5V or a user supplied differential reference voltage applied between REFIN2+ and REFIN2- that is between 1V and 5.25V.

The gain factor tells you what kind of voltage range you are able to supply to the analog inputs based on your reference voltage. Presuming your photomultipler has a "default" voltage of 0V, you will want a gain factor of 1 so that the Pmod is able to successfully read your input voltages. An example datastream that shows you how to read the data register and configure the device so that only one channel is enabled (as well as setting the gain factor) is provided in the PmodAD5 Reference Manual. To set the Pseudo differential voltage measurement, you would need to set the Pseudo bit to a value of 1 in the datastream. 

As for the 20% noise that you are experiencing, it sounds like the photomultiplier does not have a very clean output (I'm presuming it's sending a single dc output). How are you powering the photomultiplier and is there anything else being powered from the same source?

Link to comment
Share on other sites

Oh, sorry - they are none-standard acronyms that a lot of people use.

 

MISO is "Master In, Slave Out" (i.e. serial data from the ADC to the FPGA), MOSI is "Master Out Slave In" (i.e data from the FPGA to the ADC).  So connect MOSI to the ADC's data in pin, and MISO to the ADC's data out.

 

For me they are far more intuitive to use than "data_in" and "data_out", which depend on your frame of reference.

 

From the details in the datasheet, we know that data is ready when the ADC's DOUT signal goes from high to low.

Link to comment
Share on other sites

As per page 11 of the data sheet:

 

CS - Chip Select Input. This is an active low logic input used to select the ADC. CS can be used to select the ADC in
systems with more than one device on the serial bus or as a frame synchronization signal in communicating
with the device. CS can be hardwired low, allowing the ADC to operate in 3-wire mode with SCLK, DIN, and
DOUT used to interface with the device.
 
As per page 12 of the data sheet:
 
SYNC - Logic input that allows for synchronization of the digital filters and analog modulators when using a number
of AD7193 devices. While SYNC is low, the nodes of the digital filter, the filter control logic, and the calibration
control logic are reset, and the analog modulator is also held in its reset state. SYNC does  not affect the digital
interface but does reset RDY to a high state if it is low. SYNC has a pull-up resistor internally to DVDD.
 
As per page 12 of the datasheet:
 
DOUT/RDY operates as a data ready pin, going low to indicate
the completion of a conversion
 
It's all in there!
 
Oh, and why 49? Well it takes 50 cycles to count from 0 to 49. So when using a 50 MHz system clock counting to 49 is a good way to generate a 1 MHz SPI clock.
 
 
Link to comment
Share on other sites

Hi,

Yea its all in there...but I realised that the datasheet is 56 pages long so I was just going over it quickly...thus i missed almost all the relevant parts...Now I can see a clear picture..I hope the programming is ok :) Thanks a lot for your guidance :) and keep up the good work (Y)

Link to comment
Share on other sites

Hi 1116345,

 
Hamster has given a great explanation (as he always does) on how to get the code for your FPGA up and running, but there are a couple more external hardware things that you'll need to do.
 
The PmodAD5 uses Analog Devices AD7193 to do all of the analog-to-digital conversion. However, this particular chip only takes analog inputs as a differential pair. By default, it expects that you would be pairing AIN1 (A1 on the 6x2 female header) with AIN2 (A2 on the 6x2 female header).  
 
It also expects that you supply a reference voltage on the AVDD pin (something between 3V and 5.25V) and a ground reference voltage on the ground pin (0V) that are on header J4.
 
Since you are using a light sensor, you will likely want to change the gain from the default of 128 to a gain of 1 in order to allow your analog input to have a wider range with respect to the analog voltage reference. To do this, you would need to write to the last three bits in the configuration register (pg 27) to 000 in order to have a gain of 1. If your reference voltage (AVDD on header J4) is 5V, this will allow you to have an maximum input voltage of up to 3.75V (from page 32 under Programmable Gain Array).
 
Please let me know if you have any more questions.
 
Thanks,
JColvin
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...