基于@staunchheart提供的git代码,增加了NS2009的触摸屏驱动,在widora tiny200s开发板上初步测试press和release 事件触发无误。
下面是NS2009触摸屏调试的相关步骤:
1.I2C0上的SDA、SCLK飞线上拉10K欧姆电阻至3.3V。
2.编写NS2009的rt thread 驱动 package, 组件为drv_tp_ns2009.c 及其头文件。
2.1 本人只是将其作为组件编写,并未在系统上做实际注册,后续此处有更新会贴出来。
2.2 此次使用查询方式实现触摸事件的捕捉,具体为实现一个loop thread.而后main调用运行该thread即可。
2.3 仅实现了touch press 和release 事件,move事件考虑后续添加。
3.在env下使用scons命令编译系统后进行烧录。
附件为ns2009驱动模块的完整代码,贴图为证:)
最后感谢@staunchheart给我等后来者提供了一个的可用的平台,Thanks a lot!
本站下载: ns2009_drivers.rar (文件已解压在下方)
drv_tp_ns2009.c
#include "drv_tp_ns2009.h"
struct rt_i2c_bus_device *i2c_bus;
struct ns2009_device ns2009_dev={false};
rt_thread_t TP_Thread;
on_touch_message_handle on_touch_callback_func;
static int ns2009_ts_read_data(struct rt_i2c_bus_device * dev, rt_uint8_t cmd, rt_uint16_t * val);
static int ns2009_ts_report(ns2009_device_t dev);
static bool ns2009_init();
static void ns2009_report_thread(void* parameter);
static int ns2009_ts_read_data(struct rt_i2c_bus_device * dev, rt_uint8_t cmd, rt_uint16_t * val)
{
struct rt_i2c_msg msgs[2];
int ret;
uint8_t raw_data[2];
msgs[0].addr = dev->addr;
msgs[0].flags = RT_I2C_WR;
msgs[0].len = 1;
msgs[0].buf = &cmd;
msgs[1].addr = dev->addr;
msgs[1].flags = RT_I2C_RD;
msgs[1].len = 2;
msgs[1].buf = raw_data;
ret=ingenic_i2c_xfer(dev, msgs, 2);//this must 2
*val = (raw_data[0] << 4) | (raw_data[1] >> 4);
if (ret==2)
return 0;
else
return 1;
}
static int ns2009_ts_report(ns2009_device_t dev)
{
uint16_t x, y, z1;
int ret;
struct touch_message msg;
ret = ns2009_ts_read_data(i2c_bus, NS2009_READ_Z1_LOW_POWER_12BIT, &z1);
if (ret)
return ret;
if (z1 >= NS2009_PEN_UP_Z1_ERR)
{
ret = ns2009_ts_read_data(i2c_bus, NS2009_READ_X_LOW_POWER_12BIT,&x);
if (ret)
return ret;
ret = ns2009_ts_read_data(i2c_bus, NS2009_READ_Y_LOW_POWER_12BIT,&y);
if (ret)
return ret;
if (!dev->pen_down)
{
//rt_kprintf("ABS_X is %d",x);
//rt_kprintf("ABS_Y is %d",y);
//rt_kprintf("tp was pressed\n");
dev->pen_down = true;
x=(x-X_Origin)*X_Adapt_Width/X_Width;
y=(y-Y_Origin)*Y_Adapt_Heigth/Y_Heigth;
msg.x = x;
msg.y = y;
msg.event = TOUCH_EVENT_DOWN;
(on_touch_callback_func)(&msg);
}
}
else if (dev->pen_down)
{
//rt_kprintf("ABS_X is %d",x);
//rt_kprintf("ABS_Y is %d",y);
//rt_kprintf("tp was released\n");
msg.x = x;
msg.y = y;
msg.event = TOUCH_EVENT_UP;
(on_touch_callback_func)(&msg);
dev->pen_down = false;
}
on_touch_callback_func(&msg);
return 0;
}
static bool ns2009_init()
{
//rt_uint8_t cmd[2];
//rt_uint8_t buffer[6] = {0};
i2c_bus = rt_i2c_bus_device_find(TOUCH_I2C_NAME);
RT_ASSERT(i2c_bus);
if(rt_device_open(&i2c_bus->parent, RT_DEVICE_OFLAG_RDWR) != RT_EOK)
{
//TPDEBUG("[TP] %s I2C not open error!\n", TOUCH_I2C_NAME);
rt_kprintf("I2C open error\n");
return false;
}
i2c_bus->addr=NS2009_Addr;
// rt_thread_delay(RT_TICK_PER_SECOND / 5);
return true;
}
static void ns2009_report_thread(void* parameter)
{
ns2009_init();
while(1)
{
ns2009_ts_report(&ns2009_dev);
//rt_kprintf("softwind study rtt on nano pail!\n");
rt_thread_delay(10);
}
}
void Run_TP_Thread()
{
TP_Thread = rt_thread_create( "tpThread",
ns2009_report_thread,
RT_NULL,
TP_THREAD_STACK_SIZE,
TP_THREAD_PRIORITY,
TP_THREAD_TIMESLICE );
if (TP_Thread != RT_NULL)
rt_thread_startup(TP_Thread);
else
rt_kprintf("thread create fail\n");
}
void start_touch_listen(on_touch_message_handle call_back)
{
on_touch_callback_func=call_back;
}
drv_tp_ns2009.h
#ifndef NS2009_Unit
#define NS2009_Unit
#include "stdbool.h"
#include <rtthread.h>
#include <rtdevice.h>
#include "drv_touch.h"
#include "drv_i2c.h"
/* polling interval in ms */
#define POLL_INTERVAL 30
/* this driver uses 12-bit readout */
#define MAX_12BIT 0xfff
#define TOUCH_I2C_NAME "i2c0"
#define NS2009_Device_ID "ns2009"
#define NS2009_READ_X_LOW_POWER_12BIT 0xc0
#define NS2009_READ_Y_LOW_POWER_12BIT 0xd0
#define NS2009_READ_Z1_LOW_POWER_12BIT 0xe0
#define NS2009_READ_Z2_LOW_POWER_12BIT 0xf0
#define NS2009_DEF_X_FUZZ 32
#define NS2009_DEF_Y_FUZZ 16
#define NS2009_PEN_UP_Z1_ERR 80
#define NS2009_Addr (0x90>>1)
#define TP_THREAD_PRIORITY 25
#define TP_THREAD_STACK_SIZE 512
#define TP_THREAD_TIMESLICE 5
#define X_Origin 300
#define X_Width (3870-300)
#define X_Adapt_Width 800
#define Y_Origin 380
#define Y_Heigth (3900-380)
#define Y_Adapt_Heigth 480
struct ns2009_device
{
//struct rt_i2c_bus_device *i2c_bus;
bool pen_down;
};
typedef struct ns2009_device * ns2009_device_t;
void Run_TP_Thread();
#endif
最近编辑记录 windbleed (2020-06-08 09:41:17)
离线
感谢楼主分享!
离线
这个不错,以后用得上,谢谢楼主
离线
感谢分享。
离线
on_touch_callback_func这外写法其实是很差劲的写法,耦合得太紧。。当时刚开始学习RTT,只想着快点调通,现在看着都觉得有些惭愧,这个代码还拿到GIT上给朋友们看。
建议朋友参考
https://github.com/RT-Thread-packages/gt9147
的写法。等TINY200的R3版出来后再重新上传一个。
离线
大家好啊,尤其是看到staunchheart也关心此贴很欣慰,现在又在widora tiny200上再次调整了该系统的触摸部分,增加了move事件,贴上代码和相关视频分享给大家哦!注意widora的i2c0接口和licheenano不一样。widora 用的:PD0 PD12, liceenano用的PE11 PE12哦,后续等中断版本出来了再做分享:)
离线
离线
离线
离线
离线
谢谢晕哥:)!
@windbleed
感谢楼主热心分享,晚点我加入精华帖列表。
离线
刚在此链接了读了9147.c文件,看到 rt_hw_touch_register(touch_device, name, RT_DEVICE_FLAG_INT_RX, RT_NULL);此语句就知道您RTT驱动部分确实进阶了,后续2009的驱动也会更新为注册设备:),等我把中断机制先实现哦!
on_touch_callback_func这外写法其实是很差劲的写法,耦合得太紧。。当时刚开始学习RTT,只想着快点调通,现在看着都觉得有些惭愧,这个代码还拿到GIT上给朋友们看。
建议朋友参考
https://github.com/RT-Thread-packages/gt9147
的写法。等TINY200的R3版出来后再重新上传一个。
离线
基于@staunchheart提供的git代码,增加了NS2009的触摸屏驱动,在widora tiny200s开发板上初步测试press和release 事件触发无误。
下面是NS2009触摸屏调试的相关步骤:1.I2C0上的SDA、SCLK飞线上拉10K欧姆电阻至3.3V。
2.编写NS2009的rt thread 驱动 package, 组件为drv_tp_ns2009.c 及其头文件。
2.1 本人只是将其作为组件编写,并未在系统上做实际注册,后续此处有更新会贴出来。
2.2 此次使用查询方式实现触摸事件的捕捉,具体为实现一个loop thread.而后main调用运行该thread即可。
2.3 仅实现了touch press 和release 事件,move事件考虑后续添加。3.在env下使用scons命令编译系统后进行烧录。
...
t-thread+littlevgl fb改成800*480 需要怎么修改 我修改了发现不行 可以分享下细节么
离线
学习了 这个是怎么校准的
离线
关于校准问题回复如下:
此版本是根据实际测试结果直接在代码上进行的校准。你可以在头文件上看到如下宏定义:
#define X_Origin 300
#define X_Width (3870-300)
#define X_Adapt_Width 800
#define Y_Origin 380
#define Y_Heigth (3900-380)
#define Y_Adapt_Heigth 480
300就是在5寸电阻屏上通过打log方式从2009读出的的X轴最左边值。380 是Y轴最上边值。
3870是X轴最右边值,3900是Y轴最下边值。
800 和480是需要适配的像素值。这里有个转换公式可以在.c文件中看到:
x=(x-X_Origin)*X_Adapt_Width/X_Width;
y=(y-Y_Origin)*Y_Adapt_Heigth/Y_Heigth;
由2009读出的x,y原始坐标经过该公式就可转换为精度很高的准确值。
最近编辑记录 windbleed (2020-06-23 21:09:02)
离线
t-thread+littlevgl fb改成800*480 需要怎么修改 我修改了发现不行 可以分享下细节么
关于 800*480LCD驱动的修改其实并不在本贴主题内,但确实有相关性,后面我抽空把关键代码贴出来。
最近编辑记录 windbleed (2020-06-23 21:15:21)
离线
学习了,感谢老师! 这个不错,以后用得上。
离线
遇见了问题修改为800*480分辨率的时候,请大神贴出关键部分
关于 800*480LCD驱动的修改其实并不在本贴主题内,但确实有相关性,后面我抽空把关键代码贴出来。
离线
关于 800*480LCD驱动的修改其实并不在本贴主题内,但确实有相关性,后面我抽空把关键代码贴出来。
drv_fb.c 修改timing
.timing = {
.pixel_clock_hz = 33000000,
.h_back_porch = 46,
.h_front_porch = 210,
.h_sync_len = 2,
.v_back_porch = 23,
.v_front_porch = 22,
.v_sync_len = 2,
.h_sync_active = 0,
.v_sync_active = 0,
.den_active = 1,
.clk_active = 1,
},
rtconfig.h 修改 macro
#define LV_HOR_RES 800
#define LV_VER_RES 480
另外提示注意源码DEBE和DEFE时钟配置可能有坑,修改如下:
static void f1c100s_clk_defe_init(struct lcd_f1c100s_device *dev)
{
clk_mux_set_parent(dev->virtccu + CCU_DEFE_CLK, 3, 24, 0);
//clk_divider_set_rate(dev->virtccu + CCU_DEFE_CLK, 4, 0, RT_TRUE, 24000000, 198000000);
clk_divider_set_rate(dev->virtccu + CCU_DEFE_CLK, 4, 0, RT_TRUE, 198000000, 198000000);
}
static void f1c100s_clk_debe_init(struct lcd_f1c100s_device *dev)
{
clk_mux_set_parent(dev->virtccu + CCU_DEBE_CLK, 3, 24, 0);
//clk_divider_set_rate(dev->virtccu + CCU_DEBE_CLK, 4, 0, RT_TRUE, 24000000, 198000000);
clk_divider_set_rate(dev->virtccu + CCU_DEBE_CLK, 4, 0, RT_TRUE, 198000000, 198000000);
}
请注意检查!
最近编辑记录 windbleed (2020-07-03 15:54:40)
离线
感谢分享。
离线
离线