使用fpga初始化OV7670摄像头
OV7670摄像头初始化通过SCCI接口,由 I2C_Controller.v 底层SCCI 驱动模块和上层初始化参数配置构成 I2C_CCD_Config.v 。
模块应用硬件平台:
http://item.taobao.com/item.htm?id=6933324904
// ——————————————————————–
// Copyright (c) 2005 by amfpga.taobao.com .
// ——————————————————————–
// ——————————————————————–
//
// Terasic Technologies Inc
// 356 Fu-Shin E. Rd Sec. 1. JhuBei City,
// HsinChu County, Taiwan
// 302
//
// web: http://amfpga.taobao.com
// email: owein@163.com
//
// ——————————————————————–
//
// Major Functions:I2C_Controller.v
//
// ——————————————————————–
//
// Revision History :
// ——————————————————————–
// Ver 😐 Author 😐 Mod. Date 😐 Changes Made:
// V1.0 😐 Joe Yang 😐 05/07/10 😐 Initial Revision
// ——————————————————————–
module I2C_Controller (
CLOCK,
I2C_SCLK,//I2C CLOCK
I2C_SDAT,//I2C DATA
I2C_DATA,//DATA:[SLAVE_ADDR,SUB_ADDR,DATA]
GO, //GO transfor
END, //END transfor
W_R, //W_R
ACK, //ACK
RESET,
//TEST
SD_COUNTER,
SDO
);
input CLOCK;
input [23:0]I2C_DATA;
input GO;
input RESET;
input W_R;
inout I2C_SDAT;
output I2C_SCLK;
output END;
output ACK;
//TEST
output [5:0] SD_COUNTER;
output SDO;
reg SDO;
reg SCLK;
reg END;
reg [23:0]SD;
reg [5:0]SD_COUNTER;
wire I2C_SCLK=SCLK | ( ((SD_COUNTER >= 4) & (SD_COUNTER <=30))? ~CLOCK :0 );
wire I2C_SDAT=SDO?1\’bz:0 ;
reg ACK1,ACK2,ACK3;
wire ACK=ACK1 | ACK2 |ACK3;
//–I2C COUNTER
always @(negedge RESET or posedge CLOCK ) begin
if (!RESET) SD_COUNTER=6\’b111111;
else begin
if (GO==0)
SD_COUNTER=0;
else
if (SD_COUNTER < 6\’b111111) SD_COUNTER=SD_COUNTER+1;
end
end
//—-
always @(negedge RESET or posedge CLOCK ) begin
if (!RESET) begin SCLK=1;SDO=1; ACK1=0;ACK2=0;ACK3=0; END=1; end
else
case (SD_COUNTER)
6\’d0 : begin ACK1=0 ;ACK2=0 ;ACK3=0 ; END=0; SDO=1; SCLK=1;end
//start
6\’d1 : begin SD=I2C_DATA;SDO=0;end
6\’d2 : SCLK=0;
//SLAVE ADDR
6\’d3 : SDO=SD[23];
6\’d4 : SDO=SD[22];
6\’d5 : SDO=SD[21];
6\’d6 : SDO=SD[20];
6\’d7 : SDO=SD[19];
6\’d8 : SDO=SD[18];
6\’d9 : SDO=SD[17];
6\’d10 : SDO=SD[16];
6\’d11 : SDO=1\’b1;//ACK
//SUB ADDR
6\’d12 : begin SDO=SD[15]; ACK1=I2C_SDAT; end
6\’d13 : SDO=SD[14];
6\’d14 : SDO=SD[13];
6\’d15 : SDO=SD[12];
6\’d16 : SDO=SD[11];
6\’d17 : SDO=SD[10];
6\’d18 : SDO=SD[9];
6\’d19 : SDO=SD[8];
6\’d20 : SDO=1\’b1;//ACK
//DATA
6\’d21 : begin SDO=SD[7]; ACK2=I2C_SDAT; end
6\’d22 : SDO=SD[6];
6\’d23 : SDO=SD[5];
6\’d24 : SDO=SD[4];
6\’d25 : SDO=SD[3];
6\’d26 : SDO=SD[2];
6\’d27 : SDO=SD[1];
6\’d28 : SDO=SD[0];
6\’d29 : SDO=1\’b1;//ACK
//stop
6\’d30 : begin SDO=1\’b0; SCLK=1\’b0; ACK3=I2C_SDAT; end
6\’d31 : SCLK=1\’b1;
6\’d32 : begin SDO=1\’b1; END=1; end
endcase
end
endmodule
////////////////////////////////////////////////////////////////////////////////////////////////////////
////////// I2C_CCD_Config.v
////////////////////////////////////////////////////////////////////////////////////////////////////////
module I2C_CCD_Config ( // Host Side
iCLK,
iRST_N,
//iExposure,
// I2C Side
I2C_SCLK,
I2C_SDAT,
cmos_finish );
// Host Side
input iCLK;
input iRST_N;
//input [15:0] iExposure;
// I2C Side
output I2C_SCLK;
inout I2C_SDAT;
output cmos_finish;
// Internal Registers/Wires
reg [15:0] mI2C_CLK_DIV;
reg [23:0] mI2C_DATA;
reg mI2C_CTRL_CLK;
reg mI2C_GO;
wire mI2C_END;
wire mI2C_ACK;
reg [15:0] LUT_DATA;
reg [15:0] LUT_INDEX;
reg [3:0] mSetup_ST;
// Clock Setting
parameter CLK_Freq = 100000000; // 100 MHz
parameter I2C_Freq = 20000; // 200 KHz
// LUT Data Number
parameter LUT_SIZE = 165;
///////////////////// I2C Control Clock ////////////////////////
always@(posedge iCLK or negedge iRST_N)
begin
if(!iRST_N)
begin
mI2C_CTRL_CLK <= 0;
mI2C_CLK_DIV <= 0;
end
else
begin
if( mI2C_CLK_DIV < (CLK_Freq/I2C_Freq) )
mI2C_CLK_DIV <= mI2C_CLK_DIV+1;
else
begin
mI2C_CLK_DIV <= 0;
mI2C_CTRL_CLK <= ~mI2C_CTRL_CLK;
end
end
end
////////////////////////////////////////////////////////////////////
I2C_Controller ua ( .CLOCK(mI2C_CTRL_CLK), // Controller Work Clock
.I2C_SCLK(I2C_SCLK), // I2C CLOCK
.I2C_SDAT(I2C_SDAT), // I2C DATA
.I2C_DATA(mI2C_DATA), // DATA:[SLAVE_ADDR,SUB_ADDR,DATA]
.GO(mI2C_GO), // GO transfor
.END(mI2C_END), // END transfor
.ACK(mI2C_ACK), // ACK
.RESET(iRST_N) );
////////////////////////////////////////////////////////////////////
/*the slave device 8-bit address. The SADDR pin is used
to select between two different addresses in case of
conflict with another device. If SADDR is LOW, the
slave address is 0x90; if SADDR is HIGH, the slave
address is 0xBA.*/
////////////////////// Config Control ////////////////////////////
reg cmos_finish;
always@(posedge mI2C_CTRL_CLK or negedge iRST_N)
begin
if(!iRST_N)
begin
LUT_INDEX <= 0;
mSetup_ST <= 0;
mI2C_GO <= 0;
cmos_finish <= 1\’b0;
end
else
begin
if(LUT_INDEX<LUT_SIZE)
begin
case(mSetup_ST)
0: begin
mI2C_DATA <= {8\’h42,LUT_DATA};
mI2C_GO <= 1;
mSetup_ST <= 1;
end
1: begin
if(mI2C_END)
begin
if(!mI2C_ACK)
mSetup_ST <= 2;
else
mSetup_ST <= 0;
mI2C_GO <= 0;
end
end
2: begin
LUT_INDEX <= LUT_INDEX+1;
mSetup_ST <= 0;
end
endcase
end
else
cmos_finish <= 1\’b1;
end
end
////////////////////////////////////////////////////////////////////
///////////////////// Config Data LUT //////////////////////////
always
begin
case(LUT_INDEX)
0 : LUT_DATA <= 16\’h3a04;
1 : LUT_DATA <= 16\’h40d0;
2 : LUT_DATA <= 16\’h1214; // Mirror Row and Columns
3 : LUT_DATA <= 16\’h3280;
4 : LUT_DATA <= 16\’h1716;
5 : LUT_DATA <= 16\’h1804; // Green 1 Gain
6 : LUT_DATA <= 16\’h1902;
7 : LUT_DATA <= 16\’h1a7b; // Blue Gain
8 : LUT_DATA <= 16\’h0306;
9 : LUT_DATA <= 16\’h0c38; // Red Gain
10 : LUT_DATA <= 16\’h3e00;
11 : LUT_DATA <= 16\’h7000; // Green 2 Gain
12 : LUT_DATA <= 16\’h7100;
13 : LUT_DATA <= 16\’h7211; // H_Blanking
14 : LUT_DATA <= 16\’h7300;
15 : LUT_DATA <= 16\’ha202; // V_Blanking
16 : LUT_DATA <= 16\’h1101;
17 : LUT_DATA <= 16\’h7a20;
18 : LUT_DATA <= 16\’h7b1c;
19 : LUT_DATA <= 16\’h7c28;
20 : LUT_DATA <= 16\’h7d3c;
21 : LUT_DATA <= 16\’h7e55;
22 : LUT_DATA <= 16\’h7f68;
23 : LUT_DATA <= 16\’h8076;
24 : LUT_DATA <= 16\’h8180;
25 : LUT_DATA <= 16\’h8288;
26 : LUT_DATA <= 16\’h838f;
27 : LUT_DATA <= 16\’h8496;
28 : LUT_DATA <= 16\’h85a3;
29 : LUT_DATA <= 16\’h86af;
30 : LUT_DATA <= 16\’h87c4;
31 : LUT_DATA <= 16\’h88d7;
32 : LUT_DATA <= 16\’h89e8;
33 : LUT_DATA <= 16\’h138f;
34 : LUT_DATA <= 16\’h0000;
35 : LUT_DATA <= 16\’h1000;
36 : LUT_DATA <= 16\’h0d00;
37 : LUT_DATA <= 16\’h1410;
38 : LUT_DATA <= 16\’ha505;
39 : LUT_DATA <= 16\’hab07;
40 : LUT_DATA <= 16\’h2475;
41 : LUT_DATA <= 16\’h2563;
42 : LUT_DATA <= 16\’h26a5;
43 : LUT_DATA <= 16\’h9f78;
44 : LUT_DATA <= 16\’ha068;
45 : LUT_DATA <= 16\’ha103;
46 : LUT_DATA <= 16\’ha6df;
47 : LUT_DATA <= 16\’ha7df;
48 : LUT_DATA <= 16\’ha8f0;
49 : LUT_DATA <= 16\’ha990;
50 : LUT_DATA <= 16\’haa94;
51 : LUT_DATA <= 16\’h13e5;
52 : LUT_DATA <= 16\’h0e61;
53 : LUT_DATA <= 16\’h0f4b;
54 : LUT_DATA <= 16\’h1602;
55 : LUT_DATA <= 16\’h1e07;
56 : LUT_DATA <= 16\’h2102;
57 : LUT_DATA <= 16\’h2291;
58 : LUT_DATA <= 16\’h2907;
59 : LUT_DATA <= 16\’h330b;
60 : LUT_DATA <= 16\’h350b;
61 : LUT_DATA <= 16\’h371d;
62 : LUT_DATA <= 16\’h3871;
63 : LUT_DATA <= 16\’h392a;
64 : LUT_DATA <= 16\’h3c00;
65 : LUT_DATA <= 16\’h4d40;
66 : LUT_DATA <= 16\’h4e20;
67 : LUT_DATA <= 16\’h690c;
68 : LUT_DATA <= 16\’h6b40;
69 : LUT_DATA <= 16\’h7419;
70 : LUT_DATA <= 16\’h8d4f;
71 : LUT_DATA <= 16\’h8e00;
72 : LUT_DATA <= 16\’h8f00;
73 : LUT_DATA <= 16\’h9000;
74 : LUT_DATA <= 16\’h9100;
75 : LUT_DATA <= 16\’h9200;
76 : LUT_DATA <= 16\’h9600;
77 : LUT_DATA <= 16\’h9a80;
78 : LUT_DATA <= 16\’hb084;
79 : LUT_DATA <= 16\’hb10c;
80 : LUT_DATA <= 16\’hb20e;
81 : LUT_DATA <= 16\’hb382;
82 : LUT_DATA <= 16\’hb80a;
83 : LUT_DATA <= 16\’h4314;
84 : LUT_DATA <= 16\’h44f0;
85 : LUT_DATA <= 16\’h4534;
86 : LUT_DATA <= 16\’h4658;
87 : LUT_DATA <= 16\’h4728;
88 : LUT_DATA <= 16\’h483a;
89 : LUT_DATA <= 16\’h5988;
90 : LUT_DATA <= 16\’h5a88;
91 : LUT_DATA <= 16\’h5b44;
92 : LUT_DATA <= 16\’h5c67;
93 : LUT_DATA <= 16\’h5e0e;
94 : LUT_DATA <= 16\’h6404;
95 : LUT_DATA <= 16\’h6520;
96 : LUT_DATA <= 16\’h6605;
97 : LUT_DATA <= 16\’h9404;
98 : LUT_DATA <= 16\’h9508;
99 : LUT_DATA <= 16\’h6c0a;
100 : LUT_DATA <= 16\’h6d55;
101 : LUT_DATA <= 16\’h6e11;
102 : LUT_DATA <= 16\’h6f9f;
103 : LUT_DATA <= 16\’h6a40;
104 : LUT_DATA <= 16\’h0140;
105 : LUT_DATA <= 16\’h0240;
106 : LUT_DATA <= 16\’h13e7;
107 : LUT_DATA <= 16\’h1500;
108 : LUT_DATA <= 16\’h4f80;
109 : LUT_DATA <= 16\’h5080;
110 : LUT_DATA <= 16\’h5100;
111 : LUT_DATA <= 16\’h5222;
112 : LUT_DATA <= 16\’h535e;
113 : LUT_DATA <= 16\’h5480;
114 : LUT_DATA <= 16\’h589e;
115 : LUT_DATA <= 16\’h4108;
116 : LUT_DATA <= 16\’h3f00;
117 : LUT_DATA <= 16\’h7505;
118 : LUT_DATA <= 16\’h76c5;
119 : LUT_DATA <= 16\’h4c00;
120 : LUT_DATA <= 16\’h7701;
121 : LUT_DATA <= 16\’h3dc2;
122 : LUT_DATA <= 16\’h4b09;
123 : LUT_DATA <= 16\’hc960;
124 : LUT_DATA <= 16\’h4138;
125 : LUT_DATA <= 16\’h5640;
126 : LUT_DATA <= 16\’h3411;//
127 : LUT_DATA <= 16\’h3b02;
128 : LUT_DATA <= 16\’ha489;
129 : LUT_DATA <= 16\’h9600;
130 : LUT_DATA <= 16\’h9730;
131 : LUT_DATA <= 16\’h9820;
132 : LUT_DATA <= 16\’h9930;
133 : LUT_DATA <= 16\’h9a84;
134 : LUT_DATA <= 16\’h9b29;
135 : LUT_DATA <= 16\’h9c03;
136 : LUT_DATA <= 16\’h9d4c;
137 : LUT_DATA <= 16\’h9e3f;
138 : LUT_DATA <= 16\’h7804;
139 : LUT_DATA <= 16\’h7910;
140 : LUT_DATA <= 16\’hc87e;
141 : LUT_DATA <= 16\’h790a;
142 : LUT_DATA <= 16\’hc880;
143 : LUT_DATA <= 16\’h790b;
144 : LUT_DATA <= 16\’hc801;
145 : LUT_DATA <= 16\’h790b;
146 : LUT_DATA <= 16\’hc801;
147 : LUT_DATA <= 16\’h790c;
148 : LUT_DATA <= 16\’hc820;
149 : LUT_DATA <= 16\’h7909;
150 : LUT_DATA <= 16\’hc820;
151 : LUT_DATA <= 16\’h7909;
152 : LUT_DATA <= 16\’hc820;
153 : LUT_DATA <= 16\’h7909;
154 : LUT_DATA <= 16\’hc880;
155 : LUT_DATA <= 16\’h7902;
156 : LUT_DATA <= 16\’hc8c0;
157 : LUT_DATA <= 16\’h7903;
158 : LUT_DATA <= 16\’hc840;
159 : LUT_DATA <= 16\’h7905;
160 : LUT_DATA <= 16\’hc830;
161 : LUT_DATA <= 16\’h7926;
162 : LUT_DATA <= 16\’h0903;
163 : LUT_DATA <= 16\’h5500;
164 : LUT_DATA <= 16\’h5640;
165 : LUT_DATA <= 16\’h3b42;
default:LUT_DATA <= 16\’h0000;
endcase
end
////////////////////////////////////////////////////////////////////
endmodule