📄 matrix_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]={ {'*','1','4','7'}, {'0','2','5','8'}, {'#','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 get_btnStatus();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 int get_btnStatus(){ u8 row=0; int btn_status=0; button_up_or_down=0; do { while(button_read(&row)); if(row != 0x80 && (row & 0x80)) { //button down btn_status=1; return btn_status; } }while(button_up_or_down<9); //button up btn_status=0; return btn_status; }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"); int status=0; static int hangUp_or_call=1; while(1) { while(button_read(&row)); temp_col=col;//keep the col value if((row & 0x80) && (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 { while(get_btnStatus()); /* 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); */ 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; } } } else { if(!(row & ~0x80)) { if( !row && get_btnStatus() == 1) { ch='n'; copy_to_user(buf,&ch,count); hangUp_or_call = 2; } else if( row && get_btnStatus() == 0 ) { ch='y'; copy_to_user(buf,&ch,count); hangUp_or_call = 1; } } } } //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_col=0; u8 position[2]={0}; int btn_status=0; 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); 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; } }while(button_up_or_down<9); btn_status=0; copy_to_user(arg,&btn_status,1); */ btn_status=get_btnStatus(); 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 + -