Files

137 lines
6.1 KiB
C++
Raw Permalink Normal View History

2024-06-21 10:32:32 +02:00
#ifdef INPUTDRIVER_MATRIX_TYPE
2025-01-12 18:08:57 +01:00
#include "input/KeyMatrixInputDriver.h"
2024-06-21 10:32:32 +02:00
#include "Arduino.h"
2025-01-12 18:08:57 +01:00
#include "util/ILog.h"
2024-06-21 10:32:32 +02:00
// PICOmputer S3 keyboard matrix
#if INPUTDRIVER_MATRIX_TYPE == 1
constexpr byte keys_cols[] = {44, 47, 17, 15, 13, 41};
constexpr byte keys_rows[] = {12, 16, 42, 18, 14, 7};
constexpr unsigned char KeyMap[3][sizeof(keys_rows)][sizeof(keys_cols)] = {{{' ', '.', 'm', 'n', 'b', 0x9}, // next
{0x0a, 'l', 'k', 'j', 'h', 0x12}, // down
{'p', 'o', 'i', 'u', 'y', 0x0b}, // prev
{0x08, 'z', 'x', 'c', 'v', 0x11}, // up
2024-06-21 10:32:32 +02:00
{'a', 's', 'd', 'f', 'g', 0x1b},
{'q', 'w', 'e', 'r', 't', 0x1a}},
{ // SHIFT
2024-06-27 14:51:20 +02:00
{'_', ',', 'M', 'N', 'B', 0x03}, // end
2024-06-21 10:32:32 +02:00
{0x0d, 'L', 'K', 'J', 'H', 0x14}, // left
{'P', 'O', 'I', 'U', 'Y', 0x02}, // home
2024-06-27 14:51:20 +02:00
{0x7f, 'Z', 'X', 'C', 'V', 0x13}, // right
2024-06-21 10:32:32 +02:00
{'A', 'S', 'D', 'F', 'G', 0x09},
{'Q', 'W', 'E', 'R', 'T', 0x1a}},
{// SHIFT-SHIFT
2024-06-27 14:51:20 +02:00
{':', ';', '>', '<', '"', '{'},
2024-06-21 10:32:32 +02:00
{'~', '-', '*', '&', '+', '['},
{'0', '9', '8', '7', '6', '}'},
{'=', '(', ')', '?', '/', ']'},
{'!', '@', '#', '$', '%', '\\'},
{'1', '2', '3', '4', '5', 0x1a}}};
#endif
KeyMatrixInputDriver::KeyMatrixInputDriver(void) {}
void KeyMatrixInputDriver::init(void)
{
for (byte i = 0; i < sizeof(keys_rows); i++) {
pinMode(keys_rows[i], OUTPUT);
digitalWrite(keys_rows[i], HIGH);
}
for (byte i = 0; i < sizeof(keys_cols); i++) {
pinMode(keys_cols[i], INPUT_PULLUP);
}
keyboard = lv_indev_create();
lv_indev_set_type(keyboard, LV_INDEV_TYPE_KEYPAD);
lv_indev_set_read_cb(keyboard, keyboard_read);
2024-06-27 14:51:20 +02:00
if (!inputGroup) {
inputGroup = lv_group_create();
lv_group_set_default(inputGroup);
}
lv_indev_set_group(keyboard, inputGroup);
2024-06-21 10:32:32 +02:00
}
/******************************************************************
LV_KEY_NEXT: Focus on the next object
LV_KEY_PREV: Focus on the previous object
LV_KEY_ENTER: Triggers LV_EVENT_PRESSED, LV_EVENT_CLICKED, or LV_EVENT_LONG_PRESSED etc. events
LV_KEY_UP: Increase value or move upwards
LV_KEY_DOWN: Decrease value or move downwards
LV_KEY_RIGHT: Increase value or move to the right
LV_KEY_LEFT: Decrease value or move to the left
LV_KEY_ESC: Close or exit (E.g. close a Drop down list)
LV_KEY_DEL: Delete (E.g. a character on the right in a Text area)
LV_KEY_BACKSPACE: Delete a character on the left (E.g. in a Text area)
LV_KEY_HOME: Go to the beginning/top (E.g. in a Text area)
LV_KEY_END: Go to the end (E.g. in a Text area)
LV_KEY_UP = 17, // 0x11
LV_KEY_DOWN = 18, // 0x12
LV_KEY_RIGHT = 19, // 0x13
LV_KEY_LEFT = 20, // 0x14
LV_KEY_ESC = 27, // 0x1B
LV_KEY_DEL = 127, // 0x7F
LV_KEY_BACKSPACE = 8, // 0x08
LV_KEY_ENTER = 10, // 0x0A, '\n'
LV_KEY_NEXT = 9, // 0x09, '\t'
LV_KEY_PREV = 11, // 0x0B, '
LV_KEY_HOME = 2, // 0x02, STX
LV_KEY_END = 3, // 0x03, ETX
*******************************************************************/
void KeyMatrixInputDriver::keyboard_read(lv_indev_t *indev, lv_indev_data_t *data)
{
static int shift = 0;
2024-07-02 21:29:43 +02:00
static uint32_t prevkey = 0;
2024-06-21 10:32:32 +02:00
2024-07-02 21:29:43 +02:00
data->key = 0;
data->state = LV_INDEV_STATE_RELEASED;
2024-06-21 10:32:32 +02:00
if (INPUTDRIVER_MATRIX_TYPE == 1) {
// scan for keypresses
for (byte i = 0; i < sizeof(keys_rows); i++) {
digitalWrite(keys_rows[i], LOW);
for (byte j = 0; j < sizeof(keys_cols); j++) {
if (digitalRead(keys_cols[j]) == LOW) {
2024-07-02 21:29:43 +02:00
data->key = (uint32_t)KeyMap[shift][i][j];
2024-06-21 10:32:32 +02:00
break;
}
}
digitalWrite(keys_rows[i], HIGH);
}
2024-07-02 21:29:43 +02:00
2024-07-03 00:39:06 +02:00
// suppress repeating key, only repeat five times/s
// the enter key is an exception for LONG_PRESSED monitoring
2024-06-27 14:51:20 +02:00
static uint32_t lastPressed = millis();
2024-07-03 00:39:06 +02:00
if (data->key != 0 && (data->key == LV_KEY_ENTER || (millis() > lastPressed + 200))) {
2024-07-02 21:29:43 +02:00
lastPressed = millis();
prevkey = data->key;
switch (data->key) {
case 0x1a: // Shift
if (++shift > 2) {
shift = 0;
2024-06-21 10:32:32 +02:00
}
2024-07-02 21:29:43 +02:00
data->key = 0;
return; // don't process shift as key input
default:
break;
2024-06-21 10:32:32 +02:00
}
2024-07-02 21:29:43 +02:00
data->state = LV_INDEV_STATE_PRESSED;
2024-10-17 09:06:42 +02:00
ILOG_DEBUG("Key 0x%x pressed", data->key);
2024-07-03 00:39:06 +02:00
} else {
if (prevkey != 0) {
data->state = LV_INDEV_STATE_RELEASED;
data->key = prevkey; // must provide released key here!
2024-10-17 09:06:42 +02:00
// ILOG_DEBUG("Key 0x%x released", prevkey);
2024-07-03 00:39:06 +02:00
prevkey = 0;
}
2024-06-21 10:32:32 +02:00
}
}
}
#endif