2024-06-27 14:50:57 +02:00
|
|
|
#ifdef INPUTDRIVER_ENCODER_TYPE
|
|
|
|
|
|
2025-01-12 18:08:57 +01:00
|
|
|
#include "input/EncoderInputDriver.h"
|
2024-06-27 14:50:57 +02:00
|
|
|
#include "Arduino.h"
|
2025-01-12 18:08:57 +01:00
|
|
|
#include "util/ILog.h"
|
2024-06-27 14:50:57 +02:00
|
|
|
|
|
|
|
|
volatile EncoderInputDriver::EncoderActionType EncoderInputDriver::action = TB_ACTION_NONE;
|
|
|
|
|
|
|
|
|
|
EncoderInputDriver::EncoderInputDriver(void) {}
|
|
|
|
|
|
|
|
|
|
void EncoderInputDriver::init(void)
|
|
|
|
|
{
|
2024-07-03 10:14:24 +02:00
|
|
|
// trackball or joystick type encoder with four directions
|
2024-06-27 14:50:57 +02:00
|
|
|
if (INPUTDRIVER_ENCODER_TYPE == 3) {
|
|
|
|
|
#ifdef INPUTDRIVER_ENCODER_LEFT
|
|
|
|
|
pinMode(INPUTDRIVER_ENCODER_LEFT, INPUT_PULLUP);
|
|
|
|
|
attachInterrupt(INPUTDRIVER_ENCODER_LEFT, intLeftHandler, RISING);
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef INPUTDRIVER_ENCODER_RIGHT
|
|
|
|
|
pinMode(INPUTDRIVER_ENCODER_RIGHT, INPUT_PULLUP);
|
|
|
|
|
attachInterrupt(INPUTDRIVER_ENCODER_RIGHT, intRightHandler, RISING);
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef INPUTDRIVER_ENCODER_UP
|
|
|
|
|
pinMode(INPUTDRIVER_ENCODER_UP, INPUT_PULLUP);
|
|
|
|
|
attachInterrupt(INPUTDRIVER_ENCODER_UP, intUpHandler, RISING);
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef INPUTDRIVER_ENCODER_DOWN
|
|
|
|
|
pinMode(INPUTDRIVER_ENCODER_DOWN, INPUT_PULLUP);
|
|
|
|
|
attachInterrupt(INPUTDRIVER_ENCODER_DOWN, intDownHandler, RISING);
|
2024-07-04 12:44:50 +02:00
|
|
|
#endif
|
|
|
|
|
#ifdef INPUTDRIVER_ENCODER_BTN
|
2024-09-05 21:52:10 +02:00
|
|
|
pinMode(INPUTDRIVER_ENCODER_BTN, INPUT);
|
2024-06-27 14:50:57 +02:00
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
encoder = lv_indev_create();
|
|
|
|
|
lv_indev_set_type(encoder, LV_INDEV_TYPE_ENCODER);
|
|
|
|
|
lv_indev_set_read_cb(encoder, encoder_read);
|
|
|
|
|
|
|
|
|
|
if (!inputGroup) {
|
|
|
|
|
inputGroup = lv_group_create();
|
|
|
|
|
lv_group_set_default(inputGroup);
|
|
|
|
|
}
|
|
|
|
|
lv_indev_set_group(encoder, inputGroup);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EncoderInputDriver::encoder_read(lv_indev_t *indev, lv_indev_data_t *data)
|
|
|
|
|
{
|
|
|
|
|
// encoder w/o interrupts but read GPIOs directly
|
|
|
|
|
if (INPUTDRIVER_ENCODER_TYPE == 1) {
|
|
|
|
|
#ifdef INPUTDRIVER_ENCODER_LEFT
|
|
|
|
|
if (digitalRead(INPUTDRIVER_ENCODER_LEFT))
|
|
|
|
|
data->enc_diff = -1;
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef INPUTDRIVER_ENCODER_RIGHT
|
|
|
|
|
if (digitalRead(INPUTDRIVER_ENCODER_RIGHT))
|
|
|
|
|
data->enc_diff = 1;
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef INPUTDRIVER_ENCODER_BTN
|
2024-07-03 10:14:24 +02:00
|
|
|
// FIXME: need same logix as below to trigger LONG_PRESSED events
|
2024-06-27 14:50:57 +02:00
|
|
|
if (!digitalRead(INPUTDRIVER_ENCODER_BTN)) {
|
|
|
|
|
data->key = LV_KEY_ENTER;
|
|
|
|
|
data->state = LV_INDEV_STATE_PRESSED;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
2024-07-04 12:44:50 +02:00
|
|
|
// trackball/joystick with additional up/down inputs to control sliders
|
2024-06-27 14:50:57 +02:00
|
|
|
else if (INPUTDRIVER_ENCODER_TYPE == 3) {
|
2024-07-03 10:14:24 +02:00
|
|
|
static uint32_t prevkey = 0;
|
2024-06-27 14:50:57 +02:00
|
|
|
static uint32_t lastPressed = millis();
|
2024-07-03 10:14:24 +02:00
|
|
|
|
|
|
|
|
data->key = 0;
|
|
|
|
|
data->enc_diff = 0;
|
|
|
|
|
data->state = LV_INDEV_STATE_RELEASED;
|
|
|
|
|
|
|
|
|
|
#ifdef INPUTDRIVER_ENCODER_BTN
|
|
|
|
|
if (action == TB_ACTION_NONE) {
|
|
|
|
|
if (!digitalRead(INPUTDRIVER_ENCODER_BTN)) {
|
2024-08-21 18:47:58 +02:00
|
|
|
action = TB_ACTION_PRESSED;
|
2024-07-03 10:14:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2024-07-23 00:17:03 +02:00
|
|
|
// slow down repeating key to max. four events per second
|
2024-07-03 10:14:24 +02:00
|
|
|
// the button is an exception for LONG_PRESSED monitoring
|
2024-07-23 00:17:03 +02:00
|
|
|
if (action != TB_ACTION_NONE && (action == TB_ACTION_PRESSED || millis() > lastPressed + 250)) {
|
2024-06-27 14:50:57 +02:00
|
|
|
if (action == TB_ACTION_PRESSED) {
|
|
|
|
|
data->key = LV_KEY_ENTER;
|
|
|
|
|
data->state = LV_INDEV_STATE_PRESSED;
|
|
|
|
|
} else if (action == TB_ACTION_UP) {
|
|
|
|
|
data->enc_diff = -1;
|
|
|
|
|
} else if (action == TB_ACTION_DOWN) {
|
|
|
|
|
data->enc_diff = 1;
|
|
|
|
|
} else if (action == TB_ACTION_LEFT) {
|
2024-07-03 10:14:24 +02:00
|
|
|
data->key = LV_KEY_DOWN; // slider widget reacts on UP/DOWN
|
2024-06-27 14:50:57 +02:00
|
|
|
data->state = LV_INDEV_STATE_PRESSED;
|
|
|
|
|
} else if (action == TB_ACTION_RIGHT) {
|
2024-07-03 10:14:24 +02:00
|
|
|
data->key = LV_KEY_UP; // slider widget reacts on UP/DOWN
|
2024-06-27 14:50:57 +02:00
|
|
|
data->state = LV_INDEV_STATE_PRESSED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastPressed = millis();
|
2024-07-03 10:14:24 +02:00
|
|
|
prevkey = data->key;
|
2024-06-27 14:50:57 +02:00
|
|
|
action = TB_ACTION_NONE;
|
2024-07-03 10:14:24 +02:00
|
|
|
} else {
|
|
|
|
|
// this logic is required for LONG_PRESSED event, see lv_indev.c
|
|
|
|
|
if (prevkey != 0) {
|
|
|
|
|
data->state = LV_INDEV_STATE_RELEASED;
|
|
|
|
|
data->key = prevkey;
|
|
|
|
|
prevkey = 0;
|
|
|
|
|
}
|
2024-06-27 14:50:57 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EncoderInputDriver::intPressHandler()
|
|
|
|
|
{
|
|
|
|
|
action = TB_ACTION_PRESSED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EncoderInputDriver::intDownHandler()
|
|
|
|
|
{
|
|
|
|
|
action = TB_ACTION_DOWN;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EncoderInputDriver::intUpHandler()
|
|
|
|
|
{
|
|
|
|
|
action = TB_ACTION_UP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EncoderInputDriver::intLeftHandler()
|
|
|
|
|
{
|
|
|
|
|
action = TB_ACTION_LEFT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EncoderInputDriver::intRightHandler()
|
|
|
|
|
{
|
|
|
|
|
action = TB_ACTION_RIGHT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|