【嵌入式程序设计】—— TP自适应

最近又要求职了,梳理了下这两年折腾的东西,发现有个产品很可惜,都开发完了,但是没上市。中兴的一款手表,我很喜欢那个金属壳子,结实,拿在手里沉甸甸,可以用来砸核桃。

当时调TP的时候,换了几个厂家,程序里要做自适应,还好TP控制器里都有唯一的特征值,所以可以识别出设备类型。这里都是i2c接口的TP,如果接口不一样还得调整。

tp_driver.c

#include "tp_driver.h"
#include "em_gpio.h"
#include "i2c_driver.h"

static void tp_init(void)
{
    GPIO_PinModeSet(TP_REST_PORT, TP_REST_PIN, gpioModePushPull, 1);
    GPIO_PinOutSet(TP_REST_PORT, TP_REST_PIN);

    GPIO_PinModeSet(TP_INT_PORT,TP_INT_PIN, gpioModeInput,0);
    //GPIO_PinModeSet(TP_INT_PORT,TP_INT_PIN, gpioModeInputPullFilter,0);

    GPIO_IntConfig(TP_INT_PORT, TP_INT_PIN, false, true, true);

    GPIO_PinModeSet(TP_PW_PORT,TP_PW_PIN, gpioModeWiredAnd,0);
    GPIO_PinOutClear(TP_PW_PORT, TP_PW_PIN);

}

static void tp_rest(void)
{
    GPIO_PinOutClear(TP_PW_PORT, TP_PW_PIN);
    GPIO_PinOutSet(TP_REST_PORT, TP_REST_PIN);
    uint32_t i =1000;
    while(--i);
    GPIO_PinOutClear(TP_REST_PORT, TP_REST_PIN);
    i =1000;
    while(--i);
    GPIO_PinOutSet(TP_REST_PORT, TP_REST_PIN);
}

static uint8_t search_device(void)
{
    uint8_t reset_data[4]={0};
    uint8_t tp_data[4]={0};

    tp_rest();
    uint32_t i= 6000000;
    while(--i);
    I2C->ReadBytesWithoutReg(0x15<<1,reset_data,4);
    if( (reset_data[0]==0x55) &&
        (reset_data[1]==0x55) &&
        (reset_data[2]==0x55) &&
        (reset_data[3]==0x55)
       )
    {
        uint8_t fireware_id_cmd[4]=     {0x53, 0xf0, 0x00, 0x01};
        uint8_t fireware_id_major;
        uint8_t fireware_id_minor;
        uint16_t fireware_id;
        I2C->WriteBytesWithoutReg(0x15<<1,fireware_id_cmd,4);
        i=5000;
        while(--i);
        I2C->ReadBytesWithoutReg(0x15<<1,tp_data,4);
        fireware_id_major = ((tp_data[1]&0x0f)<<4) | ((tp_data[2]&0xf0)>>4) ;
        fireware_id_minor = ((tp_data[2]&0x0f)<<4) | ((tp_data[3]&0xf0)>>4) ;
        fireware_id = fireware_id_major<<8 | fireware_id_minor;
        if(fireware_id == 0x1AB0)
        {
            return TP_eWD1000;
        }
    }
    else
    {
        uint8_t vendor_id;
        I2C->readbyte(I2C0, 0x7c, 0xA8, &vendor_id);
        if(vendor_id == 0x5f)
        {
            return TP_FT3X07;
        }
        else
        {
            tp_type  =  NULL;
            GPIO_PinOutSet(TP_PW_PORT, TP_PW_PIN); //tp power down
            I2C->init();
            return 0;
        }
    }
}

