Skip to content

Commit

Permalink
feat(input_drivers): new input drivers for lvgl (#125)
Browse files Browse the repository at this point in the history
* feat(input_drivers): new input drivers for lvgl
* Added encoder input driver for lvgl
* Added keyapd input driver for lvgl
* Updated touchpad input driver for lvgl to have interface to get underlying touch driver
* Updated docs

* doc: rebuild
  • Loading branch information
finger563 authored Nov 11, 2023
1 parent 7385ff3 commit 393144f
Show file tree
Hide file tree
Showing 96 changed files with 1,109 additions and 177 deletions.
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
Expand Up @@ -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;
Expand Down
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
Expand Up @@ -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
Expand Down
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
Expand Up @@ -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
Expand Up @@ -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
Expand Up @@ -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/>
Expand All @@ -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>
Expand Down
4 changes: 2 additions & 2 deletions docs/adc/ads1x15.html
Original file line number Diff line number Diff line change
Expand Up @@ -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/>
Expand All @@ -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">
Expand Down
4 changes: 2 additions & 2 deletions docs/adc/ads7138.html
Original file line number Diff line number Diff line change
Expand Up @@ -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/>
Expand All @@ -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">
Expand Down
Loading

0 comments on commit 393144f

Please sign in to comment.