Implements bottom-edge swipe-up gesture detection and delayed touch-select with tracking state. Adds isTouchTapCandidate() to distinguish taps from swipes. Includes LilyGo T5 S3 board configuration with USB CDC logging transport for boards where Serial operator bool reports false incorrectly.
137 lines
4.9 KiB
C++
137 lines
4.9 KiB
C++
#pragma once
|
|
|
|
#include <Arduino.h>
|
|
#include <InputManager.h>
|
|
|
|
// Display SPI pins (custom pins for XteinkX4, not hardware SPI defaults)
|
|
#define EPD_SCLK 8 // SPI Clock
|
|
#define EPD_MOSI 10 // SPI MOSI (Master Out Slave In)
|
|
#define EPD_CS 21 // Chip Select
|
|
#define EPD_DC 4 // Data/Command
|
|
#define EPD_RST 5 // Reset
|
|
#define EPD_BUSY 6 // Busy
|
|
|
|
#define SPI_MISO 7 // SPI MISO, shared between SD card and display (Master In Slave Out)
|
|
|
|
#define BAT_GPIO0 0 // Battery voltage
|
|
|
|
#define UART0_RXD 20 // Used for USB connection detection
|
|
|
|
// Xteink X3 Hardware
|
|
#define X3_I2C_SDA 20
|
|
#define X3_I2C_SCL 0
|
|
#define X3_I2C_FREQ 400000
|
|
|
|
// TI BQ27220 Fuel gauge I2C
|
|
#define I2C_ADDR_BQ27220 0x55 // Fuel gauge I2C address
|
|
#define BQ27220_SOC_REG 0x2C // StateOfCharge() command code (%)
|
|
#define BQ27220_CUR_REG 0x0C // Current() command code (signed mA)
|
|
#define BQ27220_VOLT_REG 0x08 // Voltage() command code (mV)
|
|
|
|
// Analog DS3231 RTC I2C
|
|
#define I2C_ADDR_DS3231 0x68 // RTC I2C address
|
|
#define DS3231_SEC_REG 0x00 // Seconds command code (BCD)
|
|
|
|
// QST QMI8658 IMU I2C
|
|
#define I2C_ADDR_QMI8658 0x6B // IMU I2C address
|
|
#define I2C_ADDR_QMI8658_ALT 0x6A // IMU I2C fallback address
|
|
#define QMI8658_WHO_AM_I_REG 0x00 // WHO_AM_I command code
|
|
#define QMI8658_WHO_AM_I_VALUE 0x05 // WHO_AM_I expected value
|
|
|
|
class HalGPIO {
|
|
#if CROSSPOINT_EMULATED == 0
|
|
InputManager inputMgr;
|
|
#endif
|
|
|
|
bool lastUsbConnected = false;
|
|
bool usbStateChanged = false;
|
|
|
|
public:
|
|
enum class DeviceType : uint8_t { X4, X3 };
|
|
|
|
private:
|
|
DeviceType _deviceType = DeviceType::X4;
|
|
|
|
public:
|
|
HalGPIO() = default;
|
|
|
|
// Inline device type helpers for cleaner downstream checks
|
|
inline bool deviceIsX3() const { return _deviceType == DeviceType::X3; }
|
|
inline bool deviceIsX4() const { return _deviceType == DeviceType::X4; }
|
|
|
|
// True on the Xteink X3/X4 boards. Unlike deviceIsX3/X4 (which both stay "X4"
|
|
// on non-C3 boards), this keys off BoardConfig::ACTIVE.board, so it reliably
|
|
// gates Xteink-only features (sunlight fix) and non-Xteink-only ones (touch).
|
|
bool isXteinkDevice() const;
|
|
|
|
// Start button GPIO and setup SPI for screen and SD card
|
|
void begin();
|
|
|
|
// Button input methods
|
|
void update();
|
|
bool isPressed(uint8_t buttonIndex) const;
|
|
bool wasPressed(uint8_t buttonIndex) const;
|
|
bool wasAnyPressed() const;
|
|
bool wasReleased(uint8_t buttonIndex) const;
|
|
bool wasAnyReleased() const;
|
|
unsigned long getHeldTime() const;
|
|
unsigned long getPowerButtonHeldTime() const;
|
|
|
|
// Touch: one-shot tap with the release position normalized 0..1 in the panel's
|
|
// native orientation. Returns false on non-touch devices. (Reusable gesture
|
|
// primitive; see MappedInputManager for the top-left = Back mapping.)
|
|
bool wasTouchTap(float& nx, float& ny) const;
|
|
|
|
// Press-edge of a touch: true on touch-down with the down position normalized
|
|
// 0..1 (panel native). For showing the pressed/selected element before release.
|
|
bool wasTouchDown(float& nx, float& ny) const;
|
|
|
|
// True while a touch remains within tap slop; writes touch-down position and held time.
|
|
bool isTouchTapCandidate(float& nx, float& ny, unsigned long& heldMs) const;
|
|
|
|
// Duration (ms) of the last touch contact, latched on release. Valid on the
|
|
// release frame (alongside wasTouchTap). For tap-vs-long-press decisions.
|
|
unsigned long lastTouchHeldMs() const;
|
|
|
|
// Swipe (flick) gesture on the release frame: writes the start/end positions
|
|
// normalized 0..1 in the panel's native frame (map via GfxRenderer::tapToLogical).
|
|
// A swipe also raises wasTouchTap(), so check this first. False on non-touch.
|
|
bool wasSwipe(float& nxStart, float& nyStart, float& nxEnd, float& nyEnd) const;
|
|
|
|
// True if a touch controller is present/active (runtime gate; false on the C3).
|
|
bool hasTouch() const;
|
|
|
|
// True if a touch press or release happened this frame (the touch analogue of
|
|
// wasAnyPressed/Released), for resetting idle/sleep timers and CPU frequency.
|
|
bool wasTouchActivity() const;
|
|
|
|
// Setup wake up GPIO and enter deep sleep
|
|
void startDeepSleep();
|
|
|
|
// Verify power button was held long enough after wakeup.
|
|
// If verification fails, enters deep sleep and does not return.
|
|
// Should only be called when wakeup reason is PowerButton.
|
|
void verifyPowerButtonWakeup(uint16_t requiredDurationMs, bool shortPressAllowed);
|
|
|
|
// Check if USB is connected
|
|
bool isUsbConnected() const;
|
|
|
|
// Returns true once per edge (plug or unplug) since the last update()
|
|
bool wasUsbStateChanged() const;
|
|
|
|
enum class WakeupReason { PowerButton, AfterFlash, AfterUSBPower, Other };
|
|
|
|
WakeupReason getWakeupReason() const;
|
|
|
|
// Button indices
|
|
static constexpr uint8_t BTN_BACK = 0;
|
|
static constexpr uint8_t BTN_CONFIRM = 1;
|
|
static constexpr uint8_t BTN_LEFT = 2;
|
|
static constexpr uint8_t BTN_RIGHT = 3;
|
|
static constexpr uint8_t BTN_UP = 4;
|
|
static constexpr uint8_t BTN_DOWN = 5;
|
|
static constexpr uint8_t BTN_POWER = 6;
|
|
};
|
|
|
|
extern HalGPIO gpio;
|