read 0x00

main
lincaigui 7 months ago
parent 97cbfb3f2b
commit 41d463d7be

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -19,7 +19,8 @@ parameter IDLE = 4'd0,
DEVICE_ADDR = 4'd6, DEVICE_ADDR = 4'd6,
DATA = 4'd7, DATA = 4'd7,
WAIT = 4'd8, WAIT = 4'd8,
STOP = 4'd9; NACK = 4'd9,
STOP = 4'd10;
reg [3: 0] state_c; reg [3: 0] state_c;
reg [3: 0] state_n; reg [3: 0] state_n;
//// ////
@ -34,6 +35,7 @@ reg [9: 0] cnt_wait ;//1000us
reg skip_en_1 ;//1 reg skip_en_1 ;//1
reg skip_en_2 ;//2 reg skip_en_2 ;//2
reg skip_en_3 ;//3 reg skip_en_3 ;//3
reg skip_en_4 ;//4
reg [2: 0] step ;// reg [2: 0] step ;//
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
@ -45,9 +47,11 @@ reg i2c_scl ;
reg [7: 0] slave_addr ; reg [7: 0] slave_addr ;
reg [7: 0] device_addr ; reg [7: 0] device_addr ;
reg [7: 0] wr_data ; reg [7: 0] wr_data ;
reg [7: 0] recv_data ;//0x20
reg ack ;// reg ack ;//
reg err_en ;//0x20
// //
assign sda_en = ((state_c == ACK_1) || (state_c == ACK_2) || (state_c == ACK_3)) ? 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)) ? 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;
//i2c //i2c
@ -87,13 +91,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))begin IDLE: if((skip_en_1 == 1'b1) || (skip_en_2 == 1'b1) || (skip_en_3 == 1'b1) || (skip_en_4 == 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))begin START: if((skip_en_1 == 1'b1) || (skip_en_2 == 1'b1) || (skip_en_3 == 1'b1) || (skip_en_4 == 1'b1))begin
state_n = SLAVE_ADDR; state_n = SLAVE_ADDR;
end end
else begin else begin
@ -102,7 +106,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))begin else if((skip_en_2 == 1'b1) || (skip_en_3 == 1'b1) || (skip_en_4 == 1'b1))begin
state_n = ACK_1; state_n = ACK_1;
end end
else begin else begin
@ -111,6 +115,9 @@ always @(*)begin
ACK_1: if((skip_en_2 == 1'b1) || (skip_en_3 == 1'b1))begin ACK_1: if((skip_en_2 == 1'b1) || (skip_en_3 == 1'b1))begin
state_n = DEVICE_ADDR; state_n = DEVICE_ADDR;
end end
else if(skip_en_4 == 1'b1)begin
state_n = DATA;
end
else begin else begin
state_n = ACK_1; state_n = ACK_1;
end end
@ -132,9 +139,21 @@ always @(*)begin
DATA: if(skip_en_2 == 1'b1)begin DATA: if(skip_en_2 == 1'b1)begin
state_n = ACK_3; state_n = ACK_3;
end end
else if(skip_en_4 == 1'b1)begin
state_n = NACK;
end
else if(err_en == 1'b1)begin
state_n = IDLE;
end
else begin else begin
state_n = DATA; state_n = DATA;
end end
NACK: if(skip_en_4 == 1'b1)begin
state_n = STOP;
end
else begin
state_n = NACK;
end
ACK_3: if(skip_en_2 == 1'b1)begin ACK_3: if(skip_en_2 == 1'b1)begin
state_n = STOP; state_n = STOP;
end end
@ -147,7 +166,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))begin STOP: if((skip_en_1 == 1'b1) || (skip_en_2 == 1'b1) || (skip_en_3 == 1'b1) || (skip_en_4 == 1'b1))begin
state_n = IDLE; state_n = IDLE;
end end
else begin else begin
@ -165,7 +184,9 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin
skip_en_1 <= 1'b0;//1 skip_en_1 <= 1'b0;//1
skip_en_2 <= 1'b0;//2 skip_en_2 <= 1'b0;//2
skip_en_3 <= 1'b0;//3 skip_en_3 <= 1'b0;//3
skip_en_4 <= 1'b0;//4
step <= 3'd0; step <= 3'd0;
err_en <= 1'b0;
cnt_i2c_clk <= 2'd0; cnt_i2c_clk <= 2'd0;
cnt_bit <= 3'd0; cnt_bit <= 3'd0;
i2c_end <= 1'b0; i2c_end <= 1'b0;
@ -197,6 +218,12 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin
else begin else begin
skip_en_3 <= 1'b0; skip_en_3 <= 1'b0;
end end
if((cnt_wait == MAX - 2'd2) && (step == 3'd3))begin
skip_en_4 <= 1'b1;
end
else begin
skip_en_4 <= 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;
@ -218,6 +245,12 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin
else begin else begin
skip_en_3 <= 1'b0; skip_en_3 <= 1'b0;
end end
if((cnt_i2c_clk == 2'd2) && (step == 3'd3))begin
skip_en_4 <= 1'b1;
end
else begin
skip_en_4 <= 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;
@ -239,6 +272,12 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin
else begin else begin
skip_en_3 <= 1'b0; skip_en_3 <= 1'b0;
end end
if((cnt_i2c_clk == 2'd2) && (step == 3'd3) && (cnt_bit == 3'd7))begin
skip_en_4 <= 1'b1;
end
else begin
skip_en_4 <= 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
@ -263,6 +302,12 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin
else begin else begin
skip_en_3 <= 1'b0; skip_en_3 <= 1'b0;
end end
if((ack == 1'b1) && (cnt_i2c_clk == 2'd2) && (step == 3'd3))begin
skip_en_4 <= 1'b1;
end
else begin
skip_en_4 <= 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;
@ -320,6 +365,33 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin
else begin else begin
skip_en_2 <= 1'b0; skip_en_2 <= 1'b0;
end end
if((cnt_i2c_clk == 2'd2) && (cnt_bit == 3'd7) && (step == 3'd3) && (recv_data == 8'h20))begin
skip_en_4 <= 1'b1;
end
else begin
skip_en_4 <= 1'b0;
end
if((cnt_i2c_clk == 2'd2) && (cnt_bit == 3'd7) && (step == 3'd3) && (recv_data != 8'h20))begin
begin
err_en <= 1'b1;
step <= 3'd0;
end
end
else begin
begin
err_en <= 1'b0;
step <= step;
end
end
end
NACK: begin
cnt_i2c_clk <= cnt_i2c_clk + 1;
if((ack == 1'b1) && (cnt_i2c_clk == 2'd2) && (step == 3'd3))begin
skip_en_4 <= 1'b1;
end
else begin
skip_en_4 <= 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;
@ -364,6 +436,12 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin
else begin else begin
skip_en_3 <= 1'b0; skip_en_3 <= 1'b0;
end end
if((cnt_i2c_clk == 2'd2) && (step == 3'd3))begin
skip_en_4 <= 1'b1;
end
else begin
skip_en_4 <= 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
@ -382,6 +460,8 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin
skip_en_1 <= 1'b0; skip_en_1 <= 1'b0;
skip_en_2 <= 1'b0; skip_en_2 <= 1'b0;
skip_en_3 <= 1'b0; skip_en_3 <= 1'b0;
skip_en_4 <= 1'b0;
err_en <= 1'b0;
step <= step; step <= step;
cnt_i2c_clk <= 2'd0; cnt_i2c_clk <= 2'd0;
cnt_bit <= 3'd0; cnt_bit <= 3'd0;
@ -390,10 +470,30 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin
endcase endcase
end end
end end
//recv_data
always @(posedge i2c_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
recv_data <= 8'h0;
end
else begin
case(state_c)
DATA: begin
if((cnt_i2c_clk == 2'd1) && (step == 3'd3))begin
recv_data <= {recv_data[6:0], sda_in};
end
else begin
recv_data <= recv_data;
end
end
default: recv_data <= recv_data;
endcase
end
end
//ack //ack
always @(*)begin always @(*)begin
case(state_c) case(state_c)
ACK_1, ACK_2, ACK_3: ack = ~sda_in; ACK_1, ACK_2, ACK_3: ack = ~sda_in;
NACK: ack = i2c_sda;//NACK
default: ack = 1'b0; default: ack = 1'b0;
endcase endcase
end end
@ -412,7 +512,12 @@ always @(*)begin
end end
3'd2: begin 3'd2: begin
slave_addr = {SLAVE_ID, 1'b0}; slave_addr = {SLAVE_ID, 1'b0};
device_addr= {8'hef}; device_addr= {8'h00};
wr_data = {8'h00};
end
3'd3: begin
slave_addr = {SLAVE_ID, 1'b1};//
device_addr= {8'h00};
wr_data = {8'h00}; wr_data = {8'h00};
end end
default:begin default:begin
@ -427,7 +532,7 @@ always @(*)begin
case(state_c) case(state_c)
IDLE: i2c_scl = 1'b1; IDLE: i2c_scl = 1'b1;
START: i2c_scl = (cnt_i2c_clk <= 2'd2) ? 1'b1 : 1'b0; START: i2c_scl = (cnt_i2c_clk <= 2'd2) ? 1'b1 : 1'b0;
SLAVE_ADDR, DEVICE_ADDR, DATA, ACK_1, ACK_2, ACK_3: SLAVE_ADDR, DEVICE_ADDR, DATA, ACK_1, ACK_2, ACK_3, NACK:
i2c_scl = ((cnt_i2c_clk == 2'd1) || (cnt_i2c_clk == 2'd2)) ? 1'b1 : 1'b0; i2c_scl = ((cnt_i2c_clk == 2'd1) || (cnt_i2c_clk == 2'd2)) ? 1'b1 : 1'b0;
WAIT: i2c_scl = 1'b0; WAIT: i2c_scl = 1'b0;
STOP: i2c_scl = (cnt_i2c_clk >= 2'd1) ? 1'b1 : 1'b0; STOP: i2c_scl = (cnt_i2c_clk >= 2'd1) ? 1'b1 : 1'b0;
@ -440,10 +545,16 @@ 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: i2c_sda = wr_data[7 - cnt_bit]; DATA: if(step == 3'd3)begin
i2c_sda = sda_in;
end
else begin
i2c_sda = wr_data[7 - cnt_bit];
end
ACK_1, ACK_2, ACK_3: ACK_1, ACK_2, ACK_3:
i2c_sda = 1'b0; i2c_sda = 1'b0;
WAIT: i2c_sda = 1'b0; WAIT: i2c_sda = 1'b0;
NACK: i2c_sda = 1'b1;//1
STOP: i2c_sda = (cnt_i2c_clk >= 2'd2) ? 1'b1 : 1'b0; STOP: i2c_sda = (cnt_i2c_clk >= 2'd2) ? 1'b1 : 1'b0;
default: i2c_sda = 1'b1; default: i2c_sda = 1'b1;
endcase endcase

Loading…
Cancel
Save