-
Notifications
You must be signed in to change notification settings - Fork 3
/
OV7660Init.vhd
151 lines (128 loc) · 5.08 KB
/
OV7660Init.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
-- Table that defines what register and data pairs to write to the OV7660 via
-- SCCB after startup. A delay is needed before writing the actual data
-- Also perform a register reset first of all in order to ensure that we know
-- what state we are writing. A simple FPGA flash might not reset the OV7660 firmware.
-- Copyright Erik Zachrisson - erik@zachrisson.info
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use work.Types.all;
use work.OV76X0Pack.all;
entity OV7660Init is
port (
Clk : in bit1;
Rst_N : in bit1;
--
NextInst : in bit1;
--
We : out bit1;
Start : out bit1;
AddrData : out word(16-1 downto 0);
--
InstPtr : out word(InstPtrW-1 downto 0)
);
end entity;
architecture fpga of OV7660Init is
constant COM2 : word(8-1 downto 0) := x"09";
constant AECH : word(8-1 downto 0) := x"10";
constant CLKRC : word(8-1 downto 0) := x"11";
constant COM7 : word(8-1 downto 0) := x"12";
constant COM8 : word(8-1 downto 0) := x"13";
constant COM9 : word(8-1 downto 0) := x"14";
constant COM10 : word(8-1 downto 0) := x"15";
constant MVFP : word(8-1 downto 0) := x"1e";
constant TSLB : word(8-1 downto 0) := x"3a";
constant COM15 : word(8-1 downto 0) := x"40";
constant MANU : word(8-1 downto 0) := x"67";
constant MANV : word(8-1 downto 0) := x"68";
constant NbrOfInst : positive := 1;
signal InstPtr_N, InstPtr_D : word(InstPtrW-1 downto 0);
-- FIXME: Potentially listen for a number of vsync pulses instead. This would
-- same a number of flops
signal Delay_N, Delay_D : word(16-1 downto 0);
begin
SyncProc : process (Clk, Rst_N)
begin
if Rst_N = '0' then
InstPtr_D <= (others => '0');
if Simulation then
Delay_D <= "1111111111111100";
end if;
if Synthesis then
Delay_D <= (others => '0');
end if;
elsif rising_edge(Clk) then
InstPtr_D <= InstPtr_N;
Delay_D <= Delay_N;
end if;
end process;
ASyncProc : process (InstPtr_D, NextInst, Delay_D)
variable InstPtr_T : word(InstPtrW-1 downto 0);
begin
InstPtr_T := InstPtr_D;
AddrData <= (others => '0');
We <= '0';
Start <= '0';
Delay_N <= Delay_D + 1;
if (RedAnd(Delay_D) = '1') then
Delay_N <= Delay_D;
if (NextInst = '1') then
InstPtr_T := InstPtr_D + 1;
end if;
case InstPtr_D is
when "0000" =>
AddrData <= COM7 & x"80"; -- SCCB Register reset
We <= '1';
Start <= '1';
when "0001" =>
AddrData <= COM2 & x"00"; -- Enable 4x drive
We <= '1';
Start <= '1';
when "0010" =>
AddrData <= MVFP & x"10"; -- Flip image to it mount
We <= '1';
Start <= '1';
-- when "0001" =>
-- AddrData <= COM7 & x"00"; -- SCCB Register reset release
-- We <= '1';
-- Start <= '1';
--
-- when "0001" =>
-- AddrData <= COM7 & x"04"; -- Enable RGB
-- We <= '1';
-- Start <= '1';
----
-- when "0010" =>
-- AddrData <= COM15 & x"D0"; -- Enable RGB565
-- We <= '1';
-- Start <= '1';
-- when "0010" =>
-- AddrData <= AECH & x"01"; --
-- We <= '1';
-- Start <= '1';
-- when "0010" =>
-- AddrData <= COM8 & x"A9"; -- Enable banding filter, disable AGC
-- We <= '1';
-- Start <= '1';
-- when "0010" =>
-- AddrData <= CLKRC & x"80"; -- Reverse PCLK
-- We <= '1';
-- Start <= '1';
-- when "0010" =>
-- AddrData <= COM2 & x"11"; -- enable soft sleep
-- We <= '1';
-- Start <= '1';
-- when "0000" =>
-- AddrData <= TSLB & x"1C"; -- enable line buffer test option
-- We <= '1';
-- Start <= '1';
when others =>
InstPtr_T := (others => '1');
Start <= '0';
end case;
end if;
InstPtr_N <= InstPtr_T;
end process;
InstPtr <= InstPtr_D;
end architecture;