OpenEdv-开源电子网

 找回密码
 立即注册

扫一扫,访问微社区

正点原子全套STM32开发资料,上千讲STM32视频教程,RT1052教程免费下载啦...
查看: 2219|回复: 4

OTT2001A电容屏 rt-thread gui 驱动

[复制链接]

  离线 

2

主题

6

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2015-1-13
在线时间
0 小时
发表于 2015-8-9 11:50:44 | 显示全部楼层 |阅读模式
MCU stm32f103 fsmc<br />
rt-thread: v2.01<br />
rt-gui: v0.8<br />
<br />
屏幕大小:800 * 480,横屏<br />
扫描方式:中断<br />
<br />
个人作简单测试,仅供参考。<br />
<br />
<br />
delay.c<br />
<div   style="background-color:#E8E8E8;">
[C] 纯文本查看 复制代码
#include "stm32f10x.h"
#include &lt;rtthread.h&gt;
#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-&gt;LOAD/(1000000/RT_TICK_PER_SECOND));

        /* 获得当前时间 */
    delta = SysTick-&gt;VAL;

        /* 循环获得当前时间,直到达到指定的时间后退出循环 */
    do
    {
        if ( delta &gt; SysTick-&gt;VAL )
            current_delay = delta - SysTick-&gt;VAL;
        else
        /* 延时跨越了一次OS tick的边界时的处理 */
            current_delay = SysTick-&gt;LOAD + delta - SysTick-&gt;VAL;
    } while( current_delay &lt; 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);
}

</div>
<br />
ctouch.c<br />
<div   style="background-color:#E8E8E8;">
[C] 纯文本查看 复制代码
/*
 * NOTE: OTT2001A buffer address is 16 bits, not 8 bits
*/

#include &lt;stdbool.h&gt;
#include "stm32f10x.h"

#include "board.h"
#include "ctouch.h"
#include "delay.h"

#include &lt;rtthread.h&gt;
#include &lt;rtgui/event.h&gt;
#include &lt;rtgui/kbddef.h&gt;
#include &lt;rtgui/rtgui_server.h&gt;
#include &lt;rtgui/rtgui_system.h&gt;

#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, &amp;GPIO_InitStructure);
    GPIO_Init(sda_gpio, &amp;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&gt;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&lt;8; i++)
    {              
        GPIO_WriteBit(sda_gpio, sda_pin, (value&amp;0x80)&gt;&gt;7?Bit_SET:Bit_RESET);
        value&lt;&lt;=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&lt;8; i++ )
	{
        GPIO_ResetBits(scl_gpio, scl_pin);
		rt_hw_us_delay(30);
		GPIO_SetBits(scl_gpio, scl_pin);
		result&lt;&lt;=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&gt;&gt;8);
	iic_wait_ack(); 	 										  		   
	iic_send_byte(reg&amp;0XFF);
	iic_wait_ack();  
	for(i=0;i&lt;size;i++)
	{
    	iic_send_byte(buf[i]);
		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&gt;&gt;8);
	iic_wait_ack(); 	 										  		   
 	iic_send_byte(reg&amp;0XFF);
	iic_wait_ack();  
 	iic_start();  	 	   
	iic_send_byte(OTT_DEVICE_ADDR_R);
	iic_wait_ack();	   
	for(i=0; i&lt;size - 1; i++)
	{	   
    	buf[i]=iic_read_byte();
        iic_send_ack();
	} 
    // last byte
    buf[i]=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, &amp;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(&amp;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(&amp;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-&gt;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-&gt;poll_timer);

    // read touch data array
    touch_read_reg(0, &amp;values[0], 23);

//    // debug data output
//    for(i=0; i&lt;23; i++)
//    {
//        rt_kprintf("|%d", values[i]);
//    }
//    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-&gt;x;
        emouse.y = touch-&gt;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-&gt;x = (((u16)values[1]&lt;&lt;8) + values[2]) * OTT_SCAL_X;
        touch-&gt;y = 480 - (((u16)values[3]&lt;&lt;8) + values[4]) * OTT_SCAL_Y;
        
        //rt_kprintf("x:%d y:%d\r\n", touch-&gt;x, touch-&gt;y);
        
        emouse.x = touch-&gt;x;
        emouse.y = touch-&gt;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(&amp;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, &amp;GPIO_InitStructure);

    // Set SDA
    GPIO_InitStructure.GPIO_Pin = sda_pin;
    GPIO_Init(sda_gpio, &amp;GPIO_InitStructure);
    
    // Set RST
    GPIO_InitStructure.GPIO_Pin = rst_rcc;
    GPIO_Init(rst_gpio, &amp;GPIO_InitStructure);
    
    // Set INT
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Pin = int_pin;
    GPIO_Init(int_gpio, &amp;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, &amp;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(&amp;(touch-&gt;parent), 0, sizeof(struct rt_device));

    /* init device structure */
    touch-&gt;parent.type = RT_Device_Class_Unknown;
    touch-&gt;parent.init = rtgui_touch_init;
    touch-&gt;parent.control = rtgui_touch_control;
    touch-&gt;parent.user_data = RT_NULL;

    /* create 1/8 second timer */
    touch-&gt;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(&amp;(touch-&gt;parent), "touch", RT_DEVICE_FLAG_RDWR);
}

#ifdef RT_USING_FINSH
#include &lt;finsh.h&gt;

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(&amp;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(&amp;emouse.parent, sizeof(struct rtgui_event_mouse));
}

FINSH_FUNCTION_EXPORT(touch_t, x &amp; y ) ;
#endif

</div>
<br />
<br />
回复

使用道具 举报

  离线 

116

主题

7608

帖子

12

精华

资深版主

Rank: 8Rank: 8

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

使用道具 举报

  离线 

2

主题

6

帖子

0

精华

新手上路

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

使用道具 举报

  离线 

74

主题

6644

帖子

5

精华

资深版主

Rank: 8Rank: 8

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

使用道具 举报

  离线 

509

主题

9万

帖子

31

精华

管理员

Rank: 12Rank: 12Rank: 12

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

使用道具 举报

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

本版积分规则




关闭

必看,必学:"原子哥”力荐上一条 /1 下一条

正点原子公众号

QQ|联系我们|手机版|官方淘宝店|微信公众平台|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2018-9-20 22:18

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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