OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4988|回复: 4

OTT2001A电容屏 rt-thread gui 驱动

[复制链接]

2

主题

6

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2015-1-13
在线时间
0 小时
发表于 2015-8-9 11:50:44 | 显示全部楼层 |阅读模式
MCU stm32f103 fsmc
rt-thread: v2.01
rt-gui: v0.8

屏幕大小:800 * 480,横屏
扫描方式:中断

个人作简单测试,仅供参考。


delay.c
[mw_shl_code=c,true]#include "stm32f10x.h" #include <rtthread.h> #include "delay.h" /** * delay in us count, us must be less then 1 os tick. * Reference: http://www.rt-thread.org/phpBB3/viewtopic.php?p=14266 * * @param us the delay time in us */ void rt_hw_us_delay(int us) { rt_uint32_t delta; rt_uint32_t current_delay; /* 获得延时经过的tick数 */ us = us * (SysTick->LOAD/(1000000/RT_TICK_PER_SECOND)); /* 获得当前时间 */ delta = SysTick->VAL; /* 循环获得当前时间,直到达到指定的时间后退出循环 */ do { if ( delta > SysTick->VAL ) current_delay = delta - SysTick->VAL; else /* 延时跨越了一次OS tick的边界时的处理 */ current_delay = SysTick->LOAD + delta - SysTick->VAL; } while( current_delay < us ); } /** * ms should be great than one tick(10ms) */ void rt_thread_delay_ms(int ms) { rt_thread_delay(ms*RT_TICK_PER_SECOND/1000); }[/mw_shl_code]

