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;