Skip to content

feat(input_drivers): new input drivers for lvgl #125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 11, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions components/input_drivers/include/encoder_input.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#pragma once

#include <algorithm>
#include <functional>

#include "lvgl.h"
#include "sdkconfig.h"

#include "logger.hpp"

namespace espp {
/**
* @brief Light wrapper around LVGL input device driver, specifically
* designed for encoders with optional home buttons.
*/
class EncoderInput {
public:
typedef std::function<void(int *enc_diff, bool button_pressed)> read_fn;

/**
* @brief Configuration structure, containing the read function for the
* encoder itself.
*/
struct Config {
read_fn read; /**< Input function for the encoder and button itself. */
Logger::Verbosity log_level{
Logger::Verbosity::WARN}; /**< Log verbosity for the input driver. */
};

/**
* @brief Initialize and register the input drivers associated with the
* encoder.
* @param config Configuration structure for the EncoderInput.
*/
EncoderInput(const Config &config)
: read_(config.read)
logger_({.tag = "EncoderInput", .level = config.log_level}) {
init();
}

/**
* @brief Unregister the input drivers associated with the Encoder.
*/
~EncoderInput() {
if (indev_encoder_) {
lv_indev_delete(indev_encoder_);
}
if (indev_button_) {
lv_indev_delete(indev_button_);
}
}

/**
* @brief Get the input device driver associated with the encoder.
* @return The input device driver associated with the encoder.
*/
lv_indev_t *get_encoder_input_device() { return indev_encoder_; }

/**
* @brief Get the input device driver associated with the button.
* @return The input device driver associated with the button.
*/
lv_indev_t *get_button_input_device() { return indev_button_; }

protected:
static void encoder_read(lv_indev_drv_t *drv, lv_indev_data_t *data) {
EncoderInput *ei = (EncoderInput *)drv->user_data;
if (ei) {
ei->encoder_read_impl(data);
}
}

void encoder_read_impl(lv_indev_data_t *data) {
int enc_diff;
bool button_pressed;
if (!read_) {
logger_.error("Invalid read function!");
return;
}
read_(&enc_diff, &button_pressed);
if (button_pressed) {
button_pressed_ = true;
}
data->state = (button_pressed) ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
data->enc_diff = enc_diff;
}

static void button_read(lv_indev_drv_t *drv, lv_indev_data_t *data) {
EncoderInput *ei = (EncoderInput *)drv->user_data;
if (ei) {
ei->home_button_read_impl(data);
}
}

void button_read_impl(lv_indev_data_t *data) {
data->state = button_pressed_ ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
}

void init() {
using namespace std::placeholders;
logger_.info("Add encoder input device to LVGL");
lv_indev_drv_init(&indev_drv_enc_);
indev_drv_enc_.type = LV_INDEV_TYPE_POINTER;
indev_drv_enc_.read_cb = &EncoderInput::encoder_read;
indev_drv_enc_.user_data = (void *)this;
indev_encoder_ = lv_indev_drv_register(&indev_drv_enc_);

logger_.info("Add button input to LVGL");
lv_indev_drv_init(&indev_drv_btn_);
indev_drv_btn_.type = LV_INDEV_TYPE_BUTTON;
indev_drv_btn_.read_cb = &EncoderInput::button_read;
indev_drv_btn_.user_data = (void *)this;
indev_button_ = lv_indev_drv_register(&indev_drv_btn_);
}

encoder_read_fn encoder_read_;
std::atomic<bool> button_pressed_{false};
lv_indev_drv_t indev_drv_enc_;
lv_indev_t *indev_encoder_;
lv_indev_drv_t indev_drv_btn_;
lv_indev_t *indev_button_;
Logger logger_;
};
} // namespace espp
108 changes: 108 additions & 0 deletions components/input_drivers/include/keypad_input.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#pragma once

#include <algorithm>
#include <functional>

#include "lvgl.h"
#include "sdkconfig.h"

#include "logger.hpp"

