Edit online

在 gt911 基础上修改新 CTP 驱动

3 Mar 2025
Read time: 23 minute(s)
本节以将 GT911 驱动修改为 CST826 驱动为例,描述通过修改已有 CTP 驱动进行 CTP 移植的详细流程。
  1. 修改编译路径

    打开 bsp/peripheral/touch/SConscript 文件,并将 GT911 文件编译路径描述修改为 CST826 文件编译路径。

    示例如下:
    • 修改前,GT911 文件编译路径:
      if GetDepend('AIC_TOUCH_PANEL_GT911'):
          CPPPATH.append(cwd + '/gt911/inc')
          src += Glob('gt911/src/*.c')
    • 修改后,CST826 文件编译路径:
      if GetDepend('AIC_TOUCH_PANEL_CST826'):
          CPPPATH.append(cwd + '/cst826/inc')
          src += Glob('cst826/src/*.c')
  2. 修改 menuconfig 设备配置
    打开 bsp/peripheral/touch/Kconfig 文件,将 GT911 的设备和设备名分别修改为 CST826 的设备和设备名:
    • 修改前:
      choice
          prompt "Select CTP device"
          default AIC_TOUCH_PANEL_GT911
          depends on AIC_USING_CTP
      
          config AIC_TOUCH_PANEL_GT911                        //设备
              bool "GT911"
      
      config AIC_TOUCH_PANEL_NAME
          string
          default "gt911"     if AIC_TOUCH_PANEL_GT911        //设备名
    • 修改后:
      choice
          prompt "Select CTP device"
          default AIC_TOUCH_PANEL_GT911
          depends on AIC_USING_CTP
      
          config AIC_TOUCH_PANEL_CST826                       //设备
              bool "CST826"
      
      config AIC_TOUCH_PANEL_NAME
          string
          default "cst826"    if AIC_TOUCH_PANEL_CST826       //设备名
  3. 修改文件名
    打开 bsp/peripheral/touch 文件目录,将 gt911 文件夹名称及其源文件名称修改为cst826
    • 修改前:


    • 修改后:


  4. 修改源代码 gt911.c 文件如下

    #include <rtthread.h>
    #include <rtdevice.h>
    #include <string.h>
    //#define DBG_TAG "gt911"
    #define DBG_TAG "cst826"
    #define DBG_LVL DBG_INFO
    #include <rtdbg.h>
    //#include "gt911.h"
    #include "cst826.h"
    //static struct rt_i2c_client gt911_client;
    static struct rt_i2c_client cst826_client;
    
    //下面的数组是gt911的部分固件数组注释掉或者直接删除
    // static rt_uint8_t GT911_CFG_TBL[] = {
    //     0x6b, 0x00, 0x04, 0x58, 0x02, 0x05, 0x0d, 0x00, 0x01, 0x0f, 0x28, 0x0f,
    //     0x50, 0x32, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    //     0x00, 0x00, 0x00, 0x8a, 0x2a, 0x0c, 0x45, 0x47, 0x0c, 0x08, 0x00, 0x00,
    //     0x00, 0x40, 0x03, 0x2c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x64, 0x32,
    //     0x00, 0x00, 0x00, 0x28, 0x64, 0x94, 0xd5, 0x02, 0x07, 0x00, 0x00, 0x04,
    //     0x95, 0x2c, 0x00, 0x8b, 0x34, 0x00, 0x82, 0x3f, 0x00, 0x7d, 0x4c, 0x00,
    //     0x7a, 0x5b, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    //     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    //     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    //     0x00, 0x00, 0x00, 0x00, 0x18, 0x16, 0x14, 0x12, 0x10, 0x0e, 0x0c, 0x0a,
    //     0x08, 0x06, 0x04, 0x02, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    //     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x18,
    //     0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x24, 0x13, 0x12, 0x10, 0x0f,
    //     0x0a, 0x08, 0x06, 0x04, 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    //     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    //     0x00, 0x00, 0x00, 0x00, 0x79, 0x01,
    // };
    
    /*
     * I2C写函数,主要传参有三个:dev,要写入的数据,写入数据的长度
     * 这个函数适用于所有的TP,编写的时候只需要更换函数名字,跟TP对应上即可
     */
    //static rt_err_t gt911_write_reg(struct rt_i2c_client *dev, rt_uint8_t *data, rt_uint8_t len)
    static rt_err_t cst826_write_reg(struct rt_i2c_client *dev, rt_uint8_t *data, rt_uint8_t len)
    {
        struct rt_i2c_msg msgs;
    
        msgs.addr = dev->client_addr;
        msgs.flags = RT_I2C_WR;
        msgs.buf = data;
        msgs.len = len;
    
        if (rt_i2c_transfer(dev->bus, &msgs, 1) == 1) {
            return RT_EOK;
        } else {
            return -RT_ERROR;
        }
    }
    
    /*
     * I2C读函数,主要传参有四个:dev,要读取的寄存器地址,接受数据的buf,读取的长度
     * 这个函数适用于所有的TP,编写的时候只需要更换函数名字,跟TP对应上即可
     */
    //static rt_err_t gt911_read_regs(struct rt_i2c_client *dev, rt_uint8_t *reg,
    //                                  rt_uint8_t *data, rt_uint8_t len)
    static rt_err_t cst826_read_regs(struct rt_i2c_client *dev, rt_uint8_t *reg,
                                     rt_uint8_t *data, rt_uint8_t len)
    {
        struct rt_i2c_msg msgs[2];
    
        msgs[0].addr = dev->client_addr;
        msgs[0].flags = RT_I2C_WR;
        msgs[0].buf = reg;
        //msgs[0].len = GT911_REGITER_LEN;
        msgs[0].len = 1;        //这里的len只能是1或者2,1对应8bit寄存器,8对应16bit寄存器
    
        msgs[1].addr = dev->client_addr;
        msgs[1].flags = RT_I2C_RD;
        msgs[1].buf = data;
        msgs[1].len = len;
    
        if (rt_i2c_transfer(dev->bus, msgs, 2) == 2) {
            return RT_EOK;
        } else {
            return -RT_ERROR;
        }
    }
    
    /*
     * 这个函数主要用于获取TP的ID,有些TP并没有具体获取ID的寄存器公开,可以删除
     */
    //static rt_err_t gt911_get_product_id(struct rt_i2c_client *dev,
    //                                      rt_uint8_t *data, rt_uint8_t len)
    // {
    //     rt_uint8_t reg[2];
    
    //     reg[0] = (rt_uint8_t)(GT911_PRODUCT_ID >> 8);
    //     reg[1] = (rt_uint8_t)(GT911_PRODUCT_ID & 0xff);
    
    //     if (gt911_read_regs(dev, reg, data, len) != RT_EOK) {
    //         LOG_E("read id failed");
    //         return -RT_ERROR;
    //     }
    //     return RT_EOK;
    // }
    
    /*
     * 这个函数主要用于获取TP的参数,包括:xy的坐标范围最大值,触摸点的个数,如果规格书没有相关描述可以删除,用rt_touch_info结构体去配置,如果想实现可以参考上一章相同函数编写
     */
    //static rt_err_t gt911_get_info(struct rt_i2c_client *dev,
    //                                struct rt_touch_info *info)
    // {
    //     rt_uint8_t reg[2];
    //     rt_uint8_t out_info[7];
    //     rt_uint8_t out_len = 7;
    
    //     reg[0] = (rt_uint8_t)(GT911_CONFIG_REG >> 8);
    //     reg[1] = (rt_uint8_t)(GT911_CONFIG_REG & 0xFF);
    
    //     if (gt911_read_regs(dev, reg, out_info, out_len) != RT_EOK) {
    //         LOG_E("read info failed");
    //         return -RT_ERROR;
    //     }
    
    //     info->range_x = (out_info[2] << 8) | out_info[1];
    //     info->range_y = (out_info[4] << 8) | out_info[3];
    //     info->point_num = out_info[5] & 0x0f;
    //     if (info->point_num > GT911_MAX_TOUCH) {
    //         info->point_num = GT911_MAX_TOUCH;
    //         rt_kprintf("Warning,tp support more than 5 points, limited to 5 points\n");
    //     }
    
    //     return RT_EOK;
    // }
    
    /*
     * 这里的静态变量主要是为了存储坐标点的数据,然后作逻辑判断
     * GT911_MAX_TOUCH是最大的触摸点个数也就是上面info->point_num定义的5,所以数组赋值了5个-1作为初始值
     * CST826M固件目前支持最大触摸点个数为2,所以CST826_MAX_TOUCH是2,也没有宽度之类的描述,故删除了pre_w数组
     */
    //static int16_t pre_x[GT911_MAX_TOUCH] = { -1, -1, -1, -1, -1 };
    //static int16_t pre_y[GT911_MAX_TOUCH] = { -1, -1, -1, -1, -1 };
    //static int16_t pre_w[GT911_MAX_TOUCH] = { -1, -1, -1, -1, -1 };
    //static rt_uint8_t s_tp_dowm[GT911_MAX_TOUCH] = {0};
    //static struct rt_touch_data *read_data = RT_NULL;
    static int16_t pre_x[CST826_MAX_TOUCH] = { -1, -1 };
    static int16_t pre_y[CST826_MAX_TOUCH] = { -1, -1 };
    static rt_uint8_t s_tp_dowm[CST826_MAX_TOUCH] = {0};
    static struct rt_touch_data *read_data = RT_NULL;
    
    /*
     * 这个是抬起事件上报函数,修改函数名即可使用
     * 如果定义上面的静态数组的时候没有定义pre_w,则下面代码关于pre_w的要删除
     */
    //static void gt911_touch_up(void *buf, int8_t id)
    static void cst826_touch_up(void *buf, int8_t id)
    {
        read_data = (struct rt_touch_data *)buf;
    
        if (s_tp_dowm[id] == 1) {
            s_tp_dowm[id] = 0;
            read_data[id].event = RT_TOUCH_EVENT_UP;
        } else {
            read_data[id].event = RT_TOUCH_EVENT_NONE;
        }
    
        read_data[id].timestamp = rt_touch_get_ts();
        //read_data[id].width = pre_w[id];
        read_data[id].x_coordinate = pre_x[id];
        read_data[id].y_coordinate = pre_y[id];
        read_data[id].track_id = id;
    
        pre_x[id] = -1; /* last point is none */
        pre_y[id] = -1;
        //pre_w[id] = -1;
    }
    
    /*
     * 这个是移动和按下事件函数,修改函数名即可使用
     * 如果定义上面的静态数组的时候没有定义pre_w,则下面代码关于pre_w的要删除
     * 包括函数传参里面的int16_t w也要删除
     */
    //static void gt911_touch_down(void *buf, int8_t id, int16_t x, int16_t y, int16_t w)
    static void cst826_touch_down(void *buf, int8_t id, int16_t x, int16_t y)
    {
        read_data = (struct rt_touch_data *)buf;
    
        if (s_tp_dowm[id] == 1) {
            read_data[id].event = RT_TOUCH_EVENT_MOVE;
        } else {
            read_data[id].event = RT_TOUCH_EVENT_DOWN;
            s_tp_dowm[id] = 1;
        }
    
        read_data[id].timestamp = rt_touch_get_ts();
        //read_data[id].width = w;
        read_data[id].x_coordinate = x;
        read_data[id].y_coordinate = y;
        read_data[id].track_id = id;
    
        pre_x[id] = x; /* save last point */
        pre_y[id] = y;
        //pre_w[id] = w;
    }
    
    //static rt_size_t gt911_read_point(struct rt_touch_device *touch, void *buf, rt_size_t read_num)
    static rt_size_t cst826_read_point(struct rt_touch_device *touch, void *buf, rt_size_t read_num)
    {
        //rt_uint8_t point_status = 0;
        rt_uint8_t touch_num = 0;
        //rt_uint8_t write_buf[3];
        //rt_uint8_t cmd[2];
        rt_uint8_t reg;     //这里将cmd[2]改成reg是因为gt911是16bit寄存器需要分开两个byte发送寄存器高低位,cst826是8bit寄存器不需要拆开
        //rt_uint8_t read_buf[8 * GT911_MAX_TOUCH] = { 0 };
        rt_uint8_t read_buf[CST826_POINT_LEN * CST826_MAX_TOUCH + 4] = { 0 };   //read_buf的长度取决于要读取多长的数据,长度计算:坐标点数据长度*坐标点个数+其他信息长度
        rt_uint8_t read_index;
        int8_t read_id = 0;
        int16_t input_x = 0;
        int16_t input_y = 0;
        //int16_t input_w = 0;      //cst826没有宽度相关寄存器描述
    
        static rt_uint8_t pre_touch = 0;
        static int8_t pre_id[GT911_MAX_TOUCH] = { 0 };
    
        rt_memset(buf, 0, sizeof(struct rt_touch_data) * read_num);
    
        /* point status register */
        //cmd[0] = (rt_uint8_t)((GT911_READ_STATUS >> 8) & 0xFF);
        //cmd[1] = (rt_uint8_t)(GT911_READ_STATUS & 0xFF);
    
        //if (gt911_read_regs(&gt911_client, cmd, &point_status, 1) != RT_EOK) {
        //    LOG_D("read point failed\n");
        //    read_num = 0;
        //    goto exit_;
        //}
    
        reg = CST826_WORK_MODE;
        if (cst826_read_regs(&cst826_client, &reg, read_buf, sizeof(read_buf)) != RT_EOK) {
            LOG_D("read point failed\n");
            read_num = 0;
            goto __exit;
        }
    
        //if (point_status == 0) /* no data */
        //{
        //    read_num = 0;
        //    goto exit_;
        //}
    
        //if ((point_status & 0x80) == 0) /* data is not ready */
        //{
        //    read_num = 0;
        //    goto exit_;
        //}
    
        //touch_num = point_status & 0x0f; /* get point num */
    
        //if (touch_num > GT911_MAX_TOUCH) /* point num is not correct */
        //{
        //    read_num = 0;
        //    goto exit_;
        //}
        touch_num = read_buf[2] & 0x0f;         //这里的获取逻辑如果不了解建议去看第一章关于规格书的阅读
        if (touch_num >= 2) {
            touch_num = 2;
        }
    
    
        //cmd[0] = (rt_uint8_t)((GT911_POINT1_REG >> 8) & 0xFF);
        //cmd[1] = (rt_uint8_t)(GT911_POINT1_REG & 0xFF);
    
        /* read point num is touch_num */
        //if (gt911_read_regs(&gt911_client, cmd, read_buf,
        //                    read_num * GT911_POINT_INFO_NUM) != RT_EOK) {
        //    LOG_D("read point failed\n");
        //    read_num = 0;
        //    goto exit_;
        //}
    
        /*
         * 下面是对坐标事件的处理,一般可以直接照抄,根据规格书更换一下信息,后面会把部分规格书信息贴在本章节最后面
         */
        if (pre_touch > touch_num)
        {
            for (read_index = 0; read_index < pre_touch; read_index++) {
                rt_uint8_t j;
    
                for (j = 0; j < touch_num; j++) /* this time touch num */
                {
                    //read_id = read_buf[j * 8] & 0x0F;
                    read_id = read_buf[5 + CST826_POINT_LEN * j] & 0xF0;
    
                    if (pre_id[read_index] == read_id) /* this id is not free */
                        break;
    
                    if (j >= touch_num - 1) {
                        rt_uint8_t up_id;
                        up_id = pre_id[read_index];
                        //gt911_touch_up(buf, up_id);
                        cst826_touch_up(buf, up_id);
                    }
                }
            }
        }
    
        if (touch_num) /* point down */
        {
            rt_uint8_t off_set;
    
            for (read_index = 0; read_index < touch_num; read_index++) {
                //off_set = read_index * 8;
                off_set = read_index * CST826_POINT_LEN;
                //read_id = read_buf[off_set] & 0x0f;
                read_id = (read_buf[off_set + 5] & 0xf0) >> 4;
                pre_id[read_index] = read_id;
                //input_x = read_buf[off_set + 1] | (read_buf[off_set + 2] << 8); /* x */
                //input_y = read_buf[off_set + 3] | (read_buf[off_set + 4] << 8); /* y */
                //input_w = read_buf[off_set + 5] | (read_buf[off_set + 6] << 8); /* size */
                input_x = ((read_buf[off_set + 3] & 0x0f) << 8) | read_buf[off_set + 4];
                input_y = ((read_buf[off_set + 5] & 0x0f) << 8) | read_buf[off_set + 6];
    
                //gt911_touch_down(buf, read_id, input_x, input_y, input_w);
                cst826_touch_down(buf, read_id, input_x, input_y);
            }
        } else if (pre_touch) {
            for (read_index = 0; read_index < pre_touch; read_index++) {
                //gt911_touch_up(buf, pre_id[read_index]);
                cst826_touch_up(buf, pre_id[read_index]);
            }
        }
    
        pre_touch = touch_num;
    
    exit_:
        //write_buf[0] = (rt_uint8_t)((GT911_READ_STATUS >> 8) & 0xFF);
        //write_buf[1] = (rt_uint8_t)(GT911_READ_STATUS & 0xFF);
        //write_buf[2] = 0x00;
        //gt911_write_reg(&gt911_client, write_buf, 3);
    
        return read_num;
    }
    /*
     * TP的控制函数,一般来说只需要实现RT_TOUCH_CTRL_GET_INFO,所以cst826只实现了这个case
     */
    //static rt_err_t gt911_control(struct rt_touch_device *touch, int cmd, void *arg)
    static rt_err_t cst826_control(struct rt_touch_device *touch, int cmd, void *data)
    {
    //     if (cmd == RT_TOUCH_CTRL_GET_ID) {
    //         return gt911_get_product_id(&gt911_client, arg, 6);
    //     }
    
    //     if (cmd == RT_TOUCH_CTRL_GET_INFO) {
    //         return gt911_get_info(&gt911_client, arg);
    //     }
    
    //     rt_uint8_t buf[4];
    //     rt_uint8_t i = 0;
    //     rt_uint8_t *config;
    
    //     config =
    //         (rt_uint8_t *)rt_calloc(1, sizeof(GT911_CFG_TBL) + GT911_REGITER_LEN);
    //     if (config == RT_NULL) {
    //         LOG_D("malloc config memory failed\n");
    //         return -RT_ERROR;
    //     }
    
    //     config[0] = (rt_uint8_t)((GT911_CONFIG_REG >> 8) & 0xFF);
    //     config[1] = (rt_uint8_t)(GT911_CONFIG_REG & 0xFF);
    
    //     memcpy(&config[2], GT911_CFG_TBL, sizeof(GT911_CFG_TBL));
    
    //     switch (cmd) {
    //         case RT_TOUCH_CTRL_SET_X_RANGE: {
    //             rt_uint16_t x_range;
    
    //             x_range = *(rt_uint16_t *)arg;
    //             config[4] = (rt_uint8_t)(x_range >> 8);
    //             config[3] = (rt_uint8_t)(x_range & 0xff);
    
    //             GT911_CFG_TBL[2] = config[4];
    //             GT911_CFG_TBL[1] = config[3];
    //             break;
    //         }
    //         case RT_TOUCH_CTRL_SET_Y_RANGE: {
    //             rt_uint16_t y_range;
    
    //             y_range = *(rt_uint16_t *)arg;
    //             config[6] = (rt_uint8_t)(y_range >> 8);
    //             config[5] = (rt_uint8_t)(y_range & 0xff);
    
    //             GT911_CFG_TBL[4] = config[6];
    //             GT911_CFG_TBL[3] = config[5];
    //             break;
    //         }
    //         case RT_TOUCH_CTRL_SET_X_TO_Y: {
    //             config[8] ^= (1 << 3);
    //             break;
    //         }
    //         case RT_TOUCH_CTRL_SET_MODE: {
    //             rt_uint16_t trig_type;
    //             trig_type = *(rt_uint16_t *)arg;
    
    //             switch (trig_type) {
    //                 case RT_DEVICE_FLAG_INT_RX:
    //                     config[8] &= 0xFC;
    //                     break;
    //                 case RT_DEVICE_FLAG_RDONLY:
    //                     config[8] &= 0xFC;
    //                     config[8] |= 0x02;
    //                     break;
    //                 default:
    //                     break;
    //             }
    //             break;
    //         }
    //         default: {
    //             break;
    //         }
    //     }
        switch(cmd)
        {
        case RT_TOUCH_CTRL_GET_ID:
            break;
        case RT_TOUCH_CTRL_GET_INFO:
            info = (struct rt_touch_info *)data;
            if (info == RT_NULL)
                return -RT_EINVAL;
    
            info->point_num = touch->info.point_num;
            info->range_x = touch->info.range_x;
            info->range_y = touch->info.range_y;
            info->type = touch->info.type;
            info->vendor = touch->info.vendor;
            break;
        case RT_TOUCH_CTRL_SET_MODE:
        case RT_TOUCH_CTRL_SET_X_RANGE:
        case RT_TOUCH_CTRL_SET_Y_RANGE:
        case RT_TOUCH_CTRL_SET_X_TO_Y:
        case RT_TOUCH_CTRL_DISABLE_INT:
        case RT_TOUCH_CTRL_ENABLE_INT:
        default:
            break;
        }
    
    //     if (gt911_write_reg(&gt911_client, config,
    //                         sizeof(GT911_CFG_TBL) + GT911_ADDR_LEN) != RT_EOK) {
    //         LOG_D("send config failed");
    //         return -1;
    //     }
    
    //     buf[0] = (rt_uint8_t)((GT911_CHECK_SUM >> 8) & 0xFF);
    //     buf[1] = (rt_uint8_t)(GT911_CHECK_SUM & 0xFF);
    //     buf[2] = 0;
    
    //     for (i = GT911_ADDR_LEN; i < sizeof(GT911_CFG_TBL) + GT911_ADDR_LEN; i++) {
    //         buf[GT911_ADDR_LEN] += config[i];
    //     }
    
    //     buf[2] = (~buf[2]) + 1;
    //     buf[3] = 1;
    
    //     gt911_write_reg(&gt911_client, buf, 4);
    //     rt_free(config);
    
         return RT_EOK;
    }
    
    //static struct rt_touch_ops gt911_touch_ops = {
    //    .touch_readpoint = gt911_read_point,
    //    .touch_control = gt911_control,
    //};
    
    /*
     * rt_touch_ops,主要是完成对读坐标和控制TP的函数注册
     */
    const struct rt_touch_ops cst826_touch_ops =
    {
        .touch_readpoint = cst826_read_point,
        .touch_control = cst826_control,
    };
    
    /*
     * rt_touch_info结构体是和get_info那个函数作用一致,无法从寄存器获取TP参数时可以通过这个结构体手动配置
     */
    struct rt_touch_info cst826_info =
    {
        RT_TOUCH_TYPE_CAPACITANCE,
        RT_TOUCH_VENDOR_UNKNOWN,
        2,
        (rt_int32_t)AIC_TOUCH_PANEL_CST826_X_RANGE,
        (rt_int32_t)AIC_TOUCH_PANEL_CST826_Y_RANGE,
    };
    
    /*
     * 这个函数主要实现对TP的初始操作
     */
    //static int rt_hw_gt911_init(const char *name, struct rt_touch_config *cfg)
    int cst826_hw_init(const char *name, struct rt_touch_config *cfg)
    {
        struct rt_touch_device *touch_device = RT_NULL;
    
        touch_device =
            (struct rt_touch_device *)rt_malloc(sizeof(struct rt_touch_device));
        if (touch_device == RT_NULL) {
            LOG_E("touch device malloc fail");
            return -RT_ERROR;
        }
        rt_memset((void *)touch_device, 0, sizeof(struct rt_touch_device));
    
        /* hw init*/
        // rst output 0
        //rt_pin_mode(*(rt_uint8_t *)cfg->user_data, PIN_MODE_OUTPUT);
        //rt_pin_write(*(rt_uint8_t *)cfg->user_data, PIN_LOW);
        //rt_thread_delay(10);
        // irq output 0
        //rt_pin_mode(cfg->irq_pin.pin, PIN_MODE_OUTPUT);
        //rt_pin_write(cfg->irq_pin.pin, PIN_LOW);
        //rt_thread_delay(2);
        // rst output 1
        //rt_pin_mode(*(rt_uint8_t *)cfg->user_data, PIN_MODE_OUTPUT);
        //rt_pin_write(*(rt_uint8_t *)cfg->user_data, PIN_HIGH);
        //rt_thread_delay(5);
        // rst input
        //rt_pin_mode(*(rt_uint8_t *)cfg->user_data, PIN_MODE_INPUT);
        //irq output 0
        //rt_pin_mode(cfg->irq_pin.pin, PIN_MODE_OUTPUT);
        //rt_pin_write(cfg->irq_pin.pin, PIN_LOW);
        //rt_thread_delay(50);
        //rt_pin_mode(cfg->irq_pin.pin, PIN_MODE_INPUT);
    
        //这里时TP初始化时的上电时序,要根据规格书来进行配置
        rt_pin_mode(*(rt_uint8_t *)cfg->user_data, PIN_MODE_OUTPUT);
        rt_pin_write(*(rt_uint8_t *)cfg->user_data, PIN_HIGH);
        rt_thread_delay(10);
    
        rt_pin_mode(*(rt_uint8_t *)cfg->user_data, PIN_MODE_OUTPUT);
        rt_pin_write(*(rt_uint8_t *)cfg->user_data, PIN_LOW);
        rt_thread_delay(10);
    
        rt_pin_mode(*(rt_uint8_t *)cfg->user_data, PIN_MODE_OUTPUT);
        rt_pin_write(*(rt_uint8_t *)cfg->user_data, PIN_HIGH);
        rt_thread_delay(100);
    
    
        //gt911_client.bus = (struct rt_i2c_bus_device *)rt_device_find(cfg->dev_name);
        //if (gt911_client.bus == RT_NULL) {
        //    LOG_E("Can't find %s device", cfg->dev_name);
        //    return -RT_ERROR;
        //}
        cst826_client.bus = (struct rt_i2c_bus_device *)rt_device_find(cfg->dev_name);
        if (cst826_client.bus == RT_NULL) {
            LOG_E("Can't find %s device", cfg->dev_name);
            return -RT_ERROR;
        }
    
        if (rt_device_open((rt_device_t)gt911_client.bus, RT_DEVICE_FLAG_RDWR) !=
            RT_EOK) {
            LOG_E("open %s device failed", cfg->dev_name);
            return -RT_ERROR;
        }
    
        //gt911_client.client_addr = GT911_ADDRESS_HIGH;
        cst826_client.client_addr = CST826_SALVE_ADDR;
        /* register touch device */
        touch_device->info = cst826_info;       //这里就是手动配置TP信息赋值的地方,如果这里有赋值就不需要实现get_info这个函数
        //touch_device->info.type = RT_TOUCH_TYPE_CAPACITANCE;
        //touch_device->info.vendor = RT_TOUCH_VENDOR_GT;
        rt_memcpy(&touch_device->config, cfg, sizeof(struct rt_touch_config));
        //touch_device->ops = &gt911_touch_ops;
        touch_device->ops = &cst826_touch_ops;
    
        if (RT_EOK != rt_hw_touch_register(touch_device, name, RT_DEVICE_FLAG_INT_RX, RT_NULL)) {
            //LOG_E("touch device gt911 init failed !!!");
            LOG_E("touch device cst826 init failed !!!");
            return -RT_ERROR;
        }
    
        //LOG_I("touch device gt911 init success");
        LOG_I("touch device cst826 init success");
        return RT_EOK;
    }
    
    /*
     * 这个函数主要实现对GPIO的初始化,这个函数只需修改函数名即可复用
     */
    //static int rt_gt911_gpio_cfg()
    static int cst826_gpio_cfg()
    {
        unsigned int g, p;
        long pin;
    
        // RST
        pin = drv_pin_get(AIC_TOUCH_PANEL_RST_PIN);
        g = GPIO_GROUP(pin);
        p = GPIO_GROUP_PIN(pin);
        hal_gpio_direction_input(g, p);
    
        // INT
        pin = drv_pin_get(AIC_TOUCH_PANEL_INT_PIN);
        g = GPIO_GROUP(pin);
        p = GPIO_GROUP_PIN(pin);
        hal_gpio_direction_input(g, p);
        hal_gpio_set_irq_mode(g, p, 0);
    
        return 0;
    }
    
    /*
     * 这个函数主要注册整个设备,改个名字和里面的函数调用名即可复用,
     */
    //static int rt_hw_gt911_port(void)
    static int rt_hw_cst826_port(void)
    {
        struct rt_touch_config cfg;
        rt_uint8_t rst_pin;
    
        //rt_gt911_gpio_cfg();
        cst826_gpio_cfg();
    
        rst_pin = drv_pin_get(AIC_TOUCH_PANEL_RST_PIN);
        cfg.dev_name = AIC_TOUCH_PANEL_I2C_CHAN;
        cfg.irq_pin.pin = drv_pin_get(AIC_TOUCH_PANEL_INT_PIN);
        cfg.irq_pin.mode = PIN_MODE_INPUT;
        cfg.user_data = &rst_pin;
    #ifdef AIC_PM_DEMO
        rt_pm_set_pin_wakeup_source(cfg.irq_pin.pin);
    #endif
    
        rt_hw_gt911_init(AIC_TOUCH_PANEL_NAME, &cfg);
    
        return 0;
    }
    
    //INIT_DEVICE_EXPORT(rt_hw_gt911_port);
    INIT_DEVICE_EXPORT(rt_hw_cst826_port);
    
  5. 修改源代码gt911.h 文件如下

    修改前:

    #ifndef __GT911_H__
    #define __GT911_H__
    
    #include "drivers/touch.h"
    #include <aic_hal_gpio.h>
    #include <aic_drv_gpio.h>
    
    #define GT911_ADDR_LEN       2
    #define GT911_REGITER_LEN    2
    #define GT911_MAX_TOUCH      5
    #define GT911_POINT_INFO_NUM 8
    
    #define GT911_ADDRESS_HIGH 0x5D
    #define GT911_ADDRESS_LOW  0x14
    
    #define GT911_COMMAND_REG 0x8040
    #define GT911_CONFIG_REG  0x8047
    #define GT911_MOD_SWT_REG 0x804D
    
    #define GT911_PRODUCT_ID  0x8140
    #define GT911_VENDOR_ID   0x814A
    #define GT911_READ_STATUS 0x814E
    
    #define GT911_POINT1_REG 0x814F
    #define GT911_POINT2_REG 0x8157
    #define GT911_POINT3_REG 0x815F
    #define GT911_POINT4_REG 0x8167
    #define GT911_POINT5_REG 0x816F
    
    #define GT911_CHECK_SUM 0x80FF
    
    #endif /* gt911.h */

    修改后:

    #ifndef __CST826_H__
    #define __CST826_H__
    
    #include <aic_hal_gpio.h>
    #include <aic_drv_gpio.h>
    #include "drivers/touch.h"
    
    #define CST826_MAX_TOUCH        2
    #define CST826_POINT_LEN        6
    #define CST826_SALVE_ADDR       0x15
    /* cst826 reg */
    #define CST826_WORK_MODE        0x00
    #define CST826_PROX_STATE       0x01
    #define CST826_TOUCH_NUM        0x02
    #define CST826_TOUCH1_XH        0x03
    #define CST826_TOUCH1_XL        0x04
    #define CST826_TOUCH1_YH        0x05
    #define CST826_TOUCH1_YL        0x06
    #define CST826_TOUCH1_PRES      0x07
    #define CST826_TOUCH1_AREA      0x08
    #define CST826_SLEEP_MODE       0xA5
    #define CST826_FW_VERSION1      0xA6
    #define CST826_FW_VERSION2      0xA7
    #define CST826_MODULE_ID        0xA8
    #define CST826_PROJECT_NAME     0xA9
    #define CST826_CHIP_TYPE1       0xAA
    #define CST826_CHIP_TYPE2       0xAB
    #define CST826_CHECKSUM1        0xAC
    #define CST826_CHECKSUM2        0xAD
    #define CST826_PROX_MODE        0xB0
    #define CST826_GES_MODE         0xD0
    #define CST826_GESTURE_ID       0xD3
    
    #define AIC_TOUCH_PANEL_CST826_X_RANGE  480
    #define AIC_TOUCH_PANEL_CST826_Y_RANGE  272
    
    #endif