module camera_iic(
clk,
rst_n,
sccb_scl,
sccb_sda,
Init_Flag
);
input clk;
input rst_n;
output sccb_scl;
inout sccb_sda;
output Init_Flag;
reg [7:0] ctl_cnt_r;
reg [7:0] pag_data;
reg [7:0] cfg_reg_data;
reg [15:0] cfg_data;
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
pag_data<= 8'd0;
cfg_reg_data<=8'd0;
cfg_data<=16'd0;
end
else begin
case(ctl_cnt_r)
8'd0 : begin pag_data<=8'd0; cfg_reg_data<=8'h33 ; cfg_data<=16'h0343 ; end
8'd1 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'hA115 ; end
8'd2 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h0020 ; end
8'd3 : begin pag_data<=8'd0; cfg_reg_data<=8'h38 ; cfg_data<=16'h0866 ; end
8'd4 : begin pag_data<=8'd2; cfg_reg_data<=8'h80 ; cfg_data<=16'h0168 ; end
8'd5 : begin pag_data<=8'd2; cfg_reg_data<=8'h81 ; cfg_data<=16'h6432 ; end
8'd6 : begin pag_data<=8'd2; cfg_reg_data<=8'h82 ; cfg_data<=16'h3296 ; end
8'd7 : begin pag_data<=8'd2; cfg_reg_data<=8'h83 ; cfg_data<=16'h9664 ; end
8'd8 : begin pag_data<=8'd2; cfg_reg_data<=8'h84 ; cfg_data<=16'h5028 ; end
8'd9 : begin pag_data<=8'd2; cfg_reg_data<=8'h85 ; cfg_data<=16'h2878 ; end
8'd10 : begin pag_data<=8'd2; cfg_reg_data<=8'h86 ; cfg_data<=16'h7850 ; end
8'd11 : begin pag_data<=8'd2; cfg_reg_data<=8'h87 ; cfg_data<=16'h0000 ; end
8'd12 : begin pag_data<=8'd2; cfg_reg_data<=8'h88 ; cfg_data<=16'h0152 ; end
8'd13 : begin pag_data<=8'd2; cfg_reg_data<=8'h89 ; cfg_data<=16'h015C ; end
8'd14 : begin pag_data<=8'd2; cfg_reg_data<=8'h8A ; cfg_data<=16'h00F4 ; end
8'd15 : begin pag_data<=8'd2; cfg_reg_data<=8'h8B ; cfg_data<=16'h0108 ; end
8'd16 : begin pag_data<=8'd2; cfg_reg_data<=8'h8C ; cfg_data<=16'h00FA ; end
8'd17 : begin pag_data<=8'd2; cfg_reg_data<=8'h8D ; cfg_data<=16'h00CF ; end
8'd18 : begin pag_data<=8'd2; cfg_reg_data<=8'h8E ; cfg_data<=16'h09AD ; end
8'd19 : begin pag_data<=8'd2; cfg_reg_data<=8'h8F ; cfg_data<=16'h091E ; end
8'd20 : begin pag_data<=8'd2; cfg_reg_data<=8'h90 ; cfg_data<=16'h0B3F ; end
8'd21 : begin pag_data<=8'd2; cfg_reg_data<=8'h91 ; cfg_data<=16'h0C85 ; end
8'd22 : begin pag_data<=8'd2; cfg_reg_data<=8'h92 ; cfg_data<=16'h0CFF ; end
8'd23 : begin pag_data<=8'd2; cfg_reg_data<=8'h93 ; cfg_data<=16'h0D86 ; end
8'd24 : begin pag_data<=8'd2; cfg_reg_data<=8'h94 ; cfg_data<=16'h163A ; end
8'd25 : begin pag_data<=8'd2; cfg_reg_data<=8'h95 ; cfg_data<=16'h0E47 ; end
8'd26 : begin pag_data<=8'd2; cfg_reg_data<=8'h96 ; cfg_data<=16'h103C ; end
8'd27 : begin pag_data<=8'd2; cfg_reg_data<=8'h97 ; cfg_data<=16'h1D35 ; end
8'd28 : begin pag_data<=8'd2; cfg_reg_data<=8'h98 ; cfg_data<=16'h173E ; end
8'd29 : begin pag_data<=8'd2; cfg_reg_data<=8'h99 ; cfg_data<=16'h1119 ; end
8'd30 : begin pag_data<=8'd2; cfg_reg_data<=8'h9A ; cfg_data<=16'h1663 ; end
8'd31 : begin pag_data<=8'd2; cfg_reg_data<=8'h9B ; cfg_data<=16'h1569 ; end
8'd32 : begin pag_data<=8'd2; cfg_reg_data<=8'h9C ; cfg_data<=16'h104C ; end
8'd33 : begin pag_data<=8'd2; cfg_reg_data<=8'h9D ; cfg_data<=16'h1015 ; end
8'd34 : begin pag_data<=8'd2; cfg_reg_data<=8'h9E ; cfg_data<=16'h1010 ; end
8'd35 : begin pag_data<=8'd2; cfg_reg_data<=8'h9F ; cfg_data<=16'h0B0A ; end
8'd36 : begin pag_data<=8'd2; cfg_reg_data<=8'hA0 ; cfg_data<=16'h0D53 ; end
8'd37 : begin pag_data<=8'd2; cfg_reg_data<=8'hA1 ; cfg_data<=16'h0D51 ; end
8'd38 : begin pag_data<=8'd2; cfg_reg_data<=8'hA2 ; cfg_data<=16'h0A44 ; end
8'd39 : begin pag_data<=8'd2; cfg_reg_data<=8'hA3 ; cfg_data<=16'h1545 ; end
8'd40 : begin pag_data<=8'd2; cfg_reg_data<=8'hA4 ; cfg_data<=16'h1643 ; end
8'd41 : begin pag_data<=8'd2; cfg_reg_data<=8'hA5 ; cfg_data<=16'h1231 ; end
8'd42 : begin pag_data<=8'd2; cfg_reg_data<=8'hA6 ; cfg_data<=16'h0047 ; end
8'd43 : begin pag_data<=8'd2; cfg_reg_data<=8'hA7 ; cfg_data<=16'h035C ; end
8'd44 : begin pag_data<=8'd2; cfg_reg_data<=8'hA8 ; cfg_data<=16'hFE30 ; end
8'd45 : begin pag_data<=8'd2; cfg_reg_data<=8'hA9 ; cfg_data<=16'h4625 ; end
8'd46 : begin pag_data<=8'd2; cfg_reg_data<=8'hAA ; cfg_data<=16'h47F3 ; end
8'd47 : begin pag_data<=8'd2; cfg_reg_data<=8'hAB ; cfg_data<=16'h5859 ; end
8'd48 : begin pag_data<=8'd2; cfg_reg_data<=8'hAC ; cfg_data<=16'h0000 ; end
8'd49 : begin pag_data<=8'd2; cfg_reg_data<=8'hAD ; cfg_data<=16'h0000 ; end
8'd50 : begin pag_data<=8'd2; cfg_reg_data<=8'hAE ; cfg_data<=16'h0000 ; end
8'd51 : begin pag_data<=8'd1; cfg_reg_data<=8'h08 ; cfg_data<=16'h01FC ; end ///////
8'd52 : begin pag_data<=8'd1; cfg_reg_data<=8'hBE ; cfg_data<=16'h0004 ; end
8'd53 : begin pag_data<=8'd0; cfg_reg_data<=8'h65 ; cfg_data<=16'hA000 ; end ////
8'd54 : begin pag_data<=8'd0; cfg_reg_data<=8'h65 ; cfg_data<=16'hA000 ; end //cfg_data<=16'd20 ; end
8'd55 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'hA102 ; end
8'd56 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h001F ; end
8'd57 : begin pag_data<=8'd1; cfg_reg_data<=8'h08 ; cfg_data<=16'h01FC ; end
8'd58 : begin pag_data<=8'd1; cfg_reg_data<=8'h08 ; cfg_data<=16'h01EC ; end
8'd59 : begin pag_data<=8'd1; cfg_reg_data<=8'h08 ; cfg_data<=16'h01FC ; end
8'd60 : begin pag_data<=8'd1; cfg_reg_data<=8'h36 ; cfg_data<=16'h0F08 ; end
8'd61 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h270B ; end
8'd62 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h0030 ; end
8'd63 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'hA121 ; end
8'd64 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h007f ; end
8'd65 : begin pag_data<=8'd0; cfg_reg_data<=8'h05 ; cfg_data<=16'h011E ; end
8'd66 : begin pag_data<=8'd0; cfg_reg_data<=8'h06 ; cfg_data<=16'h006F ; end
8'd67 : begin pag_data<=8'd0; cfg_reg_data<=8'h07 ; cfg_data<=16'hFE ; end
8'd68 : begin pag_data<=8'd0; cfg_reg_data<=8'h08 ; cfg_data<=16'd19 ; end
8'd69 : begin pag_data<=8'd0; cfg_reg_data<=8'h20 ; cfg_data<=16'h0300 ; end
8'd70 : begin pag_data<=8'd0; cfg_reg_data<=8'h21 ; cfg_data<=16'h8400 ; end
8'd71 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h2717 ; end
8'd72 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'd792 ; end
8'd73 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h270F ; end
8'd74 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h001C ; end
8'd75 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h2711 ; end
8'd76 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h003C ; end
8'd77 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h2713 ; end
8'd78 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h04B0 ; end
8'd79 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h2715 ; end
8'd80 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h0640 ; end
8'd81 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h2719 ; end
8'd82 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h0011 ; end
8'd83 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h2707 ; end
8'd84 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h0640 ; end
8'd85 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h2709 ; end
8'd86 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h04B0 ; end
8'd87 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h271B ; end
8'd88 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h001C ; end
8'd89 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h271D ; end
8'd90 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h003C ; end
8'd91 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h271F ; end
8'd92 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h04B0 ; end
8'd93 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h2721 ; end
8'd94 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h0640 ; end
8'd95 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h2723 ; end
8'd96 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h0716 ; end
8'd97 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h2725 ; end
8'd98 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h0011 ; end
8'd99 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h276B ; end
8'd100 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h0027 ; end
8'd101 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h276D ; end
8'd102 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'hE1E1 ; end
8'd103 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'hA76F ; end
8'd104 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h00E1 ; end
8'd105 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h2772 ; end
8'd106 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h0027 ; end
8'd107 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h2774 ; end
8'd108 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'hE1E1 ; end
8'd109 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'hA776 ; end
8'd110 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h00E1 ; end
8'd111 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'hA20E ; end
8'd112 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h0004 ; end
8'd113 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'hA20D ; end
8'd114 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h0004 ; end
8'd115 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h9078 ; end
8'd116 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h0000 ; end
8'd117 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h9079 ; end
8'd118 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h0000 ; end
8'd119 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h9070 ; end
8'd120 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h0000 ; end
8'd121 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h9071 ; end
8'd122 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h0000 ; end
8'd123 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'hA743 ; end
8'd124 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h0003 ; end
8'd125 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'hA744 ; end
8'd126 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h0003 ; end /////////
8'd127 : begin pag_data<=8'd0; cfg_reg_data<=8'hF2 ; cfg_data<=16'h0000 ; end
8'd128 : begin pag_data<=8'd0; cfg_reg_data<=8'h65 ; cfg_data<=16'hE000 ; end
8'd129 : begin pag_data<=8'd0; cfg_reg_data<=8'h66 ; cfg_data<=16'h1402 ; end // PLL_REG M=20,N=2 40M
8'd130 : begin pag_data<=8'd0; cfg_reg_data<=8'h67 ; cfg_data<=16'h0504 ; end
8'd131 : begin pag_data<=8'd0; cfg_reg_data<=8'h65 ; cfg_data<=16'hA000 ; end ///////////
8'd132 : begin pag_data<=8'd0; cfg_reg_data<=8'h65 ; cfg_data<=16'h2000 ; end ///////////
8'd133 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h2703 ; end
8'd134 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'd320 ; end //设置LCD 窗口大小
8'd135 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h2705 ; end
8'd136 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'd240 ; end
8'd137 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h2707 ; end
8'd138 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'd320 ; end
8'd139 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h2709 ; end
8'd140 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'd240 ; end
8'd141 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h2779 ; end
8'd142 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'd320 ; end
8'd143 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'h277B ; end
8'd144 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'd240 ; end
8'd145 : begin pag_data<=8'd1; cfg_reg_data<=8'hC6 ; cfg_data<=16'hA103 ; end
8'd146 : begin pag_data<=8'd1; cfg_reg_data<=8'hC8 ; cfg_data<=16'h0005 ; end
8'd147 : begin pag_data<=8'd1; cfg_reg_data<=8'h97 ; cfg_data<=16'h0020 ; end
8'd148 : begin pag_data<=8'd1; cfg_reg_data<=8'h97 ; cfg_data<=16'h0020 ; end //输出RGB565格式
8'd149 : begin pag_data<=8'd1; cfg_reg_data<=8'h98 ; cfg_data<=16'h0000 ; end
default:;
endcase
end
end
//产生sccb_iic需要的时钟
//---------------------------------------------
//分频部分
reg[2:0] cnt; // cnt=0:scl上升沿,cnt=1:scl高电平中间,cnt=2:scl下降沿,cnt=3:scl低电平中间
reg[12:0] cnt_delay; //500循环计数,产生iic所需要的时钟
reg scl_r; //时钟脉冲寄存器
reg[31:0] power_delay;
//reg chg_clk_fre;//改变iic频率
always @ (posedge clk or negedge rst_n) begin
if(!rst_n)
cnt_delay <= 13'd0;
else if(power_delay==32'd25000000) begin //上电延时100ms
if(cnt_delay == 13'd1999)
cnt_delay <= 13'd0; //计数到10us为scl的周期,即10KHz
else
cnt_delay <= cnt_delay+1'b1; //时钟计数
end
else
cnt_delay<=13'd500; //高电平
end
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) cnt <= 3'd5;
else begin
case (cnt_delay)
13'd499: cnt <= 3'd1; //cnt=1:scl高电平中间,用于数据采样
13'd1005: cnt <= 3'd2; //cnt=2:scl下降沿后面点
13'd1499: cnt <= 3'd3; //cnt=3:scl低电平中间,用于数据变化
13'd1995: cnt <= 3'd0; //cnt=0:scl上升沿前面点
default: cnt <= 3'd5;
endcase
end
end
`define SCL_POS (cnt==3'd0) //cnt=0:scl上升沿前面点
`define SCL_HIG (cnt==3'd1) //cnt=1:scl高电平中间,用于数据采样
`define SCL_NEG (cnt==3'd2) //cnt=2:scl下降沿后面点
`define SCL_LOW (cnt==3'd3) //cnt=3:scl低电平中间,用于数据变化
always @ (posedge clk or negedge rst_n) begin
if(!rst_n)
scl_r <= 1'b0;
else if(cnt_delay==13'd1999)
scl_r <= 1'b1; //scl信号上升沿
else if(cnt_delay==13'd999)
scl_r <= 1'b0; //scl信号下降沿
end
//初始化状态机进程
parameter IDLE =5'd0;
//写页寄存器
parameter START1 =5'd1;
parameter ADDR1 =5'd2;
parameter ACK1 =5'd3;
parameter PAG_REG =5'd4;
parameter ACK2 =5'd5;
parameter PAG_DATH =5'd6;
parameter ACK3 =5'd7;
parameter PAG_DATL =5'd8;
parameter ACK4 =5'd9;
parameter STOP1 =5'd10;
parameter DELAY1 =5'd11;
//写配置寄存器
parameter START2 =5'd12;
parameter ADDR2 =5'd13;
parameter ACK5 =5'd14;
parameter CFG_REG =5'd15;
parameter ACK6 =5'd16;
parameter CFG_DATH =5'd17;
parameter ACK7 =5'd18;
parameter CFG_DATL =5'd19;
parameter ACK8 =5'd20;
parameter STOP2 =5'd21;
parameter DELAY2 =5'd22;
parameter DELAY3 =5'd23;
parameter POWER_DLY =5'd24;
parameter STOP3 =5'd25;
//控制sccb_sda方向
reg sda_r; //输出数据寄存器
reg sda_link; //输出数据sda信号inout方向控制位
reg[4:0] Init_State;
reg[7:0] trans_data_r; //在IIC上传送的数据寄存器
reg[3:0] num; //读写的字节计数
reg[31:0] sccb_delay;
reg[19:0] st_delay;//停止信号和开始信号间隔时间10ms
reg[19:0] st_delay2;
`define MT9D111_WRITE 8'hba //被寻址器件地址(写操作)
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
Init_State<=POWER_DLY;
ctl_cnt_r<=8'd0;
sccb_delay<=32'd0;
power_delay<=32'd0;
st_delay<=20'd0;
st_delay2<=20'd0;
end
else begin
case(Init_State)
IDLE: begin
sda_link<=1'b1; //SDA设置为输出
sda_r<=1'b1;
if(ctl_cnt_r==8'd150)
Init_State<=IDLE;
else begin
Init_State<=START1;
trans_data_r<=`MT9D111_WRITE;
end
end
/////////////////////////////////////
START1: begin //SCL在高电平期间,sda从高到低
if(ctl_cnt_r==8'd150) begin //初始化完成
Init_State<=IDLE;
power_delay<=32'd0;
sda_link<=1'b1;
sda_r<=1'b1;//释放iic
end
else if(pag_data==8'd3) begin
Init_State<=DELAY3;
power_delay<=32'd0;
sda_link<=1'b1;
sda_r<=1'b1;//释放iic
end
else begin
if(`SCL_HIG) begin
sda_r<=1'b0; //拉低sda产生开始信号
Init_State<=ADDR1;
trans_data_r<=`MT9D111_WRITE; //从机地址
num<=4'd0;
end
else
Init_State<=START1;
end
end
//////////////////////////////
ADDR1: begin
if(`SCL_LOW) begin
if(num == 4'd8) begin
num <= 4'd0; //num计数清零
sda_r <= 1'b1;
sda_link <= 1'b0; //sda置为高阻态(input)
Init_State<= ACK1;
end
else begin
Init_State<=ADDR1;
num <= num+1'b1;
case (num)
4'd0: sda_r <= trans_data_r[7];
4'd1: sda_r <= trans_data_r[6];
4'd2: sda_r <= trans_data_r[5];
4'd3: sda_r <= trans_data_r[4];
4'd4: sda_r <= trans_data_r[3];
4'd5: sda_r <= trans_data_r[2];
4'd6: sda_r <= trans_data_r[1];
4'd7: sda_r <= trans_data_r[0];
default: ;
endcase
end
end
else
Init_State<=ADDR1;
end
/////////////////////////////////
ACK1: begin
if(`SCL_NEG) begin
if(sccb_sda==1'b0) begin
Init_State<=PAG_REG; //从机响应信号
trans_data_r<=8'hF0;
end
else
Init_State <= STOP3;
sda_link<=1'b1;
end
else
Init_State<= ACK1; //等待从机响应
end
////////////////////////////////////
PAG_REG: begin
if(`SCL_LOW) begin
if(num == 4'd8) begin
num <= 4'd0; //num计数清零
sda_r <= 1'b1;
sda_link <= 1'b0; //sda置为高阻态(input)
Init_State<= ACK2;
end
else begin
Init_State<=PAG_REG;
num <= num+1'b1;
case (num)
4'd0: sda_r <= trans_data_r[7];
4'd1: sda_r <= trans_data_r[6];
4'd2: sda_r <= trans_data_r[5];
4'd3: sda_r <= trans_data_r[4];
4'd4: sda_r <= trans_data_r[3];
4'd5: sda_r <= trans_data_r[2];
4'd6: sda_r <= trans_data_r[1];
4'd7: sda_r <= trans_data_r[0];
default: ;
endcase
end
end
else
Init_State<=PAG_REG;
end
/////////////////////////////////
ACK2: begin
if(`SCL_NEG) begin
if(sccb_sda==1'b0) begin
Init_State<=PAG_DATH; //从机响应信号
trans_data_r<=8'h00;
end
else
Init_State <= STOP3;
sda_link<=1'b1;
end
else
Init_State<= ACK2; //等待从机响应
end
////////////////////////////////////
PAG_DATH: begin
if(`SCL_LOW) begin
if(num == 4'd8) begin
num <= 4'd0; //num计数清零
sda_r <= 1'b1;
sda_link <= 1'b0; //sda置为高阻态(input)
Init_State<= ACK3;
end
else begin
Init_State<=PAG_DATH;
num <= num+1'b1;
case (num)
4'd0: sda_r <= trans_data_r[7];
4'd1: sda_r <= trans_data_r[6];
4'd2: sda_r <= trans_data_r[5];
4'd3: sda_r <= trans_data_r[4];
4'd4: sda_r <= trans_data_r[3];
4'd5: sda_r <= trans_data_r[2];
4'd6: sda_r <= trans_data_r[1];
4'd7: sda_r <= trans_data_r[0];
default: ;
endcase
end
end
else
Init_State<=PAG_DATH;
end
///////////////////////////////
ACK3: begin
if(`SCL_NEG) begin
if(sccb_sda==1'b0) begin
Init_State<=PAG_DATL; //从机响应信号
trans_data_r<=pag_data;
end
else
Init_State <= STOP3;
sda_link<=1'b1;
end
else
Init_State<= ACK3; //等待从机响应
end
///////////////////////////////
PAG_DATL: begin
if(`SCL_LOW) begin
if(num == 4'd8) begin
num <= 4'd0; //num计数清零
sda_r <= 1'b1;
sda_link <= 1'b0; //sda置为高阻态(input)
Init_State<= ACK4;
end
else begin
Init_State<=PAG_DATL;
num <= num+1'b1;
case (num)
4'd0: sda_r <= trans_data_r[7];
4'd1: sda_r <= trans_data_r[6];
4'd2: sda_r <= trans_data_r[5];
4'd3: sda_r <= trans_data_r[4];
4'd4: sda_r <= trans_data_r[3];
4'd5: sda_r <= trans_data_r[2];
4'd6: sda_r <= trans_data_r[1];
4'd7: sda_r <= trans_data_r[0];
default: ;
endcase
end
end
else
Init_State<=PAG_DATL;
end
////////////////////////////////////////
ACK4: begin
if(`SCL_NEG) begin
if(sccb_sda==1'b0) begin
Init_State <=STOP1; //从机响应信号
end
else
Init_State <= STOP3; ;
sda_link <=1'b1;
end
else
Init_State<= ACK4; //等待从机响应
end
////////////////////////////////////
STOP1: begin
if(`SCL_LOW) begin
sda_link <= 1'b1;
sda_r <= 1'b0;
Init_State<= STOP1;
end
else if(`SCL_HIG) begin
sda_r <= 1'b1; //scl为高时,sda产生上升沿(结束信号)
Init_State<= DELAY1;
end
else
Init_State <= STOP1;
end
//////////////////////////////
DELAY1: begin
if(st_delay==20'd500000) begin //延时10ms
power_delay<=32'd25000000; //恢复SCL时钟
st_delay<=20'd0;
Init_State <= START2;
end
else begin
power_delay<=32'd0; //禁能I2C时钟
st_delay<=st_delay+1'b1;
Init_State <= DELAY1;
end
end
/////////////////////////
START2: begin
if(`SCL_HIG) begin //scl为高电平中间
sda_r <= 1'b0; //拉低数据线sda,产生起始位信号
Init_State <=ADDR2;
trans_data_r<=`MT9D111_WRITE;
end
else
Init_State <= START2;
end
///////////////////////////////
ADDR2: begin
if(`SCL_LOW) begin
if(num == 4'd8) begin
num <= 4'd0; //num计数清零
sda_r <= 1'b1;
sda_link <= 1'b0; //sda置为高阻态(input)
Init_State<= ACK5;
end
else begin
Init_State<=ADDR2;
num <= num+1'b1;
case (num)
4'd0: sda_r <= trans_data_r[7];
4'd1: sda_r <= trans_data_r[6];
4'd2: sda_r <= trans_data_r[5];
4'd3: sda_r <= trans_data_r[4];
4'd4: sda_r <= trans_data_r[3];
4'd5: sda_r <= trans_data_r[2];
4'd6: sda_r <= trans_data_r[1];
4'd7: sda_r <= trans_data_r[0];
default: ;
endcase
end
end
else
Init_State<=ADDR2;
end
////////////////////////////////////////
ACK5: begin
if(`SCL_NEG) begin
if(sccb_sda==1'b0) begin
Init_State <=CFG_REG; //从机响应信号
trans_data_r <=cfg_reg_data;
end
else
Init_State <= STOP3;
sda_link <=1'b1;
end
else
Init_State<= ACK5; //等待从机响应
end
/////////////////////////////////////////
CFG_REG: begin
if(`SCL_LOW) begin
if(num == 4'd8) begin
num <= 4'd0; //num计数清零
sda_r <= 1'b1;
sda_link <= 1'b0; //sda置为高阻态(input)
Init_State<= ACK6;
end
else begin
Init_State<=CFG_REG;
num <= num+1'b1;
case (num)
4'd0: sda_r <= trans_data_r[7];
4'd1: sda_r <= trans_data_r[6];
4'd2: sda_r <= trans_data_r[5];
4'd3: sda_r <= trans_data_r[4];
4'd4: sda_r <= trans_data_r[3];
4'd5: sda_r <= trans_data_r[2];
4'd6: sda_r <= trans_data_r[1];
4'd7: sda_r <= trans_data_r[0];
default: ;
endcase
end
end
else
Init_State<=CFG_REG;
end
////////////////////////////////////////
ACK6: begin
if(`SCL_NEG) begin
if(sccb_sda==1'b0) begin
Init_State <=CFG_DATH; //从机响应信号
trans_data_r<=cfg_data[15:8];
end
else
Init_State <= STOP3;
sda_link <=1'b1;
end
else
Init_State<= ACK6; //等待从机响应
end
///////////////////////////////////////
CFG_DATH: begin
if(`SCL_LOW) begin
if(num == 4'd8) begin
num <= 4'd0; //num计数清零
sda_r <= 1'b1;
sda_link <= 1'b0; //sda置为高阻态(input)
Init_State<= ACK7;
end
else begin
Init_State<=CFG_DATH;
num <= num+1'b1;
case (num)
4'd0: sda_r <= trans_data_r[7];
4'd1: sda_r <= trans_data_r[6];
4'd2: sda_r <= trans_data_r[5];
4'd3: sda_r <= trans_data_r[4];
4'd4: sda_r <= trans_data_r[3];
4'd5: sda_r <= trans_data_r[2];
4'd6: sda_r <= trans_data_r[1];
4'd7: sda_r <= trans_data_r[0];
default: ;
endcase
end
end
else
Init_State<=CFG_DATH;
end
////////////////////////////////////////
ACK7: begin
if(`SCL_NEG) begin
if(sccb_sda==1'b0) begin
Init_State <=CFG_DATL; //从机响应信号
trans_data_r <=cfg_data[7:0];
end
else
Init_State <= STOP3;
sda_link <=1'b1;
end
else
Init_State<= ACK7; //等待从机响应
end
///////////////////////////////////////////////
CFG_DATL: begin
if(`SCL_LOW) begin
if(num == 4'd8) begin
num <= 4'd0; //num计数清零
sda_r <= 1'b1;
sda_link <= 1'b0; //sda置为高阻态(input)
Init_State<= ACK8;
end
else begin
Init_State<=CFG_DATL;
num <= num+1'b1;
case (num)
4'd0: sda_r <= trans_data_r[7];
4'd1: sda_r <= trans_data_r[6];
4'd2: sda_r <= trans_data_r[5];
4'd3: sda_r <= trans_data_r[4];
4'd4: sda_r <= trans_data_r[3];
4'd5: sda_r <= trans_data_r[2];
4'd6: sda_r <= trans_data_r[1];
4'd7: sda_r <= trans_data_r[0];
default: ;
endcase
end
end
else
Init_State<=CFG_DATL;
end
////////////////////////////////////////
ACK8: begin
if(`SCL_NEG) begin
if(sccb_sda==1'b0) begin
Init_State <=STOP2; //从机响应信号
end
else
Init_State <= STOP3;
sda_link <=1'b1;
end
else
Init_State<= ACK8; //等待从机响应
end
///////////////////////////////////
STOP2: begin
if(`SCL_LOW) begin
sda_link <= 1'b1;
sda_r <= 1'b0;
Init_State<= STOP2;
end
else if(`SCL_HIG) begin
sda_r <= 1'b1; //scl为高时,sda产生上升沿(结束信号)
Init_State<= DELAY2;
end
else
Init_State <= STOP2;
end
////////////////////////////////
DELAY2: begin
if(st_delay2==20'd500000) begin //延时10ms
power_delay<=32'd25000000; //恢复SCL时钟
st_delay2<=20'd0;
Init_State <= START1;
ctl_cnt_r<=ctl_cnt_r+1'b1; //切换到写下一个寄存器
end
else begin
power_delay<=32'd0; //禁能I2C时钟
st_delay2<=st_delay2+1'b1;
Init_State <= DELAY2;
end
end
//////////////////////////////////////
DELAY3: begin
if(sccb_delay==32'd25000000) begin //延时500ms
power_delay<=32'd25000000; //恢复SCL时钟
sccb_delay<=32'd0;
Init_State <= START1;
//ctl_cnt_r<=ctl_cnt_r+1'b1; //切换到写下一个寄存器
end
else begin
power_delay<=32'd0; //禁能I2C时钟
sccb_delay <=sccb_delay+1'b1;
Init_State <= DELAY3;
end
end
//////////////////////////////
POWER_DLY:begin
if(power_delay<32'd25000000)begin
power_delay<=power_delay+1'b1;
Init_State <= POWER_DLY;
end
else
Init_State <= IDLE;
end
///////////////////////////////////////
STOP3: begin
if(`SCL_LOW) begin
sda_link <= 1'b1;
sda_r <= 1'b0;
Init_State<= STOP3;
end
else if(`SCL_HIG) begin
sda_r <= 1'b1; //scl为高时,sda产生上升沿(结束信号)
Init_State<= START1;
// ctl_cnt_r<=1'b0; //重新写
end
else
Init_State <= STOP3;
end
default: ;
//////////////////////////////////////////
endcase
end
end
assign sccb_sda = sda_link? sda_r:1'bz;
assign sccb_scl = scl_r; //产生sccb_iic所需要的时钟
assign Init_Flag=(ctl_cnt_r==150)? 1'b0 : 1'b1;
endmodule