/************************gt9xx_config 触控驱动控制器********************* --1.上电后通过控制IO_t_ini和O_t_rst对触控芯片的工作模式进行设置,设置器件地址为0XBA --2.状态机中,通过轮询方式,不断访问触控芯片,读取坐标,这里读取3组坐标信息 *********************************************************************/
`timescale 1ns / 1ns
module gt9xx_config ( input I_clk, //系统时钟输入 input I_rstn, //系统复位 output O_t_rst, //触控屏中断信号,也用于上电初始化 inout IO_t_ini, //触控屏复位信号,也用于上电初始化 output reg O_iic_req, //I2C总线读写请求 output reg [31:0] O_wr_data, //I2C写数据 output reg [7:0] O_wr_cnt, //I2C写数据长度 input [31:0] I_rd_data, //I2C读数据 output reg [7:0] O_rd_cnt, //I2C读数据长度 input I_iic_busy,//I2C总线忙 output [15:0] O_tp1_x, //触控坐标1 X轴坐标 output [15:0] O_tp1_y, //触控坐标1 y轴坐标 output [15:0] O_tp2_x, //触控坐标2 X轴坐标 output [15:0] O_tp2_y, //触控坐标2 y轴坐标 output [15:0] O_tp3_x, //触控坐标3 X轴坐标 output [15:0] O_tp3_y //触控坐标3 y轴坐标 );
`define GT_CTRL_REG 16'h4080 //GT9xx控制寄存器 `define GT_CFGS_REG 16'h4780 //GT9xx配置起始地址寄存器 `define GT_CHECK_REG 16'hFF80 //GT9xx校验和寄存器 `define GT_PID_REG 16'h4081 //GT9xx产品ID寄存器
`define GT_GSTID_REG 16'h4E81 //GT9xx当前检测到的触摸状态寄存器 `define GT_TP1_REG 16'h5081 //第一个触摸点数据地址 `define GT_TP2_REG 16'h5881 //第二个触摸点数据地址 `define GT_TP3_REG 16'h6081 //第三个触摸点数据地址 //`define GT_TP4_REG 16'h6881 //第四个触摸点数据地址 //`define GT_TP5_REG 16'h7081 //第五个触摸点数据地址
//reset counter for delay time
reg t_ini_r=0 ; reg [24:0] rst_cnt = 25'd0;
assign O_t_rst = (rst_cnt[24] | rst_cnt[23]); // 触控芯片的复位,上电期间用于设置工作模式
assign IO_t_ini = (t_ini_r == 1'b0) ? 1'b0 : 1'bz; //中断信号上电期间用于设置工作模式
//上电后复位计数器 always@(posedge I_clk or negedge I_rstn) begin if(I_rstn == 1'b0) rst_cnt <= 0; else if(!rst_cnt[24]) rst_cnt <= rst_cnt + 1'b1; else rst_cnt <= rst_cnt; end
//触控芯片上电复位计数器 always@(posedge I_clk or negedge I_rstn) begin if(I_rstn == 1'b0 || rst_cnt[24] == 1'b0) t_ini_r <= 1'b0; else if(rst_cnt[24]) t_ini_r <= 1'b1; else t_ini_r <= t_ini_r; end
reg [3:0]TS_S; //状态机寄存器 reg [7:0]i; //计数器寄存器 reg [47:0] touch_x; //X坐标寄存器,保存3组X坐标数据,每组16bits reg [47:0] touch_y; //X坐标寄存器,保存3组y坐标数据,每组16bits
//把坐标分离开,方便观察和使用 wire [15:0]touch_x1 = touch_x[15:0]; wire [15:0]touch_x2 = touch_x[31:16]; wire [15:0]touch_x3 = touch_x[47:32]; wire [15:0]touch_y1 = touch_y[15:0]; wire [15:0]touch_y2 = touch_y[31:16]; wire [15:0]touch_y3 = touch_y[47:32];
assign O_tp1_x = touch_x1; assign O_tp1_y = touch_y1; assign O_tp2_x = touch_x2; assign O_tp2_y = touch_y2; assign O_tp3_x = touch_x3; assign O_tp3_y = touch_y3;
reg [7 :0] ctstate; //坐标状态寄存器 wire [47:0] GT9XX_TPX_TBL = {`GT_TP3_REG,`GT_TP2_REG,`GT_TP1_REG};//触控芯片相关寄存器初始化
//vio 观察坐标 vio_0 vio_dg (.clk(I_clk), .probe_in0(touch_x1), .probe_in1(touch_y1), .probe_in2(touch_x2), .probe_in3(touch_y2), .probe_in4(touch_x3), .probe_in5(touch_y3)); //ila 在线逻辑分析仪观察状内部信号和状态机 ila_0 ila_dg (.clk(I_clk),.probe0({TS_S,O_t_rst,O_iic_req,ctstate}));
//状态机 always@(posedge I_clk) begin if(!rst_cnt[24])begin //复位初始化信号和寄存器 i <= 8'd0; O_iic_req <= 1'b0; O_rd_cnt <= 8'd0; O_wr_data[31:0] <= {24'd0,8'hba};//8'hba为芯片的器件地址 touch_x <= 48'd0; touch_y <= 48'd0; ctstate <= 8'd0; TS_S <= 4'd0; end else begin case(TS_S) 0:begin//设置触控芯片的软件复位 O_iic_req <= 1'b1; //发送I2C总线操作请求 O_wr_cnt <= 8'd4; //写入4个数据 O_wr_data[23 :8] <= `GT_CTRL_REG; //GT9xx控制寄存器地址 O_wr_data[31:24] <= 8'd2; //软件复位值 if(I_iic_busy) //等在总线忙 TS_S <= 4'd1; //下一个状态 end 1:begin //等待I2C总线空闲 O_iic_req <= 1'b0; if(!I_iic_busy)begin //等待I2C总线空闲,代表I2C操作完成,软件复位完成 TS_S <= 4'd2;//下一个状态 end end 2:begin//重置触控屏芯片的控制寄存器 O_iic_req <= 1'b1;//发送I2C总线操作请求 O_wr_cnt <= 8'd4;//写入4个数据 O_wr_data[23 :8] <= `GT_CTRL_REG; //GT9xx控制寄存器地址 O_wr_data[31:24] <= 8'd0; //重置控制寄存器为0 if(I_iic_busy) //等在总线忙 TS_S <= 4'd3; //下一个状态 end 3:begin //等待I2C总线空闲 O_iic_req <= 1'b0; if(!I_iic_busy)//等待I2C总线空闲,代表I2C操作完成,软件复位完成 TS_S <= 4'd4;//下一个状态 end 4:begin//读取坐标值 O_iic_req <= 1'b1; O_wr_data[23 :8] <= `GT_GSTID_REG; //GT9xx触摸状态寄存器 O_wr_cnt <= 8'd3; //写入3个数据,器件地址,寄存器地址 O_rd_cnt <= 8'd1; //读出1个数据,状态寄存器 i <= 8'd0; //i用于计数 if(I_iic_busy) //等在总线忙 TS_S <= 4'd5; //下一个状态 end 5:begin //等待I2C总线空闲 O_iic_req <= 1'b0; if(!I_iic_busy)//等待I2C总线空闲,代表I2C操作完成,已经读到`GT_GSTID_REG状态寄存器 TS_S <= 4'd6;//下一个状态 end 6:begin //判断状态寄存器 if(I_rd_data[7:0]&8'h80)begin //确认状态寄存器是否有触控事件发生 ctstate <= I_rd_data[7:0]&8'h07;//触控状态,有多少触控点事件发生 TS_S <= 4'd7; //下一个状态 end else TS_S <= 4'd4; //如果没有触控事件发生,继续回到前一个状态,继续读状态寄存器 end 7:begin//重置触控状态寄存器 O_iic_req <= 1'b1; O_wr_data[23 :8] <= `GT_GSTID_REG; //GT9xx触摸状态寄存器 O_wr_data[31:24] <= 8'd0; //设置寄存器值为0 O_wr_cnt <= 8'd4; //I2C写入4BYTES O_rd_cnt <= 8'd0; //I2C不需要读数据 i <= 8'd0; //i计数器清零 if(I_iic_busy) //等待总线忙 ,代表I2C控制器开始工作 TS_S <= 4'd8; end 8:begin //等待I2C总线空闲 O_iic_req <= 1'b0; if(!I_iic_busy) //等待I2C总线空闲,代表I2C完成 `GT_GSTID_REG的重置 TS_S <= 4'd9; end 9:begin //读取1个坐标 O_iic_req <= 1'b1; O_wr_data[23 :8] <= GT9XX_TPX_TBL[i*16 +: 16]; //坐标的寄存器地址 O_wr_cnt <= 8'd3; //I2C 写3BYTES O_rd_cnt <= 8'd4; //i2c 读4BYTES if(I_iic_busy)//等待总线忙 ,代表I2C控制器开始工作 TS_S <= 4'd10; end 10:begin//等待I2C总线空闲 O_iic_req <= 1'b0; if(!I_iic_busy)//等待I2C总线空闲,代表I2C完成 GT9XX_TPX_TBL中对应的坐标寄存器读 TS_S <= 4'd11; end 11:begin //保存坐标值 touch_x[i*16 +: 16] <= I_rd_data[15: 0]; touch_y[i*16 +: 16] <= I_rd_data[31:16]; i <= i + 1'b1; //i计数器+1 if(i<8'd2) //判断本次是否读完3组坐标 TS_S <= 4'd9; //如果没读完,继续读 else TS_S <= 4'd4; //如果读完了,回到状态4 end default:TS_S <= 4'd0; endcase end end
endmodule |