namespace espp {
/**
* @brief Light wrapper around LVGL input device driver, specifically
* designed for keypads.
*/
class KeypadInput {
public:
typedef std::function<void(bool *up, bool *down, bool *left, bool *right, bool *enter, bool *escape)> read_fn;

/**
* @brief Configuration structure, containing the read function for the
* keypad itself.
*/
struct Config {
read_fn read; /**< Input function for the keypad. */
Logger::Verbosity log_level{
Logger::Verbosity::WARN}; /**< Log verbosity for the input driver. */
};

/**
* @brief Initialize and register the input drivers associated with the
* keypad.
* @param config Configuration structure for the KeypadInput.
*/
KeypadInput(const Config &config)
: read_(config.read),
logger_({.tag = "KeypadInput", .level = config.log_level}) {
init();
}

/**
* @brief Unregister the input drivers associated with the Keypad.
*/
~KeypadInput() {
if (indev_keypad_) {
lv_indev_delete(indev_keypad_);
}
}

/**
* @brief Get the input device driver associated with the keypad.
* @return The input device driver associated with the keypad.
*/
lv_indev_t *get_input_device() { return indev_keypad_; }

protected:
static void keypad_read(lv_indev_drv_t *drv, lv_indev_data_t *data) {
KeypadInput *ki = (KeypadInput *)drv->user_data;
if (ki) {
ki->keypad_read_impl(data);
}
}

void keypad_read_impl(lv_indev_data_t *data) {
if (!read_) {
logger_.error("Invalid read function!");
return;
}
logger_.info("Reading keypad...");
bool up,down,left,right,enter,escape;
read_(&up, &down, &left, &right, &enter, &escape);
data->state = LV_INDEV_STATE_PRESSED;
if (escape) {
data->key = LV_KEY_ESC;
} else if (enter) {
data->key = LV_KEY_ENTER;
} else if (up) {
data->key = LV_KEY_UP;
} else if (down) {
data->key = LV_KEY_DOWN;
} else if (left) {
data->key = LV_KEY_LEFT;
} else if (right) {
data->key = LV_KEY_RIGHT;
} else {
data->state = LV_INDEV_STATE_RELEASED;
}
logger_.debug("Keypad state: up: {}, down: {}, left: {}, right: {}, enter: {}, escape: {}",
up, down, left, right, enter, escape);
logger_.debug("Keypad data: state: {}, key: {}", (int)data->state, (int)data->key);
}

void init() {
using namespace std::placeholders;
logger_.info("Add keypad input device to LVGL");
lv_indev_drv_init(&indev_drv_keypad_);
indev_drv_keypad_.type = LV_INDEV_TYPE_KEYPAD;
indev_drv_keypad_.read_cb = &KeypadInput::keypad_read;
indev_drv_keypad_.user_data = (void *)this;
indev_keypad_ = lv_indev_drv_register(&indev_drv_keypad_);
}

read_fn read_;
lv_indev_drv_t indev_drv_keypad_;
lv_indev_t *indev_keypad_;
Logger logger_;
};
} // namespace espp
12 changes: 12 additions & 0 deletions components/input_drivers/include/touchpad_input.hpp
Original file line number Diff line number Diff line change
@@ -65,6 +65,18 @@ class TouchpadInput {
}
}

/**
* @brief Get a pointer to the LVGL input device driver for the touchpad.
* @return Pointer to the LVGL input device driver for the touchpad.
*/
lv_indev_t *get_touchpad_input_device() { return indev_touchpad_; }

/**
* @brief Get a pointer to the LVGL input device driver for the home button.
* @return Pointer to the LVGL input device driver for the home button.
*/
lv_indev_t *get_home_button_input_device() { return indev_button_; }

