⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 matrix_button.c~

📁 矩阵button驱动
💻 C~
字号:
#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/ioctl.h>#include <linux/types.h>#include <linux/config.h>#include <linux/init.h>#include <linux/unistd.h>//#include <linux/io.h>#include "matrix_button.h"#include "btn_ioctl_cmd.h"//used for continueing send data to 74LS164 for checking out which row and column.static struct timer_list GC3210_74LS164_timer;static u8 col=0;//for output.                 //used in the GC3210_74LS164_timer() and  matrix_button_read()               //used in the function getKeyValue() and getKey();//this is the phone key layoutstatic u8 key[8][4]={                       {'f','1','4','7'},                       {'0','2','5','8'},                       {'g','3','6','9'},                       {'e','h',' ','k'},                       {' ',' ',' ',' '},                       {' ','a','j','b'},                       {' ',' ',' ','i'},                       {' ',' ',' ','l'},                   };                                      static int button_up_or_down=0;//count the number of sending data after press button               static int delay(int time);/**function: fetch the button row number from 74HC165*arg:       row , the button row number *return     int , judge whether press two keys; */static int button_read(u8 * row);/**function: send 8 bits to 74LS164 for checking out with column and row. *becase the power (the bit value is 1 )from 74LS164 cross the button point and directly come to 74HC165.*through checking whick bit value is 1 , know which row is the button row*return : none*/static void sendData(u8 data);      static void GC3210_74LS164_timer_handler(void);static u8 getKeyValue(u8 x,u8 position_Y);static u8 getKey(u8 position[2]);static int matrix_button_open(struct inode *inode,struct file *file);static ssize_t matrix_button_read(struct file *filp,char __user *buf,size_t count,loff_t *oppos);static int matrix_button_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg);static int delay(int time){    while(--time);    return 0;}static int button_read(u8 * row){        int judge=0;    int time;    u8 val=0,reg=0;    * row = 0;        //printk("================button read\n");    //printk("button_read\n");    //CLK=0    reg = * BUTTON_74HC165_CLK_O;    * BUTTON_74HC165_CLK_O = reg & ~(1<<0);    //PL=0    reg = * BUTTON_74HC165_PL_O;    * BUTTON_74HC165_PL_O  = reg & ~(1<<2);    //delay 10000    delay(2);    //PL=1    reg= * BUTTON_74HC165_PL_O;    * BUTTON_74HC165_PL_O  = reg | (1<<2);    //scanf keyboard    for(time=0;time<8;time++)    {        reg = * BUTTON_74HC165_DATA_I;        val = (reg & (1<<1));        val =val>>1;        * row |= val << time;                if(val) judge++;//judge whether press two keys                //CLK=1        reg = * BUTTON_74HC165_CLK_O;        * BUTTON_74HC165_CLK_O = reg | (1<<0);                //delay(10);        //CLK=0        reg = * BUTTON_74HC165_CLK_O;        * BUTTON_74HC165_CLK_O = reg & ~(1<<0);    }        return judge >2 ? 1 : 0;    }static void sendData(u8 data){//send a byte    int time;    //u8 val=0,reg=0;    u8 reg=0;        for(time=0;time<8;time++)    {        //SCL = 0        reg = * BUTTON_74LS164_SCL_O;        * BUTTON_74LS164_SCL_O = reg & ~(1<<4);        //send a bit        if(data & (1<<time))        {            reg = * BUTTON_74LS164_SDA_O;            * BUTTON_74LS164_SDA_O = reg | (1<<3);        }        else        {            reg = * BUTTON_74LS164_SDA_O;            * BUTTON_74LS164_SDA_O = reg & ~(1<<3);        }        delay(10);         //SCL = 1        reg = * BUTTON_74LS164_SCL_O;        * BUTTON_74LS164_SCL_O = reg | (1<<4);                //delay(10);    }    }static void GC3210_74LS164_timer_handler(void){    static int time=0;    //int i=0;        time = ++time % 8;    col=1<<time;    sendData( col );    ++button_up_or_down;    //printk("col=%x\n", ++button_up_or_down % 8;col);    //printk("GC3210_74LS164_timer_handler\n");    GC3210_74LS164_timer.expires=jiffies + TIMER_DELAY;    add_timer(&GC3210_74LS164_timer);}static int matrix_button_open(struct inode *inode,struct file *file){    u8 reg;        printk("open matrix button \n");    //* BUTTON_LPB_MISC_CFG = ENABLE_LPB_MISC_CFG;    //* BUTTON_GPIO_OE = 0x05;        //reset    * BUTTON_LPB_MISC_CFG &=0x0;    * BUTTON_GPIO_OE &= 0x0;    //enable LPB MISC CFG    * BUTTON_LPB_MISC_CFG |= ENABLE_LPB_MISC_CFG;    //enable CLK output    * BUTTON_GPIO_OE |= ENABLE_GPIO_OE_CLK;    //enable PL output    * BUTTON_GPIO_OE |= ENABLE_GPIO_OE_PL;    //enable DATA input    * BUTTON_GPIO_OE &= ENABLE_GPIO_OE_DATA;    //enable LCD SDA output    * BUTTON_GPIO_OE |= ENABLE_GPIO_OE_LCD_DATA;    //enable LCD CLK output    * BUTTON_GPIO_OE |= ENABLE_GPIO_OE_LCD_CLK;    #if Y    reg = * BUTTON_74HC165_PL_O;    printk("74HC165 PL is %x\n",reg);    reg = * BUTTON_74HC165_CLK_O;       printk("74HC165 CLK is %x\n",reg);    reg = * BUTTON_74LS164_SDA_O;       printk("74HC165 CLK is %x\n",reg);    reg = * BUTTON_74LS164_SCL_O;       printk("74HC165 CLK is %x\n",reg);#endif            //initialize the timer for reading key data        init_timer(&GC3210_74LS164_timer);    GC3210_74LS164_timer.expires=jiffies + TIMER_DELAY;    GC3210_74LS164_timer.function=(void *)(GC3210_74LS164_timer_handler);    GC3210_74LS164_timer.data=0;        add_timer(&GC3210_74LS164_timer);        //return nonseekable_open(inode,file);    return 0;}////the key[][] variable is global variable,which represent the phone key layoutstatic u8 getKeyValue(u8 x,u8 position_Y){         if(!(position_Y & ~0x40)) return key[x][3];    if(!(position_Y & ~0x20)) return key[x][2];    if(!(position_Y & ~0x10)) return key[x][1];    if(!(position_Y & ~0x08)) return key[x][0];        printk("the position_Y key is not existing\n");    return 0xff;}////the key[][] variable is global variable,which represent the phone key layoutstatic u8 getKey(u8 position[2]){    u8 keyValue=0;    if(!(position[0] & 0x80)) return 'n';//hang up    if(!(position[0] & ~0x80)) return keyValue=getKeyValue(7,position[1]);//call        if(!(position[0] & ~0x81)) return keyValue=getKeyValue(0,position[1]);    if(!(position[0] & ~0x82)) return keyValue=getKeyValue(1,position[1]);    if(!(position[0] & ~0x84)) return keyValue=getKeyValue(2,position[1]);    if(!(position[0] & ~0x88)) return keyValue=getKeyValue(3,position[1]);    if(!(position[0] & ~0xa0)) return keyValue=getKeyValue(5,position[1]);    if(!(position[0] & ~0xc0)) return keyValue=getKeyValue(6,position[1]);            printk("the position_X key is not existing\n");    return 0xff;}static ssize_t matrix_button_read(struct file *filp,char __user *buf,size_t count,loff_t *oppos){    u8 row=0,temp_row=0,temp_col=0;    u8 position[2]={0};    u8 ch=0;    int num=0;    //printk(" matrix button read\n");     while(1)    {        while(button_read(&row));        temp_col=col;//keep the col value        if(row && (row & ~0x80))//check whether the row is what we need         {            temp_row=row;//keep the row value                        while(button_read(&row));//eliminate dither            if(temp_row==row)//eliminate dither            {                do                {//just ready for accepting next key value,so hold the process                    msleep(10);                    while(button_read(&row));                    if(num++>30)                    {                        break;                    }                }                while(!(row & ~0x80) || temp_row==row);                printk(" matrix button read temp_row:%x\n",temp_row);                printk(" matrix button read row:%x\n",row);                                position[0]=temp_row;                position[1]=temp_col;                ch=getKey(position);//get the key value                if(ch)                {                    copy_to_user(buf,&ch,count);//copy it to the user room                    break;                }            }        }            }        //put_user((u8 *)buf,ch);    return  count; }static int matrix_button_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg){    u8 row=0,temp_row=0,temp_col=0;    u8 position[2]={0};    int temptemp=0,temp1=-1;    int btn_status=0;        //printk("matrix button ioctl\n");        switch(cmd)    {        case BTN_GET_POSITION:            //if press two key at the same time , continue reading;            while(button_read(&row));            temp_col=col;//keep the col value                        position[0]=row;            position[1]=temp_col;            copy_to_user(arg,position,2);            //printk("matrix_button_ioctl\n");            break;        case BTN_GET_STATUS:                        button_up_or_down=0;            do            {                                while(button_read(&row));                                if(row != 0x80 && (row & 0x80))                {                    btn_status=1;                    copy_to_user(arg,&btn_status,1);                    return 0;                }                               //printk("BTN_GET_STATUS :%d,%d\n",button_up_or_down,temptemp);            }while(button_up_or_down<9);                        btn_status=0;            copy_to_user(arg,&btn_status,1);                        break;                    default :            ;                }    return 0;}static struct file_operations matrix_button_fops={    .open=matrix_button_open,    .ioctl=matrix_button_ioctl,    .read=matrix_button_read,};static int __init matrix_button_init(void){    int ret;    printk("=================Matrix button init================\n");    ret=register_chrdev(0,"matrix_button",&matrix_button_fops);    if(ret<0)    {        printk("matrix button can not get magor number : initial error\n");        return ret;    }    return 0;}static  void  __exit matrix_button_exit(void){    printk("=================Matrix button exit=====================\n");}module_init(matrix_button_init);module_exit(matrix_button_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -