OpenCores
URL https://opencores.org/ocsvn/ov7670-sccb/ov7670-sccb/trunk

Subversion Repositories ov7670-sccb

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /ov7670-sccb/trunk
    from Rev 5 to Rev 4
    Reverse comparison

Rev 5 → Rev 4

/hdl/SCCBMaster.vhd
0,0 → 1,447
---------------------------------------------------------------------------------------------------------------------------------------------
-- OV7670 kamera modulu ayarlarinin yapilmasi icin SCCB protokolunu kullanir. Bu protokol I2C uyumludur.
-- SCCB protokolu I2C'den farkli olarak lojik-1 durumuna da sahiptir.
-- High - Low - High Impedance
--
-- Bu protokolun en onemli noktasi; ACK ve NACK bitleri yazma islemi icin gereksizdir. Bu bitler yerine
-- "Don't Care" isimli lojik-0 biti kullanılır. Asagida ornek bir yazma isleminin veri paketi gorulmektedir:
--
-- |A6|A5|A4|A3|A2|A1|A0|R/W|DC|-|R7|R6|R5|R4|R3|R2|R1|R0|DC|-|D7|D6|D5|D4|D3|D2|D1|D0|DC|
-- 7-bit Address 8-Bit Register/Data 8-bit Data
-- R => lojik-1
-- W => lojik-0
--
-- SCCB hattindan sadece veri gonderileceginden sadece WRITE islemi eklenmistir. OV7670 kamera modulu paralel
-- 8-bit kamera veri hatti bulunduruyor. Bu noktada READ adimi eklenmedi!
--
-- Kullanilan kaynaklar : OV7670 Datasheet
-- : OmniVision SCCB Specification
-- : http://www.dejazzer.com/hardware.html (Face detection on FPGA: OV7670 CMOS camera + DE2-115 FPGA board)
-- : http://www.dejazzer.com/eigenpi/digital_camera/digital_camera.html
--
-- TODO => Aciklamalari Ingilizce yap!
--
---------------------------------------------------------------------------------------------------------------------------------------------
 
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use IEEE.NUMERIC_STD.all;
 
entity SCCBMaster is
generic(
GInputClock : integer := 50_000_000; -- FPGA' nin ana clock hizi
GBusClock : integer := 400_000 -- SCCB hattinin calistirilmasi icin belirlenecek hiz (400 kHz SCCB fast mode)
);
port(
PIClock : in std_logic; -- Sistem clock girisi
PIReset : in std_logic; -- Reset(active low) girisi
PIEnable : in std_logic; -- SCCB hattini aktif edecek enable girisi
PIAddress : in std_logic_vector(6 downto 0); -- SCCB hattina bagli olan slave cihazlarinin ana adreslerini isaret eden giris
PIRegister : in std_logic_vector(7 downto 0); -- Slave birimin islem yapilacak register adresini belirten giris
PIWriteData : in std_logic_vector(7 downto 0); -- Master -> Slave yonunde yazilacak data
PIMode : in std_logic; -- SCCB mod secenegi girisi
PIStart : in std_logic; -- SCCB master backend calistirma girisi
PODone : out std_logic; -- SCCB arayuzunun yazma islemini bitirdigini belirten cikis
POReady : out std_logic; -- SCCB arayuzunun islem yapmaya hazir oldugunu belirten cikis
PIOSIOD : inout std_logic; -- SCCB seri data cikisi - girisi
POSIOC : out std_logic -- SCCB seri clock cikisi
);
end SCCBMaster;
 
architecture Behavioral of SCCBMaster is
 
------------------------------------------------------------------------------------------------------------------
-- Bu adimda sistemin calisacagi durum makinesinin durumlari, giris ve cikis portlarina baglanacak sinyaller,
-- durumlar icin gerekli olacak counter ve busy bitleri gibi sinyaller olusturulmustur.
------------------------------------------------------------------------------------------------------------------
 
type TStatesWrite is (idle, start_condition, send_addr, addr_dc, send_reg, reg_dc, send_data, data_dc, stop);
signal SStateWriteBase : TStatesWrite := idle;
constant CClockCountMax : integer := (GInputClock / GBusClock);
signal SStart : std_logic := '0';
signal SStartReg : std_logic := '0';
signal SStartedWrite : std_logic := '0';
signal SMode : std_logic := '0';
 
signal SEnable : std_logic := '0';
signal SAddress : std_logic_vector(6 downto 0) := (others => '0');
signal SRegister : std_logic_vector(7 downto 0) := (others => '0');
signal SWriteData : std_logic_vector(7 downto 0) := (others => '0');
signal SBusy : std_logic := '0';
signal SBusy2 : std_logic := '0';
signal SDone : std_logic := '0';
signal SReady : std_logic := '0';
 
signal SDataClockRef : std_logic := '0';
signal SDataClockRefPrev : std_logic := '0';
-- signal SSIODClock : std_logic := '0'; -- DEBUG AMACLIDIR!
-- signal SSIODClockPrev : std_logic; -- DEBUG AMACLIDIR!
signal SSIOCClock : std_logic := '1';
signal SSIOCClockPrev : std_logic;
signal SSIODWrite : std_logic := '0';
signal SSIODRead : std_logic := '0';
signal SSIOCWrite : std_logic := '0';
signal SSIOCRead : std_logic := '0';
signal SAddr : std_logic_vector(6 downto 0) := (others => '0');
signal SReg : std_logic_vector(7 downto 0) := (others => '0');
signal SData : std_logic_vector(7 downto 0) := (others => '0');
signal SAddrReg : std_logic_vector(6 downto 0) := (others => '0');
signal SRegReg : std_logic_vector(7 downto 0) := (others => '0');
signal SDataReg : std_logic_vector(7 downto 0) := (others => '0');
signal SCounter : integer range 0 to 8 := 0;
 
signal SCounterSCCB : integer range 0 to CClockCountMax := 0;
signal SCounter2 : integer range 0 to 3 := 0;
 
begin
 
------------------------------------------------------------------------
-- Bu adimda giris ve cikis portlari sinyallere yonlendirilmistir.
------------------------------------------------------------------------
SStart <= PIStart;
SEnable <= PIEnable;
SAddress <= PIAddress;
SRegister <= PIRegister;
SWriteData <= PIWriteData;
SMode <= PIMode;
PODone <= SDone;
POReady <= SReady;
 
PIOSIOD <= SSIODWrite when SEnable = '1' else 'Z';
 
SStartReg <= '1' when SStart = '1' and SEnable = '1' else
'0' when (SSIOCClock = '0' and SSIOCClockPrev = '1') or PIReset = '0' or SEnable = '0' else
SStartReg;
 
-------------------------------------------------------------------------------------------------------------------------------
-- READY prosesi; eger yazma islemi bittiyse(SDone == '1') ve yazma durum makinesi baslangictaysa(SStateWriteBase == idle)
-- SReady sinyalini lojik-1 yapar. Ayrica sistem durdurulduysa(PIReset == '0') SReady sinyalini lojik-0 yapar.
-------------------------------------------------------------------------------------------------------------------------------
READY : process(PIClock, PIReset)
begin
if PIReset = '0' then
SReady <= '0';
elsif rising_edge(PIClock) then
if SStateWriteBase = idle then
SReady <= '1';
else
SReady <= '0';
end if;
end if;
end process;
 
-------------------------------------------------------------------------------------------------------------------------------
-- Backend tarafina gelen baslatma sinyaline gore(SStart == '1') address, register ve data bilgilerini olusturulan register
-- sinyallerine atar. Sistemin resetlenme durumuna gore bu sinyaller temizlenir.
-------------------------------------------------------------------------------------------------------------------------------
 
DATA_CAPTURE : process(PIClock, PIReset)
begin
if PIReset = '0' then
SAddrReg <= (others => '0');
SRegReg <= (others => '0');
SDataReg <= (others => '0');
elsif rising_edge(PIClock) then
if SStart = '1' then
SAddrReg <= SAddress;
SRegReg <= SRegister;
SDataReg <= SWriteData;
elsif SSIOCClock = '0' and SSIOCClockPrev = '1' then
SAddrReg <= SAddrReg;
SRegReg <= SRegReg;
SDataReg <= SDataReg;
else
SAddrReg <= SAddrReg;
SRegReg <= SRegReg;
SDataReg <= SDataReg;
end if;
end if;
end process;
 