static void ReadXY(uint16_t *tp_x,uint16_t *tp_y)
{
    uint8_t tp_type = search_device();
    if (tp_type == TP_eWD1000)
    {
        uint16_t *tp_x1=0;
        uint16_t *tp_y2=0;
        uint8_t tp_data[4]={0};
        uint8_t fireware_id_cmd[4]=     {0x53, 0xf0, 0x00, 0x01};
        uint8_t fireware_version_cmd[4]={0x53, 0x00, 0x00, 0x01};
        uint8_t boot_code_cmd[4]=       {0x53, 0x10, 0x00, 0x01};
        uint8_t x_resolution_cmd[4]=    {0x53, 0x60, 0x00, 0x00};
        uint8_t y_resolution_cmd[4]=    {0x53, 0x63, 0x00, 0x00};
        uint8_t tp_sleep_cmd[4]=        {0x54, 0x50, 0x00, 0x01};

    //  可以不用写信息
    /*
        I2C->WriteBytesWithoutReg(0x15<<1,x_resolution_cmd,4);
        int i =  2000;
        while(--i);
        I2C->ReadBytesWithoutReg(0x15<<1,tp_data,8);
        *tp_x = (tp_data[2]) | ((tp_data[3]&0xf0)<<4);    

        I2C->WriteBytesWithoutReg(0x15<<1,y_resolution_cmd,4);
        i =  2000;
        while(--i);
        I2C->ReadBytesWithoutReg(0x15<<1,tp_data,8);
        *tp_y = (tp_data[2]) | ((tp_data[3]&0xf0)<<4);  

    */
        I2C->ReadBytesWithoutReg(0x15<<1,tp_data,8);
        *tp_x = ((uint16_t)((tp_data[1]&0xf0)<<4) | tp_data[2]) ;
        *tp_y = ((uint16_t)((tp_data[1]&0x0f)<<8) | tp_data[3]) ;

        //支持两点触碰
        //*tp_x1 = ((uint16_t)((tp_data[4]&0xf0)<<4) | tp_data[5]) ;
        //*tp_y2 = ((uint16_t)((tp_data[4]&0x0f)<<8) | tp_data[6]) ;
    }
    else if(tp_type == TP_FT3X07)
    {
        uint8_t tp_data[4];
        uint8_t x_h=0, x_l=0, y_h=0, y_l=0;
        I2C->readbyte(I2C0, 0x7c, 0x03, &tp_data[0]);
        I2C->readbyte(I2C0, 0x7c, 0x04, &tp_data[1]);
        I2C->readbyte(I2C0, 0x7c, 0x05, &tp_data[2]);
        I2C->readbyte(I2C0, 0x7c, 0x06, &tp_data[3]);

        x_h= tp_data[0];
        x_l= tp_data[1];
        *tp_x = ((x_h <<8)&0xff)| x_l;
        y_h= tp_data[2];
        y_l= tp_data[3];
        *tp_y = ((y_h <<8)&0xff)| y_l;
    }
    else
    {

    }
}

static void tp_int_enable(void)
{
    GPIO_IntConfig(TP_INT_PORT, TP_INT_PIN, true, true, true);
}

static void tp_int_disable(void)
{
    GPIO_IntConfig(TP_INT_PORT, TP_INT_PIN, true, true, false);
}

static void tp_sleep(void){
   //I2C->writebyte(I2C0, 0x7c, 0xa5, 0x03);
   GPIO_PinOutSet(TP_PW_PORT, TP_PW_PIN);
}
TP_T TP_D=
{
    tp_init,
    tp_rest,
    search_device,
    ReadXY,
    tp_int_enable,
    tp_int_disable,
    tp_sleep,

};
TP_T *TP=&TP_D;

tp_driver.h

#ifndef __TOUCH_DRIVER_H
#define __TOUCH_DRIVER_H
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>

enum tp_type_t{

    TP_FT3X07=1,
    TP_eWD1000

};

#define TOUCH_PANNEL_ADDR (0x7C)

#define TP_INT_PORT (gpioPortA)
#define TP_INT_PIN (3)

#define TP_PIN_IS_HI()        ( ( GPIO->P[TP_INT_PORT].DIN & (0x1<<TP_INT_PIN)) == (0x1<<TP_INT_PIN))
#define TP_PIN_IS_LO()        ( ( GPIO->P[TP_INT_PORT].DIN & (0x1<<TP_INT_PIN)) == 0x0 )

#define TP_REST_PORT (gpioPortA)
#define TP_REST_PIN (4)

#define TP_PW_PORT (gpioPortE)
#define TP_PW_PIN (15)

typedef struct
{
  void (*init)(void);
  void (*rest)(void);
  void (*search_device)(void);
  void (*ReadXY)(uint16_t *tp_x,uint16_t *tp_y);
  void (*int_enable)(void);
  void (*int_disable)(void);
  void (*sleep)(void);
}TP_T;

extern TP_T *TP;

#endif
时间: 2024-10-05 08:35:22

【嵌入式程序设计】—— TP自适应的相关文章

2014025688 《嵌入式程序设计》第七周学习总结

2014025688(30) <嵌入式程序设计>第七周学习总结 有名管道 FIFO也称为有名管道,它是一种文件类型.FIFO简单理解,就是它能把两个不相关的进程联系起来,FIFO就像一个公共通道,解决了不同进程之间的"代沟".普通的无名管道只能让相关的进程进行沟通(比如父shell和子shell之间).FIFO严格遵循先进先出(first in first out),对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾.它们不支持诸如lseek()等文件定

2014025644 嵌入式程序设计 第七周学习总结

