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