-------------------------------------------------------------------------------------------------------------------------------
-- CLKGEN prosesi; SCCB arayuzu icin gerekli olan REFERANS saat sinyallerini uretir. Bu noktada onemli olan durum sudur:
-- OV7670 datasheeti incelendiginde gonderilecek veriler SIOC cikisinin lojik-0 olduğu durumun tam ortasında degistirilir.
-- Bu nedenden dolayi SIOC cikisi icin ek olarak bu cikisin yari periyoduna sahip ikincil bir saat sinyali uretilir.
--
-- |¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯|_______ =====>>> SIOC Referans Saat
-- | | | | |
-- | | | | |
-- |¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_ =====>>> DATA Referans Saat
--
-------------------------------------------------------------------------------------------------------------------------------
CLKGEN : process(PIClock)
variable VCounter : integer range 0 to CClockCountMax := 0;
begin
if rising_edge(PIClock) then
--SSIODClockPrev <= SSIODClock;
SSIOCClockPrev <= SSIOCClock;
SDataClockRefPrev <= SDataClockRef;
if SCounterSCCB = (CClockCountMax / 4) - 1 then
SDataClockRef <= not SDataClockRef;
if SCounter2 = 1 then
--SSIODClock <= not SSIODClock;
SSIOCClock <= not SSIOCClock;
SCounter2 <= 0;
else
SCounter2 <= SCounter2 + 1;
end if;
SCounterSCCB <= 0;
else
SCounterSCCB <= SCounterSCCB +1;
end if;
 
end if;
end process;
 
-------------------------------------------------------------------------------------------------------------------------------------------
-- DATA_WRITE prosesi; SCCB arayuzune uygun olarak yazma islemi yapacak olan durum makinesini icerir. Aktif 0 olarak ca-
-- lisan PIReset, aktif oldugu durumda butun islemleri, sayicilari, cikislari ve registerleri temizler.
--
-- !!!!ONEMLI!!!!
-- SCCB arayuzu, idle durumundayken SIOD hattini yuksek empedans('Z'), SIOC hattini ise lojik-1 seviyesinde tutar. Baslangic kosulu,
-- SIOD hattini 'Z' durumundan lojik-1 durumuna getirir, ardindan SIOC hattini referans saatin yarı periyodu kadar bekledikten sonra
-- lojik-0 yaparak haberlesmeyi baslatir. Bitme kosulu ise, eger baska veri yazilmayacaksa ilk olarak SIOC'yi lojik-1, ardindan SIOD
-- hattini yarim periyot bekledikten sonra 'Z' yapar. Ancak baska veri yazilmaya devam edecek ise SIOD hattini 'Z' yerine lojik-1 yapar.
--
--
-- SIOD -------¯¯¯¯¯¯¯| |¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯| |¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|
-- |_______________________________| |_______________| |______
-- | | | | | | |
-- | | | | | | |
-- | | | | | | |
-- SIOC ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯| |¯¯¯¯¯¯¯| | |¯¯¯¯¯¯¯| | |¯¯¯¯¯¯¯| | |¯¯¯¯¯¯¯| | |¯¯¯¯¯¯¯| |
-- |_______________| |_______| |_______| |_______| |_______| |___|______
-- | | | | | | |
-- | | | | | | |
-- SIOC Ref |¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯|_______
-- | | | | | | |
-- | | | | | | |
-- SIOD Ref |¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_
--
-------------------------------------------------------------------------------------------------------------------------------------------
 