嵌入式程序设计 第七周 有名管道 有名管道和无名管道的区别 (1) 无名管道:管道是半双工的,数据只能向一个方向流动:需要双方通信时,需要建立起两个管道:只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程). 单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中. 数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出.写入的内容每次都添加在管道缓冲区的末尾,并且每次都是

2014025637《嵌入式程序设计》第一周学习总结

学习总结 1.安装软件以及初识linux总结 <嵌入式程序设计>这门课程开了一周,我从没有安装软件到能够写一个简单的程序,这其中有很多的问题,刚开始安装软件时安装软件有很多的错误,以至于重装了一次系统,由于种种原因上课时没能跟上老师的步伐进行复习,好在在课下的时候找时间都进行了练习,复习了一下以前的操作符命令. 2.上课编程作业 利用gcc打印hello word vi命令是新建一个文件 ls命令是显示列表 3.实验楼作业 在linux中,最重要的是命令,包含了两个过程,就是输入和输出 输入就

2014025689 嵌入式程序设计 第七周学习总结

嵌入式程序设计 第七周   第七周课程主要学习了有名管道和消息队列的传输和接收.   一丶有名管道   有名管道和无名管道的区别: 1.  有名管道定义:可以使互不相关的两个进程实现彼此通信的管道就是有名管道.有名管道可以通过路径名来指出,并且在文件系统中是可见的.在建立了管道之后,两个进程就可以把它当作普通文件一样进行读写操作,使用非常方便.不过值得注意的是,FIFO 是严格地遵循先进先出规则的,对管道及 FIFO 的读总是从开始处返回数据,对它们的写则把数据添加到末尾,它们不支持如 lsee

201405644 嵌入式程序设计第五周学习总结

嵌入式课程设计第五周学习总结 标准 I/O 编程 标准 I/O 提供流缓冲的目的是尽可能减少使用 read()和 write()等系统调用的数量.标准 I/O 提供了 3 种类型 的缓冲存储.全缓冲.行缓冲.不带缓冲. 打开文件 打开文件有三个标准函数,分别为:fopen().fdopen()和 freopen().其中 fopen()可以指定打开文件的路径和模式,fdopen()可以指定打开的文件描述符和模式,而 freopen() 除可指定打开的文件.模式外,还可指定特定的 I/O 流. f

2014025635《嵌入式程序设计》第二周总结

1.课本学习总结 gcc编译器 GCC(GNU Compiler Collection,GNU编译器套件),是由 GNU 开发的编程语言编译器.它是以GPL许可证所发行的自由软件,也是 GNU计划的关键部分.GCC原本作为GNU操作系统的官方编译器,现已被大多数类Unix操作系统(如Linux.BSD.Mac os x等)采纳为标准的编译器,GCC同样适用于微软的Windows.[2]  GCC是自由软件过程发展中的著名例子,由自由软件基金会以GPL协议发布.它是GNU项目中符合ANSI C标准

2014025627 《嵌入式程序设计》第三、四周学习总结

教材学习内容总结 本周的学习目标是,学习和掌握Bootloader启动原理并且掌握Bootloader的移植和编译过程.首先学习了安装arm-linux-gcc交叉编译工具,解压缩交叉编译工具源码,然后测arm-linux-gcc是否可运行,发现报错,主要原因是当前系统环境是x86_64位,而arm-linux-gcc是32位,需要解决64位系统下安装32位软件的问题.输入  后再次测试arm-linux-gcc是否可运行,提示arm-linux-gcc:no input files,说明该文件

20140256985《嵌入式程序设计》第三、四周学习总结

1.第三四周学习情况 上课能跟上,而且新的虚拟机非常好使,编辑代码的时候很是方便,没有上一个虚拟机那么复杂,非常好用! 2实验楼学习内容    (1).安装并解压arm-linux-gcc交叉编译工具 (2).测试arm-linux-gcc是否可运行 (3).解决64位系统下安装32位软件的问题和 (4).将arm-linxu-gcc加入环境变量PATH中 (5).bootboader的配置,移植和编译 解压文件 建立板级支持包 修改eduk2410文件 修改Makefile文件 编译U-Boo

2014025689《嵌入式程序设计》第一周学习总结

这一周主要学习了vim的使用和Linux的一些基本的操作,并在电脑上操作 一.vim的基本指令 vi的使用 创建目录的命令:mrkdir+目录 将一个目录下的文件拷贝到另一个目录下:cp /原目录 /新目录 进入目录:cd+目录 设定行号命令:set number 移至指定行:行号G 删除行:dd 复制该行:将光标移到该行yy 粘贴:p 将光标移到最后一行行首:G或者shift+g 撤销:u 光标移动到指定字符:/+指定字符 gcc编译的操作方法 gcc test.c -o test gcc -