KEYPAD使用参考


REVISION HISTORY

Revision No.
Description
Date
1.0
  • Initial release
  • 04/18/2024
    1.1
  • doc refine & add Chapter 5 "FAQ"
  • 04/11/2025

    1. 概述

    keypad控制器是专门设计用于提供扫描矩阵寻址键盘的灵活和通用功能。 假设小键盘是一个8x8矩阵,原理是小键盘控制器交替发送扫描码到小键盘的第1列到第8列,然后从第1行到第8行读取值。一次扫描一列,不断循环 扫描列。 当键盘控制器检测到每个由行码改变的按键状态时,都会有一个寄存器来保持按下和释放状态并发送中断信号。

    2. 功能描述

    基本功能:

    在键盘按下按键后,可以识别保存键盘状态并上报event事件。在运行user space APP时,会在串口回报对应键值,即识别出正在按下的按键,目前键盘支持3x3或4x4或7x7的按键,但是它们的接线方式略有不同,(详见3. 硬件连接介绍章节)。

    进阶功能:

    多按键:keypad支持多按键同时按下并加以识别,目前支持的最多四个按键同时按下。

    去抖动:可以将一定时间内电压不稳的情况通过滤波滤掉。

    模式:可以自由选择触发中断的时机,按下时触发或松开时触发或按下松开都触发。

    • mode 0 为在按下松开时分别产生对应中断。

    • mode 1 为在按下时产生按下中断,松开时不产生中断。

    • mode 2 为在松开时产生松开中断,按下时不产生中断。

    • mode 3 有三种子模式,分别对应前三种模式的中断触发方式,只其存入标志位的值略有不同。

    行列选择:可以自由选择行列组合,前提为其行列数应小于等于其设置的padmux数,即在3*3的情况下,行列选择只能为0/½/3。

    3. 硬件连接介绍

    keypad standard代表keypad的规格,其对应键盘行列数量,padmux配置以及相匹配的gpio状态。

    standard padmux 规格(行数*列数)
    7 reg_key7x7_mode_1 7*7
    72 reg_key7x7_mode_2 7*7
    6 reg_key6x6_mode_1 6*6
    5 reg_key5x5_mode_1 5*5
    52 reg_key5x5_mode_2 5*5
    4 reg_key4x4_mode_1 4*4
    3 reg_key3x3_mode_1 3*3

    keypad standard与padmux,硬件连接关系如下:

    standard padmux 硬件连接示意(行数*列数)
    7|72|6|5 reg_key7x7_mode_1|reg_key7x7_mode_2|
    reg_key6x6_mode_1|reg_key5x5_mode_1
    keypad-connect-7x7
    52 reg_key5x5_mode_2 keypad-connect-5x5mode2
    4 reg_key4x4_mode_1 keypad-connect-4x4
    3 reg_key3x3_mode_1 keypad-connect-3x3

    4. kernel用法介绍

    4.1 kernel config配置

    在编译kernel时需要选择的配置如下:

        Device Driver-->
            [*] SStar SoC platform drivers-->
                [*] Sstar Keypad driver
        Device Driver-->
            [*] Input device support-->
                [*] Event interface
    

    4.2. keypad的dts配置

    可以通过配置dtsi中keypad项设定driver的基本参数。dtsi的参数展示如下:

    1.      keypad {
    2.          compatible = "sstar,keypad";
    3.          reg = <0x0 0x1F201E00 0x0 0x100>;
    4.          keypadmode = <0>;
    5.          clocks = <&CLK_keypad>;
    6.          interrupts=<GIC_SPI INT_IRQ_KEYPAD IRQ_TYPE_LEVEL_HIGH>;
    7.          keypad-row1 = <KEY_ESC KEY_8         KEY_W KEY_P          KEY_F           KEY_GRAVE     KEY_N          KEY_SPACE>;
    8.          keypad-row2 = <KEY_1   KEY_9         KEY_E KEY_LEFTBRACE  KEY_G           KEY_LEFTSHIFT KEY_M          KEY_CAPSLOCK>;
    9.          keypad-row3 = <KEY_2   KEY_0         KEY_R KEY_RIGHTBRACE KEY_H           KEY_BACKSLASH KEY_COMMA      KEY_F1>;
    10.         keypad-row4 = <KEY_3   KEY_MINUS     KEY_T KEY_ENTER      KEY_J           KEY_Z         KEY_DOT        KEY_F2>;
    11.         keypad-row5 = <KEY_4   KEY_EQUAL     KEY_Y KEY_LEFTCTRL   KEY_K           KEY_X         KEY_SLASH      KEY_F3>;
    12.         keypad-row6 = <KEY_5   KEY_BACKSPACE KEY_U KEY_A          KEY_L           KEY_C         KEY_RIGHTSHIFT KEY_F4>;
    13.         keypad-row7 = <KEY_6   KEY_TAB       KEY_I KEY_S          KEY_SEMICOLON   KEY_V         KEY_KPASTERISK KEY_F5>;
    14.         keypad-row8 = <KEY_7   KEY_Q         KEY_O KEY_D          KEY_APOSTROPHE  KEY_B         KEY_LEFTALT    KEY_F6>;
    15.         status = "okay";
    16.     };
    

    KEYPAD DTS说明:

    参数 释义 备注
    reg 设定寄存器bank地址 禁止修改
    clocks 设定时钟源 禁止修改
    interrupts 设置irq中断号 禁止修改
    keypadmode keypad的工作模式 mode 0 为在按下松开时分别产生对应中断。
    mode 1 为在按下时产生按下中断,松开时不产生中断
    mode 2 为在松开时产生松开中断,按下时不产生中断。
    mode 3 有三种子模式,分别对应前三种模式的中断触发方式,只其存入标志位的值略有不同。
    Keypad-rowX 用户定义键值 keypad各行各列对应的键值,可以根据需求自定义

    4.3. Padmux的配置

    以ssm001a-s01a为例,打开arch/arm64/boot/dts/sstar/pcupid-ssm001a-s01a-padmux.dtsi

    找到需要配置的keypad padmux,把#if 0改为#if 1,如下图:

    #if 0
                    // KEY PAD 7x7 MODE 1
                    <PAD_GPIOE_05               PINMUX_FOR_KEY7X7_MODE_1       MDRV_PUSE_KEYPAD77_MODE1_R6>,
                    <PAD_GPIOE_06               PINMUX_FOR_KEY7X7_MODE_1       MDRV_PUSE_KEYPAD77_MODE1_R5>,
                    <PAD_GPIOE_07               PINMUX_FOR_KEY7X7_MODE_1       MDRV_PUSE_KEYPAD77_MODE1_R4>,
                    <PAD_GPIOE_09               PINMUX_FOR_KEY7X7_MODE_1       MDRV_PUSE_KEYPAD77_MODE1_R3>,
                    <PAD_GPIOE_10               PINMUX_FOR_KEY7X7_MODE_1       MDRV_PUSE_KEYPAD77_MODE1_R2>,
                    <PAD_GPIOE_11               PINMUX_FOR_KEY7X7_MODE_1       MDRV_PUSE_KEYPAD77_MODE1_R1>,
                    <PAD_GPIOE_12               PINMUX_FOR_KEY7X7_MODE_1       MDRV_PUSE_KEYPAD77_MODE1_R0>,
                    <PAD_GPIOE_13               PINMUX_FOR_KEY7X7_MODE_1       MDRV_PUSE_KEYPAD77_MODE1_S0>,
                    <PAD_GPIOE_14               PINMUX_FOR_KEY7X7_MODE_1       MDRV_PUSE_KEYPAD77_MODE1_S1>,
                    <PAD_GPIOE_15               PINMUX_FOR_KEY7X7_MODE_1       MDRV_PUSE_KEYPAD77_MODE1_S2>,
                    <PAD_GPIOE_16               PINMUX_FOR_KEY7X7_MODE_1       MDRV_PUSE_KEYPAD77_MODE1_S3>,
                    <PAD_GPIOE_17               PINMUX_FOR_KEY7X7_MODE_1       MDRV_PUSE_KEYPAD77_MODE1_S4>,
                    <PAD_GPIOE_18               PINMUX_FOR_KEY7X7_MODE_1       MDRV_PUSE_KEYPAD77_MODE1_S5>,
                    <PAD_GPIOE_19               PINMUX_FOR_KEY7X7_MODE_1       MDRV_PUSE_KEYPAD77_MODE1_S6>,
    #endif
    #if 0
                    // KEY PAD 7x7 MODE 2
                    <PAD_GPIOA_12               PINMUX_FOR_KEY7X7_MODE_2       MDRV_PUSE_KEYPAD77_MODE2_R6>,
                    <PAD_GPIOA_13               PINMUX_FOR_KEY7X7_MODE_2       MDRV_PUSE_KEYPAD77_MODE2_R5>,
                    <PAD_GPIOA_14               PINMUX_FOR_KEY7X7_MODE_2       MDRV_PUSE_KEYPAD77_MODE2_R4>,
                    <PAD_GPIOA_15               PINMUX_FOR_KEY7X7_MODE_2       MDRV_PUSE_KEYPAD77_MODE2_R3>,
                    <PAD_GPIOA_16               PINMUX_FOR_KEY7X7_MODE_2       MDRV_PUSE_KEYPAD77_MODE2_R2>,
                    <PAD_GPIOA_17               PINMUX_FOR_KEY7X7_MODE_2       MDRV_PUSE_KEYPAD77_MODE2_R1>,
                    <PAD_GPIOA_18               PINMUX_FOR_KEY7X7_MODE_2       MDRV_PUSE_KEYPAD77_MODE2_R0>,
                    <PAD_GPIOA_19               PINMUX_FOR_KEY7X7_MODE_2       MDRV_PUSE_KEYPAD77_MODE2_S0>,
                    <PAD_GPIOB_00               PINMUX_FOR_KEY7X7_MODE_2       MDRV_PUSE_KEYPAD77_MODE2_S1>,
                    <PAD_GPIOB_01               PINMUX_FOR_KEY7X7_MODE_2       MDRV_PUSE_KEYPAD77_MODE2_S2>,
                    <PAD_GPIOB_02               PINMUX_FOR_KEY7X7_MODE_2       MDRV_PUSE_KEYPAD77_MODE2_S3>,
                    <PAD_GPIOB_03               PINMUX_FOR_KEY7X7_MODE_2       MDRV_PUSE_KEYPAD77_MODE2_S4>,
                    <PAD_GPIOB_04               PINMUX_FOR_KEY7X7_MODE_2       MDRV_PUSE_KEYPAD77_MODE2_S5>,
                    <PAD_GPIOB_05               PINMUX_FOR_KEY7X7_MODE_2       MDRV_PUSE_KEYPAD77_MODE2_S6>,
    #endif
    #if 0
                    // KEY PAD 6x6 MODE 1
                    <PAD_GPIOE_06               PINMUX_FOR_KEY6X6_MODE_1       MDRV_PUSE_KEYPAD66_MODE1_R5>,
                    <PAD_GPIOE_07               PINMUX_FOR_KEY6X6_MODE_1       MDRV_PUSE_KEYPAD66_MODE1_R4>,
                    <PAD_GPIOE_09               PINMUX_FOR_KEY6X6_MODE_1       MDRV_PUSE_KEYPAD66_MODE1_R3>,
                    <PAD_GPIOE_10               PINMUX_FOR_KEY6X6_MODE_1       MDRV_PUSE_KEYPAD66_MODE1_R2>,
                    <PAD_GPIOE_11               PINMUX_FOR_KEY6X6_MODE_1       MDRV_PUSE_KEYPAD66_MODE1_R1>,
                    <PAD_GPIOE_12               PINMUX_FOR_KEY6X6_MODE_1       MDRV_PUSE_KEYPAD66_MODE1_R0>,
                    <PAD_GPIOE_13               PINMUX_FOR_KEY6X6_MODE_1       MDRV_PUSE_KEYPAD66_MODE1_S0>,
                    <PAD_GPIOE_14               PINMUX_FOR_KEY6X6_MODE_1       MDRV_PUSE_KEYPAD66_MODE1_S1>,
                    <PAD_GPIOE_15               PINMUX_FOR_KEY6X6_MODE_1       MDRV_PUSE_KEYPAD66_MODE1_S2>,
                    <PAD_GPIOE_16               PINMUX_FOR_KEY6X6_MODE_1       MDRV_PUSE_KEYPAD66_MODE1_S3>,
                    <PAD_GPIOE_17               PINMUX_FOR_KEY6X6_MODE_1       MDRV_PUSE_KEYPAD66_MODE1_S4>,
                    <PAD_GPIOE_18               PINMUX_FOR_KEY6X6_MODE_1       MDRV_PUSE_KEYPAD66_MODE1_S5>,
    #endif
    #if 0
                    // KEY PAD 5x5 MODE 1
                    <PAD_GPIOE_07               PINMUX_FOR_KEY5X5_MODE_1       MDRV_PUSE_KEYPAD55_MODE1_R4>,
                    <PAD_GPIOE_09               PINMUX_FOR_KEY5X5_MODE_1       MDRV_PUSE_KEYPAD55_MODE1_R3>,
                    <PAD_GPIOE_10               PINMUX_FOR_KEY5X5_MODE_1       MDRV_PUSE_KEYPAD55_MODE1_R2>,
                    <PAD_GPIOE_11               PINMUX_FOR_KEY5X5_MODE_1       MDRV_PUSE_KEYPAD55_MODE1_R1>,
                    <PAD_GPIOE_12               PINMUX_FOR_KEY5X5_MODE_1       MDRV_PUSE_KEYPAD55_MODE1_R0>,
                    <PAD_GPIOE_13               PINMUX_FOR_KEY5X5_MODE_1       MDRV_PUSE_KEYPAD55_MODE1_S0>,
                    <PAD_GPIOE_14               PINMUX_FOR_KEY5X5_MODE_1       MDRV_PUSE_KEYPAD55_MODE1_S1>,
                    <PAD_GPIOE_15               PINMUX_FOR_KEY5X5_MODE_1       MDRV_PUSE_KEYPAD55_MODE1_S2>,
                    <PAD_GPIOE_16               PINMUX_FOR_KEY5X5_MODE_1       MDRV_PUSE_KEYPAD55_MODE1_S3>,
                    <PAD_GPIOE_17               PINMUX_FOR_KEY5X5_MODE_1       MDRV_PUSE_KEYPAD55_MODE1_S4>,
    #endif
    #if 0
                    // KEY PAD 5x5 MODE 2
                    <PAD_GPIOE_09               PINMUX_FOR_KEY5X5_MODE_2       MDRV_PUSE_KEYPAD55_MODE2_R4>,
                    <PAD_GPIOE_10               PINMUX_FOR_KEY5X5_MODE_2       MDRV_PUSE_KEYPAD55_MODE2_R3>,
                    <PAD_GPIOE_11               PINMUX_FOR_KEY5X5_MODE_2       MDRV_PUSE_KEYPAD55_MODE2_R2>,
                    <PAD_GPIOE_12               PINMUX_FOR_KEY5X5_MODE_2       MDRV_PUSE_KEYPAD55_MODE2_R1>,
                    <PAD_GPIOE_13               PINMUX_FOR_KEY5X5_MODE_2       MDRV_PUSE_KEYPAD55_MODE2_R0>,
                    <PAD_GPIOE_14               PINMUX_FOR_KEY5X5_MODE_2       MDRV_PUSE_KEYPAD55_MODE2_S0>,
                    <PAD_GPIOE_15               PINMUX_FOR_KEY5X5_MODE_2       MDRV_PUSE_KEYPAD55_MODE2_S1>,
                    <PAD_GPIOE_16               PINMUX_FOR_KEY5X5_MODE_2       MDRV_PUSE_KEYPAD55_MODE2_S2>,
                    <PAD_GPIOE_17               PINMUX_FOR_KEY5X5_MODE_2       MDRV_PUSE_KEYPAD55_MODE2_S3>,
                    <PAD_GPIOE_18               PINMUX_FOR_KEY5X5_MODE_2       MDRV_PUSE_KEYPAD55_MODE2_S4>,
    #endif
    #if 0
                    // KEY PAD 4x4 MODE 1
                    <PAD_GPIOA_18               PINMUX_FOR_KEY4X4_MODE_1      MDRV_PUSE_KEYPAD44_MODE1_R3>,
                    <PAD_GPIOA_19               PINMUX_FOR_KEY4X4_MODE_1      MDRV_PUSE_KEYPAD44_MODE1_R2>,
                    <PAD_GPIOB_00               PINMUX_FOR_KEY4X4_MODE_1      MDRV_PUSE_KEYPAD44_MODE1_R1>,
                    <PAD_GPIOB_01               PINMUX_FOR_KEY4X4_MODE_1      MDRV_PUSE_KEYPAD44_MODE1_R0>,
                    <PAD_GPIOB_02               PINMUX_FOR_KEY4X4_MODE_1      MDRV_PUSE_KEYPAD44_MODE1_S0>,
                    <PAD_GPIOB_03               PINMUX_FOR_KEY4X4_MODE_1      MDRV_PUSE_KEYPAD44_MODE1_S1>,
                    <PAD_GPIOB_04               PINMUX_FOR_KEY4X4_MODE_1      MDRV_PUSE_KEYPAD44_MODE1_S2>,
                    <PAD_GPIOB_05               PINMUX_FOR_KEY4X4_MODE_1      MDRV_PUSE_KEYPAD44_MODE1_S3>,
    #endif
    #if 0
                    // KEY PAD 3x3 MODE 1
                    <PAD_GPIOA_12                PINMUX_FOR_KEY3X3_MODE_1      MDRV_PUSE_KEYPAD33_MODE1_R2>,
                    <PAD_GPIOA_13                PINMUX_FOR_KEY3X3_MODE_1      MDRV_PUSE_KEYPAD33_MODE1_R1>,
                    <PAD_GPIOA_14                PINMUX_FOR_KEY3X3_MODE_1      MDRV_PUSE_KEYPAD33_MODE1_R0>,
                    <PAD_GPIOA_15                PINMUX_FOR_KEY3X3_MODE_1      MDRV_PUSE_KEYPAD33_MODE1_S0>,
                    <PAD_GPIOA_16                PINMUX_FOR_KEY3X3_MODE_1      MDRV_PUSE_KEYPAD33_MODE1_S1>,
                    <PAD_GPIOA_17                PINMUX_FOR_KEY3X3_MODE_1      MDRV_PUSE_KEYPAD33_MODE1_S2>,
    #endif
    

    第一列为引脚索引号,可以在drivers/sstar/inlcude/{chipname}/gpio.h中查到;

    第二列为模式定义,在drivers/sstar/gpio/{chipname}/hal_pinmux.chal_gpio_st_padmux_info数组里,罗列了所有引脚的复用关系,查询该引脚支持哪些复用功能可以查询该数组;

    第三列为引脚及搭配模式的索引名称,可在drivers/sstar/include/drv_puse.h里查询。

    4.4. 模块使用介绍

    4.4.1. Sample code

    Demo位置:kernel/drivers/sstar/keypad/verify/key.c

    1. cat /proc/bus/input/devices获取keypad在挂载在哪个input节点

    2. 通过轮询读取dev/input/event节点捕获event信息

      1.  int main(int argc, char *argv[])
      2.  {
      3.      int                fd;
      4.      struct input_event ev_key;
      5.      if (argc != 3 && argc != 2)
      6.      {
      7.          printf("Usage:\n");
      8.          printf("%s /dev/input/event0 or /dev/input/event1 + enable\n", argv[0]);
      9.          return 0;
      10.     }
      11.     fd = open(argv[1], O_RDWR);
      12.     if (fd < 0)
      13.     {
      14.         perror("open device buttons");
      16.         exit(1);
      17.     }
      18.     if (argc == 3)
      19.     {
      20.         if (strcmp("enable", argv[2]) == 0)
      21.         {
      22.             test_key1(fd, &ev_key);
      23.             test_key2(fd, &ev_key);
      24.             test_key3(fd, &ev_key);
      25.         }
      26.         else
      27.         {
      28.             printf("%s /dev/input/event0 or /dev/input/event1 + enable\n", argv[0]);
      29.             return 0;
      30.         }
      31.     }
      32.     else if (argc == 2)
      33.     {
      34.         printf("enter normal mode\n");
      35.         while (1)
      36.         {
      37.             read(fd, &ev_key, sizeof(struct input_event));
      38.             printf("type:%d,code:%d,value:%d\n", ev_key.type, ev_key.code, ev_key.value);
      39.         }
      40.     }
      41.     close(fd);
      42.     return 0;
      43. }
      

    编译方法:

    arm-linux-gnueabihf-gcc -o key key.c;     //编译出应用程序
    

    使用方法:

    ./key /dev/input/event0 or /dev/input/event1 + enable
    

    参数1:选择keypad input event节点

    参数2(可选):enable代表进入测试模式

    eg1.

    ./key /dev/input/event0
    

    按键事件会被捕获并在终端输出。

    eg2.

    ./key /dev/input/event0 enable
    

    测试单按键按下、双按键同时按下、三按键同时按下功能是否正常。

    需要按以下顺序不重复地

    1. 按下全部49个单按键

    2. 按下8组双按键

    3. 按下4组三按键

    识别到上面三个任务完成后,测试程序会正常退出

    4.4.2. cmd改变参数的方法介绍

    keypad debug的方式主要是使用注册的节点改变参数,以达到测试不同功能的目的。

    pcupid:/sys/bus/platform/devices/1f201e00.keypad/

    在对应路径下echo对应参数到名为keypad的节点,即可改变对应参数,完成参数。

    4.4.2.1 mode

    命令:echo mode=X > keypad

    X:0或1或2或3

    此命令用于控制keypad的模式,具体模式详见4.2. keypad的dts配置章节,简单来说可以控制keypad的中断触发方式。

    4.4.2.2 clk

    命令:echo clk=X > keypad

    X:0或1

    此命令用于控制keypad的时钟的开关,其时钟频率为固定12M。clk=1时keypad时钟使能;clk=0时,keypad时钟关闭。

    4.4.2.3 debounce

    命令:echo debounce=X > keypad

    X:大于0的任意整数值,默认值为14,最大值不超过255。

    此命令用于控制keypad的去抖动滤波的持续时间,原理为设置滤波持续的周期数以决定其持续时间,最短不小于一个周期时间。

    4.4.2.4 glhrmclk

    命令:echo glhrmclk=X > keypad

    X:大于0的任意整数值,最大值不超过12000000,默认值为32000,建议设置相邻数量级。

    此命令用于控制keypad的去抖动滤波的频率,最高为keypad时钟频率12M。与周期数共同作用决定debounce time的长短。

    4.4.2.5 scanclk

    命令:echo scanclk=X > keypad

    X:大于0的任意整数值,最大值不超过12000000,默认值为32000,建议设置相邻数量级。

    此命令用于控制keypad的扫描频率(scan rate),最高为其时钟频12M。扫描频率除以使用的scan pin脚数就是每个pin脚的低电平持续时间,key的识别就是通过低电平触发。

    4.4.2.6 force

    命令:echo force=X > keypad

    X:0或1

    此命令用于控制keypad的force interrupt的开关,在测试时可以通过此方式强制IP在未按下按键时触发中断。置1时强制触发;置0时关闭。

    4.4.2.7 dbg

    命令:echo dbg=X > keypad

    X:0或1

    此命令用于控制keypad的debug message打印,置1时开启,置0时关闭。

    4.4.2.8 submode

    命令:echo submode=X > keypad

    X:0或1或2

    此命令用于控制keypad的mode3的三种子模式,具体模式信息详见4.2. keypad的dts配置章节。

    4.4.2.9 row

    命令:echo row=X > keypad

    X:0或1或2或3或4或5或6或7

    此命令用于控制keypad的行数,可以控制keypad响应的行数,最大值视padmux模式,例如padmux为3*3,则设置行数为4无意义,最大值只能设置为3。

    4.4.2.10 col

    命令:echo col=X > keypad

    X:0或1或2或3或4或5或6或7

    此命令用于控制keypad的列数,可以控制keypad响应的列行数,最大值视padmux模式,例如padmux为3*3,则设置列数为4无意义,最大值只能设置为3。

    4.4.2.11 align

    命令:echo align=X > keypad

    X:大于0的任意整数值,一般设置区间为42ms~170ms

    此命令用于控制keypad的同步时间,用于控制多按键同时按下的识别时间。

    4.4.2.12 standard

    命令:echo standard=X > keypad

    X:可见章节2的Standard表格

    此命令用于控制keypad Standard,同时能控制行列数量以及gpio状态等矩阵键盘属性(不包括padmux)。

    5. FAQ

    根据实际模块情况来决定:

    Q1:KEYPAD按键出现重复触发的现象,如何消抖

    由于硬件环境的差异,keypad在部分硬件平台的的消抖能力不足,具体表现为按下一次出现多次反馈,该问题可以通过配置keypad内部的消抖电路参数,降低抖动出现的概率。

    1. 使用命令增大keypad的debounce系数:

      echo debounce=X > keypad

      X:大于0的任意整数值,默认值为14,最大值不超过255。

      此命令用于控制keypad的去抖动滤波的持续时间,原理为设置滤波持续的周期数以决定其持续时间,最短不小于一个周期时间。

    2. 如果1设定为最高后的效果还不明显,可以进一步使用以下命令:

      echo glhrmclk=X > keypad

      减小keypad去抖动滤波的频率。

      X:大于0的任意整数值,默认值为32000,最大值不超过12000000,建议设置相邻数量级。

      此命令用于控制keypad的去抖动滤波的频率,最高为keypad时钟频率12M。与周期数共同作用决定debounce time的长短。

    Q2:keypad有中断但没有事件且reg_key_final_status寄存器中存在异常值

    观察初始化日志,发现初始化后reg_key_final_status寄存器中存在异常值,这种异常可能是电平不稳定导致的。

    观察原理图。key0的网络和KEY0_USB3网络通过0欧电阻跨接,KEY0_USB3下拉到地,影响read的正常波形,导致keypad的reg_key_final_status寄存器数据异常。

    按键事件press,release是成对存在的,波形异常导致按键事件没有正常复位,故不产生新的事件。

    keypad_q2_2

    keypad_q2_3

    下拉电阻影响KEY0的波形,导致事件无法正常上报。

    拆除R754,消除了下拉的影响。

    Q3:判断keypad小板线序问题

    硬件做版可能不会考虑keypad的插入方向,如果插错方向可能导致部分行列的按键没有反应,以及key code的增长顺序由从左到右增长变为从上到下增长

    判断方向的方法

    测试板子上keypad接口的电压分布,两端的四个脚是gnd,图示标注位置的是3.3,可以通过测量主板上3.3的位置来确定朝向。

    keypad_q3_1

    Q4:部分行列的按键没有反应

    原因一:引脚没有引出

    有些接口上的keypad端口引出不完整,同样可能导致部分行列的按键没有反应,如下图的9,12悬空,缺少key5,key6的引出,导致keypad缺两行。

    检查原理图

    keypad_q4_1

    原因二:PADMUX占用

    keypad的优先级不高,引脚容易被占用,比较明显的特征是部分引脚的波形异常,比如像是其他通信协议

    检查表格{chipname}tmux_test.xlsm

    7*7 KEYPAD使用的引脚是PAD_KEY0-PAD_KEY13,检查padmux中是不是有其他module在占用,这个module可能对keypad造成影响,如图的SDIO。

    keypad_q4_2

    方法一:

    检查对应module的padmux是否启用,编辑对应板子的padmux.dtsi,有占用的配置全都改为#if 0

    keypad_q4_3

    方法二:

    如果上面的方法没有效果,可以直接下padmux的寄存器关闭所有有嫌疑的padmux,之后再排查具体是哪个module导致的