/************************************************
name : touch.h
desc :
author : HuangXinfeng
date : 2018.09.07
************************************************/
#ifndef __TOUCH_H__
#define __TOUCH_H__
#ifdef __cplusplus
extern "C" {
#endif
#define TP_BASE_ADDR 0x01c24800
#define TP_CTRL0 0x00
#define TP_CTRL1 0x04
#define TP_CTRL2 0x08
#define TP_CTRL3 0x0c
#define TP_INT_FIFOC 0x10
#define TP_INT_FIFOS 0x14
#define TP_TPR 0x18
#define TP_CDAT 0x1c
#define TEMP_DATA 0x20
#define TP_DATA 0x24
/* TP_CTRL0 bits */
#define ADC_FIRST_DLY(x) ((x) << 24) /* 8 bits */
#define ADC_FIRST_DLY_MODE(x) ((x) << 23)
#define ADC_CLK_SEL(x) ((x) << 22)
#define ADC_CLK_DIV(x) ((x) << 20) /* 3 bits */
#define FS_DIV(x) ((x) << 16) /* 4 bits */
#define T_ACQ(x) ((x) << 0) /* 16 bits */
/* TP_CTRL1 bits */
#define STYLUS_UP_DEBOUN(x) ((x) << 12) /* 8 bits */
#define STYLUS_UP_DEBOUN_EN(x) ((x) << 9)
#define TOUCH_PAN_CALI_EN(x) ((x) << 6)
#define TP_DUAL_EN(x) ((x) << 5)
#define TP_MODE_EN(x) ((x) << 4)
#define TP_ADC_SELECT(x) ((x) << 3)
#define ADC_CHAN_SELECT(x) ((x) << 0) /* 3 bits */
/* on sun6i, bits 3~6 are left shifted by 1 to 4~7 */
#define SUN6I_TP_MODE_EN(x) ((x) << 5)
/* TP_CTRL2 bits */
#define TP_SENSITIVE_ADJUST(x) ((x) << 28) /* 4 bits */
#define TP_MODE_SELECT(x) ((x) << 26) /* 2 bits */
#define PRE_MEA_EN(x) ((x) << 24)
#define PRE_MEA_THRE_CNT(x) ((x) << 0) /* 24 bits */
/* TP_CTRL3 bits */
#define FILTER_EN(x) ((x) << 2)
#define FILTER_TYPE(x) ((x) << 0) /* 2 bits */
/* TP_INT_FIFOC irq and fifo mask / control bits */
#define TEMP_IRQ_EN(x) ((x) << 18)
#define OVERRUN_IRQ_EN(x) ((x) << 17)
#define DATA_IRQ_EN(x) ((x) << 16)
#define TP_DATA_XY_CHANGE(x) ((x) << 13)
#define FIFO_TRIG(x) ((x) << 8) /* 5 bits */
#define DATA_DRQ_EN(x) ((x) << 7)
#define FIFO_FLUSH(x) ((x) << 4)
#define TP_UP_IRQ_EN(x) ((x) << 1)
#define TP_DOWN_IRQ_EN(x) ((x) << 0)
/* TP_INT_FIFOS irq and fifo status bits */
#define TEMP_DATA_PENDING BIT(18)
#define FIFO_OVERRUN_PENDING BIT(17)
#define FIFO_DATA_PENDING BIT(16)
#define TP_IDLE_FLG BIT(2)
#define TP_UP_PENDING BIT(1)
#define TP_DOWN_PENDING BIT(0)
/* TP_TPR bits */
#define TEMP_ENABLE(x) ((x) << 16)
#define TEMP_PERIOD(x) ((x) << 0) /* t = x * 256 * 16 / clkin */
#ifdef __cplusplus
}
#endif
#endif
/************************************************
name : touch.h
desc :
author : HuangXinfeng
date : 2018.09.08
************************************************/
#include "touch.h"
#include "io.h"
struct IntTypeStu
{
u32_t INTC_VECTOR_REG;
u32_t INTC_BASE_ADDR_REG;
u32_t INTC_CTRL_REG;
u32_t INTC_PEND_REG0;
u32_t INTC_PEND_REG1;
u32_t INTC_EN_REG0;
u32_t INTC_EN_REG1;
};
void TouchInit()
{
u32_t addr;
u32_t val;
/* 配置 GPIOA0 为 TPX1 TPY1 TP X2 TPY2*/
addr = 0x01c20800 + 0x00;
val = read32(addr);
val &= ~(0x0000ffff); //低14位清0
val |= 0x22222222; //010 TP模式即每位都是2
write32(addr, val);
val = read32(TP_BASE_ADDR+TP_CTRL0);
/*24M / 6 = 4Mhz(CLK_IN)/ 2^13(8192) = 488.28125 hz*/
/*Conversion Time = 1 / (4MHz/13Cycles) = 3.25us*/
/*触摸ADC获取时间T_ACQ = CLK_IN /(16*(1+63)) = 3906.25hz 左右*/
write32(TP_BASE_ADDR+TP_CTRL0, (0x1f << 23)|ADC_CLK_SEL(0) | ADC_CLK_DIV(2) | FS_DIV(7) | T_ACQ(63));
/*00: FIFO store X1,Y1 data for single touch no pressure mode*/
val = read32(TP_BASE_ADDR+TP_CTRL2);
val = (0x08 << 28) | TP_MODE_SELECT(0) | (0 << 24)|0xFFF;
write32(TP_BASE_ADDR+TP_CTRL2, val);
val = read32(TP_BASE_ADDR+TP_CTRL3);//使能滤波器
write32(TP_BASE_ADDR + TP_CTRL3, FILTER_EN(1) | val);
write32(TP_BASE_ADDR + TP_TPR, TEMP_ENABLE(1) | TEMP_PERIOD(1953));//温度转换寄存器
val = read32(TP_BASE_ADDR+TP_CTRL1);
val = (5<<12) | (1<< 9) | (0<<8) | (1 << 5) | TP_MODE_EN(0) | 0x00; //4通道使能
write32( TP_BASE_ADDR + TP_CTRL1, val);
write32( TP_BASE_ADDR + TP_CDAT, 0xc00);
write32( TP_BASE_ADDR + 0x38, 0x22);
write32(TP_BASE_ADDR + TP_INT_FIFOC , TEMP_IRQ_EN(1) | OVERRUN_IRQ_EN(0) | DATA_IRQ_EN(1) | FIFO_TRIG(0x02) | TP_DATA_XY_CHANGE(0)| FIFO_FLUSH(1) | TP_UP_IRQ_EN(1) | TP_DOWN_IRQ_EN(1));
// write32(TP_BASE_ADDR + TP_INT_FIFOC, 0x00);
addr = 0x01c20400 + 0x20; //INT Enable register0
val = read32(addr);
val |= (1 << 20);
write32(addr, val);
val = read32(0x01c20400 + 0x30);
val &= ~(1 << 20); //释放屏蔽位
write32(0x01c20400 + 0x30, val);
}
extern int touchx,touchy,temperature;
__irq void HandleIRQ()
{
u32_t x, y;
u32_t val;
if(read32(INTC_PEND_REG0) & (1 << 13))//定时器0中断
{
SystickMs();
write32(TIMER_BASS_ADDR+TMR_IRQ_STA_REG, 0x01);//清除中断
}
else if(read32(INTC_PEND_REG0) & (1 << 20))//触摸屏中断
{
val = read32(0x01C24800 + 0x14);
if (val & (1 << 16))//fifo data irq
{
if (((val<<17) >> 8) > 5)
{
touchx = x = read32(TP_BASE_ADDR+TP_DATA);
touchy = y = read32(TP_BASE_ADDR+TP_DATA);
x = 1;
}
}
if (val & (1 << 18))//温度传感器中断
{
temperature = read32(TP_BASE_ADDR+0x20);
}
if (val & (1 << 0))//按下中断
{
x = 1;
}
if (val & (1 << 1))//抬起中断
{
y = 1;
}
write32(TP_BASE_ADDR+TP_INT_FIFOS, val);
// write32(TP_BASE_ADDR + TP_INT_FIFOC , read32(0x01C24800 + 0x14) | FIFO_FLUSH(1));
// write32(TP_BASE_ADDR+TP_INT_FIFOS, read32(0x01C24800 + 0x14) | (0x01) | (1 << 17));
// write32(0x01c20400+ 0x10 , (1 << 20) );
}
}
int main(void)
{
......
*((void * volatile *)0x00000038) = (void *volatile)HandleIRQ;//IRQ地址
......
}
离线
谢谢共享,有空我也拿出吃灰的 licheepi nano 试一试。
离线
谢谢晕哥共享,我刚好准备上触摸,这周就着重把这个移植到xboot框架下去
离线
谢谢晕哥,我有一个HDMI屏,刚好自己组装上去一个触摸屏,也是GT911
离线
多谢晕哥,要用到呢
离线
晕哥,nano板子上是不是要将那四个触摸屏的焊盘用线焊接到专门的GPIO上啊?
离线
电阻屏直接就可以用吗?应该需要校准吧
离线
达克罗德 说:电阻屏直接就可以用吗?应该需要校准吧
是的,目前只读到adc数据,需要滤波和校准算法。
很多stm32项目都是移植tslib.
我去看下tslib
离线
查了一下, xboot 已经内置各种滤波算法 和 ns2009(licheepi zero)电阻触摸芯片驱动了.
应该在 ts-ns2009.c 基础上改改就可以了。
https://github.com/xboot/xboot/blob/master/src/arch/arm32/mach-v3s/driver/ts-ns2009.c
https://github.com/xboot/xboot/tree/master/src/lib/libc/filter
https://github.com/xboot/xboot/blob/master/src/lib/libc/filter/tsfilter.c
离线
查了一下, xboot 已经内置各种滤波算法 和 ns2009(licheepi zero)电阻触摸芯片驱动了.
应该在 ts-ns2009.c 基础上改改就可以了。https://github.com/xboot/xboot/blob/master/src/arch/arm32/mach-v3s/driver/ts-ns2009.c
https://github.com/xboot/xboot/tree/master/src/lib/libc/filter
https://github.com/xboot/xboot/blob/master/src/lib/libc/filter/tsfilter.c
太好了!
离线
X1-->A0
Y1-->A2
X2-->A1
Y2-->A3
离线
看手册时发现全志带硬件filter,不需要软件滤波了,这点很好。
现在就是校准不太明白了,得做个gui来让用户点几个点来算?看来还得研究下tslib。
另外有个寄存器是触发校准,这个校准是什么含义?看起来不需要用户参与,完成后自动清0
离线
4.2.7.2. TP Control Register 1
TOUCH_PAN_CALI_EN.
Touch Panel Calibration
1: start Calibration, it is clear to 0 after calibration
这个硬件校准手册写得太坑, 根本就不知道如何入手。
那个硬件滤波做得确实不错, 不知道效果如何.
离线
参考晕哥代码,昨晚搞TP到半夜,几个发现:
1. 要和屏幕匹配坐标的话,管脚连接应该是这样(交换了X1和X2,Y1和Y2)
X1-->A1
Y1-->A3
X2-->A0
Y2-->A2
其实还需要交换X和Y,因为我发现X和Y轴反了,不过我就在软件中处理了,没有再试硬件交换管脚
2. 报点坐标基本正常,用了V3S的校准值
"calibration": [14052, 21, -2411064, -67, 8461, -1219628, 65536],
3. TOUCH_PAN_CALI_EN必须要打开,似乎是因为
write32( TP_BASE_ADDR + TP_CDAT, 0xc00);
这一句改了CDAT之后需要校准一下,否者坐标不正确。此校准似乎是内部ADC相关校准,和#2这个校准无关
遇到的问题:
现在卡在fifo中断的处理,每次down的中断后,fifo读出很多脏数据;开机第一次down是读到32个乱的坐标,而之后每次up之后再down,前n个数据都是历史坐标而不是新的down的位置。不知道哪里fifo没处理好还是什么,调了2个小时无果。。。
附修正坐标的函数给大家试试:
static void ts_f1c100s_xy_correction(struct ts_f1c100s_pdata_t * pdat, int *x, int *y)
{
*x = (pdat->cal[2] + pdat->cal[0] * *x + pdat->cal[1] * *y) / pdat->cal[6];
*y = (pdat->cal[5] + pdat->cal[3] * *x + pdat->cal[4] * *y) / pdat->cal[6];
}
cal就是#2中的校准值
离线
非常感谢分享!
楼顶的程序是我朋友调的, 我只是路过打了一壶酱油.
我记得有个Linux的驱动,能给我发一下吗?我记得QQ里提到过
最近编辑记录 达克罗德 (2018-09-15 10:48:02)
离线
找到原因了,原来down中断不能读fifo,我本想在down中断就得到第一个坐标,看来是把fifo读指针给破坏了。我的理解fifo为空也不应该破坏读指针呀
所以这个down中断用处不大,down后的第一个数据得等fifo数据中断才能得到。
等我整理下把代码传上来
离线
晕哥 说:非常感谢分享!
楼顶的程序是我朋友调的, 我只是路过打了一壶酱油.我记得有个Linux的驱动,能给我发一下吗?我记得QQ里提到过
这个帖子有:
https://whycan.cn/t_1596.html
https://github.com/torvalds/linux/blob/master/drivers/input/touchscreen/sun4i-ts.c
https://github.com/torvalds/linux/blob/master/arch/arm/boot/dts/sun4i-a10.dtsi
离线
达克罗德 说:晕哥 说:非常感谢分享!
楼顶的程序是我朋友调的, 我只是路过打了一壶酱油.我记得有个Linux的驱动,能给我发一下吗?我记得QQ里提到过
这个帖子有:
https://whycan.cn/t_1596.html
https://github.com/torvalds/linux/blob/master/drivers/input/touchscreen/sun4i-ts.c
https://github.com/torvalds/linux/blob/master/arch/arm/boot/dts/sun4i-a10.dtsi
早看到这个就好了,可以绕开几个坑。。。哭
离线
离线
太好了,感谢分享,楼主的代码和xboot风格很一致,看起来就舒服
离线
https://whycan.cn/files/members/3/QQ20180915160317.png
用这个 IDA 软件分析 melis 库不错。
IDA 真强大!话说melis会开源吗?
离线
离线
touch.h
/************************************************ name : touch.h desc : author : HuangXinfeng date : 2018.09.07 ************************************************/ #ifndef __TOUCH_H__ #define __TOUCH_H__ #ifdef __cplusplus extern "C" { #endif #define TP_BASE_ADDR 0x01c24800 #define TP_CTRL0 0x00 #define TP_CTRL1 0x04 #define TP_CTRL2 0x08 #define TP_CTRL3 0x0c #define TP_INT_FIFOC 0x10 #define TP_INT_FIFOS 0x14 #define TP_TPR 0x18 #define TP_CDAT 0x1c #define TEMP_DATA 0x20 #define TP_DATA 0x24 /* TP_CTRL0 bits */ #define ADC_FIRST_DLY(x) ((x) << 24) /* 8 bits */ #define ADC_FIRST_DLY_MODE(x) ((x) << 23) #define ADC_CLK_SEL(x) ((x) << 22) #define ADC_CLK_DIV(x) ((x) << 20) /* 3 bits */ #define FS_DIV(x) ((x) << 16) /* 4 bits */ #define T_ACQ(x) ((x) << 0) /* 16 bits */ /* TP_CTRL1 bits */ #define STYLUS_UP_DEBOUN(x) ((x) << 12) /* 8 bits */ #define STYLUS_UP_DEBOUN_EN(x) ((x) << 9) #define TOUCH_PAN_CALI_EN(x) ((x) << 6) #define TP_DUAL_EN(x) ((x) << 5) #define TP_MODE_EN(x) ((x) << 4) #define TP_ADC_SELECT(x) ((x) << 3) #define ADC_CHAN_SELECT(x) ((x) << 0) /* 3 bits */ /* on sun6i, bits 3~6 are left shifted by 1 to 4~7 */ #define SUN6I_TP_MODE_EN(x) ((x) << 5) /* TP_CTRL2 bits */ #define TP_SENSITIVE_ADJUST(x) ((x) << 28) /* 4 bits */ #define TP_MODE_SELECT(x) ((x) << 26) /* 2 bits */ #define PRE_MEA_EN(x) ((x) << 24) #define PRE_MEA_THRE_CNT(x) ((x) << 0) /* 24 bits */ /* TP_CTRL3 bits */ #define FILTER_EN(x) ((x) << 2) #define FILTER_TYPE(x) ((x) << 0) /* 2 bits */ /* TP_INT_FIFOC irq and fifo mask / control bits */ #define TEMP_IRQ_EN(x) ((x) << 18) #define OVERRUN_IRQ_EN(x) ((x) << 17) #define DATA_IRQ_EN(x) ((x) << 16) #define TP_DATA_XY_CHANGE(x) ((x) << 13) #define FIFO_TRIG(x) ((x) << 8) /* 5 bits */ #define DATA_DRQ_EN(x) ((x) << 7) #define FIFO_FLUSH(x) ((x) << 4) #define TP_UP_IRQ_EN(x) ((x) << 1) #define TP_DOWN_IRQ_EN(x) ((x) << 0) /* TP_INT_FIFOS irq and fifo status bits */ #define TEMP_DATA_PENDING BIT(18) #define FIFO_OVERRUN_PENDING BIT(17) #define FIFO_DATA_PENDING BIT(16) #define TP_IDLE_FLG BIT(2) #define TP_UP_PENDING BIT(1) #define TP_DOWN_PENDING BIT(0) /* TP_TPR bits */ #define TEMP_ENABLE(x) ((x) << 16) #define TEMP_PERIOD(x) ((x) << 0) /* t = x * 256 * 16 / clkin */ #ifdef __cplusplus } #endif #endif
touch.c
/************************************************ name : touch.h desc : author : HuangXinfeng date : 2018.09.08 ************************************************/ #include "touch.h" #include "io.h" struct IntTypeStu { u32_t INTC_VECTOR_REG; u32_t INTC_BASE_ADDR_REG; u32_t INTC_CTRL_REG; u32_t INTC_PEND_REG0; u32_t INTC_PEND_REG1; u32_t INTC_EN_REG0; u32_t INTC_EN_REG1; }; void TouchInit() { u32_t addr; u32_t val; /* 配置 GPIOA0 为 TPX1 TPY1 TP X2 TPY2*/ addr = 0x01c20800 + 0x00; val = read32(addr); val &= ~(0x0000ffff); //低14位清0 val |= 0x22222222; //010 TP模式即每位都是2 write32(addr, val); val = read32(TP_BASE_ADDR+TP_CTRL0); /*24M / 6 = 4Mhz(CLK_IN)/ 2^13(8192) = 488.28125 hz*/ /*Conversion Time = 1 / (4MHz/13Cycles) = 3.25us*/ /*触摸ADC获取时间T_ACQ = CLK_IN /(16*(1+63)) = 3906.25hz 左右*/ write32(TP_BASE_ADDR+TP_CTRL0, (0x1f << 23)|ADC_CLK_SEL(0) | ADC_CLK_DIV(2) | FS_DIV(7) | T_ACQ(63)); /*00: FIFO store X1,Y1 data for single touch no pressure mode*/ val = read32(TP_BASE_ADDR+TP_CTRL2); val = (0x08 << 28) | TP_MODE_SELECT(0) | (0 << 24)|0xFFF; write32(TP_BASE_ADDR+TP_CTRL2, val); val = read32(TP_BASE_ADDR+TP_CTRL3);//使能滤波器 write32(TP_BASE_ADDR + TP_CTRL3, FILTER_EN(1) | val); write32(TP_BASE_ADDR + TP_TPR, TEMP_ENABLE(1) | TEMP_PERIOD(1953));//温度转换寄存器 val = read32(TP_BASE_ADDR+TP_CTRL1); val = (5<<12) | (1<< 9) | (0<<8) | (1 << 5) | TP_MODE_EN(0) | 0x00; //4通道使能 write32( TP_BASE_ADDR + TP_CTRL1, val); write32( TP_BASE_ADDR + TP_CDAT, 0xc00); write32( TP_BASE_ADDR + 0x38, 0x22); write32(TP_BASE_ADDR + TP_INT_FIFOC , TEMP_IRQ_EN(1) | OVERRUN_IRQ_EN(0) | DATA_IRQ_EN(1) | FIFO_TRIG(0x02) | TP_DATA_XY_CHANGE(0)| FIFO_FLUSH(1) | TP_UP_IRQ_EN(1) | TP_DOWN_IRQ_EN(1)); // write32(TP_BASE_ADDR + TP_INT_FIFOC, 0x00); addr = 0x01c20400 + 0x20; //INT Enable register0 val = read32(addr); val |= (1 << 20); write32(addr, val); val = read32(0x01c20400 + 0x30); val &= ~(1 << 20); //释放屏蔽位 write32(0x01c20400 + 0x30, val); }
main.c
extern int touchx,touchy,temperature; __irq void HandleIRQ() { u32_t x, y; u32_t val; if(read32(INTC_PEND_REG0) & (1 << 13))//定时器0中断 { SystickMs(); write32(TIMER_BASS_ADDR+TMR_IRQ_STA_REG, 0x01);//清除中断 } else if(read32(INTC_PEND_REG0) & (1 << 20))//触摸屏中断 { val = read32(0x01C24800 + 0x14); if (val & (1 << 16))//fifo data irq { if (((val<<17) >> 8) > 5) { touchx = x = read32(TP_BASE_ADDR+TP_DATA); touchy = y = read32(TP_BASE_ADDR+TP_DATA); x = 1; } } if (val & (1 << 18))//温度传感器中断 { temperature = read32(TP_BASE_ADDR+0x20); } if (val & (1 << 0))//按下中断 { x = 1; } if (val & (1 << 1))//抬起中断 { y = 1; } write32(TP_BASE_ADDR+TP_INT_FIFOS, val); // write32(TP_BASE_ADDR + TP_INT_FIFOC , read32(0x01C24800 + 0x14) | FIFO_FLUSH(1)); // write32(TP_BASE_ADDR+TP_INT_FIFOS, read32(0x01C24800 + 0x14) | (0x01) | (1 << 17)); // write32(0x01c20400+ 0x10 , (1 << 20) ); } } int main(void) { ...... *((void * volatile *)0x00000038) = (void *volatile)HandleIRQ;//IRQ地址 ...... }
这个有完整工程吗?
离线
大神,裸机有这个驱动吗?我移植到裸机没反应!
离线
晕哥 说:https://whycan.cn/files/members/3/QQ20180915160317.png
用这个 IDA 软件分析 melis 库不错。
IDA 真强大!话说melis会开源吗?
晕哥,你干脆把melis库的视频部分也逆向出来吧。
离线
大神,裸机有这个驱动吗?我移植到裸机没反应!
不好意思才看到,又改了一次,现在xboot最新里的应该是可用的,另外还要注意硬件连接
离线
晕哥,请教下,我的nano已经焊接到了底板上面,怎么跳线到触摸接口上面,没看到上面的X1 Y1等的焊盘
离线
离线
tianjjff 说:晕哥,请教下,我的nano已经焊接到了底板上面,怎么跳线到触摸接口上面,没看到上面的X1 Y1等的焊盘
板子拍个照片, 因为荔枝派nano有几个版本。
这样看得到吗?
离线
背面没有焊接到底板的时候是有的,那个我看到了,焊接到底板后X1 X2 Y1 Y2的焊盘就被挡住了,我开始以为RGB接口会把这四根线接到芯片上面的,今天量了一下居然是没连上的
离线
离线
tianjjff 说:背面没有焊接到底板的时候是有的,那个我看到了,焊接到底板后X1 X2 Y1 Y2的焊盘就被挡住了,我开始以为RGB接口会把这四根线接到芯片上面的,今天量了一下居然是没连上的
那只能试一试另外飞线了
嗯,我这个程序不用触摸也没关系,只是想测试下触摸功能
离线
touch.h
/************************************************ name : touch.h desc : author : HuangXinfeng date : 2018.09.07 ************************************************/ #ifndef __TOUCH_H__ #define __TOUCH_H__ #ifdef __cplusplus extern "C" { #endif #define TP_BASE_ADDR 0x01c24800 #define TP_CTRL0 0x00 #define TP_CTRL1 0x04 #define TP_CTRL2 0x08 #define TP_CTRL3 0x0c #define TP_INT_FIFOC 0x10 #define TP_INT_FIFOS 0x14 #define TP_TPR 0x18 #define TP_CDAT 0x1c #define TEMP_DATA 0x20 #define TP_DATA 0x24 /* TP_CTRL0 bits */ #define ADC_FIRST_DLY(x) ((x) << 24) /* 8 bits */ #define ADC_FIRST_DLY_MODE(x) ((x) << 23) #define ADC_CLK_SEL(x) ((x) << 22) #define ADC_CLK_DIV(x) ((x) << 20) /* 3 bits */ #define FS_DIV(x) ((x) << 16) /* 4 bits */ #define T_ACQ(x) ((x) << 0) /* 16 bits */ /* TP_CTRL1 bits */ #define STYLUS_UP_DEBOUN(x) ((x) << 12) /* 8 bits */ #define STYLUS_UP_DEBOUN_EN(x) ((x) << 9) #define TOUCH_PAN_CALI_EN(x) ((x) << 6) #define TP_DUAL_EN(x) ((x) << 5) #define TP_MODE_EN(x) ((x) << 4) #define TP_ADC_SELECT(x) ((x) << 3) #define ADC_CHAN_SELECT(x) ((x) << 0) /* 3 bits */ /* on sun6i, bits 3~6 are left shifted by 1 to 4~7 */ #define SUN6I_TP_MODE_EN(x) ((x) << 5) /* TP_CTRL2 bits */ #define TP_SENSITIVE_ADJUST(x) ((x) << 28) /* 4 bits */ #define TP_MODE_SELECT(x) ((x) << 26) /* 2 bits */ #define PRE_MEA_EN(x) ((x) << 24) #define PRE_MEA_THRE_CNT(x) ((x) << 0) /* 24 bits */ /* TP_CTRL3 bits */ #define FILTER_EN(x) ((x) << 2) #define FILTER_TYPE(x) ((x) << 0) /* 2 bits */ /* TP_INT_FIFOC irq and fifo mask / control bits */ #define TEMP_IRQ_EN(x) ((x) << 18) #define OVERRUN_IRQ_EN(x) ((x) << 17) #define DATA_IRQ_EN(x) ((x) << 16) #define TP_DATA_XY_CHANGE(x) ((x) << 13) #define FIFO_TRIG(x) ((x) << 8) /* 5 bits */ #define DATA_DRQ_EN(x) ((x) << 7) #define FIFO_FLUSH(x) ((x) << 4) #define TP_UP_IRQ_EN(x) ((x) << 1) #define TP_DOWN_IRQ_EN(x) ((x) << 0) /* TP_INT_FIFOS irq and fifo status bits */ #define TEMP_DATA_PENDING BIT(18) #define FIFO_OVERRUN_PENDING BIT(17) #define FIFO_DATA_PENDING BIT(16) #define TP_IDLE_FLG BIT(2) #define TP_UP_PENDING BIT(1) #define TP_DOWN_PENDING BIT(0) /* TP_TPR bits */ #define TEMP_ENABLE(x) ((x) << 16) #define TEMP_PERIOD(x) ((x) << 0) /* t = x * 256 * 16 / clkin */ #ifdef __cplusplus } #endif #endif
touch.c
/************************************************ name : touch.h desc : author : HuangXinfeng date : 2018.09.08 ************************************************/ #include "touch.h" #include "io.h" struct IntTypeStu { u32_t INTC_VECTOR_REG; u32_t INTC_BASE_ADDR_REG; u32_t INTC_CTRL_REG; u32_t INTC_PEND_REG0; u32_t INTC_PEND_REG1; u32_t INTC_EN_REG0; u32_t INTC_EN_REG1; }; void TouchInit() { u32_t addr; u32_t val; /* 配置 GPIOA0 为 TPX1 TPY1 TP X2 TPY2*/ addr = 0x01c20800 + 0x00; val = read32(addr); val &= ~(0x0000ffff); //低14位清0 val |= 0x22222222; //010 TP模式即每位都是2 write32(addr, val); val = read32(TP_BASE_ADDR+TP_CTRL0); /*24M / 6 = 4Mhz(CLK_IN)/ 2^13(8192) = 488.28125 hz*/ /*Conversion Time = 1 / (4MHz/13Cycles) = 3.25us*/ /*触摸ADC获取时间T_ACQ = CLK_IN /(16*(1+63)) = 3906.25hz 左右*/ write32(TP_BASE_ADDR+TP_CTRL0, (0x1f << 23)|ADC_CLK_SEL(0) | ADC_CLK_DIV(2) | FS_DIV(7) | T_ACQ(63)); /*00: FIFO store X1,Y1 data for single touch no pressure mode*/ val = read32(TP_BASE_ADDR+TP_CTRL2); val = (0x08 << 28) | TP_MODE_SELECT(0) | (0 << 24)|0xFFF; write32(TP_BASE_ADDR+TP_CTRL2, val); val = read32(TP_BASE_ADDR+TP_CTRL3);//使能滤波器 write32(TP_BASE_ADDR + TP_CTRL3, FILTER_EN(1) | val); write32(TP_BASE_ADDR + TP_TPR, TEMP_ENABLE(1) | TEMP_PERIOD(1953));//温度转换寄存器 val = read32(TP_BASE_ADDR+TP_CTRL1); val = (5<<12) | (1<< 9) | (0<<8) | (1 << 5) | TP_MODE_EN(0) | 0x00; //4通道使能 write32( TP_BASE_ADDR + TP_CTRL1, val); write32( TP_BASE_ADDR + TP_CDAT, 0xc00); write32( TP_BASE_ADDR + 0x38, 0x22); write32(TP_BASE_ADDR + TP_INT_FIFOC , TEMP_IRQ_EN(1) | OVERRUN_IRQ_EN(0) | DATA_IRQ_EN(1) | FIFO_TRIG(0x02) | TP_DATA_XY_CHANGE(0)| FIFO_FLUSH(1) | TP_UP_IRQ_EN(1) | TP_DOWN_IRQ_EN(1)); // write32(TP_BASE_ADDR + TP_INT_FIFOC, 0x00); addr = 0x01c20400 + 0x20; //INT Enable register0 val = read32(addr); val |= (1 << 20); write32(addr, val); val = read32(0x01c20400 + 0x30); val &= ~(1 << 20); //释放屏蔽位 write32(0x01c20400 + 0x30, val); }
main.c
extern int touchx,touchy,temperature; __irq void HandleIRQ() { u32_t x, y; u32_t val; if(read32(INTC_PEND_REG0) & (1 << 13))//定时器0中断 { SystickMs(); write32(TIMER_BASS_ADDR+TMR_IRQ_STA_REG, 0x01);//清除中断 } else if(read32(INTC_PEND_REG0) & (1 << 20))//触摸屏中断 { val = read32(0x01C24800 + 0x14); if (val & (1 << 16))//fifo data irq { if (((val<<17) >> 8) > 5) { touchx = x = read32(TP_BASE_ADDR+TP_DATA); touchy = y = read32(TP_BASE_ADDR+TP_DATA); x = 1; } } if (val & (1 << 18))//温度传感器中断 { temperature = read32(TP_BASE_ADDR+0x20); } if (val & (1 << 0))//按下中断 { x = 1; } if (val & (1 << 1))//抬起中断 { y = 1; } write32(TP_BASE_ADDR+TP_INT_FIFOS, val); // write32(TP_BASE_ADDR + TP_INT_FIFOC , read32(0x01C24800 + 0x14) | FIFO_FLUSH(1)); // write32(TP_BASE_ADDR+TP_INT_FIFOS, read32(0x01C24800 + 0x14) | (0x01) | (1 << 17)); // write32(0x01c20400+ 0x10 , (1 << 20) ); } } int main(void) { ...... *((void * volatile *)0x00000038) = (void *volatile)HandleIRQ;//IRQ地址 ...... }
晕哥,我看了下这个文件有的寄存器手册里面找不到,
比如#define TP_TPR 0x18
#define TEMP_DATA 0x20 这两个寄存器在手册里没有,我看的是F1C600的手册
离线
明白
离线
这个是我朋友写的,应该是从A20手册搬来的
"calibration": [14052, 21, -2411064, -67, 8461, -1219628, 65536]
请问晕哥, 上面的触屏校准怎样确定?每个值代表什么?
另外我接上屏幕XY值老跳得厉害,,,引脚悬空却稳定,,,是什么原因?
离线
Administrator 我电脑老是提示要安装vid1f3apidefe8这个驱动,有这个驱动 发一下
离线
Administrator 我电脑老是提示要安装vid1f3apidefe8这个驱动,有这个驱动 发一下
没听说过
离线
达克大神,请问你先前不是整理过rtthread+f1c100s+littlevgl吗,这个官方自带的Tp整理到rtthread+littlevgl代码里面了吗,应该怎么加里面呢。
离线
谢谢分享,正打算试试触摸
离线
你们有没有遇到X,Y坐标数据互换的情况,触摸坐标会发生XY互换,不知道什么情况
离线
达神, 使用[14052, 21, -2411064, -67, 8461, -1219628, 65536], 我在800*480的上面校准,发现有负数的点, 这组数字怎么设置的?
离线
楼主,可以看一下的你的linux内核吗
离线
现在卡到触摸屏了,f1c100sPA0-PA3线接上了,这个ns2009.c,设备树不知道怎么配置
离线
@晕哥
大佬, 我用 https://github.com/minilogic/f1c_nonos 在Linux下调试裸机程序,但是遇到一个问题,我直接复制您的例程,编译的时候出现了截图里的错误,不知道如何解决。。。。[
请问,如何把MDK里的中断例程引入到linxu下的裸机程序里?
谢谢
离线
上面的裸机中断问题已经由@Ozelot帮忙解决,如果有遇到类似问题的小伙伴,可以参考Ozelot大佬的例程,感谢@Ozelot大佬。
参考例程:https://github.com/minilogic/f1c_nonos/tree/main/src/irq
离线