linux pcf8574键盘驱动移植

1、I2C扩展矩阵键盘

使用的是I2C接口的PCF8574扩展的4X4矩阵键盘,可以使用I2C和中断引脚扩展,这里使用的是I2C轮询方式去扩展。

2、判断芯片的地址

# i2cdetect -l               #查看系统使能的i2c总线,这里只有i2c0一个
i2c-0   i2c             mv64xxx_i2c adapter                     I2C adapter
# i2cdetect -r -y 0          //检测总线上的设备。-y表示省去交互式
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- 38 -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

这里显示I2C上挂了两个设备,0x50是存储芯片AT24C256,0x38应该就是PCF8574T的地址。

通过PCF8574的芯片手册和硬件原理图确认一下确实是0x38

按住不同的按键通过指令i2cdump的不同日志,可以进一步确定地址和硬件连接情况。

# i2cdump -f -y 0 0x38
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f    .???????????????
10: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f    ????????????????
20: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f     !"#$%&'()*+,-./
30: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f    0123456789:;<=>?
40: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f    @ABCDEFGHIJKLMNO
50: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f    PQRSTUVWXYZ[\]^_
60: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f    `abcdefghijklmno
70: 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f    pqrstuvwxyz{|}~?
80: 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f    ????????????????
90: 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f    ????????????????
a0: a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af    ????????????????
b0: b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf    ????????????????
c0: c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf    ????????????????
d0: d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df    ????????????????
e0: e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef    ????????????????
f0: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff    ???????????????.
# i2cdump -f -y 0 0x38
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 00 01 02 03 04 05 06 07 00 01 02 03 04 05 06 07    .???????.???????
10: 10 11 12 13 14 15 16 17 10 11 12 13 14 15 16 17    ????????????????
20: 20 21 22 23 24 25 26 27 20 21 22 23 24 25 26 27     !"#$%&' !"#$%&'
30: 30 31 32 33 34 35 36 37 30 31 32 33 34 35 36 37    0123456701234567
40: 40 41 42 43 44 45 46 47 40 41 42 43 44 45 46 47    @ABCDEFG@ABCDEFG
50: 50 51 52 53 54 55 56 57 50 51 52 53 54 55 56 57    PQRSTUVWPQRSTUVW
60: 60 61 62 63 64 65 66 67 60 61 62 63 64 65 66 67    `abcdefg`abcdefg
70: 70 71 72 73 74 75 76 77 70 71 72 73 74 75 76 77    pqrstuvwpqrstuvw
80: 00 01 02 03 04 05 06 07 88 89 8a 8b 8c 8d 8e 8f    .???????????????
90: 10 11 12 13 14 15 16 17 98 99 9a 9b 9c 9d 9e 9f    ????????????????
a0: 20 21 22 23 24 25 26 27 a8 a9 aa ab ac ad ae af     !"#$%&'????????
b0: 30 31 32 33 34 35 36 37 b8 b9 ba bb bc bd be bf    01234567????????
c0: 40 41 42 43 44 45 46 47 c8 c9 ca cb cc cd ce cf    @ABCDEFG????????
d0: 50 51 52 53 54 55 56 57 d8 d9 da db dc dd de df    PQRSTUVW????????
e0: 60 61 62 63 64 65 66 67 e8 e9 ea eb ec ed ee ef    `abcdefg????????
f0: 70 71 72 73 74 75 76 77 f8 f9 fa fb fc fd fe ff    pqrstuvw???????.

 3、修改dts文件

&i2c0 {
	status = "okay";

	pcf8574t: pcf8574t@38 {
		compatible = "pcf8574_keypad";
		reg = <0x38>;
	
	};
};

4、修改内核源码

1)I2C加中断方式:4.13内核源码中自带

文件路径:drivers/input/misc/pcf8574_keypad.c

2)I2C轮询方式

这里参考触摸屏代码:drivers/input/touchscreen/ns2009.c进行的修改。

5、验证

1)指令验证

