0
votes

I've been trying to comunicate with the LTC2426 DAC via SPI and I've failed missrebly. Now I'm seeking for help. Could someone tell me why my code doesn't work. The CSDAC Works properly the SCLK is generated and the 32 bits are sent but still I may have screwed the timing. I would be very thankful şf someone help me fix the code.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity DAC is
    port
        (
            CLK : in STD_LOGIC;         
            SCLK : out STD_LOGIC;
            MOSI : out STD_LOGIC;
            CSDAC : out STD_LOGIC := '1'        
        );  
end DAC;

architecture Behavioral of DAC is
Signal Counter : Integer range 0 to 32 := 0;
Signal CurrentBit : Integer range 0 to 32 := 0;
Signal DataSent : STD_LOGIC := '1';
Constant Data : STD_LOGIC_VECTOR(31 downto 0) := X"0030FFF0";
Signal Slope : STD_LOGIC := '0';
begin
Prescaler : process(CLK) 
begin
    if rising_edge(CLK) then
        if Counter = 5 then
            Slope <= not(Slope);
            Counter <= 0;
        else
            Counter <= Counter + 1;
        end if;
    end if; 
end process;
SCLK <= SLOPE;
WriteDac : process(CLK) 
begin
    if rising_edge(CLK) then
         if DataSent = '1' then
            if CurrentBit <= 31 then
                CSDAC <= '0';
                MOSI <= Data(CurrentBit);
                CurrentBit <= CurrentBit +1;
            else
                CSDAC <= '1';       
                DataSent <= '0';                
            end if;
         end if;
    end if;
end process;
end Behavioral;

EDIT : NEW CODE

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity DAC is
    port
        (
            CLK : in STD_LOGIC;         
            SCLK : out STD_LOGIC;
            MOSI : out STD_LOGIC;
            DEBUG : out STD_LOGIC := '1';
            CSDAC : out STD_LOGIC := '1'        
        );  
end DAC;

architecture Behavioral of DAC is
Signal Counter : Integer range 0 to 6 := 0;
Signal Counter2 : Integer range 0 to 33 := 0;
Signal CurrentBit : Integer range 0 to 33 := 0;
Signal Fixed : STD_LOGIC := '0';
Signal DataSent : STD_LOGIC := '0';
Constant Data : STD_LOGIC_VECTOR(31 downto 0) := X"0FFF0C00";
Signal Slope_last : STD_LOGIC := '0'; 
Signal Slope : STD_LOGIC := '0';
Signal MSS : STD_LOGIC := '0';
begin

WriteDac : process(CLK) 
begin
    if rising_edge(CLK) then
        if Counter = 5 then
            Slope_last <= Slope;
            Slope <= not(Slope);
           if Slope_last = '1' and Slope = '0' then
                if Fixed = '1' then
                    if DataSent = '0' then
                        if CurrentBit <= 31 then
                            CSDAC <= '0';
                            DEBUG <= '0';
                            MOSI <= Data(CurrentBit);
                            CurrentBit <= CurrentBit +1;
                         else
                            MOSI <= '0';
                            CSDAC <= '1';
                            DEBUG <= '1';
                            DataSent <= '1';
                        end if;
                    end if;
                else
                  if Counter2 <= 31 then
                        CSDAC <= '1';
                        DEBUG <= '1';
                        Counter2 <= Counter2 + 1;
                        MSS <= not(MSS);
                        MOSI <= MSS;
                  else  
                        Fixed <= '1';
                        MOSI <= '0';
                  end if;
                end if;
            end if;
        else
            Counter <= Counter + 1;
        end if;
    end if;
end process;
SCLK <= SLOPE;

end Behavioral;

I'm pulsing the MOSI because when i send couple of bits the SCLK recovers. First SCLK runs on about 1.4 mhz when i pulse the mosi it recovers to 4.167MHZ note that 1.4mhz or so it can be 1.5mhz I cant remember it too good.

2

2 Answers

0
votes

Could it be your second process should be sensitive to SCLK (or slope) i.s.o. CLK? You could check opencores.org for some examples of an SPI module. Even if written in Verilog, It't a nice example how things could be done.

0
votes

you must update your bit counter (CurrentBit) related to SCK. e.g.:

...
WriteDac : process(CLK) 
begin
   if rising_edge(CLK) then
      slope_last<=slope;

      if slope_last='1' and slope='0' then -- e.g. falling edge!
          if DataSent = '1' then
 ...