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

📄 kbd7312.c

📁 嵌入式下实验的新的驱动设计源代码
💻 C
字号:
#include <linux/config.h>
#include <linux/utsname.h>
#include <linux/kernel.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/poll.h>
#include <asm/irq.h>

#include <asm/segment.h>


#define KBD_IRQ_NUM		0
#define KEYBOARD_MAJOR 	59 

static short Ready;
static char KeyValue;
static DECLARE_WAIT_QUEUE_HEAD(KbdWait);

static int col_global;
static int keypressed = 0;

void dly(int n)
{
	int i, j;

	for(i = 0; i < 1000; i++)
		for(j = 0; j < n; j++)
			;
}
static void KbdInterrupt(int irq, void *dev_id, struct pt_regs *regs)
{
	unsigned char value;
	
	Ready = 0;
	
	value = *(unsigned char *)0xff000000;
	keypressed = 1;	
	if(col_global == 0) {
		if(value == 0x1) {
			KeyValue = 1;
			printk("KeyValue = %d\n", KeyValue);
//			printk("col = %d, row = 1\n", col_global + 1);
		} 

		if(value & 0x2) {
			KeyValue = 5;
			printk("KeyValue = %d\n", KeyValue);
//			printk("col = %d, row = 2\n", col_global + 1);
		} 

		if(value & 0x4) {
			KeyValue = 9;
			printk("KeyValue = %d\n", KeyValue);
//			printk("col = %d, row = 3\n", col_global + 1);
		} 
			
		if(value & 0x8) {
			KeyValue = 13;
			printk("KeyValue = %d\n", KeyValue);
//			printk("col = %d, row = 4\n", col_global + 1);
		} 

		dly(1000);
	} 
	else if (col_global == 1) {
		if(value & 0x1) {
			KeyValue = 2;
			printk("KeyValue = %d\n", KeyValue);
//			printk("col = %d, row = 1\n", col_global + 1);
		}

		if(value & 0x2) {
			KeyValue = 6;
			printk("KeyValue = %d\n", KeyValue);
//			printk("col = %d, row = 2\n", col_global + 1);
		} 

		if(value & 0x4) {
			KeyValue = 10;
			printk("KeyValue = %d\n", KeyValue);
//			printk("col = %d, row = 3\n", col_global + 1);
		}
			
		if(value & 0x8) {
			KeyValue = 14;
			printk("KeyValue = %d\n", KeyValue);
//			printk("col = %d, row = 4\n", col_global + 1);
		} 
		
		dly(1000);
	}
	else if(col_global == 2) {
		if(value & 0x1) {
			KeyValue = 3;
			printk("KeyValue = %d\n", KeyValue);
//			printk("col = %d, row = 1\n", col_global + 1);
		} 

		if(value & 0x2) {
			KeyValue = 7;
			printk("KeyValue = %d\n", KeyValue);
//			printk("col = %d, row = 2\n", col_global + 1);
		} 

		if(value & 0x4) {
			KeyValue = 11;
			printk("KeyValue = %d\n", KeyValue);
//			printk("col = %d, row = 3\n", col_global + 1);
		} 
			
		if(value & 0x8) {
			KeyValue = 15;
			printk("KeyValue = %d\n", KeyValue);
//			printk("col = %d, row = 4\n", col_global + 1);
		} 
	
		dly(1000);
	}
	else if(col_global == 3) {
		if(value & 0x1) {
			KeyValue = 4;
			printk("KeyValue = %d\n", KeyValue);
//			printk("col = %d, row = 1\n", col_global + 1);
		} 

		if(value & 0x2) {
			KeyValue = 8;
			printk("KeyValue = %d\n", KeyValue);
//			printk("col = %d, row = 2\n", col_global + 1);
		} 

		if(value & 0x4) {
			KeyValue = 12;
			printk("KeyValue = %d\n", KeyValue);
//			printk("col = %d, row = 3\n", col_global + 1);
		} 
			
		if(value & 0x8) {
			KeyValue = 16;
			printk("KeyValue = %d\n", KeyValue);
//			printk("col = %d, row = 4\n", col_global + 1);
		} 

		dly(1000);
	}
#if 0	//test ok	
	if(value & 0x1) {
		printk("col = %d, row = 1\n", col_global + 1);
	}

	if(value & 0x2) {
		printk("col = %d, row = 2\n", col_global + 1);
	}

	if(value & 0x4) {
		printk("col = %d, row = 3\n", col_global + 1);
	}
			
	if(value & 0x8) {
		printk("col = %d, row = 4\n", col_global + 1);
	}
	
//			printk("value = 0x%02x\n", value);
			dly(500);
#endif			

#if 0	
	while(1){			
		again:
			printk("\n0x80000100 : 0x%08x\n", *(unsigned char *)0xff000100);
			printk("0x80000000 : 0x%08x\n", *(unsigned char *)0xff000000);
			
			printk("n= %d\n", n);

			printk("interrupt\n");
			value = *(unsigned char *)0xff000000;
			
			if(value & 0x1) {
				printk("col = %d, row = 1\n", n + 1);
			}

			if(value & 0x2) {
				printk("col = %d, row = 2\n", n + 1);
			}

			if(value & 0x4) {
				printk("col = %d, row = 3\n", n + 1);
			}
			
			if(value & 0x8) {
				printk("col = %d, row = 4\n", n + 1);
			}
//			printk("value = 0x%02x\n", value);
			dly(500);
			*(unsigned long *)0xff000100 += 1;
			*(unsigned long *)0xff001700 |= 0xff;		//clear
			n += 1;
			if( n == 4) {
				*(unsigned long *)0xff000100 -= 4;
				n -= 4;
				goto scan_exit;
			}
			goto again;
	}
#endif	
				
	//	*(unsigned long *)0xff001700 |= 0xff;		//clear
}