DATA_WRITE : process(PIClock, PIReset)
variable VCounter : integer range 0 to 16 := 0;
begin
if PIReset = '0' then
SStateWriteBase <= idle;
SStartedWrite <= '0';
SAddr <= (others => '0');
SReg <= (others => '0');
SData <= (others => '0');
SSIODWrite <= 'Z';
SSIOCWrite <= '1';
SBusy <= '0';
SDone <= '0';
SBusy2 <= '0';
VCounter := 0;
SCounter <= 7;
elsif rising_edge(PIClock) then
case SStateWriteBase is
-------------------------------------------------------------------------------------------------------------------------------------------
-- "idle" durumu; SStartReg tetiklendiginde address, register ve data bilgilerini registerlerden toplar ve SIOC referans
-- saatinin yukselen kenarinda "start_condition" durumuna gecer.
-- SStartReg'in tetiklenmedigi durumda sistem reset (SIOD = 'Z' - SIOC = '1') durumunda kalir.
-------------------------------------------------------------------------------------------------------------------------------------------
when idle =>
if SSIOCClock = '0' and SSIOCClockPrev = '1' then
if SStartReg = '1' then
SSIODWrite <= '1';
SSIOCWrite <= '1';
SStartedWrite <= '1';
SDone <= '0';
SAddr <= SAddrReg;
SReg <= SRegReg;
SData <= SDataReg;
else
SAddr <= (others => '0');
SReg <= (others => '0');
SData <= (others => '0');
SStateWriteBase <= idle;
SSIODWrite <= 'Z';
SSIOCWrite <= '1';
SStartedWrite <= '0';
SDone <= '1';
end if;
elsif SSIOCClock = '1' and SSIOCClockPrev = '0' and SStartedWrite = '1' then
SSIODWrite <= '0';
SStartedWrite <= '0';
SStateWriteBase <= start_condition;
end if;
-------------------------------------------------------------------------------------------------------------------------------------------
-- "start_condition" durumu; 2 SIOC referans clock darbesinden sonra SIOD referansinin yukselen kenari ve SIOC referansinin
-- lojik-0 oldugu anda cache olarak alinan address verisinin ilk bitini sola 1 kere kaydirarak SIOD hattina yazar ve "send_addr"
-- durumuna gecer.
-------------------------------------------------------------------------------------------------------------------------------------------
when start_condition =>
if SSIOCClock = '0' and SSIOCClockPrev = '1' then
SBusy <= '1';
if SBusy = '1' then
SBusy2 <= '1';
end if;
SSIOCWrite <= '0';
elsif SDataClockRef = '1' and SDataClockRefPrev = '0' and SSIOCClock = '0' and SBusy2 = '1' then
if SAddr(6) = '1' then
SSIODWrite <= '1';
SAddr <= std_logic_vector(shift_left(unsigned(SAddr), 1));
elsif SAddr(6) = '0' then
SSIODWrite <= '0';
SAddr <= std_logic_vector(shift_left(unsigned(SAddr), 1));
end if;
SBusy <= '0';
SBusy2 <= '0';
SStateWriteBase <= send_addr;
 
else
SStateWriteBase <= start_condition;
end if;
-------------------------------------------------------------------------------------------------------------------------------------------
-- "send_addr" durumu; SIOD referansinin yukselen kenari ve SIOC referansinin lojik-0 oldugu anda address verisinin geri kalanini
-- SIOD hattina yazar. Ardindan "Don't Care" bit durumuna gecer ve gecerken SIOD hattini lojik-0 tutar.
-------------------------------------------------------------------------------------------------------------------------------------------
when send_addr =>
if SDataClockRef = '1' and SDataClockRefPrev = '0' and SSIOCClock = '0' then
if VCounter <= 5 then
VCounter := VCounter + 1;
if(SAddr(6) = '1') then
SSIODWrite <= '1';
SAddr <= std_logic_vector(shift_left(unsigned(SAddr), 1));
elsif (SAddr(6) = '0') then
SSIODWrite <= '0';
SAddr <= std_logic_vector(shift_left(unsigned(SAddr), 1));
end if;
else
VCounter := 0;
SSIODWrite <= '0'; ---->>>> Don't Care Bit!
SStateWriteBase <= addr_dc;
SBusy <= '0';
end if;
else
SStateWriteBase <= send_addr;
end if;
 
