/* pi2ps2.c -- Raspberry Pi PS/2 keyboard device driver using the UART.
*
* Copyright 2014 Stephen Burke 7w0n0d3@gmail.com
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the Linux kernel source for more details.
*
* The following resources helped me greatly:
*
* The Linux kernel module programming howto
* Copyright (C) 2001 Jay Salzman
*
* The Linux USB input subsystem Part 1
* Copyright (C) 2007 Brad Hards
*
* PS/2 keyboard interfacing
* Copyright (C) 1998-2013 Adam Chapweske
*
* kbd FAQ
* Copyright (C) 2009 Andries Brouwer
*
* Keyboard data and clock lines must be pulled up to +5V with 4.7K resistors
* Data line must be limited to 3.0V.
* Connecting a blue or white LED between the data line and ground is a simple way to accomplish this.
* Data line is then connected to P1 pin 10 (RX) on the Raspberry Pi.
* Clock line is left unconnected.
* The keyboard also needs +5v (about 125 mA) and ground.
*
*/
//remember to remove all ttyAMA0 references in /boot/cmdline.txt and /etc/inittab
//use companion userspace program ps2test to determine module parameters
//and use them like this: insmod ps2.ko integer=15 fractional=38
//default parameters should be correct for an IBM Model M keyboard.
//You don't need to do anything special to compile this module.
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/io.h>
#define IO_BASE 0x20000000
//gpio
#define GPFSEL1 0x200004/4
//uart
#define DR 0x201000/4
#define CR 0x201030/4
#define IBRD 0x201024/4
#define FBRD 0x201028/4
#define LCRH 0x20102c/4
#define IMSC 0x201038/4
int divider = 15;
int fractional = 38;
static unsigned keyup = 0;
static unsigned escape = 0;
static unsigned pause = 0;
static unsigned *(uart);
volatile unsigned *(io_base);
static struct input_dev *ps2;
static unsigned char translate[256] = {
/* Raw SET 2 scancode table */
/* 00 */ KEY_RESERVED, KEY_F9, KEY_RESERVED, KEY_F5, KEY_F3, KEY_F1, KEY_F2, KEY_F12,
/* 08 */ KEY_ESC, KEY_F10, KEY_F8, KEY_F6, KEY_F4, KEY_TAB, KEY_GRAVE, KEY_RESERVED,
/* 10 */ KEY_RESERVED, KEY_LEFTALT, KEY_LEFTSHIFT, KEY_RESERVED, KEY_LEFTCTRL, KEY_Q, KEY_1, KEY_RESERVED,
/* 18 */ KEY_RESERVED, KEY_RESERVED, KEY_Z, KEY_S, KEY_A, KEY_W, KEY_2, KEY_RESERVED,
/* 20 */ KEY_RESERVED, KEY_C, KEY_X, KEY_D, KEY_E, KEY_4, KEY_3, KEY_RESERVED,
/* 28 */ KEY_RESERVED, KEY_SPACE, KEY_V, KEY_F, KEY_T, KEY_R, KEY_5, KEY_RESERVED,
/* 30 */ KEY_RESERVED, KEY_N, KEY_B, KEY_H, KEY_G, KEY_Y, KEY_6, KEY_RESERVED,
/* 38 */ KEY_RESERVED, KEY_RIGHTALT, KEY_M, KEY_J, KEY_U, KEY_7, KEY_8, KEY_RESERVED,
/* 40 */ KEY_RESERVED, KEY_COMMA, KEY_K, KEY_I, KEY_O, KEY_0, KEY_9, KEY_RESERVED,
/* 48 */ KEY_RESERVED, KEY_DOT, KEY_SLASH, KEY_L, KEY_SEMICOLON, KEY_P, KEY_MINUS, KEY_RESERVED,
/* 50 */ KEY_RESERVED, KEY_RESERVED, KEY_APOSTROPHE,KEY_RESERVED, KEY_LEFTBRACE, KEY_EQUAL, KEY_RESERVED, KEY_RESERVED,
/* 58 */ KEY_CAPSLOCK, KEY_RIGHTSHIFT,KEY_ENTER, KEY_RIGHTBRACE,KEY_RESERVED, KEY_BACKSLASH,KEY_RESERVED, KEY_RESERVED,
/* 60 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_BACKSPACE, KEY_RESERVED,
/* 68 */ KEY_RESERVED, KEY_KP1, KEY_RESERVED, KEY_KP4, KEY_KP7, KEY_RESERVED, KEY_HOME, KEY_RESERVED,
/* 70 */ KEY_KP0, KEY_KPDOT, KEY_KP2, KEY_KP5, KEY_KP6, KEY_KP8, KEY_ESC, KEY_NUMLOCK,
/* 78 */ KEY_F11, KEY_KPPLUS, KEY_KP3, KEY_KPMINUS, KEY_KPASTERISK,KEY_KP9, KEY_SCROLLLOCK,KEY_RESERVED,
/* 80 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_F7, KEY_SYSRQ, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 88 */ KEY_PAUSE, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 90 */ KEY_RESERVED, KEY_RIGHTALT, KEY_RESERVED, KEY_RESERVED, KEY_RIGHTCTRL, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 98 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* a0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* a8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* b0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* b8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* c0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* c8 */ KEY_RESERVED, KEY_RESERVED, KEY_KPSLASH, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* d0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* d8 */ KEY_RESERVED, KEY_RESERVED, KEY_KPENTER, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* e0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* e8 */ KEY_RESERVED, KEY_END, KEY_RESERVED, KEY_LEFT, KEY_HOME, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* f0 */ KEY_INSERT, KEY_DELETE, KEY_DOWN, KEY_RESERVED, KEY_RIGHT, KEY_UP, KEY_RESERVED, KEY_RESERVED,
/* f8 */ KEY_RESERVED, KEY_RESERVED, KEY_PAGEDOWN, KEY_RESERVED, KEY_PRINT, KEY_PAGEUP, KEY_RESERVED, KEY_RESERVED
}
;
module_param(divider,int,0);
module_param(fractional,int,0);
irq_handler_t irq_handler(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned key = *(uart);
if ((key & (1<<8)) != 0) printk(KERN_INFO "pi2ps2 framing error\n");
if ((key & (1<<9)) != 0) printk(KERN_INFO "pi2ps2 parity error\n");
if ((key & (1<<10)) != 0) printk(KERN_INFO "pi2ps2 break error\n");
if ((key & (1<<11)) != 0) printk(KERN_INFO "pi2ps2 overrun error\n");
key = key & 0xff;
if (key == 0xf0) {
keyup = 1;
return 0;
}
if (key == 0xe0) {
escape = 1;
return 0;
}
if (key == 0xe1) {
pause = 2;
return 0;
}
if (pause == 2) {
pause = 1;
return 0;
}
if (pause == 1) {
key = 0x88;
pause = 0;
}
if (escape == 1) {
key |= 0x80;
escape = 0;
}
key = translate[key];
if (keyup == 1) {
input_report_key(ps2,key,0);
keyup = 0;
}
else input_report_key(ps2,key,1);
input_sync(ps2);
return 0;
}
int init_module(void)
{
int i, retval;
unsigned key;
io_base = ioremap(IO_BASE,0x400000);
//set pin 10 as uart rxd
*(io_base+GPFSEL1) &= ~(7<<15);
*(io_base+GPFSEL1) |= (4<<15);
//set uart to receive 8 bit, 1 stop, odd parity
*(io_base+CR) = 0;
*(io_base+LCRH) = ((3<<5)|(1<<1));
//set baud rate to command line parameters
*(io_base+IBRD) = divider;
*(io_base+FBRD) = fractional;
//flush buffer
key=*(io_base+DR);
//interrupts on
*(io_base+IMSC) = (1<<4);
//uart on
*(io_base+CR) = (1<<9);
*(io_base+CR) |= 1;
iounmap(io_base);
uart = ioremap(IO_BASE+(DR*4),1);
ps2=input_allocate_device();
ps2->name = "pi2ps2";
ps2->phys = "ps2/input0";
ps2->id.bustype = BUS_HOST;
ps2->id.vendor = 0x0001;
ps2->id.product = 0x0001;
ps2->id.version = 0x0100;
ps2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
ps2->keycode = translate;
ps2->keycodes
没有合适的资源?快使用搜索试试~ 我知道了~
基于串口的树莓派ps/2驱动
共9个文件
c:3个
png:3个
htm:1个
5星 · 超过95%的资源 需积分: 16 11 下载量 13 浏览量
2015-01-23
16:59:04
上传
评论
收藏 264KB ZIP 举报
温馨提示
一个基于串口的树莓派ps/2 Linux驱动.PS/2的DATA线接串口的RX线,PS/2的CLK空置。用前要测试键盘的频率。 Using two resistors, a blue LED, a few other bits, and a kernel module you can use a PS/2 keyboard by connecting it to the Pi serial port. This works because I have found that you can read a keyboard without using the keyboard clock line if you use a serial port running at a custom speed. This works so long as the keyboard clock period is regular, which I have found to be the case with all keyboards I have tested.
资源推荐
资源详情
资源评论
收起资源包目录
ps2pi.zip (9个子文件)
ps2pi
ps2pi.c 9KB
CHANGELOG 446B
ps2pi_files
ps2-pi.png 6KB
finished.png 199KB
layout.png 39KB
probe.c 3KB
ps2pi.htm 22KB
ps2test.c 5KB
COPYING 35KB
共 9 条
- 1
资源评论
- clon792018-01-10不错,正好需要这个东西。
dongly
- 粉丝: 0
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功