|
|
@ -9,7 +9,8 @@ module i2c_ctrl(
|
|
|
|
output reg [2: 0] step ,
|
|
|
|
output reg [2: 0] step ,
|
|
|
|
output reg i2c_clk ,
|
|
|
|
output reg i2c_clk ,
|
|
|
|
output wire scl ,
|
|
|
|
output wire scl ,
|
|
|
|
inout wire sda
|
|
|
|
inout wire sda ,
|
|
|
|
|
|
|
|
output reg [7: 0] po_data
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
);
|
|
|
|
);
|
|
|
@ -44,6 +45,7 @@ reg skip_en_3 ;//步骤3跳转信号,配置0x00
|
|
|
|
reg skip_en_4 ;//步骤4跳转信号,读取0x20
|
|
|
|
reg skip_en_4 ;//步骤4跳转信号,读取0x20
|
|
|
|
reg skip_en_5 ;//步骤5跳转信号,配置51寄存器
|
|
|
|
reg skip_en_5 ;//步骤5跳转信号,配置51寄存器
|
|
|
|
reg skip_en_6 ;//步骤6跳转信号,配置0x43
|
|
|
|
reg skip_en_6 ;//步骤6跳转信号,配置0x43
|
|
|
|
|
|
|
|
reg skip_en_7 ;//步骤7跳转信号,读取0x43
|
|
|
|
reg [1: 0] cnt_i2c_clk ;//i2c计数器
|
|
|
|
reg [1: 0] cnt_i2c_clk ;//i2c计数器
|
|
|
|
reg [2: 0] cnt_bit ;//bit计数器
|
|
|
|
reg [2: 0] cnt_bit ;//bit计数器
|
|
|
|
reg i2c_end ;//i2c结束信号
|
|
|
|
reg i2c_end ;//i2c结束信号
|
|
|
@ -58,7 +60,7 @@ reg [7: 0] recv_data ;//接受0x20寄存器
|
|
|
|
reg ack ;//接受信号
|
|
|
|
reg ack ;//接受信号
|
|
|
|
reg err_en ;//接受到0x20有误
|
|
|
|
reg err_en ;//接受到0x20有误
|
|
|
|
//三态门
|
|
|
|
//三态门
|
|
|
|
assign sda_en = ((state_c == ACK_1) || (state_c == ACK_2) || (state_c == ACK_3) || (state_c == DATA && step == 3'd3)) ? 1'b0: 1'b1;//发送主机控制从机,接受主机释放
|
|
|
|
assign sda_en = ((state_c == ACK_1) || (state_c == ACK_2) || (state_c == ACK_3) || (state_c == DATA && (step == 3'd3 || step == 3'd6))) ? 1'b0: 1'b1;//发送主机控制从机,接受主机释放
|
|
|
|
assign sda_in = sda;
|
|
|
|
assign sda_in = sda;
|
|
|
|
assign sda = (sda_en == 1'b1)? i2c_sda : 1'bz;
|
|
|
|
assign sda = (sda_en == 1'b1)? i2c_sda : 1'bz;
|
|
|
|
//cfg_start
|
|
|
|
//cfg_start
|
|
|
@ -107,13 +109,13 @@ end
|
|
|
|
//状态机第二段
|
|
|
|
//状态机第二段
|
|
|
|
always @(*)begin
|
|
|
|
always @(*)begin
|
|
|
|
case(state_c)
|
|
|
|
case(state_c)
|
|
|
|
IDLE: if((skip_en_1 == 1'b1) || (skip_en_2 == 1'b1) || (skip_en_3 == 1'b1) || (skip_en_4 == 1'b1) || (skip_en_5 == 1'b1) || (skip_en_6 == 1'b1))begin
|
|
|
|
IDLE: if((skip_en_1 == 1'b1) || (skip_en_2 == 1'b1) || (skip_en_3 == 1'b1) || (skip_en_4 == 1'b1) || (skip_en_5 == 1'b1) || (skip_en_6 == 1'b1) || (skip_en_7 == 1'b1))begin
|
|
|
|
state_n = START;
|
|
|
|
state_n = START;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
else begin
|
|
|
|
state_n = IDLE;
|
|
|
|
state_n = IDLE;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
START: if((skip_en_1 == 1'b1) || (skip_en_2 == 1'b1) || (skip_en_3 == 1'b1) || (skip_en_4 == 1'b1) || (skip_en_5 == 1'b1) || (skip_en_6 == 1'b1))begin
|
|
|
|
START: if((skip_en_1 == 1'b1) || (skip_en_2 == 1'b1) || (skip_en_3 == 1'b1) || (skip_en_4 == 1'b1) || (skip_en_5 == 1'b1) || (skip_en_6 == 1'b1) || (skip_en_7 == 1'b1))begin
|
|
|
|
state_n = SLAVE_ADDR;
|
|
|
|
state_n = SLAVE_ADDR;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
else begin
|
|
|
@ -122,7 +124,7 @@ always @(*)begin
|
|
|
|
SLAVE_ADDR: if(skip_en_1 == 1'b1)begin
|
|
|
|
SLAVE_ADDR: if(skip_en_1 == 1'b1)begin
|
|
|
|
state_n = WAIT;
|
|
|
|
state_n = WAIT;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else if((skip_en_2 == 1'b1) || (skip_en_3 == 1'b1) || (skip_en_4 == 1'b1) || (skip_en_5 == 1'b1) || (skip_en_6 == 1'b1))begin
|
|
|
|
else if((skip_en_2 == 1'b1) || (skip_en_3 == 1'b1) || (skip_en_4 == 1'b1) || (skip_en_5 == 1'b1) || (skip_en_6 == 1'b1) || (skip_en_7 == 1'b1))begin
|
|
|
|
state_n = ACK_1;
|
|
|
|
state_n = ACK_1;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
else begin
|
|
|
@ -131,7 +133,7 @@ always @(*)begin
|
|
|
|
ACK_1: if((skip_en_2 == 1'b1) || (skip_en_3 == 1'b1) || (skip_en_5 == 1'b1) || (skip_en_6 == 1'b1))begin
|
|
|
|
ACK_1: if((skip_en_2 == 1'b1) || (skip_en_3 == 1'b1) || (skip_en_5 == 1'b1) || (skip_en_6 == 1'b1))begin
|
|
|
|
state_n = DEVICE_ADDR;
|
|
|
|
state_n = DEVICE_ADDR;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else if(skip_en_4 == 1'b1)begin
|
|
|
|
else if((skip_en_4 == 1'b1) || (skip_en_7 == 1'b1))begin
|
|
|
|
state_n = DATA;
|
|
|
|
state_n = DATA;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
else begin
|
|
|
@ -155,7 +157,7 @@ always @(*)begin
|
|
|
|
DATA: if((skip_en_2 == 1'b1) || (skip_en_5 == 1'b1))begin
|
|
|
|
DATA: if((skip_en_2 == 1'b1) || (skip_en_5 == 1'b1))begin
|
|
|
|
state_n = ACK_3;
|
|
|
|
state_n = ACK_3;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else if(skip_en_4 == 1'b1)begin
|
|
|
|
else if((skip_en_4 == 1'b1) || (skip_en_7 == 1'b1))begin
|
|
|
|
state_n = NACK;
|
|
|
|
state_n = NACK;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else if(err_en == 1'b1)begin
|
|
|
|
else if(err_en == 1'b1)begin
|
|
|
@ -164,7 +166,7 @@ always @(*)begin
|
|
|
|
else begin
|
|
|
|
else begin
|
|
|
|
state_n = DATA;
|
|
|
|
state_n = DATA;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
NACK: if(skip_en_4 == 1'b1)begin
|
|
|
|
NACK: if((skip_en_4 == 1'b1) || (skip_en_7 == 1'b1))begin
|
|
|
|
state_n = STOP;
|
|
|
|
state_n = STOP;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
else begin
|
|
|
@ -182,7 +184,7 @@ always @(*)begin
|
|
|
|
else begin
|
|
|
|
else begin
|
|
|
|
state_n = WAIT;
|
|
|
|
state_n = WAIT;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
STOP: if((skip_en_1 == 1'b1) || (skip_en_2 == 1'b1) || (skip_en_3 == 1'b1) || (skip_en_4 == 1'b1) || (skip_en_5 == 1'b1) || (skip_en_6 == 1'b1))begin
|
|
|
|
STOP: if((skip_en_1 == 1'b1) || (skip_en_2 == 1'b1) || (skip_en_3 == 1'b1) || (skip_en_4 == 1'b1) || (skip_en_5 == 1'b1) || (skip_en_6 == 1'b1) || (skip_en_7 == 1'b1))begin
|
|
|
|
state_n = IDLE;
|
|
|
|
state_n = IDLE;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
else begin
|
|
|
@ -203,6 +205,7 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin
|
|
|
|
skip_en_4 <= 1'b0;//步骤4跳转信号
|
|
|
|
skip_en_4 <= 1'b0;//步骤4跳转信号
|
|
|
|
skip_en_5 <= 1'b0;//步骤5跳转信号
|
|
|
|
skip_en_5 <= 1'b0;//步骤5跳转信号
|
|
|
|
skip_en_6 <= 1'b0;//步骤6跳转信号
|
|
|
|
skip_en_6 <= 1'b0;//步骤6跳转信号
|
|
|
|
|
|
|
|
skip_en_7 <= 1'b0;//步骤7跳转信号
|
|
|
|
step <= 3'd0;
|
|
|
|
step <= 3'd0;
|
|
|
|
err_en <= 1'b0;
|
|
|
|
err_en <= 1'b0;
|
|
|
|
cnt_i2c_clk <= 2'd0;
|
|
|
|
cnt_i2c_clk <= 2'd0;
|
|
|
@ -254,6 +257,12 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin
|
|
|
|
else begin
|
|
|
|
else begin
|
|
|
|
skip_en_6 <= 1'b0;
|
|
|
|
skip_en_6 <= 1'b0;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if((cnt_wait == MAX - 2'd2) && (step == 3'd6))begin
|
|
|
|
|
|
|
|
skip_en_7 <= 1'b1;
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
else begin
|
|
|
|
|
|
|
|
skip_en_7 <= 1'b0;
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
START: begin
|
|
|
|
START: begin
|
|
|
|
cnt_i2c_clk <= cnt_i2c_clk + 1'd1;
|
|
|
|
cnt_i2c_clk <= cnt_i2c_clk + 1'd1;
|
|
|
@ -293,6 +302,12 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin
|
|
|
|
else begin
|
|
|
|
else begin
|
|
|
|
skip_en_6 <= 1'b0;
|
|
|
|
skip_en_6 <= 1'b0;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if((cnt_i2c_clk == 2'd2) && (step == 3'd6))begin
|
|
|
|
|
|
|
|
skip_en_7 <= 1'b1;
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
else begin
|
|
|
|
|
|
|
|
skip_en_7 <= 1'b0;
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
SLAVE_ADDR: begin
|
|
|
|
SLAVE_ADDR: begin
|
|
|
|
cnt_i2c_clk <= cnt_i2c_clk + 1'd1;
|
|
|
|
cnt_i2c_clk <= cnt_i2c_clk + 1'd1;
|
|
|
@ -332,6 +347,12 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin
|
|
|
|
else begin
|
|
|
|
else begin
|
|
|
|
skip_en_6 <= 1'b0;
|
|
|
|
skip_en_6 <= 1'b0;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if((cnt_i2c_clk == 2'd2) && (step == 3'd6) && (cnt_bit == 3'd7))begin
|
|
|
|
|
|
|
|
skip_en_7 <= 1'b1;
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
else begin
|
|
|
|
|
|
|
|
skip_en_7 <= 1'b0;
|
|
|
|
|
|
|
|
end
|
|
|
|
if((cnt_bit == 3'd7) && (cnt_i2c_clk == 2'd3))begin
|
|
|
|
if((cnt_bit == 3'd7) && (cnt_i2c_clk == 2'd3))begin
|
|
|
|
cnt_bit <= 3'd0;
|
|
|
|
cnt_bit <= 3'd0;
|
|
|
|
end
|
|
|
|
end
|
|
|
@ -374,6 +395,12 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin
|
|
|
|
else begin
|
|
|
|
else begin
|
|
|
|
skip_en_6 <= 1'b0;
|
|
|
|
skip_en_6 <= 1'b0;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if((ack == 1'b1) && (cnt_i2c_clk == 2'd2) && (step == 3'd6))begin
|
|
|
|
|
|
|
|
skip_en_7 <= 1'b1;
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
else begin
|
|
|
|
|
|
|
|
skip_en_7 <= 1'b0;
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
DEVICE_ADDR:begin
|
|
|
|
DEVICE_ADDR:begin
|
|
|
|
cnt_i2c_clk <= cnt_i2c_clk + 1'b1;
|
|
|
|
cnt_i2c_clk <= cnt_i2c_clk + 1'b1;
|
|
|
@ -467,6 +494,12 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin
|
|
|
|
else begin
|
|
|
|
else begin
|
|
|
|
skip_en_5 <= 1'b0;
|
|
|
|
skip_en_5 <= 1'b0;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if((cnt_i2c_clk == 2'd2) && (cnt_bit == 3'd7) && (step == 3'd6))begin
|
|
|
|
|
|
|
|
skip_en_7 <= 1'b1;
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
else begin
|
|
|
|
|
|
|
|
skip_en_7 <= 1'b0;
|
|
|
|
|
|
|
|
end
|
|
|
|
if((cnt_i2c_clk == 2'd2) && (cnt_bit == 3'd7) && (step == 3'd3) && (recv_data != 8'h20))begin
|
|
|
|
if((cnt_i2c_clk == 2'd2) && (cnt_bit == 3'd7) && (step == 3'd3) && (recv_data != 8'h20))begin
|
|
|
|
begin
|
|
|
|
begin
|
|
|
|
err_en <= 1'b1;
|
|
|
|
err_en <= 1'b1;
|
|
|
@ -488,6 +521,12 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin
|
|
|
|
else begin
|
|
|
|
else begin
|
|
|
|
skip_en_4 <= 1'b0;
|
|
|
|
skip_en_4 <= 1'b0;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if((ack == 1'b1) && (cnt_i2c_clk == 2'd2) && (step == 3'd6))begin
|
|
|
|
|
|
|
|
skip_en_7 <= 1'b1;
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
else begin
|
|
|
|
|
|
|
|
skip_en_7 <= 1'b0;
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
ACK_3: begin
|
|
|
|
ACK_3: begin
|
|
|
|
cnt_i2c_clk <= cnt_i2c_clk + 1;
|
|
|
|
cnt_i2c_clk <= cnt_i2c_clk + 1;
|
|
|
@ -556,6 +595,12 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin
|
|
|
|
else begin
|
|
|
|
else begin
|
|
|
|
skip_en_6 <= 1'b0;
|
|
|
|
skip_en_6 <= 1'b0;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if((cnt_i2c_clk == 2'd2) && (step == 3'd6))begin
|
|
|
|
|
|
|
|
skip_en_7 <= 1'b1;
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
else begin
|
|
|
|
|
|
|
|
skip_en_7 <= 1'b0;
|
|
|
|
|
|
|
|
end
|
|
|
|
if(cnt_i2c_clk == 2'd2)begin
|
|
|
|
if(cnt_i2c_clk == 2'd2)begin
|
|
|
|
i2c_end <= 1'b1;
|
|
|
|
i2c_end <= 1'b1;
|
|
|
|
end
|
|
|
|
end
|
|
|
@ -580,6 +625,7 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin
|
|
|
|
skip_en_4 <= 1'b0;
|
|
|
|
skip_en_4 <= 1'b0;
|
|
|
|
skip_en_5 <= 1'b0;
|
|
|
|
skip_en_5 <= 1'b0;
|
|
|
|
skip_en_6 <= 1'b0;
|
|
|
|
skip_en_6 <= 1'b0;
|
|
|
|
|
|
|
|
skip_en_7 <= 1'b0;
|
|
|
|
err_en <= 1'b0;
|
|
|
|
err_en <= 1'b0;
|
|
|
|
step <= step;
|
|
|
|
step <= step;
|
|
|
|
cnt_i2c_clk <= 2'd0;
|
|
|
|
cnt_i2c_clk <= 2'd0;
|
|
|
@ -597,7 +643,7 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin
|
|
|
|
else begin
|
|
|
|
else begin
|
|
|
|
case(state_c)
|
|
|
|
case(state_c)
|
|
|
|
DATA: begin
|
|
|
|
DATA: begin
|
|
|
|
if((cnt_i2c_clk == 2'd1) && (step == 3'd3))begin
|
|
|
|
if((cnt_i2c_clk == 2'd1) && ((step == 3'd3) || (step == 3'd6)))begin
|
|
|
|
recv_data <= {recv_data[6:0], sda_in};
|
|
|
|
recv_data <= {recv_data[6:0], sda_in};
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
else begin
|
|
|
@ -649,6 +695,11 @@ always @(*)begin
|
|
|
|
device_addr= 8'h43;
|
|
|
|
device_addr= 8'h43;
|
|
|
|
wr_data = 8'h00;
|
|
|
|
wr_data = 8'h00;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
3'd6: begin
|
|
|
|
|
|
|
|
slave_addr = {SLAVE_ID, 1'b1};//读取
|
|
|
|
|
|
|
|
device_addr= 8'h43;
|
|
|
|
|
|
|
|
wr_data = 8'h00;
|
|
|
|
|
|
|
|
end
|
|
|
|
default:begin
|
|
|
|
default:begin
|
|
|
|
slave_addr = 8'h0;
|
|
|
|
slave_addr = 8'h0;
|
|
|
|
device_addr = 8'h0;
|
|
|
|
device_addr = 8'h0;
|
|
|
@ -674,7 +725,7 @@ always @(*)begin
|
|
|
|
START: i2c_sda = (cnt_i2c_clk > 2'd1) ? 1'b0 : 1'b1;
|
|
|
|
START: i2c_sda = (cnt_i2c_clk > 2'd1) ? 1'b0 : 1'b1;
|
|
|
|
SLAVE_ADDR: i2c_sda = slave_addr[7 - cnt_bit];
|
|
|
|
SLAVE_ADDR: i2c_sda = slave_addr[7 - cnt_bit];
|
|
|
|
DEVICE_ADDR:i2c_sda = device_addr[7 - cnt_bit];
|
|
|
|
DEVICE_ADDR:i2c_sda = device_addr[7 - cnt_bit];
|
|
|
|
DATA: if(step == 3'd3)begin
|
|
|
|
DATA: if((step == 3'd3) || (step == 3'd6))begin
|
|
|
|
i2c_sda = sda_in;
|
|
|
|
i2c_sda = sda_in;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
else begin
|
|
|
@ -689,4 +740,15 @@ always @(*)begin
|
|
|
|
endcase
|
|
|
|
endcase
|
|
|
|
end
|
|
|
|
end
|
|
|
|
assign scl = i2c_scl;
|
|
|
|
assign scl = i2c_scl;
|
|
|
|
|
|
|
|
always @(posedge i2c_clk or negedge sys_rst_n)begin
|
|
|
|
|
|
|
|
if(!sys_rst_n)begin
|
|
|
|
|
|
|
|
po_data <= 8'h0;
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
else if((state_c == DATA) && (step == 3'd6) && (cnt_bit == 3'd7) && (cnt_i2c_clk == 2'd3) && (recv_data != 8'h00))begin
|
|
|
|
|
|
|
|
po_data <= recv_data;
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
else begin
|
|
|
|
|
|
|
|
po_data <= po_data;
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
endmodule
|
|
|
|
endmodule
|