/************************************************
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地址
......
}
离线
查了一下, 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
离线
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
这个硬件校准手册写得太坑, 根本就不知道如何入手。
那个硬件滤波做得确实不错, 不知道效果如何.
离线
晕哥 说:非常感谢分享!
楼顶的程序是我朋友调的, 我只是路过打了一壶酱油.我记得有个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
离线
离线
离线
离线