static int KbdClose(struct inode * inode, struct file * file)
{ 
	MOD_DEC_USE_COUNT; 
	return 0;
}

static int KbdOpen(struct inode * inode, struct file * file)
{
	MOD_INC_USE_COUNT;
	
	*(unsigned long *)0xff000040 |= 0xfffffffff;
        *(unsigned long *)0xff001100 |= 0x000000008;
        *(unsigned long *)0xff000100 |= 0x000000009;
	enable_irq(16);
	return 0;
}

static int KbdRead(struct file * file, char * buffer, size_t count, loff_t *ppos)
{
        unsigned char *kbuf=kmalloc(16, GFP_KERNEL);
	*kbuf = KeyValue;
	copy_to_user(buffer, kbuf, 1);
	kfree(kbuf);
	
	//copy_to_user(buffer, &KeyValue, sizeof KeyValue);
	//Ready = 0;
	return sizeof 1;
}
/*
 * select for mouse input
 */
static unsigned int KbdSelect(
	struct file *file, 
	struct poll_table_struct *wait)
{
    	if (Ready)
        return 1;
	poll_wait(file, &KbdWait, wait);
	return 0;
}

static int KbdIoctl(
        struct inode *inode,
        struct file *file,
        unsigned int cmd,
        unsigned long arg
)
{
	int flag = 0;
	keypressed = 0;	
        switch(cmd) {
		case 0:
			for(col_global = 0; col_global < 4; col_global++){
				if(col_global == 0 ) {				
					*(unsigned long *)0xff000100 &= ~0xf;
					*(unsigned long *)0xff000100 |= 0x8;
					dly(1000);
				}
				else if( col_global == 1) {
					*(unsigned long *)0xff000100 &= ~0xf;
					*(unsigned long *)0xff000100 |= 0x9;
					dly(1000);
				}	
				else if( col_global == 2) {
					*(unsigned long *)0xff000100 &= ~0xf;
					*(unsigned long *)0xff000100 |= 0xa;
					dly(1000);
				}	
				else if( col_global == 3) {
					*(unsigned long *)0xff000100 &= ~0xf;
					*(unsigned long *)0xff000100 |= 0xb;
					dly(1000);
				}	
			}
			if (keypressed == 1)
			{
				keypressed = 0;
				return KeyValue;				
			}
			break;
		case 2:
			if( flag == 0) {
				*(unsigned long *)0xff000100 += 1;
				flag = 1;
			} else if (flag == 1){
				*(unsigned long *)0xff000100 -= 1;
				flag = 0;
			}
			break;
		case 1:
			{
			unsigned char value;
			int n = 0;
		
			while(1){			
		again:
//			printk("0x80000100 : 0x%08x\n", *(unsigned char *)0xff000100);
//			printk("0x80000000 : 0x%08x\n", *(unsigned char *)0xff000000);
			
//			printk("n= %d\n", n);

			value = *(unsigned char *)0xff000000;
			
			if(value & 0x1) {
				printk("col = %d, row = 1\n", n + 1);
			}

			if(value & 0x2) {
				printk("col = %d, row = 2\n", n + 1);
			}

			if(value & 0x4) {
				printk("col = %d, row = 3\n", n + 1);
			}
			
			if(value & 0x8) {
				printk("col = %d, row = 4\n", n + 1);
			}
//			printk("value = 0x%02x\n", value);
			dly(500);
			*(unsigned long *)0xff000100 += 1;
			n += 1;
			if( n == 4) {
				*(unsigned long *)0xff000100 -= 4;
				n -= 4;
				break;
			}
			goto again;
		}// end for
			break;	
		} //end case 0	
		
	        default:
                return -EINVAL;
        }
	//return 1;
}

struct file_operations Kbd_fops = {
	read:	KbdRead,
	poll:	KbdSelect, 	/* select */
	open:	KbdOpen,
	ioctl:	KbdIoctl,
	release:	KbdClose,
};

int keyboard_init(void)
{
        int     rc;

        Ready = 0;

        rc = register_chrdev(KEYBOARD_MAJOR, "ep7312-keyboard", &Kbd_fops);
        if (rc < 0) {
                printk(KERN_WARNING "Keyboard: can't get Major %d\n",
                        KEYBOARD_MAJOR);
                return rc; 
        }
        printk("Keyboard Driver Support\n");

	*(unsigned long *)0xff000040 |= 0xfffffffff;
	*(unsigned long *)0xff001100 |= 0x000000008;
	*(unsigned long *)0xff000100 |= 0x000000009;
	
	
	if ( request_irq(16, KbdInterrupt, 0, "mykbd", NULL) ) {
		printk("Keyboard: Cannot register interrupt.\n");
		return -EBUSY;
	}
	return 0;
}

void keyboard_cleanup(void)
{    
     free_irq(16, NULL);	 
     unregister_chrdev(KEYBOARD_MAJOR, "ep7312-keyboard");
     return;
}	

module_init(keyboard_init);
module_exit(keyboard_cleanup);

⌨️ 快捷键说明

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