跳转至

KeyboardReader 及其实现

头文件: utility/Keyboard/KeyboardReader/KeyboardReader.h

KeyboardReader 是一个用于读取物理按键矩阵的抽象接口。有两个具体实现,根据板型自动选择。


Point2D_t

struct Point2D_t {
    int x = 0;
    int y = 0;

    bool operator==(const Point2D_t& other) const;
};

表示按键矩阵上的物理位置: - x — 列索引(0–13) - y — 行索引(0–3)


KeyboardReader(抽象基类)

class KeyboardReader {
public:
    virtual ~KeyboardReader() = default;
    virtual void begin();
    virtual void update();
    const std::vector<Point2D_t>& keyList() const;
protected:
    std::vector<Point2D_t> _key_list;
};
方法 说明
begin() 初始化硬件。在子类中重写以配置 GPIO / I2C。
update() 扫描按键矩阵并填充 _key_list。在子类中重写。
keyList() 返回当前按下的按键坐标列表。

IOMatrixKeyboardReader

头文件: utility/Keyboard/KeyboardReader/IOMatrix.h
用于: M5Cardputer(标准版)

GPIO 矩阵扫描实现。使用 3 个输出引脚和 7 个输入引脚来扫描一个 4 行 × 7 列 × 2 的矩阵(通过时分复用实现 4×14)。

引脚分配

角色 引脚
输出(行选择) 8911
输入(列读取) 131534567

工作原理

  1. begin() — 将输出引脚配置为 OUTPUT,输入引脚配置为 INPUT_PULLUP
  2. update() — 迭代 8 步(0–7),在输出引脚上设置 3 位行地址,然后读取 7 个输入引脚。前 4 步映射到列 x_1,后 4 步映射到列 x_2(参见 X_map_chart)。检测到的按键按下以 Point2D_t 形式推入 _key_list
class IOMatrixKeyboardReader : public KeyboardReader {
public:
    void begin() override;
    void update() override;
private:
    const std::vector<int> output_list = {8, 9, 11};
    const std::vector<int> input_list  = {13, 15, 3, 4, 5, 6, 7};
    const Chart_t X_map_chart[7];
    void set_output(const std::vector<int>& pinList, uint8_t output);
    uint8_t get_input(const std::vector<int>& pinList);
};

TCA8418KeyboardReader

头文件: utility/Keyboard/KeyboardReader/TCA8418.h
用于: M5Cardputer-ADV

基于 I2C 的键盘驱动,使用 TCA8418 按键矩阵控制器芯片。中断驱动:当有按键事件时,GPIO ISR 设置标志位。

硬件参数

项目
I2C 总线 内部(m5::In_I2C
I2C 地址 0x34
中断引脚 GPIO 11
矩阵大小 7 行 × 8 列

工作原理

  1. begin() — 通过 I2C 初始化 TCA8418,配置 7×8 矩阵,在 GPIO 11 上附加 CHANGE 中断。
  2. update() — 在主循环中调用。如果 ISR 标志被设置,从 TCA8418 的 FIFO 读取按键事件,将行/列重映射到 M5Cardputer 坐标系统,并更新 _key_list(添加新的按下事件,移除释放事件)。
class TCA8418KeyboardReader : public KeyboardReader {
public:
    TCA8418KeyboardReader(int interrupt_pin = -1);
    void begin() override;
    void update() override;
private:
    struct KeyEventRaw_t { bool state; uint8_t row; uint8_t col; };
    std::unique_ptr<Adafruit_TCA8418> _tca8418;
    volatile bool _isr_flag;
    int _interrupt_pin;
    static void IRAM_ATTR gpio_isr_handler(void* arg);
};
构造函数参数 默认值 说明
interrupt_pin -1(自动 → GPIO 11) 按键事件的中断引脚

Adafruit_TCA8418(内部驱动)

头文件: utility/Adafruit_TCA8418/Adafruit_TCA8418.h

TCA8418 芯片的内部 I2C 驱动,继承自 m5::I2C_Device。从 Adafruit 的库适配而来,使用 M5Unified 的 I2C 抽象。通常仅由 TCA8418KeyboardReader 内部使用。

class Adafruit_TCA8418 : public m5::I2C_Device {
public:
    Adafruit_TCA8418(uint8_t i2c_addr = 0x34, uint32_t freq = 400000,
                     m5::I2C_Class* i2c = &m5::In_I2C);
    bool begin();
    bool matrix(uint8_t rows, uint8_t columns);
    uint8_t getEvent();
    uint8_t flush();
    void enableInterrupts();
    void disableInterrupts();
    // ... GPIO、消抖等控制方法 ...
};