Sfoglia il codice sorgente

dedicated gpio: matrix keyboard example

morris 5 anni fa
parent
commit
d51a62e33a

+ 1 - 1
examples/peripherals/gpio/CMakeLists.txt → examples/peripherals/gpio/generic_gpio/CMakeLists.txt

@@ -3,4 +3,4 @@
 cmake_minimum_required(VERSION 3.5)
 
 include($ENV{IDF_PATH}/tools/cmake/project.cmake)
-project(gpio)
+project(generic-gpio)

+ 1 - 1
examples/peripherals/gpio/Makefile → examples/peripherals/gpio/generic_gpio/Makefile

@@ -3,7 +3,7 @@
 # project subdirectory.
 #
 
-PROJECT_NAME := gpio
+PROJECT_NAME := generic-gpio
 
 include $(IDF_PATH)/make/project.mk
 

+ 0 - 0
examples/peripherals/gpio/README.md → examples/peripherals/gpio/generic_gpio/README.md


+ 1 - 1
examples/peripherals/gpio/example_test.py → examples/peripherals/gpio/generic_gpio/example_test.py

@@ -10,7 +10,7 @@ import ttfw_idf
 @ttfw_idf.idf_example_test(env_tag="Example_TWAI1", target=['esp32', 'esp32s2'], ci_target=['esp32'])
 def test_examples_gpio(env, extra_data):
     app_name = "gpio"
-    dut = env.get_dut(app_name, "examples/peripherals/gpio")
+    dut = env.get_dut(app_name, "examples/peripherals/gpio/generic_gpio")
     dut.start_app()
     res = dut.expect(ttfw_idf.MINIMUM_FREE_HEAP_SIZE_RE)
     if not res:

+ 0 - 0
examples/peripherals/gpio/main/CMakeLists.txt → examples/peripherals/gpio/generic_gpio/main/CMakeLists.txt


+ 0 - 0
examples/peripherals/gpio/main/component.mk → examples/peripherals/gpio/generic_gpio/main/component.mk


+ 0 - 0
examples/peripherals/gpio/main/gpio_example_main.c → examples/peripherals/gpio/generic_gpio/main/gpio_example_main.c


+ 6 - 0
examples/peripherals/gpio/matrix_keyboard/CMakeLists.txt

@@ -0,0 +1,6 @@
+# The following lines of boilerplate have to be in your project's
+# CMakeLists in this exact order for cmake to work correctly
+cmake_minimum_required(VERSION 3.5)
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+project(matrix-keyboard)

+ 79 - 0
examples/peripherals/gpio/matrix_keyboard/README.md

@@ -0,0 +1,79 @@
+| Supported Targets | ESP32-S2 |
+| ----------------- | -------- |
+
+# Matrix Keyboard Example (based on Dedicated GPIO)
+
+(See the README.md file in the upper level 'examples' directory for more information about examples.)
+
+## Overview
+
+This example mainly illustrates how to drive a common matrix keyboard using the dedicated GPIO APIs, including:
+
+* Manipulate the level on a group of GPIOs
+* Trigger edge interrupt
+* Read level on a group of GPIOs
+
+Dedicated GPIO is designed to speed up CPU operations on one or a group of GPIOs by writing assembly codes with Espressif customized instructions (please refer TRM to get more information about these instructions).
+
+This matrix keyboard driver is interrupt-driven, supports a configurable debounce time. GPIOs used by row and column lines are also configurable during driver installation stage.
+
+## How to use example
+
+### Hardware Required
+
+This example can run on any target that has the dedicated feature (e.g. ESP32-S2). It's not necessary for your matrix board to have pull-up resisters on row/column lines. The driver has enabled internal pull-up resister by default. A typical matrix board should look as follows:
+
+```
+row_0   +--------+-------------------+------------------------------+-----------------+
+                 |                   |                              |
+                 |       +           |       +                      |       +
+                 |     +-+-+         |     +-+-+          ......    |     +-+-+
+  .              +-----+   +-----+   +-----+   +-----+              +-----+   +-----+
+  .                              |                   |                              |
+  .                      .       |           .       |                      .       |
+                         .       |           .       |    ......            .       |
+                         .       |           .       |                      .       |
+                         .       |           .       |                      .       |
+                                 |                   |                              |
+row_n   +--------+-------------------+------------------------------+-----------------+
+                 |               |   |               |              |               |
+                 |       +       |   |       +       |              |       +       |
+                 |     +-+-+     |   |     +-+-+     |    ......    |     +-+-+     |
+                 +-----+   +-----+   +-----+   +-----+              +-----+   +-----+
+                                 |                   |                              |
+                                 |                   |                              |
+                                 |                   |                              |
+                                 +                   +                              +
+                                col_0               col_1          ......          col_m
+```
+
+### Build and Flash
+
+Build the project and flash it to the board, then run monitor tool to view serial output:
+
+```
+idf.py -p PORT flash monitor
+```
+
+(Replace PORT with the name of the serial port to use.)
+
+(To exit the serial monitor, type ``Ctrl-]``.)
+
+See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
+
+## Example Output
+
+```
+I (2883) example: press event, key code = 0002
+I (3003) example: release event, key code = 0002
+I (5053) example: press event, key code = 0001
+I (5203) example: release event, key code = 0001
+I (6413) example: press event, key code = 0000
+I (6583) example: release event, key code = 0000
+I (7963) example: press event, key code = 0003
+I (8113) example: release event, key code = 0003
+I (8773) example: press event, key code = 0103
+I (8923) example: release event, key code = 0103
+I (9543) example: press event, key code = 0203
+I (9683) example: release event, key code = 0203
+```

