mirror of
https://github.com/markqvist/RNode_Firmware.git
synced 2026-04-28 09:43:08 +00:00
Board definition (BOARD_TWATCH_ULT = 0x45) for LilyGo T-Watch Ultra with verified pin mapping from LilyGoLib hardware docs. Working subsystems: - SX1262 LoRa radio: online at 868 MHz, tested with rnsd/Reticulum - AXP2101 PMU: all power rails configured, battery monitoring, charging - MIA-M10Q GPS: UART at 38400 baud, TinyGPSPlus NMEA parsing - PCF85063A RTC: time read/write, GPS sync infrastructure - XL9555 GPIO expander: I2C driver, LoRa antenna switch - BLE: initialized, KISS protocol responsive - Deep sleep: button wake (PMU IRQ GPIO 7), timer wake for beacon - Beacon sleep cycle: periodic wake for GPS beacon TX in standalone mode New files: - VISION.md: R-Watch product vision document - XL9555.h: minimal I2C GPIO expander driver - CO5300.h: QSPI AMOLED display driver (not yet functional) Display driver (CO5300.h) is written but disabled (HAS_DISPLAY=false). QSPI init succeeds but pixel writes don't reach the display controller. Suspected XL9555/BHI260AP GPIO expander pin mapping issue under investigation.
106 lines
3.3 KiB
C
106 lines
3.3 KiB
C
// XL9555 I2C GPIO Expander - Minimal driver for T-Watch Ultra
|
|
// Two 8-bit ports (0-7 = port 0, 8-15 = port 1)
|
|
// Registers: 0x00/0x01 input, 0x02/0x03 output, 0x06/0x07 direction (1=input, 0=output)
|
|
|
|
#ifndef XL9555_H
|
|
#define XL9555_H
|
|
|
|
#include <Wire.h>
|
|
|
|
#define XL9555_ADDR 0x20
|
|
#define XL9555_REG_IN0 0x00
|
|
#define XL9555_REG_IN1 0x01
|
|
#define XL9555_REG_OUT0 0x02
|
|
#define XL9555_REG_OUT1 0x03
|
|
#define XL9555_REG_DIR0 0x06
|
|
#define XL9555_REG_DIR1 0x07
|
|
|
|
// T-Watch Ultra expander pin assignments (matching LilyGoLib numbering)
|
|
#define EXPANDS_DRV_EN 6 // Port 0, bit 6 — haptic driver enable
|
|
#define EXPANDS_DISP_EN 14 // Port 1, bit 6 — display power gate
|
|
#define EXPANDS_DISP_RST 15 // Port 1, bit 7 — display reset
|
|
#define EXPANDS_TOUCH_RST 16 // Extended pin — touch panel reset
|
|
#define EXPANDS_SD_DET 12 // Port 1, bit 4 — SD card detect (input)
|
|
#define EXPANDS_LORA_RF_SW 11 // Port 1, bit 3 — LoRa RF switch
|
|
|
|
static bool xl9555_ready = false;
|
|
static uint8_t xl9555_out[2] = {0xFF, 0xFF}; // output register cache
|
|
|
|
static uint8_t xl9555_read_reg(uint8_t reg) {
|
|
Wire.beginTransmission(XL9555_ADDR);
|
|
Wire.write(reg);
|
|
Wire.endTransmission(false);
|
|
Wire.requestFrom((uint8_t)XL9555_ADDR, (uint8_t)1);
|
|
return Wire.available() ? Wire.read() : 0xFF;
|
|
}
|
|
|
|
static void xl9555_write_reg(uint8_t reg, uint8_t val) {
|
|
Wire.beginTransmission(XL9555_ADDR);
|
|
Wire.write(reg);
|
|
Wire.write(val);
|
|
Wire.endTransmission();
|
|
}
|
|
|
|
bool xl9555_init() {
|
|
Wire.beginTransmission(XL9555_ADDR);
|
|
if (Wire.endTransmission() != 0) return false;
|
|
|
|
// Set output pin directions (0 = output, 1 = input)
|
|
// Port 0: pin 6 (DRV_EN) as output, rest input
|
|
uint8_t dir0 = 0xFF & ~(1 << 6);
|
|
// Port 1: pins 3 (LORA_RF_SW), 6 (DISP_EN), 7 (DISP_RST) as output
|
|
uint8_t dir1 = 0xFF & ~((1 << 3) | (1 << 6) | (1 << 7));
|
|
|
|
xl9555_write_reg(XL9555_REG_DIR0, dir0);
|
|
xl9555_write_reg(XL9555_REG_DIR1, dir1);
|
|
|
|
// Read current output state
|
|
xl9555_out[0] = xl9555_read_reg(XL9555_REG_OUT0);
|
|
xl9555_out[1] = xl9555_read_reg(XL9555_REG_OUT1);
|
|
|
|
xl9555_ready = true;
|
|
return true;
|
|
}
|
|
|
|
void xl9555_set(uint8_t pin, bool value) {
|
|
if (!xl9555_ready) return;
|
|
uint8_t port = (pin >= 8) ? 1 : 0;
|
|
uint8_t bit = pin % 8;
|
|
|
|
if (value) {
|
|
xl9555_out[port] |= (1 << bit);
|
|
} else {
|
|
xl9555_out[port] &= ~(1 << bit);
|
|
}
|
|
xl9555_write_reg(port == 0 ? XL9555_REG_OUT0 : XL9555_REG_OUT1, xl9555_out[port]);
|
|
}
|
|
|
|
bool xl9555_get(uint8_t pin) {
|
|
if (!xl9555_ready) return false;
|
|
uint8_t port = (pin >= 8) ? 1 : 0;
|
|
uint8_t bit = pin % 8;
|
|
uint8_t val = xl9555_read_reg(port == 0 ? XL9555_REG_IN0 : XL9555_REG_IN1);
|
|
return (val >> bit) & 1;
|
|
}
|
|
|
|
// Convenience functions for sleep entry
|
|
void xl9555_sleep_prepare() {
|
|
if (!xl9555_ready) return;
|
|
xl9555_set(EXPANDS_DISP_RST, false); // hold display in reset
|
|
xl9555_set(EXPANDS_DRV_EN, false); // disable haptic
|
|
xl9555_set(EXPANDS_DISP_EN, false); // gate display power
|
|
}
|
|
|
|
void xl9555_wake_display() {
|
|
if (!xl9555_ready) return;
|
|
xl9555_set(EXPANDS_DISP_EN, true); // enable display power
|
|
xl9555_set(EXPANDS_DISP_RST, false); // reset pulse
|
|
delay(50);
|
|
xl9555_set(EXPANDS_DISP_RST, true);
|
|
}
|
|
|
|
void xl9555_enable_lora_antenna() {
|
|
xl9555_set(EXPANDS_LORA_RF_SW, true); // select built-in antenna
|
|
}
|
|
|
|
#endif
|