ctouch.c
[mw_shl_code=c,true]/* * NOTE: OTT2001A buffer address is 16 bits, not 8 bits */ #include <stdbool.h> #include "stm32f10x.h" #include "board.h" #include "ctouch.h" #include "delay.h" #include <rtthread.h> #include <rtgui/event.h> #include <rtgui/kbddef.h> #include <rtgui/rtgui_server.h> #include <rtgui/rtgui_system.h> #define scl_rcc RCC_APB2Periph_GPIOB #define scl_gpio GPIOB #define scl_pin GPIO_Pin_6 #define sda_rcc RCC_APB2Periph_GPIOB #define sda_gpio GPIOB #define sda_pin GPIO_Pin_7 #define rst_rcc RCC_APB2Periph_GPIOC #define rst_gpio GPIOC #define rst_pin GPIO_Pin_6 #define int_rcc RCC_APB2Periph_GPIOC #define int_gpio GPIOC #define int_pin GPIO_Pin_9 // iic device address #define OTT_DEVICE_ADDR_W 0XB2 // Device address for write #define OTT_DEVICE_ADDR_R 0XB3 // Device address for read // buffer address #define OTT_BUFFER_ADDR_SENSOR 0X0D00 // Buffer address for turn on/off sensor // scale parameter #define OTT_SCAL_X 0.2963 //screen width/OTT_MAX_X #define OTT_SCAL_Y 0.32 //screen heigh/OTT_MAX_Y struct rtgui_touch_device { struct rt_device parent; rt_timer_t poll_timer; rt_uint16_t x, y; }; static struct rtgui_touch_device *touch = RT_NULL; /** * This function delay for iic clock change */ void iic_delay() { rt_hw_us_delay(5); } /** * This function will set sda pin to Input/Output mode * * @param isInput the value declear for input(1) output(0) */ void touch_sda_mode(int isInput) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = isInput ? GPIO_Mode_IPD : GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = sda_pin; GPIO_Init(sda_gpio, &GPIO_InitStructure); GPIO_Init(sda_gpio, &GPIO_InitStructure); } /** * This function will generate iic start signal */ void iic_start(void) { touch_sda_mode(0); //sda pin mode set to output GPIO_SetBits(sda_gpio, sda_pin); GPIO_SetBits(scl_gpio, scl_pin); rt_hw_us_delay(30); //START:when CLK is high,DATA change form high to low GPIO_ResetBits(sda_gpio, sda_pin); iic_delay(); // Hold iic bus for prepare to send or receive data GPIO_ResetBits(scl_gpio, scl_pin); } /** * This function will generate iic stop signal */ void iic_stop(void) { touch_sda_mode(0);//sda pin mode set to output GPIO_SetBits(scl_gpio, scl_pin); rt_hw_us_delay(30); //STOP:when CLK is high DATA change form low to high GPIO_ResetBits(sda_gpio, sda_pin); iic_delay(); // send iic bus stop signal GPIO_SetBits(sda_gpio, sda_pin); rt_hw_us_delay(5); } /** * This function will wait for iic ack signal */ u8 iic_wait_ack(void) { u8 read_count = 0; touch_sda_mode(1); //SDA pin mode set to input GPIO_SetBits(sda_gpio, sda_pin); GPIO_SetBits(scl_gpio, scl_pin); while(GPIO_ReadInputDataBit(sda_gpio, sda_pin)) { if(++read_count>250) { iic_stop(); return 1; } rt_hw_us_delay(1); } GPIO_ResetBits(scl_gpio, scl_pin); return 0; } /** * This function send a iic ack signal */ void iic_send_ack(void) { GPIO_ResetBits(scl_gpio, scl_pin); touch_sda_mode(0); iic_delay(); GPIO_ResetBits(sda_gpio, sda_pin); iic_delay(); GPIO_SetBits(scl_gpio, scl_pin); iic_delay(); GPIO_ResetBits(scl_gpio, scl_pin); } /** * This function send a iic nack signal */ void iic_send_nack(void) { GPIO_ResetBits(scl_gpio, scl_pin); touch_sda_mode(0); iic_delay(); GPIO_SetBits(sda_gpio, sda_pin); iic_delay(); GPIO_SetBits(scl_gpio, scl_pin); iic_delay(); GPIO_ResetBits(scl_gpio, scl_pin); } /** * This function will send a byte data to iic bus * @param value the byte value will be sent */ void iic_send_byte(u8 value) { u8 i; touch_sda_mode(0); GPIO_ResetBits(scl_gpio, scl_pin); // pull down scl pin to start send data iic_delay(); for(i=0; i<8; i++) { GPIO_WriteBit(sda_gpio, sda_pin, (value&0x80)>>7?Bit_SET:Bit_RESET); value<<=1; GPIO_SetBits(scl_gpio, scl_pin); iic_delay(); GPIO_ResetBits(scl_gpio, scl_pin); iic_delay(); } } /** * This function will read a byte from iic bus * @retrun the value of readed */ u8 iic_read_byte(void) { u8 i, result=0; touch_sda_mode(1); for(i=0; i<8; i++ ) { GPIO_ResetBits(scl_gpio, scl_pin); rt_hw_us_delay(30); GPIO_SetBits(scl_gpio, scl_pin); result<<=1; if(GPIO_ReadInputDataBit(sda_gpio, sda_pin)) { result++; } } return result; } /** * This function will write values to device buffer(register) * @param reg the device buffer address * @param buf the values memery address * @param size the size of the write values * * @return write status, if sucesse return 0 */ int touch_write_reg(u16 reg, u8 *buf, int size) { int i; int result=0; iic_start(); iic_send_byte(OTT_DEVICE_ADDR_W); iic_wait_ack(); iic_send_byte(reg>>8); iic_wait_ack(); iic_send_byte(reg&0XFF); iic_wait_ack(); for(i=0;i<size;i++) { iic_send_byte(buf); result=iic_wait_ack(); if(result)break; } iic_stop(); return result; } /** * This function will read values from device buffer(register) * @param reg the device buffer address * @param buf the values memery address * @param size the size of the read values */ void touch_read_reg(u16 reg, u8 *buf, int size) { u8 i; iic_start(); iic_send_byte(OTT_DEVICE_ADDR_W); iic_wait_ack(); iic_send_byte(reg>>8); iic_wait_ack(); iic_send_byte(reg&0XFF); iic_wait_ack(); iic_start(); iic_send_byte(OTT_DEVICE_ADDR_R); iic_wait_ack(); for(i=0; i<size - 1; i++) { buf=iic_read_byte(); iic_send_ack(); } // last byte buf=iic_read_byte(); iic_send_nack(); iic_stop(); } /** * This function will turn on/off the touchpad sensor * @param enable the value of enable(1) or disable(0) */ void touch_control_sensor(int enable) { unsigned char value=0x00; if(enable) { value=0x80; } touch_write_reg(OTT_BUFFER_ADDR_SENSOR, &value, 1); } static void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; /* Enable the EXTI9 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } rt_inline void EXTI_Enable(rt_uint32_t enable) { EXTI_InitTypeDef EXTI_InitStructure; /* Configure EXTI */ EXTI_InitStructure.EXTI_Line = EXTI_Line9; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//Falling?????? Rising???? EXTI_InitStructure.EXTI_LineCmd = enable ? ENABLE : DISABLE; EXTI_Init(&EXTI_InitStructure); EXTI_ClearITPendingBit(EXTI_Line1); } static void EXTI_Configuration(void) { GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource9); /* Configure EXTI */ EXTI_Enable(1); } void EXTI9_5_IRQHandler(void) { /* disable interrupt */ EXTI_Enable(0); /* start timer */ rt_timer_start(touch->poll_timer); EXTI_ClearITPendingBit(EXTI_Line9); } /** * This function will read touch coordinator from iic bus, * then post to rt gui server as mouse event. * (Note: just process sigle touch, igonre multi touch * * @param parameter the value of rt_timer parameter */ void touch_timeout(void* parameter) { u8 i, values[23]; static unsigned int touched_down = 0; struct rtgui_event_mouse emouse; rt_timer_stop(touch->poll_timer); // read touch data array touch_read_reg(0, &values[0], 23); // // debug data output // for(i=0; i<23; i++) // { // rt_kprintf("|%d", values); // } // rt_kprintf("|\r\n"); // only process sigle touch, ignore multi touch. if (values[0] == 0) { // when values[0] == 0, that was release touch, hands leaved. // release mouse up event emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; emouse.button = (RTGUI_MOUSE_BUTTON_LEFT |RTGUI_MOUSE_BUTTON_UP); /* use old value */ emouse.x = touch->x; emouse.y = touch->y; touched_down = 0; } else if (values[0] == 1) { // mouse down event emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; emouse.parent.sender = RT_NULL; touch->x = (((u16)values[1]<<8) + values[2]) * OTT_SCAL_X; touch->y = 480 - (((u16)values[3]<<8) + values[4]) * OTT_SCAL_Y; //rt_kprintf("x:%d y:%d\r\n", touch->x, touch->y); emouse.x = touch->x; emouse.y = touch->y; /* init mouse button */ emouse.button = ((touched_down ? RTGUI_MOUSE_BUTTON_LEFT : RTGUI_MOUSE_BUTTON_RIGHT) |RTGUI_MOUSE_BUTTON_DOWN); touched_down = 1; } else { // multi toch, do nothing. } if (emouse.parent.type){ /* send event to server */ rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse)); } EXTI_Enable(1); } void touch_hw_init(void) { // Enable RCC GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(scl_rcc|sda_rcc|rst_rcc|int_rcc|RCC_APB2Periph_AFIO,ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // Set SCL GPIO_InitStructure.GPIO_Pin = scl_pin; GPIO_Init(scl_gpio, &GPIO_InitStructure); // Set SDA GPIO_InitStructure.GPIO_Pin = sda_pin; GPIO_Init(sda_gpio, &GPIO_InitStructure); // Set RST GPIO_InitStructure.GPIO_Pin = rst_rcc; GPIO_Init(rst_gpio, &GPIO_InitStructure); // Set INT GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Pin = int_pin; GPIO_Init(int_gpio, &GPIO_InitStructure); // Set RST to high GPIO_SetBits(rst_gpio, rst_pin); // Pull up INT to high GPIO_SetBits(int_gpio, int_pin); // Set SCL and SDA output to high GPIO_SetBits(scl_gpio, scl_pin); GPIO_SetBits(sda_gpio, sda_pin); // Reset touch device GPIO_ResetBits(rst_gpio, rst_pin); rt_thread_delay_ms(100); // Release reset pin GPIO_SetBits(rst_gpio, rst_pin); rt_thread_delay_ms(100); } /* RT-Thread Device Interface */ static rt_err_t rtgui_touch_init (rt_device_t dev) { NVIC_Configuration(); EXTI_Configuration(); return RT_EOK; } static rt_err_t rtgui_touch_control (rt_device_t dev, rt_uint8_t cmd, void *args) { return RT_EOK; } void rtgui_touch_hw_init(void) { touch_hw_init(); // Open touch device sensor touch_control_sensor(1); { u8 value = 0; // Read device status from sensor register touch_read_reg(OTT_BUFFER_ADDR_SENSOR, &value, 1); if(value!=0x80) { rt_kprintf("Touch initialization failed!\r\nCTP ID:%x\r\n",value); return; } } touch = (struct rtgui_touch_device*)rt_malloc (sizeof(struct rtgui_touch_device)); if (touch == RT_NULL) return; /* no memory yet */ /* clear device structure */ rt_memset(&(touch->parent), 0, sizeof(struct rt_device)); /* init device structure */ touch->parent.type = RT_Device_Class_Unknown; touch->parent.init = rtgui_touch_init; touch->parent.control = rtgui_touch_control; touch->parent.user_data = RT_NULL; /* create 1/8 second timer */ touch->poll_timer = rt_timer_create("touch", touch_timeout, RT_NULL, RT_TICK_PER_SECOND/50, RT_TIMER_FLAG_ONE_SHOT); rtgui_touch_init(RT_NULL); /* register touch device to RT-Thread */ rt_device_register(&(touch->parent), "touch", RT_DEVICE_FLAG_RDWR); } #ifdef RT_USING_FINSH #include <finsh.h> void touch_t( rt_uint16_t x , rt_uint16_t y ) { struct rtgui_event_mouse emouse ; emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; emouse.parent.sender = RT_NULL; emouse.x = x ; emouse.y = y ; /* init mouse button */ emouse.button = (RTGUI_MOUSE_BUTTON_LEFT |RTGUI_MOUSE_BUTTON_DOWN ); rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse)); rt_thread_delay(2) ; emouse.button = (RTGUI_MOUSE_BUTTON_LEFT |RTGUI_MOUSE_BUTTON_UP ); rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse)); } FINSH_FUNCTION_EXPORT(touch_t, x & y ) ; #endif[/mw_shl_code]


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

120

主题

7877

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
发表于 2015-8-9 12:52:51 | 显示全部楼层
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

2

主题

6

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2015-1-13
在线时间
0 小时
 楼主| 发表于 2015-8-9 13:35:09 | 显示全部楼层
刚发现 行381 操作符?的两个值写反了。
看rtgui的touch代码,移动手指时,发送右键消息,不确定是什么逻辑。
回复 支持 反对

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2015-8-9 21:11:26 | 显示全部楼层
多谢分享。。。
开往春天的手扶拖拉机
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2015-8-9 21:35:26 | 显示全部楼层
谢谢分享.....
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 18:46

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表