+ 7 - 0
examples/peripherals/gpio/matrix_keyboard/components/matrix_keyboard/CMakeLists.txt

@@ -0,0 +1,7 @@
+set(component_srcs "src/matrix_keyboard.c")
+
+idf_component_register(SRCS "${component_srcs}"
+                       INCLUDE_DIRS "include"
+                       PRIV_INCLUDE_DIRS ""
+                       PRIV_REQUIRES "driver"
+                       REQUIRES "")

+ 142 - 0
examples/peripherals/gpio/matrix_keyboard/components/matrix_keyboard/include/matrix_keyboard.h

@@ -0,0 +1,142 @@
+// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include <stdint.h>
+#include "esp_err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAKE_KEY_CODE(row, col) ((row << 8) | (col))
+#define GET_KEY_CODE_ROW(code)  ((code >> 8) & 0xFF)
+#define GET_KEY_CODE_COL(code)  (code & 0xFF)
+
+/**
+ * @brief Type defined for matrix keyboard handle
+ *
+ */
+typedef struct matrix_kbd_t *matrix_kbd_handle_t;
+
+/**
+ * @brief Matrix keyboard event ID
+ *
+ */
+typedef enum {
+    MATRIX_KBD_EVENT_DOWN, /*!< Key is pressed down */
+    MATRIX_KBD_EVENT_UP    /*!< Key is released */
+} matrix_kbd_event_id_t;
+
+/**
+ * @brief Type defined for matrix keyboard event handler
+ *
+ * @note The event handler runs in a OS timer context
+ *
+ * @param[in] mkbd_handle Handle of matrix keyboard that return from `matrix_kbd_install`
+ * @param[in] event Event ID, refer to `matrix_kbd_event_id_t` to see all supported events
+ * @param[in] event_data Data for corresponding event
+ * @param[in] handler_args Arguments that user passed in from `matrix_kbd_register_event_handler`
+ * @return Currently always return ESP_OK
+ */
+typedef esp_err_t (*matrix_kbd_event_handler)(matrix_kbd_handle_t mkbd_handle, matrix_kbd_event_id_t event, void *event_data, void *handler_args);
+
+/**
+ * @brief Configuration structure defined for matrix keyboard
+ *
+ */
+typedef struct {
+    const int *row_gpios;  /*!< Array, contains GPIO numbers used by row line */
+    const int *col_gpios;  /*!< Array, contains GPIO numbers used by column line */
+    uint32_t nr_row_gpios; /*!< row_gpios array size */
+    uint32_t nr_col_gpios; /*!< col_gpios array size */
+    uint32_t debounce_ms;  /*!< Debounce time */
+} matrix_kbd_config_t;
+
+/**
+ * @brief Default configuration for matrix keyboard driver
+ *
+ */
+#define MATRIX_KEYBOARD_DEFAULT_CONFIG() \
+{                                        \
+    .row_gpios = NULL,                   \
+    .col_gpios = NULL,                   \
+    .nr_row_gpios = 0,                   \
+    .nr_col_gpios = 0,                   \
+    .debounce_ms = 20,                   \
+}
+
+/**
+ * @brief Install matrix keyboard driver
+ *
+ * @param[in] config Configuration of matrix keyboard driver
+ * @param[out] mkbd_handle Returned matrix keyboard handle if installation succeed
+ * @return
+ *      - ESP_OK: Install matrix keyboard driver successfully
+ *      - ESP_ERR_INVALID_ARG: Install matrix keyboard driver failed because of some invalid argument
+ *      - ESP_ERR_NO_MEM: Install matrix keyboard driver failed because there's no enough capable memory
+ *      - ESP_FAIL: Install matrix keyboard driver failed because of other error
+ */
+esp_err_t matrix_kbd_install(const matrix_kbd_config_t *config, matrix_kbd_handle_t *mkbd_handle);
+
+/**
+ * @brief Uninstall matrix keyboard driver
+ *
+ * @param[in] mkbd_handle Handle of matrix keyboard that return from `matrix_kbd_install`
+ * @return
+ *      - ESP_OK: Uninstall matrix keyboard driver successfully
+ *      - ESP_ERR_INVALID_ARG: Uninstall matrix keyboard driver failed because of some invalid argument
+ *      - ESP_FAIL: Uninstall matrix keyboard driver failed because of other error
+ */
+esp_err_t matrix_kbd_uninstall(matrix_kbd_handle_t mkbd_handle);
+
+/**
+ * @brief Start matrix keyboard driver
+ *
+ * @param[in] mkbd_handle Handle of matrix keyboard that return from `matrix_kbd_install`
+ * @return
+ *      - ESP_OK: Start matrix keyboard driver successfully
+ *      - ESP_ERR_INVALID_ARG: Start matrix keyboard driver failed because of some invalid argument
+ *      - ESP_FAIL: Start matrix keyboard driver failed because of other error
+ */
+esp_err_t matrix_kbd_start(matrix_kbd_handle_t mkbd_handle);
+
+/**
+ * @brief Stop matrix kayboard driver
+ *
+ * @param[in] mkbd_handle Handle of matrix keyboard that return from `matrix_kbd_install`
+ * @return
+ *      - ESP_OK: Stop matrix keyboard driver successfully
+ *      - ESP_ERR_INVALID_ARG: Stop matrix keyboard driver failed because of some invalid argument
+ *      - ESP_FAIL: Stop matrix keyboard driver failed because of other error
+ */
+esp_err_t matrix_kbd_stop(matrix_kbd_handle_t mkbd_handle);
+
+/**
+ * @brief Register matrix keyboard event handler
+ *
+ * @param[in] mkbd_handle Handle of matrix keyboard that return from `matrix_kbd_install`
+ * @param[in] handler Event handler
+ * @param[in] args Arguments that will be passed to the handler
+ * @return
+ *      - ESP_OK: Register event handler successfully
+ *      - ESP_ERR_INVALID_ARG: Register event handler failed because of some invalid argument
+ *      - ESP_FAIL: Register event handler failed because of other error
+ */
+esp_err_t matrix_kbd_register_event_handler(matrix_kbd_handle_t mkbd_handle, matrix_kbd_event_handler handler, void *args);
+
+#ifdef __cplusplus
+}
+#endif

