Qt触摸屏、键盘的驱动

Qt触摸屏、键盘的驱动

1.Qt触摸屏的加入:

EP9315开 发板可以用触摸屏作为Qt的鼠标输入,这时候你需要修改$REAL_QTDIR/tmake/lib/qws/linux-arm-g++目录下的 tmake.conf文件。好了,打开这个文件,看到TMAKE_CXXFLAGS变量了吗?在后面增加一项-DQT_QWS_CUSTOM,当然这个变 量需要你打入qt-2.3.7-patch-crus1.4.3.bz2补丁才有效果,这个补丁是curris logic公司专门为Qt-2.3.7作的补丁。

2.Qt键盘的加入: 

  首 先编写驱动程序,在驱动程序中主要实现read,poll,interrupt,其中read主要针对非阻塞方法进行处理,实现poll方法,以满足应用 程序对select,FD_SET……一套函数的调用。定义等待队列static DECLARE_WAIT_QUEUE_HEAD(queue);在中断中调用wake_up_interruptible(&queue);唤 醒等待队列,在poll中调用poll_wait(filp, &queue, wait);等待中断的唤醒。

    注意事项,编译驱动的交叉编译器要和编译内核的交叉编译器一致。

 

#include <asm/system.h>

#include <linux/config.h>

#include <linux/types.h>

#include <linux/major.h>

#include <linux/string.h>

#include <linux/fcntl.h>

#include <linux/slab.h>

#include <linux/timer.h>

#include <linux/module.h>

#include <linux/init.h>

#include <linux/ioport.h>

#include <linux/poll.h>

#include <linux/fs.h>

#include <linux/sched.h>

 

#include <asm/io.h>

#include <asm/memory.h>

#include <asm/uaccess.h>

#include <asm/segment.h>

#include <asm/arch/hardware.h>

#include <asm/arch/io.h>

#include <asm/arch/irqs.h>

#include <asm/arch/regmap.h>

#include <asm/irq.h>

#define SKB_NAME "/dev/skbdriver"

 

int __init skb_init(void);

void __exit skb_exit(void);

void gpio_init(void);

static unsigned int skb_poll(struct file *filp, poll_table *wait);

static void skb_interrupt(int irq, void *dev_id, struct pt_regs *regs);

static ssize_t skb_read(struct file *filp, char *buf, size_t count, loff_t *l);

static int skb_open(struct inode *inode, struct file *filp);

static int skb_release(struct inode *inode, struct file *filp);

 

//static wait_queue_head_t queue;

static DECLARE_WAIT_QUEUE_HEAD(queue);

 

static unsigned char portdata[2];

 

 

void gpio_init(void){

    unsigned long temp;

//disable interrupt

//  temp = readl(VIC1INTENABLE)&0xf7ffffff;

//  writel(temp,VIC1INTENABLE);

    disable_irq(IRQ_GPIO);

//select irq mode  

    temp = readl(VIC1INTSELECT)&0xf7ffffff;

    writel(temp,VIC1INTSELECT);

//setup EGPIO(A(3-7),B(0,2))

//direction register

    temp = readl(GPIO_PADDR)&0x07;

    writel(temp,GPIO_PADDR);

    temp = readl(GPIO_PBDDR)&0xfa;

    writel(temp,GPIO_PBDDR);

//interrupt enable register

    temp = readl(GPIO_AINTEN)|~0x07;

    writel(temp,GPIO_AINTEN);

    temp = readl(GPIO_BINTEN)|~0xfa;

        writel(temp,GPIO_BINTEN);

//inttype1 register

    temp = readl(GPIO_AINTTYPE1)|~0x07;

    writel(temp,GPIO_AINTTYPE1);

    temp = readl(GPIO_AINTTYPE2)|~0xfa;

        writel(temp,GPIO_AINTTYPE2);

    temp = readl(GPIO_BINTTYPE1)&0x07;

        writel(temp,GPIO_BINTTYPE1);

    temp = readl(GPIO_BINTTYPE2)&0xfa;

        writel(temp,GPIO_BINTTYPE2);

//EOI register

    temp = readl(GPIO_AEOI)|~0x07;

    writel(temp,GPIO_AEOI);

        temp = readl(GPIO_BEOI)|~0xfa;

        writel(temp,GPIO_BEOI);

//debounce register

    temp = readl(GPIO_ADB)|~0x07;

    writel(temp,GPIO_ADB);

        temp = readl(GPIO_BDB)|~0xfa;

        writel(temp,GPIO_BDB);

//enable interrupt

//        temp = readl(VIC1INTENABLE)|~0xf7ffffff;

//         writel(temp,VIC1INTENABLE);

   

//  init_waitqueue_head(&queue);

    portdata[0]=0xf8;

    portdata[1]=0x05;

    enable_irq(IRQ_GPIO);

       

}

 

static unsigned int skb_poll(struct file *filp, poll_table *wait)

{

//  printk("before poll_wait/n");

        poll_wait(filp, &queue, wait);

//  printk("in skb_poll/n");

        if (((portdata[0]&0xf8)!=0xf8)||((portdata[1]&0x05)!=0x05))

    {

//      printk("faint/n");

                return POLLIN | POLLRDNORM;

    }

        return 0;

}

 

static void skb_interrupt(int irq, void *dev_id, struct pt_regs *regs)