# cat /proc/bus/input/devices   #查看输入设备,event0是矩阵按键设备
I: Bus=0018 Vendor=0001 Product=0001 Version=0100
N: Name="pcf8574_keypad"
P: Phys=kp_data/input0
S: Sysfs=/devices/platform/soc/1c2ac00.i2c/i2c-0/0-0038/input/input1
U: Uniq=
H: Handlers=kbd event0
B: PROP=0
B: EV=3
B: KEY=14801 48000ffc


# cat /dev/input/event0        //按下不同的按键,会有不同的日志信息
# hexdump /dev/input/event0

2)应用程序验证

#include <stdio.h>
#include <linux/input.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    int keys_fd;
    char ret[2];
    struct input_event t;

    keys_fd = open("/dev/input/event0", O_RDONLY);
    if(keys_fd<=0)
    {
        printf("open /dev/event0 device error!\n");
        return 0;
    }else
    {
        printf("open /dev/event0 device ok!\n");
    }

    while(1)
    {
    if(read(keys_fd,&t,sizeof(t))==sizeof(t)) {
        //Type为EV_KEY时,value: 0表示按键抬起。1表示按键按下
        if(t.type==EV_KEY && (t.value==0||t.value==1))
        {        
            // printf("%d \n", t.code);
            switch(t.code)
            {
            case KEY_1:
            printf("KEY_1 %s\n",(t.value)?"Pressed":"Released");
            break;

            case KEY_2:
            printf("KEY_2 %s\n",(t.value)?"Pressed":"Released");
            break;

            case KEY_3:
            printf("KEY_3 %s\n",(t.value)?"Pressed":"Released");
            break;

            case KEY_4:
            printf("KEY_4 %s\n",(t.value)?"Pressed":"Released");
            break;

            case KEY_5:
            printf("KEY_5 %s\n",(t.value)?"Pressed":"Released");
            break;

            case KEY_6:
            printf("KEY_6 %s\n",(t.value)?"Pressed":"Released");
            break;

            case KEY_7:
            printf("KEY_7 %s\n",(t.value)?"Pressed":"Released");
            break;

            case KEY_8:
            printf("KEY_8 %s\n",(t.value)?"Pressed":"Released");
            break;

            case KEY_9:
            printf("KEY_9 %s\n",(t.value)?"Pressed":"Released");
            break;

            case KEY_0:
            printf("KEY_0 %s\n",(t.value)?"Pressed":"Released");
            break;

            case KEY_A:
            printf("KEY_A %s\n",(t.value)?"Pressed":"Released");
            break;

            case KEY_B:
            printf("KEY_B %s\n",(t.value)?"Pressed":"Released");
            break;

            case KEY_C:
            printf("KEY_C %s\n",(t.value)?"Pressed":"Released");
            break;

            case KEY_D:
            printf("KEY_D %s\n",(t.value)?"Pressed":"Released");
            break;

            case KEY_BACKSLASH:
            printf("KEY_# %s\n",(t.value)?"Pressed":"Released");
            break;

            case KEY_RIGHTBRACE:
            printf("KEY_* %s\n",(t.value)?"Pressed":"Released");
            break;

            default:
            printf("Other KEY:%d  %s\n",t.code,(t.value)?"Pressed":"Released");
            break;
            }      
        }
    }
    }
    close(keys_fd);
    return 0;
}

日志信息

# ./keypad_test
open /dev/event0 device ok!
KEY_1 Pressed
KEY_1 Released
KEY_2 Pressed
KEY_2 Released

KEY_3 Pressed
KEY_3 Released
KEY_4 Pressed
KEY_4 Released
KEY_5 Pressed
KEY_5 Released
KEY_6 Pressed
KEY_6 Released
KEY_7 Pressed
KEY_7 Released
KEY_8 Pressed
KEY_8 Released
KEY_9 Pressed
KEY_9 Released
KEY_0 Pressed
KEY_0 Released
KEY_* Pressed
KEY_* Released
KEY_# Pressed
KEY_# Released
KEY_A Pressed
KEY_A Released
KEY_B Pressed
KEY_B Released
KEY_C Pressed
KEY_C Released
KEY_D Pressed
KEY_D Released

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值