+ 245 - 0
examples/peripherals/gpio/matrix_keyboard/components/matrix_keyboard/src/matrix_keyboard.c

@@ -0,0 +1,245 @@
+// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#include <stdlib.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/timers.h"
+#include "esp_compiler.h"
+#include "esp_log.h"
+#include "driver/dedic_gpio.h"
+#include "driver/gpio.h"
+#include "matrix_keyboard.h"
+#include "esp_rom_sys.h"
+
+static const char *TAG = "mkbd";
+
+#define MKBD_CHECK(a, msg, tag, ret, ...)                                         \
+    do {                                                                          \
+        if (unlikely(!(a))) {                                                     \
+            ESP_LOGE(TAG, "%s(%d): " msg, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
+            ret_code = ret;                                                       \
+            goto tag;                                                             \
+        }                                                                         \
+    } while (0)
+
+typedef struct matrix_kbd_t matrix_kbd_t;
+
+struct matrix_kbd_t {
+    dedic_gpio_bundle_handle_t row_bundle;
+    dedic_gpio_bundle_handle_t col_bundle;
+    uint32_t nr_row_gpios;
+    uint32_t nr_col_gpios;
+    TimerHandle_t debounce_timer;
+    matrix_kbd_event_handler event_handler;
+    void *event_handler_args;
+    uint32_t row_state[0];
+};
+
+static IRAM_ATTR bool matrix_kbd_row_isr_callback(dedic_gpio_bundle_handle_t row_bundle, uint32_t row_index, void *args)
+{
+    BaseType_t high_task_wakeup = pdFALSE;
+    matrix_kbd_t *mkbd = (matrix_kbd_t *)args;
+
+    // temporarily disable interrupt
+    dedic_gpio_bundle_set_interrupt_and_callback(row_bundle, (1 << mkbd->nr_row_gpios) - 1, DEDIC_GPIO_INTR_NONE, NULL, NULL);
+    // get row id, start to check the col id
+    dedic_gpio_bundle_write(row_bundle, 1 << row_index, 0);
+    dedic_gpio_bundle_write(mkbd->col_bundle, (1 << mkbd->nr_col_gpios) - 1, (1 << mkbd->nr_col_gpios) - 1);
+    xTimerStartFromISR(mkbd->debounce_timer, &high_task_wakeup);
+    return high_task_wakeup == pdTRUE;
+}
+
+static void matrix_kbd_debounce_timer_callback(TimerHandle_t xTimer)
+{
+    matrix_kbd_t *mkbd = (matrix_kbd_t *)pvTimerGetTimerID(xTimer);
+
+    uint32_t row_out = dedic_gpio_bundle_read_out(mkbd->row_bundle);
+    uint32_t col_in = dedic_gpio_bundle_read_in(mkbd->col_bundle);
+    row_out = (~row_out) & ((1 << mkbd->nr_row_gpios) - 1);
+    ESP_LOGD(TAG, "row_out=%x, col_in=%x", row_out, col_in);
+    int row = -1;
+    int col = -1;
+    uint32_t key_code = 0;
+    while (row_out) {
+        row = __builtin_ffs(row_out) - 1;
+        uint32_t changed_col_bits = mkbd->row_state[row] ^ col_in;
+        while (changed_col_bits) {
+            col = __builtin_ffs(changed_col_bits) - 1;
+            ESP_LOGD(TAG, "row=%d, col=%d", row, col);
+            key_code = MAKE_KEY_CODE(row, col);
+            if (col_in & (1 << col)) {
+                mkbd->event_handler(mkbd, MATRIX_KBD_EVENT_UP, (void *)key_code, mkbd->event_handler_args);
+            } else {
+                mkbd->event_handler(mkbd, MATRIX_KBD_EVENT_DOWN, (void *)key_code, mkbd->event_handler_args);
+            }
+            changed_col_bits = changed_col_bits & (changed_col_bits - 1);
+        }
+        mkbd->row_state[row] = col_in;
+        row_out = row_out & (row_out - 1);
+    }
+
+    // row lines set to high level
+    dedic_gpio_bundle_write(mkbd->row_bundle, (1 << mkbd->nr_row_gpios) - 1, (1 << mkbd->nr_row_gpios) - 1);
+    // col lines set to low level
+    dedic_gpio_bundle_write(mkbd->col_bundle, (1 << mkbd->nr_col_gpios) - 1, 0);
+    dedic_gpio_bundle_set_interrupt_and_callback(mkbd->row_bundle, (1 << mkbd->nr_row_gpios) - 1,
+            DEDIC_GPIO_INTR_BOTH_EDGE, matrix_kbd_row_isr_callback, mkbd);
+}
+
+esp_err_t matrix_kbd_install(const matrix_kbd_config_t *config, matrix_kbd_handle_t *mkbd_handle)
+{
+    esp_err_t ret_code = ESP_OK;
+    matrix_kbd_t *mkbd = NULL;
+    MKBD_CHECK(config, "matrix keyboard configuration can't be null", err, ESP_ERR_INVALID_ARG);
+    MKBD_CHECK(mkbd_handle, "matrix keyboard handle can't be null", err, ESP_ERR_INVALID_ARG);
+
+    mkbd = calloc(1, sizeof(matrix_kbd_t) + (config->nr_row_gpios) * sizeof(uint32_t));
+    MKBD_CHECK(mkbd, "allocate matrix keyboard context failed", err, ESP_ERR_NO_MEM);
+
+    mkbd->nr_col_gpios = config->nr_col_gpios;
+    mkbd->nr_row_gpios = config->nr_row_gpios;
+
+    // GPIO pad configuration
+    // Each GPIO used in matrix key board should be able to input and output
+    // In case the keyboard doesn't design a resister to pull up row/col line
+    // We enable the internal pull up resister, enable Open Drain as well
+    gpio_config_t io_conf = {
+        .mode = GPIO_MODE_INPUT_OUTPUT_OD,
+        .pull_up_en = 1
+    };
+
+    for (int i = 0; i < config->nr_row_gpios; i++) {
+        io_conf.pin_bit_mask = 1ULL << config->row_gpios[i];
+        gpio_config(&io_conf);
+    }
+
+    dedic_gpio_bundle_config_t bundle_row_config = {
+        .gpio_array = config->row_gpios,
+        .array_size = config->nr_row_gpios,
+        .flags = {
+            .in_en = 1,
+            .out_en = 1,
+        },
+    };
+    MKBD_CHECK(dedic_gpio_new_bundle(&bundle_row_config, &mkbd->row_bundle) == ESP_OK,
+               "create row bundle failed", err, ESP_FAIL);
+
+    for (int i = 0; i < config->nr_col_gpios; i++) {
+        io_conf.pin_bit_mask = 1ULL << config->col_gpios[i];
+        gpio_config(&io_conf);
+    }
+
+    dedic_gpio_bundle_config_t bundle_col_config = {
+        .gpio_array = config->col_gpios,
+        .array_size = config->nr_col_gpios,
+        .flags = {
+            .in_en = 1,
+            .out_en = 1,
+        },
+    };
+    MKBD_CHECK(dedic_gpio_new_bundle(&bundle_col_config, &mkbd->col_bundle) == ESP_OK,
+               "create col bundle failed", err, ESP_FAIL);
+
+    // Disable interrupt
+    dedic_gpio_bundle_set_interrupt_and_callback(mkbd->row_bundle, (1 << config->nr_row_gpios) - 1,
+            DEDIC_GPIO_INTR_NONE, NULL, NULL);
+    dedic_gpio_bundle_set_interrupt_and_callback(mkbd->col_bundle, (1 << config->nr_col_gpios) - 1,
+            DEDIC_GPIO_INTR_NONE, NULL, NULL);
+
+    // Create a ont-shot os timer, used for key debounce
+    mkbd->debounce_timer = xTimerCreate("kb_debounce", pdMS_TO_TICKS(config->debounce_ms), pdFALSE, mkbd, matrix_kbd_debounce_timer_callback);
+    MKBD_CHECK(mkbd->debounce_timer, "create debounce timer failed", err, ESP_FAIL);
+
+    * mkbd_handle = mkbd;
+    return ESP_OK;
+err:
+    if (mkbd) {
+        if (mkbd->debounce_timer) {
+            xTimerDelete(mkbd->debounce_timer, 0);
+        }
+        if (mkbd->col_bundle) {
+            dedic_gpio_del_bundle(mkbd->col_bundle);
+        }
+        if (mkbd->row_bundle) {
+            dedic_gpio_del_bundle(mkbd->row_bundle);
+        }
+        free(mkbd);
+    }
+    return ret_code;
+}
+
+esp_err_t matrix_kbd_uninstall(matrix_kbd_handle_t mkbd_handle)
+{
+    esp_err_t ret_code = ESP_OK;
+    MKBD_CHECK(mkbd_handle, "matrix keyboard handle can't be null", err, ESP_ERR_INVALID_ARG);
+    xTimerDelete(mkbd_handle->debounce_timer, 0);
+    dedic_gpio_del_bundle(mkbd_handle->col_bundle);
+    dedic_gpio_del_bundle(mkbd_handle->row_bundle);
+    free(mkbd_handle);
+    return ESP_OK;
+err:
+    return ret_code;
+}
+
+esp_err_t matrix_kbd_start(matrix_kbd_handle_t mkbd_handle)
+{
+    esp_err_t ret_code = ESP_OK;
+    MKBD_CHECK(mkbd_handle, "matrix keyboard handle can't be null", err, ESP_ERR_INVALID_ARG);
+
+    // row lines set to high level
+    dedic_gpio_bundle_write(mkbd_handle->row_bundle, (1 << mkbd_handle->nr_row_gpios) - 1, (1 << mkbd_handle->nr_row_gpios) - 1);
+    // col lines set to low level
+    dedic_gpio_bundle_write(mkbd_handle->col_bundle, (1 << mkbd_handle->nr_col_gpios) - 1, 0);
+
+    for (int i = 0; i < mkbd_handle->nr_row_gpios; i++) {
+        mkbd_handle->row_state[i] = (1 << mkbd_handle->nr_col_gpios) - 1;
+    }
+
+    // only enable row line interrupt
+    dedic_gpio_bundle_set_interrupt_and_callback(mkbd_handle->row_bundle, (1 << mkbd_handle->nr_row_gpios) - 1,
+            DEDIC_GPIO_INTR_BOTH_EDGE, matrix_kbd_row_isr_callback, mkbd_handle);
+
+    return ESP_OK;
+err:
+    return ret_code;
+}
+
+esp_err_t matrix_kbd_stop(matrix_kbd_handle_t mkbd_handle)
+{
+    esp_err_t ret_code = ESP_OK;
+    MKBD_CHECK(mkbd_handle, "matrix keyboard handle can't be null", err, ESP_ERR_INVALID_ARG);
+
+    xTimerStop(mkbd_handle->debounce_timer, 0);
+
+    // Disable interrupt
+    dedic_gpio_bundle_set_interrupt_and_callback(mkbd_handle->row_bundle, (1 << mkbd_handle->nr_row_gpios) - 1,
+            DEDIC_GPIO_INTR_NONE, NULL, NULL);
+    dedic_gpio_bundle_set_interrupt_and_callback(mkbd_handle->col_bundle, (1 << mkbd_handle->nr_col_gpios) - 1,
+            DEDIC_GPIO_INTR_NONE, NULL, NULL);
+
+    return ESP_OK;
+err:
+    return ret_code;
+}
+
+esp_err_t matrix_kbd_register_event_handler(matrix_kbd_handle_t mkbd_handle, matrix_kbd_event_handler handler, void *args)
+{
+    esp_err_t ret_code = ESP_OK;
+    MKBD_CHECK(mkbd_handle, "matrix keyboard handle can't be null", err, ESP_ERR_INVALID_ARG);
+    mkbd_handle->event_handler = handler;
+    mkbd_handle->event_handler_args = args;
+    return ESP_OK;
+err:
+    return ret_code;
+}

+ 2 - 0
examples/peripherals/gpio/matrix_keyboard/main/CMakeLists.txt

@@ -0,0 +1,2 @@
+idf_component_register(SRCS "matrix_keyboard_example_main.c"
+                       INCLUDE_DIRS "")

+ 53 - 0
examples/peripherals/gpio/matrix_keyboard/main/matrix_keyboard_example_main.c

@@ -0,0 +1,53 @@
+/* Matrix Keyboard (based on dedicated GPIO) example
+
+   This example code is in the Public Domain (or CC0 licensed, at your option.)
+
+   Unless required by applicable law or agreed to in writing, this
+   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+   CONDITIONS OF ANY KIND, either express or implied.
+*/
+#include <stdio.h>
+#include "esp_log.h"
+#include "matrix_keyboard.h"
+
+const static char *TAG = "example";
+
+/**
+ * @brief Matrix keyboard event handler
+ * @note This function is run under OS timer task context
+ */
+esp_err_t example_matrix_kbd_event_handler(matrix_kbd_handle_t mkbd_handle, matrix_kbd_event_id_t event, void *event_data, void *handler_args)
+{
+    uint32_t key_code = (uint32_t)event_data;
+    switch (event) {
+    case MATRIX_KBD_EVENT_DOWN:
+        ESP_LOGI(TAG, "press event, key code = %04x", key_code);
+        break;
+    case MATRIX_KBD_EVENT_UP:
+        ESP_LOGI(TAG, "release event, key code = %04x", key_code);
+        break;
+    }
+    return ESP_OK;
+}
+
+void app_main(void)
+{
+    matrix_kbd_handle_t kbd = NULL;
+    // Apply default matrix keyboard configuration
+    matrix_kbd_config_t config = MATRIX_KEYBOARD_DEFAULT_CONFIG();
+    // Set GPIOs used by row and column line
+    config.col_gpios = (int[]) {
+        10, 11, 12, 13
+    };
+    config.nr_col_gpios = 4;
+    config.row_gpios = (int[]) {
+        14, 15, 16, 17
+    };
+    config.nr_row_gpios = 4;
+    // Install matrix keyboard driver
+    matrix_kbd_install(&config, &kbd);
+    // Register keyboard input event handler
+    matrix_kbd_register_event_handler(kbd, example_matrix_kbd_event_handler, NULL);
+    // Keyboard start to work
+    matrix_kbd_start(kbd);
+}