protected:
static void touchpad_read(lv_indev_drv_t *drv, lv_indev_data_t *data) {
TouchpadInput *tpi = (TouchpadInput *)drv->user_data;
2 changes: 1 addition & 1 deletion components/lvgl
Submodule lvgl updated 229 files
2 changes: 2 additions & 0 deletions doc/Doxyfile
Original file line number Diff line number Diff line change
@@ -115,6 +115,8 @@ INPUT += $(PROJECT_PATH)/components/ftp/include/ftp_client_session.hpp
INPUT += $(PROJECT_PATH)/components/ft5x06/include/ft5x06.hpp
INPUT += $(PROJECT_PATH)/components/gt911/include/gt911.hpp
INPUT += $(PROJECT_PATH)/components/i2c/include/i2c.hpp
INPUT += $(PROJECT_PATH)/components/input_drivers/include/encoder_input.hpp
INPUT += $(PROJECT_PATH)/components/input_drivers/include/keypad_input.hpp
INPUT += $(PROJECT_PATH)/components/input_drivers/include/touchpad_input.hpp
INPUT += $(PROJECT_PATH)/components/joystick/include/joystick.hpp
INPUT += $(PROJECT_PATH)/components/led/include/led.hpp
13 changes: 13 additions & 0 deletions doc/en/input/encoder_input.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Encoder Input
*************

Encoder input provides a light and configurable wrapper around lvgl input
device driver - specifically designed for encoders, which have a single
incremental input and a single button.

.. ---------------------------- API Reference ----------------------------------

API Reference
-------------

.. include-build-file:: inc/encoder_input.inc
2 changes: 2 additions & 0 deletions doc/en/input/index.rst
Original file line number Diff line number Diff line change
@@ -8,4 +8,6 @@ Input APIs
gt911
tt21100
t_keyboard
encoder_input
keypad_input
touchpad_input
15 changes: 15 additions & 0 deletions doc/en/input/keypad_input.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Keypad Input
************

Keypad input provides a light and configurable wrapper around lvgl input device
driver - specifically designed for use with a keypad, which is typically a
matrix of buttons, typically containing buttons such as LEFT, RIGHT, UP, DOWN,
ENTER, ESCAPE, etc.


.. ---------------------------- API Reference ----------------------------------

API Reference
-------------

.. include-build-file:: inc/keypad_input.inc
13 changes: 13 additions & 0 deletions docs/_sources/input/encoder_input.rst.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Encoder Input
*************

Encoder input provides a light and configurable wrapper around lvgl input
device driver - specifically designed for encoders, which have a single
incremental input and a single button.

.. ---------------------------- API Reference ----------------------------------

API Reference
-------------

.. include-build-file:: inc/encoder_input.inc
2 changes: 2 additions & 0 deletions docs/_sources/input/index.rst.txt
Original file line number Diff line number Diff line change
@@ -8,4 +8,6 @@ Input APIs
gt911
tt21100
t_keyboard
encoder_input
keypad_input
touchpad_input
15 changes: 15 additions & 0 deletions docs/_sources/input/keypad_input.rst.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Keypad Input
************

Keypad input provides a light and configurable wrapper around lvgl input device
driver - specifically designed for use with a keypad, which is typically a
matrix of buttons, typically containing buttons such as LEFT, RIGHT, UP, DOWN,
ENTER, ESCAPE, etc.


.. ---------------------------- API Reference ----------------------------------

API Reference
-------------

.. include-build-file:: inc/keypad_input.inc
4 changes: 2 additions & 2 deletions docs/adc/adc_types.html
Original file line number Diff line number Diff line change
@@ -145,7 +145,7 @@
<li><a href="index.html">ADC APIs</a> &raquo;</li>
<li>ADC Types</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/esp-cpp/espp/blob/15ad5f4/docs/en/adc/adc_types.rst" class="fa fa-github"> Edit on GitHub</a>
<a href="https://github.com/esp-cpp/espp/blob/28308cc/docs/en/adc/adc_types.rst" class="fa fa-github"> Edit on GitHub</a>
</li>
</ul>
<hr/>
@@ -162,7 +162,7 @@ <h2>API Reference<a class="headerlink" href="#api-reference" title="Permalink to
<section id="header-file">
<h3>Header File<a class="headerlink" href="#header-file" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/87d6eb4/components/adc/include/adc_types.hpp">components/adc/include/adc_types.hpp</a></p></li>
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/28308cc/components/adc/include/adc_types.hpp">components/adc/include/adc_types.hpp</a></p></li>
</ul>
</section>
</section>
4 changes: 2 additions & 2 deletions docs/adc/ads1x15.html
Original file line number Diff line number Diff line change
@@ -146,7 +146,7 @@
<li><a href="index.html">ADC APIs</a> &raquo;</li>
<li>ADS1x15 I2C ADC</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/esp-cpp/espp/blob/15ad5f4/docs/en/adc/ads1x15.rst" class="fa fa-github"> Edit on GitHub</a>
<a href="https://github.com/esp-cpp/espp/blob/28308cc/docs/en/adc/ads1x15.rst" class="fa fa-github"> Edit on GitHub</a>
</li>
</ul>
<hr/>
@@ -163,7 +163,7 @@ <h2>API Reference<a class="headerlink" href="#api-reference" title="Permalink to
<section id="header-file">
<h3>Header File<a class="headerlink" href="#header-file" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/15ad5f4/components/ads1x15/include/ads1x15.hpp">components/ads1x15/include/ads1x15.hpp</a></p></li>
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/28308cc/components/ads1x15/include/ads1x15.hpp">components/ads1x15/include/ads1x15.hpp</a></p></li>
</ul>
</section>
<section id="classes">
4 changes: 2 additions & 2 deletions docs/adc/ads7138.html
Original file line number Diff line number Diff line change
@@ -146,7 +146,7 @@
<li><a href="index.html">ADC APIs</a> &raquo;</li>
<li>ADS7138 I2C ADC</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/esp-cpp/espp/blob/15ad5f4/docs/en/adc/ads7138.rst" class="fa fa-github"> Edit on GitHub</a>
<a href="https://github.com/esp-cpp/espp/blob/28308cc/docs/en/adc/ads7138.rst" class="fa fa-github"> Edit on GitHub</a>
</li>
</ul>
<hr/>
@@ -168,7 +168,7 @@ <h2>API Reference<a class="headerlink" href="#api-reference" title="Permalink to
<section id="header-file">
<h3>Header File<a class="headerlink" href="#header-file" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/15ad5f4/components/ads7138/include/ads7138.hpp">components/ads7138/include/ads7138.hpp</a></p></li>
<li><p><a class="reference external" href="https://github.com/esp-cpp/espp/blob/28308cc/components/ads7138/include/ads7138.hpp">components/ads7138/include/ads7138.hpp</a></p></li>
</ul>
</section>
<section id="classes">
Loading