{

    unsigned long temp;

    disable_irq(IRQ_GPIO);

 

        temp = readl(GPIO_AEOI)|~0x07;

        writel(temp,GPIO_AEOI);

        temp = readl(GPIO_BEOI)|~0xfa;

        writel(temp,GPIO_BEOI);

   

    portdata[0]=readl(GPIO_PADR);

    portdata[1]=readl(GPIO_PBDR);

 

//  printk("%x/t%x/n",portdata[0],portdata[1]);

 

   

    wake_up_interruptible(&queue);

    enable_irq(IRQ_GPIO);

}

 

static ssize_t skb_read(struct file *filp, char *buf, size_t count, loff_t *l)

{

    unsigned char data[2];

    ssize_t retval;

 

 

    data[0]=portdata[0];

    data[1]=portdata[1];

       

    if(((data[0]&0xf8)==0xf8)&&((data[1]&0x05)==0x05))

    {

        if (filp->f_flags & O_NONBLOCK)

        {

                        retval = -EAGAIN;

        }

    }

   

   

    if(copy_to_user(buf, &data, sizeof(data)))

        return -EFAULT;

//  printk("in skb_read/n");

    portdata[0]=0xf8;

    portdata[1]=0x05;

                                                                               

        return (sizeof(data));

 

}

 

static int skb_open(struct inode *inode, struct file *filp)

{

//  printk("in open/n");

        MOD_INC_USE_COUNT;

        return 0;

}

 

static int skb_release(struct inode *inode, struct file *filp)

{

//  printk("in release/n");

        MOD_DEC_USE_COUNT;

        return 0;

}

 

struct file_operations skb_fops = {

        read:           skb_read,

    poll:       skb_poll,

        open:           skb_open,

        release:        skb_release,

};

 

int __init skb_init(void){

    int rc;

    int ret;

    rc = register_chrdev(144,SKB_NAME, &skb_fops);

    if(rc<0){

      printk(KERN_INFO"LINBUS: Can't get Major /n");

      return rc;

    }

         printk("<1>*****************rc is %d/n",rc) ;

 

    if ((ret = request_irq(IRQ_GPIO,skb_interrupt,SA_INTERRUPT, SKB_NAME, NULL)))

        {

                printk("skb_init: failed to register IRQ/n");

                 free_irq(IRQ_GPIO, NULL);

                return ret;

        }

   

    gpio_init();

    return 0;

 

}

void __exit skb_exit(void)

{

        free_irq(IRQ_GPIO, NULL);

//        devfs_unregister_chrdev(TS_MAJOR, TS_NAME);

//        printk("ads7843 touch screen driver removed/n");

}

 

module_init(skb_init);

module_exit(skb_exit);

 

然后修改/root /Qt_arm/qt-2.3.7-emb/src/kernel/qkeyboard_qws.cpp程序,主要参考 QWSTtyKeyboardHandler的实现方法,其中QSocketNotifier的实现类似于FD_SET,也可能就是对FD_SET的封 装。最后在QWSKeyboardHandler *QWSServer::newKeyboardHandler( const QString &spec )函数中将所实现的类实例化else if ( type == "SKB" ) {

        handler = new QWSSKBKeyboardHandler(device);

//modified by bugqiao begin

class QWSSKBKeyboardHandler : public QWSPC101KeyboardHandler

{

    Q_OBJECT

public:

    QWSSKBKeyboardHandler(const QString& device);     virtual ~QWSSKBKeyboardHandler();

                                                                               

private slots:

    void readKeyboardData();

                                                                                

private:

    int fd;

};

//modified by bugqiao end

/* SKB driver */

//modified by bugqiao begin

QWSSKBKeyboardHandler::QWSSKBKeyboardHandler(const QString& device)

{

        fd = open(device.isEmpty()?"/dev/skbdriver":device.latin1(),O_RDONLY|O_NONBLOCK, 0);

        qDebug("fd = %d/n",fd);

        if ( fd >= 0 ) {

                QSocketNotifier *notifier;

                notifier = new QSocketNotifier( fd, QSocketNotifier::Read, this );

        connect( notifier, SIGNAL(activated(int)),this,

                  SLOT(readKeyboardData()) );

    }

}

                                                                                                  

QWSSKBKeyboardHandler::~QWSSKBKeyboardHandler()

{

    close(fd);

}

                                                                                                   

void QWSSKBKeyboardHandler::readKeyboardData()

{

    unsigned char portdata[2];

    int n = read(fd, &portdata, sizeof(portdata) );

    int tmp;

        qDebug("n=%d/tportdata[0]=%x/tportdata[1]=%x/n",n,portdata[0],portdata[1]);

    if ( n != 2 )

        return;

    if((tmp=portdata[0]&0x08)==0) {

        qDebug("up/n");

        processKeyEvent( 0, Qt::Key_Up, 0, 1, false );

    } else if((tmp=portdata[0]&0x10)==0) {

        qDebug("right/n");

         processKeyEvent( 0, Qt::Key_Right, 0, 1, false  );

    } else if((tmp=portdata[0]&0x20)==0) {

        qDebug("down/n");

        processKeyEvent( 0, Qt::Key_Down, 0, 1, false );

    } else if((tmp=portdata[0]&0x40)==0) {

        qDebug("left/n");

         processKeyEvent( 0, Qt::Key_Left, 0, 1, false );

    } else if((tmp=portdata[0]&0x80)==0) {

        qDebug("esc/n");

        processKeyEvent( 0, Qt::Key_Escape, 0, 1, false );

    } else if((tmp=portdata[1]&0x01)==0) {

        qDebug("return/n");

         processKeyEvent( 0, Qt::Key_Return, 0, 1, false );

    }

                                                                                                  

}

//modified by bugqiao end

最后在编写的脚本文件中增加export QWS_KEYBOARD=SKB:/dev/skbdriver

这是别人的总结,在这里参考一下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值