when addr_dc =>
if SDataClockRef = '1' and SDataClockRefPrev = '0' and SSIOCClock = '0' then
SAddr <= (others => '0');
elsif SDataClockRef = '0' and SDataClockRefPrev = '1' and SSIOCClock = '0' then
SStateWriteBase <= send_reg;
end if;
-------------------------------------------------------------------------------------------------------------------------------------------
-- "send_reg" durumu; SIOD referansinin yukselen kenari ve SIOC referansinin lojik-0 oldugu anda register verisini SIOD hattina yazar.
-- Ardindan "Don't Care" bit durumuna gecer ve gecerken SIOD hattini lojik-0 tutar.
-------------------------------------------------------------------------------------------------------------------------------------------
when send_reg =>
if SDataClockRef = '1' and SDataClockRefPrev = '0' and SSIOCClock = '0' then
SBusy <= '1';
if SBusy = '1' then
if VCounter <= 7 then
VCounter := VCounter + 1;
if(SReg(7) = '1') then
SSIODWrite <= '1';
SReg <= std_logic_vector(shift_left(unsigned(SReg), 1));
elsif (SReg(7) = '0') then
SSIODWrite <= '0';
SReg <= std_logic_vector(shift_left(unsigned(SReg), 1));
end if;
else
SBusy <= '0';
VCounter := 0;
SSIODWrite <= '0'; ---->>>> Don't Care Bit!
SStateWriteBase <= reg_dc;
end if;
end if;
end if;
-------------------------------------------------------------------------------------------------------------------------------------------
-- "reg_dc" durumu; "Don't Care" biti yazildiktan sonra diger durumlarda oldugu gibi SIOD ve SIOC referans saat sinyallerine
-- gore islem yapar. Bu sefer data verisinin ilk bitini sola kaydirarak SIOD hattina yazar ve "send_data" durumuna gecer.
-------------------------------------------------------------------------------------------------------------------------------------------
when reg_dc =>
if SDataClockRef = '1' and SDataClockRefPrev = '0' and SSIOCClock = '0' then
SReg <= (others => '0');
SStateWriteBase <= send_data;
if(SData(7) = '1') then
SSIODWrite <= '1';
SData <= std_logic_vector(shift_left(unsigned(SData), 1));
SBusy <= '0';
elsif (SData(7) = '0') then
SSIODWrite <= '0';
SData <= std_logic_vector(shift_left(unsigned(SData), 1));
SBusy <= '0';
end if;
end if;
-------------------------------------------------------------------------------------------------------------------------------------------
-- "reg_dc" durumu; gonderilmek istenen verinin ilk biti yazdirildiktan sonra geri kalan bitler sola kaydirilarak SIOD hattina
-- yazilir. Ardindan "Don't Care" biti yazilir, 1 SIOD ve SIOC referans saati beklenir ve "data_dc" durumuna gecilir.
-------------------------------------------------------------------------------------------------------------------------------------------
when send_data =>
if SDataClockRef = '1' and SDataClockRefPrev = '0' and SSIOCClock = '0' then
if VCounter <= 6 then
VCounter := VCounter + 1;
if(SData(7) = '1') then
SSIODWrite <= '1';
SData <= std_logic_vector(shift_left(unsigned(SData), 1));
elsif (SData(7) = '0') then
SSIODWrite <= '0';
SData <= std_logic_vector(shift_left(unsigned(SData), 1));
end if;
else
SSIODWrite <= '0'; ----
SBusy <= '1';
if SBusy = '1' then
VCounter := 0;
SStateWriteBase <= data_dc;
SBusy <= '0';
end if;
end if;
end if;
------------------------------------------------------------------------------------------
-- "data_dc" durumu; sadece 1 clock SIOC referans bekleyerek "stop" durumuna gecer.
------------------------------------------------------------------------------------------
when data_dc =>
if SSIOCClock = '1' and SSIOCClockPrev = '0' then
SData <= (others => '0');
SStateWriteBase <= stop;
end if;
-------------------------------------------------------------------------------------------------------------------------------------------
-- "stop" durumu; ilk olarak SCCB haberlesmesini sonlandirmak icin ilk olarak SIOC hattini lojik-1 yapar, ardindan 1 SIOC saat
-- referansi bekledikten sonra SIOD hattini lojik-1 yapar ve "idle" durumuna gecis yapar.
-------------------------------------------------------------------------------------------------------------------------------------------
when stop =>
SSIOCWrite <= '1';
if SSIOCClock = '1' and SSIOCClockPrev = '0' then
SSIODWrite <= '1';
SBusy <= '1';
SAddr <= (others => '0');
SReg <= (others => '0');
SData <= (others => '0');
if SBusy = '1' then
--SReady <= '1';
SStateWriteBase <= idle;
SDone <= '1';
SBusy <= '0';
end if;
elsif SSIOCClock = '0' and SSIOCClockPrev = '1' then
SSIODWrite <= '1';
end if;
 
when others =>
end case;
end if;
end process;
 
