diff --git a/doc/~$$配置51寄存器波形图.~vsdx b/doc/~$$配置51寄存器波形图.~vsdx new file mode 100644 index 0000000..a2fc8ae Binary files /dev/null and b/doc/~$$配置51寄存器波形图.~vsdx differ diff --git a/doc/中文版使用手册.pdf b/doc/中文版使用手册.pdf new file mode 100644 index 0000000..6738f95 Binary files /dev/null and b/doc/中文版使用手册.pdf differ diff --git a/doc/英文版数据手册.pdf b/doc/英文版数据手册.pdf new file mode 100644 index 0000000..f78b7b6 Binary files /dev/null and b/doc/英文版数据手册.pdf differ diff --git a/doc/配置51寄存器波形图.vsdx b/doc/配置51寄存器波形图.vsdx new file mode 100644 index 0000000..f095b90 Binary files /dev/null and b/doc/配置51寄存器波形图.vsdx differ diff --git a/doc/配置51寄存器状态机.vsdx b/doc/配置51寄存器状态机.vsdx new file mode 100644 index 0000000..28a1eb5 Binary files /dev/null and b/doc/配置51寄存器状态机.vsdx differ diff --git a/rtl/ges_recognize.v b/rtl/ges_recognize.v index e69de29..fe7c3a2 100644 --- a/rtl/ges_recognize.v +++ b/rtl/ges_recognize.v @@ -0,0 +1,40 @@ +module ges_recognize( + input wire sys_clk , + input wire sys_rst_n , + + output wire scl , + inout wire sda +); +wire [2: 0] step ; +wire [5: 0] cfg_num ; +wire [15: 0] cfg_data ; +wire cfg_start ; +wire i2c_clk ; +wire i2c_start ; + +paj7620_cfg paj7620_cfg_inst( +.i2c_clk (i2c_clk ), +.sys_rst_n (sys_rst_n ), +.cfg_start (cfg_start ), +.step (step ), + +.cfg_num (cfg_num ), +.cfg_data (cfg_data ), +.i2c_start (i2c_start ) +); +i2c_ctrl i2c_ctrl_inst( +.sys_clk (sys_clk ), +.sys_rst_n (sys_rst_n ), +.i2c_start (i2c_start ), +.cfg_num (cfg_num ), +.cfg_data (cfg_data ), + +.cfg_start (cfg_start ), +.step (step ), +.i2c_clk (i2c_clk ), +.scl (scl ), +.sda (sda ) + + +); +endmodule \ No newline at end of file diff --git a/rtl/i2c_ctrl.v b/rtl/i2c_ctrl.v index 6db3e55..3591955 100644 --- a/rtl/i2c_ctrl.v +++ b/rtl/i2c_ctrl.v @@ -1,9 +1,16 @@ module i2c_ctrl( - input wire sys_clk , - input wire sys_rst_n , - - output wire scl , - inout wire sda + input wire sys_clk , + input wire sys_rst_n , + input wire i2c_start , + input wire [5: 0] cfg_num , + input wire [15: 0] cfg_data , + + output reg cfg_start , + output reg [2: 0] step , + output reg i2c_clk , + output wire scl , + inout wire sda + ); parameter I2C_CLK_DIV = 5'd24, @@ -27,7 +34,6 @@ reg [3: 0] state_n; //i2c时钟计数器 reg [4: 0] cnt_clk; -reg i2c_clk; ///// //中间信号定义 @@ -36,7 +42,7 @@ reg skip_en_1 ;//步骤1跳转信号 reg skip_en_2 ;//步骤2跳转信号 reg skip_en_3 ;//步骤3跳转信号 reg skip_en_4 ;//步骤4跳转信号 -reg [2: 0] step ;//步骤 +reg skip_en_5 ;//步骤5跳转信号 reg [1: 0] cnt_i2c_clk ;//i2c计数器 reg [2: 0] cnt_bit ;//bit计数器 reg i2c_end ;//i2c结束信号 @@ -54,6 +60,15 @@ 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_in = sda; assign sda = (sda_en == 1'b1)? i2c_sda : 1'bz; +//cfg_start +always @(posedge i2c_clk or negedge sys_rst_n)begin + if(!sys_rst_n)begin + cfg_start <= 1'b0; + end + else begin + cfg_start <= i2c_end;//延迟一个时钟输出 + end +end //i2c驱动时钟设计 always @(posedge sys_clk or negedge sys_rst_n) begin if(!sys_rst_n)begin @@ -91,13 +106,13 @@ end //状态机第二段 always @(*)begin 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))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))begin state_n = START; end else begin state_n = IDLE; end - START: if((skip_en_1 == 1'b1) || (skip_en_2 == 1'b1) || (skip_en_3 == 1'b1) || (skip_en_4 == 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))begin state_n = SLAVE_ADDR; end else begin @@ -106,13 +121,13 @@ always @(*)begin SLAVE_ADDR: if(skip_en_1 == 1'b1)begin state_n = WAIT; end - else if((skip_en_2 == 1'b1) || (skip_en_3 == 1'b1) || (skip_en_4 == 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))begin state_n = ACK_1; end else begin state_n = SLAVE_ADDR; end - 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) || (skip_en_5 == 1'b1))begin state_n = DEVICE_ADDR; end else if(skip_en_4 == 1'b1)begin @@ -121,13 +136,13 @@ always @(*)begin else begin state_n = ACK_1; end - DEVICE_ADDR:if((skip_en_2 == 1'b1) || (skip_en_3 == 1'b1))begin + DEVICE_ADDR:if((skip_en_2 == 1'b1) || (skip_en_3 == 1'b1) || (skip_en_5 == 1'b1))begin state_n = ACK_2; end else begin state_n = DEVICE_ADDR; end - ACK_2: if(skip_en_2 == 1'b1)begin + ACK_2: if((skip_en_2 == 1'b1) || (skip_en_5 == 1'b1))begin state_n = DATA; end else if(skip_en_3 == 1'b1)begin @@ -136,7 +151,7 @@ always @(*)begin else begin state_n = ACK_2; end - DATA: if(skip_en_2 == 1'b1)begin + DATA: if((skip_en_2 == 1'b1) || (skip_en_5 == 1'b1))begin state_n = ACK_3; end else if(skip_en_4 == 1'b1)begin @@ -154,7 +169,7 @@ always @(*)begin else begin state_n = NACK; end - ACK_3: if(skip_en_2 == 1'b1)begin + ACK_3: if((skip_en_2 == 1'b1) || (skip_en_5 == 1'b1))begin state_n = STOP; end else begin @@ -166,7 +181,7 @@ always @(*)begin else begin state_n = WAIT; end - STOP: if((skip_en_1 == 1'b1) || (skip_en_2 == 1'b1) || (skip_en_3 == 1'b1) || (skip_en_4 == 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))begin state_n = IDLE; end else begin @@ -185,6 +200,7 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin skip_en_2 <= 1'b0;//步骤2跳转信号 skip_en_3 <= 1'b0;//步骤3跳转信号 skip_en_4 <= 1'b0;//步骤4跳转信号 + skip_en_5 <= 1'b0;//步骤5跳转信号 step <= 3'd0; err_en <= 1'b0; cnt_i2c_clk <= 2'd0; @@ -224,6 +240,12 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin else begin skip_en_4 <= 1'b0; end + if((cnt_wait == MAX - 2'd2) && (step == 3'd4))begin + skip_en_5 <= 1'b1; + end + else begin + skip_en_5 <= 1'b0; + end end START: begin cnt_i2c_clk <= cnt_i2c_clk + 1'd1; @@ -251,6 +273,12 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin else begin skip_en_4 <= 1'b0; end + if((cnt_i2c_clk == 2'd2) && (step == 3'd4))begin + skip_en_5 <= 1'b1; + end + else begin + skip_en_5 <= 1'b0; + end end SLAVE_ADDR: begin cnt_i2c_clk <= cnt_i2c_clk + 1'd1; @@ -278,6 +306,12 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin else begin skip_en_4 <= 1'b0; end + if((cnt_i2c_clk == 2'd2) && (step == 3'd4) && (cnt_bit == 3'd7))begin + skip_en_5 <= 1'b1; + end + else begin + skip_en_5 <= 1'b0; + end if((cnt_bit == 3'd7) && (cnt_i2c_clk == 2'd3))begin cnt_bit <= 3'd0; end @@ -308,6 +342,12 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin else begin skip_en_4 <= 1'b0; end + if((ack == 1'b1) && (cnt_i2c_clk == 2'd2) && (step == 3'd4))begin + skip_en_5 <= 1'b1; + end + else begin + skip_en_5 <= 1'b0; + end end DEVICE_ADDR:begin cnt_i2c_clk <= cnt_i2c_clk + 1'b1; @@ -332,6 +372,12 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin else begin skip_en_3 <= 1'b0; end + if((cnt_i2c_clk == 2'd2) && (cnt_bit == 3'd7) && (step == 3'd4))begin + skip_en_5 <= 1'b1; + end + else begin + skip_en_5 <= 1'b0; + end end ACK_2: begin cnt_i2c_clk <= cnt_i2c_clk + 1; @@ -347,6 +393,12 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin else begin skip_en_3 <= 1'b0; end + if((ack == 1'b1) && (cnt_i2c_clk == 2'd2) && (step == 3'd4))begin + skip_en_5 <= 1'b1; + end + else begin + skip_en_5 <= 1'b0; + end end DATA: begin cnt_i2c_clk <= cnt_i2c_clk + 1'b1; @@ -371,6 +423,12 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin else begin skip_en_4 <= 1'b0; end + if((cnt_i2c_clk == 2'd2) && (cnt_bit == 3'd7) && (step == 3'd4))begin + skip_en_5 <= 1'b1; + end + else begin + skip_en_5 <= 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; @@ -401,6 +459,12 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin else begin skip_en_2 <= 1'b0; end + if((ack == 1'b1) && (cnt_i2c_clk == 2'd2) && (step == 3'd4))begin + skip_en_5 <= 1'b1; + end + else begin + skip_en_5 <= 1'b0; + end end WAIT: begin if(cnt_wait == MAX - 1'd1)begin @@ -442,13 +506,22 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin else begin skip_en_4 <= 1'b0; end + if((cnt_i2c_clk == 2'd2) && (step == 3'd4))begin + skip_en_5 <= 1'b1; + end + else begin + skip_en_5 <= 1'b0; + end if(cnt_i2c_clk == 2'd2)begin i2c_end <= 1'b1; end else begin i2c_end <= 1'b0; end - if(i2c_end == 1'b1)begin + if((i2c_end == 1'b1) && (step <= 3'd3))begin + step <= step + 1'd1; + end + else if((i2c_end == 1'b1) && (step == 3'd4) && (cfg_num == 6'd51))begin step <= step + 1'd1; end else begin @@ -461,6 +534,7 @@ always @(posedge i2c_clk or negedge sys_rst_n)begin skip_en_2 <= 1'b0; skip_en_3 <= 1'b0; skip_en_4 <= 1'b0; + skip_en_5 <= 1'b0; err_en <= 1'b0; step <= step; cnt_i2c_clk <= 2'd0; @@ -520,6 +594,11 @@ always @(*)begin device_addr= {8'h00}; wr_data = {8'h00}; end + 3'd4: begin + slave_addr = {SLAVE_ID, 1'b0}; + device_addr= cfg_data[15: 8]; + wr_data = cfg_data[7: 0]; + end default:begin slave_addr = 8'h0; device_addr = 8'h0; diff --git a/rtl/paj7620_cfg.v b/rtl/paj7620_cfg.v index e69de29..2bb55bc 100644 --- a/rtl/paj7620_cfg.v +++ b/rtl/paj7620_cfg.v @@ -0,0 +1,86 @@ +module paj7620_cfg( + input wire i2c_clk , + input wire sys_rst_n , + input wire cfg_start , + input wire [2: 0] step , + + output reg [5: 0] cfg_num , + output wire [15: 0] cfg_data , + output reg i2c_start +); +wire [15: 0] cfg_data_reg[50: 0]; +always @(posedge i2c_clk or negedge sys_rst_n)begin + if(!sys_rst_n)begin + cfg_num <= 6'd0; + end + else if((cfg_start == 1'b1) && (step == 3'd4))begin + cfg_num <= cfg_num + 1'd1; + end + else begin + cfg_num <= cfg_num; + end +end +always @(posedge i2c_clk or negedge sys_rst_n)begin + if(!sys_rst_n)begin + i2c_start <= 1'b0; + end + else if((cfg_data == 1'b1) && (step == 3'd4))begin + i2c_start <= 1'b1; + end + else begin + i2c_start <= 1'b0; + end +end +assign cfg_data = (step == 3'd4) ? cfg_data_reg[cfg_num - 1]:16'h0; +assign cfg_data_reg[00] = {8'hEF,8'h00}; +assign cfg_data_reg[01] = {8'h37,8'h07}; +assign cfg_data_reg[02] = {8'h38,8'h17}; +assign cfg_data_reg[03] = {8'h39,8'h06}; +assign cfg_data_reg[04] = {8'h42,8'h01}; +assign cfg_data_reg[05] = {8'h46,8'h2D}; +assign cfg_data_reg[06] = {8'h47,8'h0F}; +assign cfg_data_reg[07] = {8'h48,8'h3C}; +assign cfg_data_reg[08] = {8'h49,8'h00}; +assign cfg_data_reg[09] = {8'h4A,8'h1E}; +assign cfg_data_reg[10] = {8'h4C,8'h20}; +assign cfg_data_reg[11] = {8'h51,8'h10}; +assign cfg_data_reg[12] = {8'h5E,8'h10}; +assign cfg_data_reg[13] = {8'h60,8'h27}; +assign cfg_data_reg[14] = {8'h80,8'h42}; +assign cfg_data_reg[15] = {8'h81,8'h44}; +assign cfg_data_reg[16] = {8'h82,8'h04}; +assign cfg_data_reg[17] = {8'h8B,8'h01}; +assign cfg_data_reg[18] = {8'h90,8'h06}; +assign cfg_data_reg[19] = {8'h95,8'h0A}; +assign cfg_data_reg[20] = {8'h96,8'h0C}; +assign cfg_data_reg[21] = {8'h97,8'h05}; +assign cfg_data_reg[22] = {8'h9A,8'h14}; +assign cfg_data_reg[23] = {8'h9C,8'h3F}; +assign cfg_data_reg[24] = {8'hA5,8'h19}; +assign cfg_data_reg[25] = {8'hCC,8'h19}; +assign cfg_data_reg[26] = {8'hCD,8'h0B}; +assign cfg_data_reg[27] = {8'hCE,8'h13}; +assign cfg_data_reg[28] = {8'hCF,8'h64}; +assign cfg_data_reg[29] = {8'hD0,8'h21}; +assign cfg_data_reg[30] = {8'hEF,8'h01}; +assign cfg_data_reg[31] = {8'h02,8'h0F}; +assign cfg_data_reg[32] = {8'h03,8'h10}; +assign cfg_data_reg[33] = {8'h04,8'h02}; +assign cfg_data_reg[34] = {8'h25,8'h01}; +assign cfg_data_reg[35] = {8'h27,8'h39}; +assign cfg_data_reg[36] = {8'h28,8'h7F}; +assign cfg_data_reg[37] = {8'h29,8'h08}; +assign cfg_data_reg[38] = {8'h3E,8'hFF}; +assign cfg_data_reg[39] = {8'h5E,8'h3D}; +assign cfg_data_reg[40] = {8'h65,8'h96}; +assign cfg_data_reg[41] = {8'h67,8'h97}; +assign cfg_data_reg[42] = {8'h69,8'hCD}; +assign cfg_data_reg[43] = {8'h6A,8'h01}; +assign cfg_data_reg[44] = {8'h6D,8'h2C}; +assign cfg_data_reg[45] = {8'h6E,8'h01}; +assign cfg_data_reg[46] = {8'h72,8'h01}; +assign cfg_data_reg[47] = {8'h73,8'h35}; +assign cfg_data_reg[48] = {8'h74,8'h00}; +assign cfg_data_reg[49] = {8'h77,8'h01}; +assign cfg_data_reg[50] = {8'hEF,8'h00}; +endmodule \ No newline at end of file