mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
dedicated gpio: matrix keyboard example
This commit is contained in:
parent
bb1369b922
commit
d51a62e33a
@ -3,4 +3,4 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(gpio)
|
||||
project(generic-gpio)
|
@ -3,7 +3,7 @@
|
||||
# project subdirectory.
|
||||
#
|
||||
|
||||
PROJECT_NAME := gpio
|
||||
PROJECT_NAME := generic-gpio
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
||||
|
@ -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:
|
6
examples/peripherals/gpio/matrix_keyboard/CMakeLists.txt
Normal file
6
examples/peripherals/gpio/matrix_keyboard/CMakeLists.txt
Normal file
@ -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
examples/peripherals/gpio/matrix_keyboard/README.md
Normal file
79
examples/peripherals/gpio/matrix_keyboard/README.md
Normal file
@ -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
|
||||
```
|
@ -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 "")
|
@ -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
|
@ -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;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
idf_component_register(SRCS "matrix_keyboard_example_main.c"
|
||||
INCLUDE_DIRS "")
|
@ -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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user