end Behavioral;
hdl/SCCBMaster.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: hdl/SCCBRegisterTable.vhd =================================================================== --- hdl/SCCBRegisterTable.vhd (nonexistent) +++ hdl/SCCBRegisterTable.vhd (revision 4) @@ -0,0 +1,327 @@ +----------------------------------------------------------------------------------- +-- OV7670 CMOS kamera modulunun RGB565 modunda calismasini saglayan register +-- ve bu registerlerin olmasi gereken verileri icerir. +----------------------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.STD_LOGIC_UNSIGNED.all; +use IEEE.NUMERIC_STD.all; + +entity SCCBRegisterTable is + port ( + PIClock : in std_logic; + PIReset : in std_logic; + PITrig : in std_logic; + PIDone : in std_logic; + PIReady : in std_logic; + POCfgFinished : out std_logic; + POStart : out std_logic; + POEnable : out std_logic; + POAddress : out std_logic_vector(6 downto 0); + PORegister : out std_logic_vector(7 downto 0); + POWriteData : out std_logic_vector(7 downto 0) + ); + +end SCCBRegisterTable; + +architecture Behavioral of SCCBRegisterTable is + constant CDeviceBaseAddress : std_logic_vector(7 downto 0) := x"21"; + constant CDeviceWriteAddress : std_logic_vector(7 downto 0) := x"42"; + constant CDeviceReadAddress : std_logic_vector(7 downto 0) := x"43"; + + + + signal STrig : std_logic := '0'; + signal SDone : std_logic := '0'; + signal SReady : std_logic := '0'; + signal SCfgFinished : std_logic := '0'; + signal SStart : std_logic := '0'; + signal SEnable : std_logic := '0'; + signal SAddress : std_logic_vector(6 downto 0) := (others => '0'); + signal SRegister : std_logic_vector(7 downto 0) := (others => '0'); + signal SWriteData : std_logic_vector(7 downto 0) := (others => '0'); + + + signal STrigPrev : std_logic := '0'; + signal STrigRising : std_logic := '0'; + signal STrigFalling : std_logic := '0'; + + signal SReadyPrev : std_logic := '0'; + signal SReadyRising : std_logic := '0'; + + signal SCounter : integer range 0 to 58 := 0; + + + signal SWaitCtr : integer range 0 to 255 := 0; + + +begin + STrig <= PITrig; + SDone <= PIDone; + SReady <= PIReady; + + POCfgFinished <= SCfgFinished; + POStart <= SStart; + POEnable <= SEnable; + POAddress <= SAddress; + PORegister <= SRegister; + POWriteData <= SWriteData; + + READY_EDGE : process(PIClock, PIReset) + begin + if PIReset = '0' then + SReadyPrev <= '0'; + SReadyRising <= '0'; + elsif rising_edge(PIClock) then + SReadyPrev <= SReady; + if SReady = '1' and SReadyPrev = '0' then + SReadyRising <= '1'; + else + SReadyRising <= '0'; + end if; + end if; + end process; + + TRIG_EDGES : process(PIClock, PIReset) + begin + if PIReset = '0' then + STrigPrev <= '0'; + STrigRising <= '0'; + STrigFalling <= '0'; + elsif rising_edge(PIClock) then + STrigPrev <= STrig; + if STrig = '1' and STrigPrev = '0' then + STrigRising <= '1'; + else + STrigRising <= '0'; + end if; + + if STrig = '0' and STrigPrev = '1' then + STrigFalling <= '1'; + else + STrigFalling <= '0'; + end if; + end if; + end process; + + BACKEND : process(PIClock, PIReset) + begin + if PIReset = '0' then + SCfgFinished <= '0'; + SStart <= '0'; + SEnable <= '0'; + SAddress <= (others => '0'); + SRegister <= (others => '0'); + SWriteData <= (others => '0'); + SCounter <= 0; + elsif rising_edge(PIClock) then + if SWaitCtr <= 254 then + SWaitCtr <= SWaitCtr + 1; + else + if (SReady = '1' and STrigFalling = '1' and SStart = '0') or (SStart = '1' and SReadyRising = '1') then + SEnable <= '1'; + SStart <= '1'; + SAddress <= CDeviceBaseAddress(6 downto 0); + if SCounter <= 56 then + SCounter <= SCounter + 1; + case SCounter is + when 0 => + SRegister <= x"12"; + SWriteData <= x"80"; + when 1 => + + SRegister <= x"12"; + SWriteData <= x"80"; + when 2 => + SRegister <= x"12"; + SWriteData <= x"04"; + when 3 => + SRegister <= x"11"; + SWriteData <= x"00"; + when 4 => + SRegister <= x"0C"; + SWriteData <= x"00"; + when 5 => + SRegister <= x"3E"; + SWriteData <= x"00"; + when 6 => + SRegister <= x"8C"; + SWriteData <= x"00"; + when 7 => + SRegister <= x"04"; + SWriteData <= x"00"; + when 8 => + SRegister <= x"40"; + SWriteData <= x"10"; + when 9 => + SRegister <= x"3A"; + SWriteData <= x"04"; + when 10 => + SRegister <= x"14"; + SWriteData <= x"38"; + when 11 => + SRegister <= x"4F"; + SWriteData <= x"40"; + when 12 => + SRegister <= x"50"; + SWriteData <= x"34"; + when 13 => + SRegister <= x"51"; + SWriteData <= x"0C"; + when 14 => + SRegister <= x"52"; + SWriteData <= x"17"; + when 15 => + SRegister <= x"53"; + SWriteData <= x"29"; + when 16 => + SRegister <= x"54"; + SWriteData <= x"40"; + when 17 => + SRegister <= x"58"; + SWriteData <= x"1E"; + when 18 => + SRegister <= x"3D"; + SWriteData <= x"C0"; + when 19 => + SRegister <= x"11"; + SWriteData <= x"00"; + when 20 => + SRegister <= x"17"; + SWriteData <= x"11"; + when 21 => + SRegister <= x"18"; + SWriteData <= x"61"; + when 22 => + SRegister <= x"32"; + SWriteData <= x"A4"; + when 23 => + SRegister <= x"19"; + SWriteData <= x"03"; + when 24 => + SRegister <= x"1A"; + SWriteData <= x"7B"; + when 25 => + SRegister <= x"03"; + SWriteData <= x"0A"; + when 26 => + SRegister <= x"0E"; + SWriteData <= x"61"; + when 27 => + SRegister <= x"0F"; + SWriteData <= x"4B"; + when 28 => + SRegister <= x"16"; + SWriteData <= x"02"; + when 29 => + SRegister <= x"1E"; + SWriteData <= x"37"; + when 30 => + SRegister <= x"21"; + SWriteData <= x"02"; + when 31 => + SRegister <= x"22"; + SWriteData <= x"91"; + when 32 => + SRegister <= x"29"; + SWriteData <= x"07"; + when 33 => + SRegister <= x"33"; + SWriteData <= x"0B"; + when 34 => + SRegister <= x"35"; + SWriteData <= x"0B"; + when 35 => + SRegister <= x"37"; + SWriteData <= x"1D"; + when 36 => + SRegister <= x"38"; + SWriteData <= x"71"; + when 37 => + SRegister <= x"39"; + SWriteData <= x"2A"; + when 38 => + SRegister <= x"3C"; + SWriteData <= x"78"; + when 39 => + SRegister <= x"4D"; + SWriteData <= x"40"; + when 40 => + SRegister <= x"4E"; + SWriteData <= x"20"; + when 41 => + SRegister <= x"69"; + SWriteData <= x"00"; + when 42 => + SRegister <= x"6B"; + SWriteData <= x"4A"; + when 43 => + SRegister <= x"74"; + SWriteData <= x"10"; + when 44 => + SRegister <= x"8D"; + SWriteData <= x"4F"; + when 45 => + SRegister <= x"8E"; + SWriteData <= x"00"; + when 46 => + SRegister <= x"8F"; + SWriteData <= x"00"; + when 47 => + SRegister <= x"90"; + SWriteData <= x"00"; + when 48 => + SRegister <= x"91"; + SWriteData <= x"00"; + when 49 => + SRegister <= x"96"; + SWriteData <= x"00"; + when 50 => + SRegister <= x"9A"; + SWriteData <= x"00"; + when 51 => + SRegister <= x"B0"; + SWriteData <= x"84"; + when 52 => + SRegister <= x"B1"; + SWriteData <= x"0C"; + when 53 => + SRegister <= x"B2"; + SWriteData <= x"0E"; + when 54 => + SRegister <= x"B3"; + SWriteData <= x"82"; + when 55 => + SRegister <= x"B8"; + SWriteData <= x"0A"; + + when others => + SRegister <= x"FF"; + SWriteData <= x"FF"; + SMode <= '0'; + SStart <= '0'; + SEnable <= '0'; + SCfgFinished <= '1'; + SCounter <= 0; + end case; + else + SAddress <= SAddress; + SEnable <= SEnable; + SStart <= '0'; + SCounter <= 0; + SRegister <= SRegister; + SWriteData <= SWriteData; + end if; + else + SAddress <= SAddress; + SEnable <= SEnable; + SStart <= SStart; + SRegister <= SRegister; + SWriteData <= SWriteData; + end if; + end if; + end if; + end process; + +end Behavioral;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.