From 0473f463fa35836d70e10e8b3e1cd5c0e6298002 Mon Sep 17 00:00:00 2001 From: Rahix <rahix@rahix.de> Date: Sat, 17 Aug 2019 08:12:20 +0200 Subject: [PATCH] feat(epicardium): Add buttons module Co-authored-by: fleur <spacecarrot@fleurshax.net> Signed-off-by: Rahix <rahix@rahix.de> --- epicardium/epicardium.h | 64 ++++++++++++++++++++++++++++++++++ epicardium/modules/buttons.c | 32 +++++++++++++++++ epicardium/modules/meson.build | 1 + 3 files changed, 97 insertions(+) create mode 100644 epicardium/modules/buttons.c diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h index 36ea64b8..ce254cb6 100644 --- a/epicardium/epicardium.h +++ b/epicardium/epicardium.h @@ -88,6 +88,8 @@ typedef _Bool bool; #define API_LIGHT_SENSOR_RUN 0x80 #define API_LIGHT_SENSOR_GET 0x81 #define API_LIGHT_SENSOR_STOP 0x82 + +#define API_BUTTONS_READ 0x90 /* clang-format on */ typedef uint32_t api_int_id_t; @@ -274,6 +276,68 @@ API_ISR(EPIC_INT_UART_RX, epic_isr_uart_rx); */ API_ISR(EPIC_INT_CTRL_C, epic_isr_ctrl_c); +/** + * Buttons + * ======= + * + */ + +/** Button IDs */ +enum epic_button { + /** ``1``, Bottom left button (bit 0). */ + BUTTON_LEFT_BOTTOM = 1, + /** ``2``, Bottom right button (bit 1). */ + BUTTON_RIGHT_BOTTOM = 2, + /** ``4``, Top right button (bit 2). */ + BUTTON_RIGHT_TOP = 4, + /** ``8``, Top left (power) button (bit 3). */ + BUTTON_LEFT_TOP = 8, + /** ``8``, Top left (power) button (bit 3). */ + BUTTON_RESET = 8, +}; + +/** + * Read buttons. + * + * :c:func:`epic_buttons_read` will read all buttons specified in ``mask`` and + * return set bits for each button which was reported as pressed. + * + * .. note:: + * + * The reset button cannot be unmapped from reset functionality. So, while + * you can read it, it cannot be used for app control. + * + * **Example**: + * + * .. code-block:: cpp + * + * #include "epicardium.h" + * + * uint8_t pressed = epic_buttons_read(BUTTON_LEFT_BOTTOM | BUTTON_RIGHT_BOTTOM); + * + * if (pressed & BUTTON_LEFT_BOTTOM) { + * // Bottom left button is pressed + * } + * + * if (pressed & BUTTON_RIGHT_BOTTOM) { + * // Bottom right button is pressed + * } + * + * :param uint8_t mask: Mask of buttons to read. The 4 LSBs correspond to the 4 + * buttons: + * + * ===== ========= ============ =========== + * ``3`` ``2`` ``1`` ``0`` + * ----- --------- ------------ ----------- + * Reset Right Top Right Bottom Left Bottom + * ===== ========= ============ =========== + * + * Use the values defined in :c:type:`epic_button` for masking, as shown in + * the example above. + * :return: Returns nonzero value if unmasked buttons are pushed. + */ +API(API_BUTTONS_READ, uint8_t epic_buttons_read(uint8_t mask)); + /** * LEDs * ==== diff --git a/epicardium/modules/buttons.c b/epicardium/modules/buttons.c new file mode 100644 index 00000000..e2cb20d3 --- /dev/null +++ b/epicardium/modules/buttons.c @@ -0,0 +1,32 @@ +#include "epicardium.h" + +#include "portexpander.h" +#include "MAX77650-Arduino-Library.h" + +#include <stdint.h> + +static const uint8_t pin_mask[] = { + [BUTTON_LEFT_BOTTOM] = 1 << 5, + [BUTTON_RIGHT_BOTTOM] = 1 << 3, + [BUTTON_RIGHT_TOP] = 1 << 6, +}; + +uint8_t epic_buttons_read(uint8_t mask) +{ + uint8_t ret = 0; + if (portexpander_detected() && (mask & 0x3)) { + uint8_t pin_status = ~portexpander_get(); + + for (uint8_t m = 1; m < 0x8; m <<= 1) { + if (mask & m && pin_status & pin_mask[m]) { + ret |= m; + } + } + } + + if (mask & BUTTON_RESET && MAX77650_getDebounceStatusnEN0()) { + ret |= BUTTON_RESET; + } + + return ret; +} diff --git a/epicardium/modules/meson.build b/epicardium/modules/meson.build index d7c9f40b..3389a409 100644 --- a/epicardium/modules/meson.build +++ b/epicardium/modules/meson.build @@ -1,4 +1,5 @@ module_sources = files( + 'buttons.c', 'dispatcher.c', 'display.c', 'fileops.c', -- GitLab