This commit is contained in:
Manuel 2025-10-25 21:50:08 +02:00 committed by GitHub
commit 1d78c5399d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 520 additions and 25 deletions

40
boards/t-watch-ultra.json Normal file
View File

@ -0,0 +1,40 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_qspi"
},
"core": "esp32",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_USB_MODE=0",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=1"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"psram_type": "qio",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "t-watch-ultra"
},
"connectivity": ["wifi", "bluetooth", "lora"],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino"],
"name": "LilyGo T-Watch Ultra",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"require_upload_port": true,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"speed": 921600
},
"url": "https://www.lilygo.cc/en-pl/products/t-watch-ultra",
"vendor": "LilyGo"
}

View File

@ -120,7 +120,7 @@ lib_deps =
[device-ui_base] [device-ui_base]
lib_deps = lib_deps =
# renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master # renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master
https://github.com/meshtastic/device-ui/archive/19b7855e9a1d9deff37391659ca7194e4ef57c43.zip https://github.com/meshtastic/device-ui/archive/af27b81b871b795eb44883e74d10d26c88d37eea.zip
; Common libs for environmental measurements in telemetry module ; Common libs for environmental measurements in telemetry module
[environmental_base] [environmental_base]

View File

@ -1149,8 +1149,52 @@ bool Power::axpChipInit()
PMU->disablePowerOutput(XPOWERS_DLDO1); // Invalid power channel, it does not exist PMU->disablePowerOutput(XPOWERS_DLDO1); // Invalid power channel, it does not exist
PMU->disablePowerOutput(XPOWERS_DLDO2); // Invalid power channel, it does not exist PMU->disablePowerOutput(XPOWERS_DLDO2); // Invalid power channel, it does not exist
PMU->disablePowerOutput(XPOWERS_VBACKUP); PMU->disablePowerOutput(XPOWERS_VBACKUP);
} } else if (HW_VENDOR == meshtastic_HardwareModel_T_WATCH_ULTRA) {
PMU->clearIrqStatus();
// Turn off the PMU charging indicator light, no physical connection
PMU->setChargingLedMode(XPOWERS_CHG_LED_OFF); // NO LED
PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300); // SD Card
PMU->enablePowerOutput(XPOWERS_ALDO1);
PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300); // Display
PMU->enablePowerOutput(XPOWERS_ALDO2);
PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300); // LoRa
PMU->enablePowerOutput(XPOWERS_ALDO3);
PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 1800); // Sensor
PMU->enablePowerOutput(XPOWERS_ALDO4);
PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300); // GPS
PMU->enablePowerOutput(XPOWERS_BLDO1);
PMU->setPowerChannelVoltage(XPOWERS_BLDO2, 3300); // Speaker
PMU->enablePowerOutput(XPOWERS_BLDO2);
PMU->setPowerChannelVoltage(XPOWERS_VBACKUP, 3300); // RTC Button battery
PMU->enablePowerOutput(XPOWERS_VBACKUP);
// PMU->enablePowerOutput(XPOWERS_DLDO1); // NFC
// UNUSED POWER CHANNEL
PMU->disablePowerOutput(XPOWERS_DCDC2);
PMU->disablePowerOutput(XPOWERS_DCDC3);
PMU->disablePowerOutput(XPOWERS_DCDC4);
PMU->disablePowerOutput(XPOWERS_DCDC5);
PMU->disablePowerOutput(XPOWERS_CPULDO);
// Enable Measure
PMU->enableBattDetection();
PMU->enableVbusVoltageMeasure();
PMU->enableBattVoltageMeasure();
PMU->enableSystemVoltageMeasure();
PMU->enableTemperatureMeasure();
// Clear all PMU interrupts
PMU->disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
}
// disable all axp chip interrupt // disable all axp chip interrupt
PMU->disableIRQ(XPOWERS_AXP2101_ALL_IRQ); PMU->disableIRQ(XPOWERS_AXP2101_ALL_IRQ);

View File

@ -484,7 +484,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
SCAN_SIMPLE_CASE(DFROBOT_RAIN_ADDR, DFROBOT_RAIN, "DFRobot Rain Gauge", (uint8_t)addr.address); SCAN_SIMPLE_CASE(DFROBOT_RAIN_ADDR, DFROBOT_RAIN, "DFRobot Rain Gauge", (uint8_t)addr.address);
SCAN_SIMPLE_CASE(LTR390UV_ADDR, LTR390UV, "LTR390UV", (uint8_t)addr.address); SCAN_SIMPLE_CASE(LTR390UV_ADDR, LTR390UV, "LTR390UV", (uint8_t)addr.address);
SCAN_SIMPLE_CASE(PCT2075_ADDR, PCT2075, "PCT2075", (uint8_t)addr.address); SCAN_SIMPLE_CASE(PCT2075_ADDR, PCT2075, "PCT2075", (uint8_t)addr.address);
SCAN_SIMPLE_CASE(CST328_ADDR, CST328, "CST328", (uint8_t)addr.address); SCAN_SIMPLE_CASE(CST328_ADDR, CST328, "Touch controller CSTxxxx", (uint8_t)addr.address);
SCAN_SIMPLE_CASE(LTR553ALS_ADDR, LTR553ALS, "LTR553ALS", (uint8_t)addr.address); SCAN_SIMPLE_CASE(LTR553ALS_ADDR, LTR553ALS, "LTR553ALS", (uint8_t)addr.address);
SCAN_SIMPLE_CASE(BHI260AP_ADDR, BHI260AP, "BHI260AP", (uint8_t)addr.address); SCAN_SIMPLE_CASE(BHI260AP_ADDR, BHI260AP, "BHI260AP", (uint8_t)addr.address);
SCAN_SIMPLE_CASE(SCD4X_ADDR, SCD4X, "SCD4X", (uint8_t)addr.address); SCAN_SIMPLE_CASE(SCD4X_ADDR, SCD4X, "SCD4X", (uint8_t)addr.address);

View File

@ -934,6 +934,9 @@ void GPS::setPowerPMU(bool on)
} else if (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE) { } else if (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE) {
// t-beam-s3-core GNSS power channel // t-beam-s3-core GNSS power channel
on ? PMU->enablePowerOutput(XPOWERS_ALDO4) : PMU->disablePowerOutput(XPOWERS_ALDO4); on ? PMU->enablePowerOutput(XPOWERS_ALDO4) : PMU->disablePowerOutput(XPOWERS_ALDO4);
} else if (HW_VENDOR == meshtastic_HardwareModel_T_WATCH_ULTRA) {
// t-watch-ultra GNSS power channel
on ? PMU->enablePowerOutput(XPOWERS_BLDO1) : PMU->disablePowerOutput(XPOWERS_BLDO1);
} }
} else if (model == XPOWERS_AXP192) { } else if (model == XPOWERS_AXP192) {
// t-beam v1.1 GNSS power channel // t-beam v1.1 GNSS power channel

View File

@ -369,7 +369,7 @@ Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_O
LOG_INFO("SSD1306 init success"); LOG_INFO("SSD1306 init success");
} }
#elif defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7789_CS) || \ #elif defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7789_CS) || \
defined(RAK14014) || defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST7796_CS) defined(RAK14014) || defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST7796_CS) || defined(CO5300_CS)
dispdev = new TFTDisplay(address.address, -1, -1, geometry, dispdev = new TFTDisplay(address.address, -1, -1, geometry,
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE); (address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
#elif defined(USE_EINK) && !defined(USE_EINK_DYNAMICDISPLAY) #elif defined(USE_EINK) && !defined(USE_EINK_DYNAMICDISPLAY)
@ -431,7 +431,7 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver)
if (on) { if (on) {
LOG_INFO("Turn on screen"); LOG_INFO("Turn on screen");
powerMon->setState(meshtastic_PowerMon_State_Screen_On); powerMon->setState(meshtastic_PowerMon_State_Screen_On);
#ifdef T_WATCH_S3 #if defined(T_WATCH_S3) || defined(T_WATCH_ULTRA)
PMU->enablePowerOutput(XPOWERS_ALDO2); PMU->enablePowerOutput(XPOWERS_ALDO2);
#endif #endif
@ -501,7 +501,7 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver)
#endif #endif
#endif #endif
#ifdef T_WATCH_S3 #if defined(T_WATCH_S3) || defined(T_WATCH_ULTRA)
PMU->disablePowerOutput(XPOWERS_ALDO2); PMU->disablePowerOutput(XPOWERS_ALDO2);
#endif #endif
enabled = false; enabled = false;
@ -601,7 +601,7 @@ void Screen::setup()
#else #else
if (!config.display.flip_screen) { if (!config.display.flip_screen) {
#if defined(ST7701_CS) || defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7789_CS) || \ #if defined(ST7701_CS) || defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7789_CS) || \
defined(RAK14014) || defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST7796_CS) defined(RAK14014) || defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST7796_CS) || defined(CO5300_CS)
static_cast<TFTDisplay *>(dispdev)->flipScreenVertically(); static_cast<TFTDisplay *>(dispdev)->flipScreenVertically();
#elif defined(USE_ST7789) #elif defined(USE_ST7789)
static_cast<ST7789Spi *>(dispdev)->flipScreenVertically(); static_cast<ST7789Spi *>(dispdev)->flipScreenVertically();

View File

@ -73,7 +73,8 @@
#endif #endif
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \ #if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST7796_CS)) && \ defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST7796_CS) || \
defined(CO5300_CS)) && \
!defined(DISPLAY_FORCE_SMALL_FONTS) !defined(DISPLAY_FORCE_SMALL_FONTS)
// The screen is bigger so use bigger fonts // The screen is bigger so use bigger fonts
#define FONT_SMALL FONT_MEDIUM_LOCAL // Height: 19 #define FONT_SMALL FONT_MEDIUM_LOCAL // Height: 19

View File

@ -21,6 +21,109 @@ uint16_t TFT_MESH = TFT_MESH_OVERRIDE;
uint16_t TFT_MESH = COLOR565(0x67, 0xEA, 0x94); uint16_t TFT_MESH = COLOR565(0x67, 0xEA, 0x94);
#endif #endif
#if defined(CO5300_CS)
#include <LovyanGFX.hpp> // Graphics and font library for AMOLED driver chip
class LGFX : public lgfx::LGFX_Device
{
lgfx::Panel_CO5300 _panel_instance;
lgfx::Bus_SPI _bus_instance;
public:
LGFX(void)
{
{
auto cfg = _bus_instance.config();
// configure SPI
cfg.spi_host = CO5300_SPI_HOST; // ESP32-S2,S3,C3 : SPI2_HOST or SPI3_HOST / ESP32 : VSPI_HOST or HSPI_HOST
cfg.spi_mode = SPI_MODE0;
cfg.freq_write = SPI_FREQUENCY; // SPI clock for transmission (up to 80MHz, rounded to the value obtained by dividing
// 80MHz by an integer)
cfg.freq_read = SPI_READ_FREQUENCY; // SPI clock when receiving
cfg.spi_3wire = false; // Set to true if reception is done on the MOSI pin
cfg.use_lock = true; // Set to true to use transaction locking
cfg.dma_channel = SPI_DMA_CH_AUTO; // SPI_DMA_CH_AUTO; // Set DMA channel to use (0=not use DMA / 1=1ch / 2=ch /
// SPI_DMA_CH_AUTO=auto setting)
cfg.pin_sclk = CO5300_SCK; // Set SPI SCLK pin number
cfg.pin_io0 = CO5300_IO0;
cfg.pin_io1 = CO5300_IO1;
cfg.pin_io2 = CO5300_IO2;
cfg.pin_io3 = CO5300_IO3;
_bus_instance.config(cfg); // applies the set value to the bus.
_panel_instance.setBus(&_bus_instance); // set the bus on the panel.
}
{ // Set the display panel control.
auto cfg = _panel_instance.config(); // Gets a structure for display panel settings.
cfg.pin_cs = CO5300_CS; // Pin number where CS is connected (-1 = disable)
cfg.pin_rst = CO5300_RESET; // Pin number where RST is connected (-1 = disable)
cfg.panel_width = TFT_WIDTH; // actual displayable width
cfg.panel_height = TFT_HEIGHT; // actual displayable height
cfg.offset_rotation = TFT_OFFSET_ROTATION; // Rotation direction value offset 0~7 (4~7 is upside down)
cfg.offset_x = TFT_OFFSET_X;
cfg.offset_y = TFT_OFFSET_Y;
cfg.dummy_read_pixel = 8; // Number of bits for dummy read before pixel readout
cfg.dummy_read_bits = 1; // Number of bits for dummy read before non-pixel data read
cfg.readable = true; // Set to true if data can be read
cfg.invert = false; // Set to true if the light/darkness of the panel is reversed
cfg.rgb_order = false; // Set to true if the panel's red and blue are swapped
cfg.dlen_16bit = false; // Set to true for panels that transmit data length in 16-bit units
cfg.bus_shared = true; // If the bus is shared with the SD card, set to true (bus control with drawJpgFile etc.)
// Set the following only when the display is shifted with a driver with a variable number of pixels
cfg.memory_width = TFT_WIDTH; // Maximum width supported by the driver IC
cfg.memory_height = TFT_HEIGHT; // Maximum height supported by the driver IC
_panel_instance.config(cfg);
}
setPanel(&_panel_instance);
}
bool enableFrameBuffer(bool auto_display = false)
{
if (_panel_instance.initPanelFb()) {
auto fbPanel = _panel_instance.getPanelFb();
if (fbPanel) {
fbPanel->setBus(&_bus_instance);
fbPanel->setAutoDisplay(auto_display);
setPanel(fbPanel);
return true;
}
}
return false;
}
void disableFrameBuffer()
{
auto fbPanel = _panel_instance.getPanelFb();
if (fbPanel) {
_panel_instance.deinitPanelFb();
setPanel(&_panel_instance);
}
}
bool init()
{
#ifdef CO5300_RESET
LOG_DEBUG("LGFX_Panel_CO5300::init()");
lgfx::pinMode(CO5300_RESET, lgfx::pin_mode_t::output);
lgfx::gpio_hi(CO5300_RESET);
delay(200);
lgfx::gpio_lo(CO5300_RESET);
delay(300);
lgfx::gpio_hi(CO5300_RESET);
delay(200);
#endif
return lgfx::LGFX_Device::init() && enableFrameBuffer(false);
}
};
static LGFX *tft = nullptr;
#endif
#if defined(ST7735S) #if defined(ST7735S)
#include <LovyanGFX.hpp> // Graphics and font library for ST7735 driver chip #include <LovyanGFX.hpp> // Graphics and font library for ST7735 driver chip
@ -1083,7 +1186,7 @@ static LGFX *tft = nullptr;
#if defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || defined(ST7796_CS) || defined(ILI9341_DRIVER) || \ #if defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || defined(ST7796_CS) || defined(ILI9341_DRIVER) || \
defined(ILI9342_DRIVER) || defined(RAK14014) || defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST72xx_DE) || \ defined(ILI9342_DRIVER) || defined(RAK14014) || defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST72xx_DE) || \
(ARCH_PORTDUINO && HAS_SCREEN != 0) defined(CO5300_CS) || (ARCH_PORTDUINO && HAS_SCREEN != 0)
#include "SPILock.h" #include "SPILock.h"
#include "TFTDisplay.h" #include "TFTDisplay.h"
#include <SPI.h> #include <SPI.h>
@ -1222,8 +1325,8 @@ void TFTDisplay::display(bool fromBlank)
// Step 4: Send the changed pixels on this line to the screen as a single block transfer. // Step 4: Send the changed pixels on this line to the screen as a single block transfer.
// This function accepts pixel data MSB first so it can dump the memory straight out the SPI port. // This function accepts pixel data MSB first so it can dump the memory straight out the SPI port.
tft->pushRect(x_FirstPixelUpdate, y, (x_LastPixelUpdate - x_FirstPixelUpdate + 1), 1, tft->pushImage(x_FirstPixelUpdate, y, (x_LastPixelUpdate - x_FirstPixelUpdate + 1), 1,
&linePixelBuffer[x_FirstPixelUpdate]); &linePixelBuffer[x_FirstPixelUpdate]);
somethingChanged = true; somethingChanged = true;
} }
@ -1282,7 +1385,7 @@ void TFTDisplay::sendCommand(uint8_t com)
// handle display on/off directly // handle display on/off directly
switch (com) { switch (com) {
case DISPLAYON: { case DISPLAYON: {
// LOG_DEBUG("Display on"); LOG_DEBUG("Display on");
backlightEnable->set(true); backlightEnable->set(true);
#if ARCH_PORTDUINO #if ARCH_PORTDUINO
display(true); display(true);
@ -1301,12 +1404,13 @@ void TFTDisplay::sendCommand(uint8_t com)
#endif #endif
#ifdef RAK14014 #ifdef RAK14014
#elif !defined(M5STACK) && !defined(ST7789_CS) // T-Deck gets brightness set in Screen.cpp in the handleSetOn function #elif !defined(M5STACK) && !defined(ST7789_CS) // T-Deck gets brightness set in Screen.cpp in the handleSetOn function
LOG_DEBUG("tft->setBrightness(172)");
tft->setBrightness(172); tft->setBrightness(172);
#endif #endif
break; break;
} }
case DISPLAYOFF: { case DISPLAYOFF: {
// LOG_DEBUG("Display off"); LOG_DEBUG("Display off");
backlightEnable->set(false); backlightEnable->set(false);
#if ARCH_PORTDUINO #if ARCH_PORTDUINO
tft->clear(); tft->clear();
@ -1325,6 +1429,7 @@ void TFTDisplay::sendCommand(uint8_t com)
#endif #endif
#ifdef RAK14014 #ifdef RAK14014
#elif !defined(M5STACK) #elif !defined(M5STACK)
LOG_DEBUG("tft->setBrightness(0)");
tft->setBrightness(0); tft->setBrightness(0);
#endif #endif
break; break;
@ -1400,8 +1505,8 @@ bool TFTDisplay::connect()
tft = new LGFX; tft = new LGFX;
#endif #endif
backlightEnable->set(true);
LOG_INFO("Power to TFT Backlight"); LOG_INFO("Power to TFT Backlight");
backlightEnable->set(true);
#ifdef UNPHONE #ifdef UNPHONE
unphone.backlight(true); // using unPhone library unphone.backlight(true); // using unPhone library
@ -1422,7 +1527,7 @@ bool TFTDisplay::connect()
tft->setRotation(1); // T-Deck has the TFT in landscape tft->setRotation(1); // T-Deck has the TFT in landscape
#elif defined(T_WATCH_S3) #elif defined(T_WATCH_S3)
tft->setRotation(2); // T-Watch S3 left-handed orientation tft->setRotation(2); // T-Watch S3 left-handed orientation
#elif ARCH_PORTDUINO || defined(SENSECAP_INDICATOR) || defined(T_LORA_PAGER) #elif ARCH_PORTDUINO || defined(SENSECAP_INDICATOR) || defined(T_LORA_PAGER) || defined(T_WATCH_ULTRA)
tft->setRotation(0); // use config.yaml to set rotation tft->setRotation(0); // use config.yaml to set rotation
#else #else
tft->setRotation(3); // Orient horizontal and wide underneath the silkscreen name label tft->setRotation(3); // Orient horizontal and wide underneath the silkscreen name label

View File

@ -95,7 +95,7 @@ void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16
(storeForwardModule->heartbeatInterval * 1200))) { // no heartbeat, overlap a bit (storeForwardModule->heartbeatInterval * 1200))) { // no heartbeat, overlap a bit
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \ #if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
defined(ST7789_CS) || defined(USE_ST7789) || defined(ILI9488_CS) || defined(HX8357_CS) || defined(ST7796_CS) || \ defined(ST7789_CS) || defined(USE_ST7789) || defined(ILI9488_CS) || defined(HX8357_CS) || defined(ST7796_CS) || \
ARCH_PORTDUINO) && \ defined(CO5300_CS) || ARCH_PORTDUINO) && \
!defined(DISPLAY_FORCE_SMALL_FONTS) !defined(DISPLAY_FORCE_SMALL_FONTS)
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(screen->ourId), y + 3 + FONT_HEIGHT_SMALL, 12, display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(screen->ourId), y + 3 + FONT_HEIGHT_SMALL, 12,
8, imgQuestionL1); 8, imgQuestionL1);
@ -107,7 +107,8 @@ void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16
#endif #endif
} else { } else {
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \ #if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
defined(ST7789_CS) || defined(USE_ST7789) || defined(ILI9488_CS) || defined(HX8357_CS) || defined(ST7796_CS)) && \ defined(ST7789_CS) || defined(USE_ST7789) || defined(ILI9488_CS) || defined(HX8357_CS) || defined(ST7796_CS) || \
defined(CO5300_CS)) && \
!defined(DISPLAY_FORCE_SMALL_FONTS) !defined(DISPLAY_FORCE_SMALL_FONTS)
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(screen->ourId), y + 3 + FONT_HEIGHT_SMALL, 16, display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(screen->ourId), y + 3 + FONT_HEIGHT_SMALL, 16,
8, imgSFL1); 8, imgSFL1);
@ -123,7 +124,7 @@ void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16
// TODO: Raspberry Pi supports more than just the one screen size // TODO: Raspberry Pi supports more than just the one screen size
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \ #if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
defined(ST7789_CS) || defined(USE_ST7789) || defined(ILI9488_CS) || defined(HX8357_CS) || defined(ST7796_CS) || \ defined(ST7789_CS) || defined(USE_ST7789) || defined(ILI9488_CS) || defined(HX8357_CS) || defined(ST7796_CS) || \
ARCH_PORTDUINO) && \ defined(CO5300_CS) || ARCH_PORTDUINO) && \
!defined(DISPLAY_FORCE_SMALL_FONTS) !defined(DISPLAY_FORCE_SMALL_FONTS)
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(screen->ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8, display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(screen->ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
imgInfoL1); imgInfoL1);

View File

@ -256,7 +256,8 @@ void UIRenderer::drawNodes(OLEDDisplay *display, int16_t x, int16_t y, const mes
} }
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \ #if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
defined(ST7789_CS) || defined(USE_ST7789) || defined(ILI9488_CS) || defined(HX8357_CS) || defined(ST7796_CS)) && \ defined(ST7789_CS) || defined(USE_ST7789) || defined(ILI9488_CS) || defined(HX8357_CS) || defined(ST7796_CS) || \
defined(CO5300_CS)) && \
!defined(DISPLAY_FORCE_SMALL_FONTS) !defined(DISPLAY_FORCE_SMALL_FONTS)
if (isHighResolution) { if (isHighResolution) {

View File

@ -28,7 +28,7 @@ const uint8_t bluetoothConnectedIcon[36] PROGMEM = {0xfe, 0x01, 0xff, 0x03, 0x03
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \ #if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST7796_CS) || \ defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST7796_CS) || \
ARCH_PORTDUINO) && \ defined(CO5300_CS) || ARCH_PORTDUINO) && \
!defined(DISPLAY_FORCE_SMALL_FONTS) !defined(DISPLAY_FORCE_SMALL_FONTS)
const uint8_t imgQuestionL1[] PROGMEM = {0xff, 0x01, 0x01, 0x32, 0x7b, 0x49, 0x49, 0x6f, 0x26, 0x01, 0x01, 0xff}; const uint8_t imgQuestionL1[] PROGMEM = {0xff, 0x01, 0x01, 0x32, 0x7b, 0x49, 0x49, 0x6f, 0x26, 0x01, 0x01, 0xff};
const uint8_t imgQuestionL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f}; const uint8_t imgQuestionL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f};

View File

@ -205,7 +205,7 @@ ScanI2C::FoundDevice rgb_found = ScanI2C::FoundDevice(ScanI2C::DeviceType::NONE,
/// The I2C address of our Air Quality Indicator (if found) /// The I2C address of our Air Quality Indicator (if found)
ScanI2C::DeviceAddress aqi_found = ScanI2C::ADDRESS_NONE; ScanI2C::DeviceAddress aqi_found = ScanI2C::ADDRESS_NONE;
#if defined(T_WATCH_S3) || defined(T_LORA_PAGER) #ifdef HAS_DRV2605
Adafruit_DRV2605 drv; Adafruit_DRV2605 drv;
#endif #endif
@ -394,6 +394,27 @@ void setup()
io.pinMode(EXPANDS_GPIO_EN, OUTPUT); io.pinMode(EXPANDS_GPIO_EN, OUTPUT);
io.digitalWrite(EXPANDS_GPIO_EN, HIGH); io.digitalWrite(EXPANDS_GPIO_EN, HIGH);
io.pinMode(EXPANDS_SD_PULLEN, INPUT); io.pinMode(EXPANDS_SD_PULLEN, INPUT);
#elif defined(T_WATCH_ULTRA)
pinMode(LORA_CS, OUTPUT);
digitalWrite(LORA_CS, HIGH);
pinMode(DISP_CS, OUTPUT);
digitalWrite(DISP_CS, HIGH);
pinMode(SDCARD_CS, OUTPUT);
digitalWrite(SDCARD_CS, HIGH);
if (io.begin(Wire, XL9555_SLAVE_ADDRESS0)) {
io.pinMode(EXPANDS_DRV_EN, OUTPUT);
io.digitalWrite(EXPANDS_DRV_EN, HIGH);
delay(1);
io.pinMode(EXPANDS_DISP_EN, OUTPUT);
io.digitalWrite(EXPANDS_DISP_EN, HIGH);
delay(1);
io.pinMode(EXPANDS_TOUCH_RST, OUTPUT);
io.digitalWrite(EXPANDS_TOUCH_RST, HIGH);
delay(1);
} else {
LOG_ERROR("io expander initialisation failed!");
}
#endif #endif
concurrency::hasBeenSetup = true; concurrency::hasBeenSetup = true;
#if ARCH_PORTDUINO #if ARCH_PORTDUINO
@ -820,7 +841,7 @@ void setup()
#endif #endif
#endif #endif
#if defined(T_WATCH_S3) || defined(T_LORA_PAGER) #ifdef HAS_DRV2605
drv.begin(); drv.begin();
drv.selectLibrary(1); drv.selectLibrary(1);
// I2C trigger by sending 'go' command // I2C trigger by sending 'go' command
@ -874,7 +895,7 @@ void setup()
#if defined(ST7701_CS) || defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || \ #if defined(ST7701_CS) || defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || \
defined(ST7789_CS) || defined(HX8357_CS) || defined(USE_ST7789) || defined(ILI9488_CS) || defined(ST7796_CS) || \ defined(ST7789_CS) || defined(HX8357_CS) || defined(USE_ST7789) || defined(ILI9488_CS) || defined(ST7796_CS) || \
defined(USE_SPISSD1306) defined(CO5300_CS) || defined(USE_SPISSD1306)
screen = new graphics::Screen(screen_found, screen_model, screen_geometry); screen = new graphics::Screen(screen_found, screen_model, screen_geometry);
#elif defined(ARCH_PORTDUINO) #elif defined(ARCH_PORTDUINO)
if ((screen_found.port != ScanI2C::I2CPort::NO_I2C || portduino_config.displayPanel) && if ((screen_found.port != ScanI2C::I2CPort::NO_I2C || portduino_config.displayPanel) &&
@ -1149,7 +1170,7 @@ void setup()
// the current region name) // the current region name)
#if defined(ST7701_CS) || defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || \ #if defined(ST7701_CS) || defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || \
defined(ST7789_CS) || defined(HX8357_CS) || defined(USE_ST7789) || defined(ILI9488_CS) || defined(ST7796_CS) || \ defined(ST7789_CS) || defined(HX8357_CS) || defined(USE_ST7789) || defined(ILI9488_CS) || defined(ST7796_CS) || \
defined(USE_SPISSD1306) defined(CO5300_CS) || defined(USE_SPISSD1306)
if (screen) if (screen)
screen->setup(); screen->setup();
#elif defined(ARCH_PORTDUINO) #elif defined(ARCH_PORTDUINO)

View File

@ -42,7 +42,7 @@ extern bool eink_found;
extern bool pmu_found; extern bool pmu_found;
extern bool isUSBPowered; extern bool isUSBPowered;
#if defined(T_WATCH_S3) || defined(T_LORA_PAGER) #ifdef HAS_DRV2605
#include <Adafruit_DRV2605.h> #include <Adafruit_DRV2605.h>
extern Adafruit_DRV2605 drv; extern Adafruit_DRV2605 drv;
#endif #endif

View File

@ -203,6 +203,8 @@
#define HW_VENDOR meshtastic_HardwareModel_M5STACK_C6L #define HW_VENDOR meshtastic_HardwareModel_M5STACK_C6L
#elif defined(HELTEC_WIRELESS_TRACKER_V2) #elif defined(HELTEC_WIRELESS_TRACKER_V2)
#define HW_VENDOR meshtastic_HardwareModel_HELTEC_WIRELESS_TRACKER_V2 #define HW_VENDOR meshtastic_HardwareModel_HELTEC_WIRELESS_TRACKER_V2
#elif defined(T_WATCH_ULTRA)
#define HW_VENDOR meshtastic_HardwareModel_T_WATCH_ULTRA
#endif #endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -0,0 +1,31 @@
#include "configuration.h"
#ifdef T_WATCH_ULTRA
#include "Arduino.h"
#include "TouchDrvCSTXXX.hpp"
#include "input/TouchScreenImpl1.h"
#include <Wire.h>
static TouchDrvCST92xx touchDrv;
static bool readTouch(int16_t *x, int16_t *y)
{
return touchDrv.isPressed() && touchDrv.getPoint(x, y, 1);
}
// T-Watch Ultra specific init
void lateInitVariant()
{
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) {
pinMode(SCREEN_TOUCH_INT, INPUT_PULLUP);
touchDrv.setPins(-1, SCREEN_TOUCH_INT);
if (touchDrv.begin(Wire, TOUCH_SLAVE_ADDRESS, I2C_SDA, I2C_SCL)) {
touchScreenImpl1 = new TouchScreenImpl1(TFT_WIDTH, TFT_HEIGHT, readTouch);
touchScreenImpl1->init();
} else {
LOG_ERROR("failed to initialize CST92xx");
}
}
}
#endif

View File

@ -30,6 +30,7 @@
// vibration motor // vibration motor
#define PIN_VIBRATION 2 #define PIN_VIBRATION 2
#define HAS_DRV2605 1
// Have SPI interface SD card slot // Have SPI interface SD card slot
#define HAS_SDCARD #define HAS_SDCARD

View File

@ -0,0 +1,93 @@
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <stdint.h>
// #ifndef digitalPinToInterrupt
// #define digitalPinToInterrupt(p) (((p) < 48) ? (p) : -1)
// #endif
#define USB_VID 0x303a
#define USB_PID 0x8227
#define USB_MANUFACTURER "LILYGO"
#define USB_PRODUCT "T-Watch-Ultra"
#define DISP_WIDTH 502
#define DISP_HEIGHT 410
// QSPI interface display
#define DISP_D0 (38)
#define DISP_D1 (39)
#define DISP_D2 (42)
#define DISP_D3 (45)
#define DISP_SCK (40)
#define DISP_CS (41)
#define DISP_RST (37)
#define DISP_TE (6)
// Interrupt IO port
#define TP_INT (12)
#define RTC_INT (1)
#define PMU_INT (7)
#define NFC_INT (5)
#define SENSOR_INT (8)
#define NFC_CS (4)
// PDM microphone
#define MIC_SCK (17)
#define MIC_DAT (18)
// MAX98357A
#define I2S_BCLK (9)
#define I2S_WCLK (10)
#define I2S_DOUT (11)
#define SD_CS (21)
// TX, RX pin connected to GPS
static const uint8_t TX = 43;
static const uint8_t RX = 44;
// BHI260,PCF85063,AXP2101,DRV2605L share I2C Bus
static const uint8_t SDA = 3;
static const uint8_t SCL = 2;
// Default sd cs pin
static const uint8_t SS = SD_CS;
static const uint8_t MOSI = 34;
static const uint8_t MISO = 33;
static const uint8_t SCK = 35;
#define GPS_TX (TX)
#define GPS_RX (RX)
#define GPS_PPS (13)
#define TP_SDA (SDA)
#define TP_SCL (SCL)
// LoRa and SD card share SPI bus -> variant.h
// #define LORA_SCK (SCK) // share spi bus
// #define LORA_MISO (MISO) // share spi bus
// #define LORA_MOSI (MOSI) // share spi bus
// #define LORA_CS (36)
// #define LORA_RST (47)
// #define LORA_BUSY (48)
// #define LORA_IRQ (14)
// External expansion chip IO definition
#define EXPANDS_DRV_EN (6)
#define EXPANDS_DISP_EN (7)
#define EXPANDS_TOUCH_RST (8)
#define EXPANDS_SD_DET (10)
// Peripheral definition exists
#define USING_XL9555_EXPANDS
#define USING_PCM_AMPLIFIER
#define USING_PDM_MICROPHONE
#define USING_PMU_MANAGE
#define USING_INPUT_DEV_TOUCHPAD
#define USING_ST25R3916
#define USING_BHI260_SENSOR
#define HAS_SD_CARD_SOCKET
#endif /* Pins_Arduino_h */

View File

@ -0,0 +1,63 @@
; LilyGo T-Watch S3
[env:t-watch-ultra]
extends = esp32s3_base
board = t-watch-ultra
board_check = true
board_build.partitions = default_16MB.csv
upload_protocol = esptool
build_flags = ${esp32_base.build_flags} -Ivariants/esp32s3/t-watch-ultra
-D T_WATCH_ULTRA
-D RADIOLIB_EXCLUDE_SX128X=1
-D RADIOLIB_EXCLUDE_SX127X=1
-D RADIOLIB_EXCLUDE_LR11X0=1
-D HAS_SDCARD
-D SDCARD_CS=21
; -DPCF85063_RTC=0x51
; -DHAS_BMA423=1
lib_deps = ${esp32s3_base.lib_deps}
lovyan03/LovyanGFX#develop ; TODO: does not yet contain Panel_CO5300 amoled driver
adafruit/Adafruit DRV2605 Library@^1.2.4
earlephilhower/ESP8266Audio@^1.9.9
earlephilhower/ESP8266SAM@^1.0.1
lewisxhe/SensorLib@0.3.1
[env:t-watch-ultra-tft]
board_level = extra
extends = env:t-watch-ultra
build_flags =
${env:t-watch-ultra.build_flags}
-D CONFIG_DISABLE_HAL_LOCKS=1
-D INPUTDRIVER_BUTTON_TYPE=0
-D HAS_SCREEN=1
-D HAS_TFT=1
-D USE_I2S_BUZZER
-D RAM_SIZE=5120
-D LV_LVGL_H_INCLUDE_SIMPLE
-D LV_CONF_INCLUDE_SIMPLE
-D LV_COMP_CONF_INCLUDE_SIMPLE
-D LV_USE_SYSMON=0
-D LV_USE_PROFILER=0
-D LV_USE_PERF_MONITOR=0
-D LV_USE_MEM_MONITOR=0
-D LV_USE_LOG=0
-D USE_LOG_DEBUG
-D LOG_DEBUG_INC=\"DebugConfiguration.h\"
-D RADIOLIB_SPI_PARANOID=0
-D LGFX_SCREEN_WIDTH=410
-D LGFX_SCREEN_HEIGHT=502
-D DISPLAY_SIZE=410x502 ; portrait mode
-D DISPLAY_SET_RESOLUTION
-D LGFX_DRIVER=LGFX_TWATCH_ULTRA
-D GFX_DRIVER_INC=\"graphics/LGFX/LGFX_T_WATCH_ULTRA.h\"
; -D LVGL_DRIVER=LVGL_T_WATCH_ULTRA
; -D LV_USE_ST7796=1
-D VIEW_320x240
-D USE_PACKET_API
-D MAP_FULL_REDRAW
-D CUSTOM_TOUCH_DRIVER
lib_deps =
${env:t-watch-ultra.lib_deps}
${device-ui_base.lib_deps}

View File

@ -0,0 +1,86 @@
// CO5300 TFT AMOLED
#define CO5300_CS 41
#define CO5300_SCK 40
#define CO5300_RESET 37
#define CO5300_TE 6
#define CO5300_IO0 38
#define CO5300_IO1 39
#define CO5300_IO2 42
#define CO5300_IO3 45
#define CO5300_SPI_HOST SPI2_HOST
#define SPI_FREQUENCY 75000000
#define SPI_READ_FREQUENCY 16000000 // irrelevant
#define TFT_HEIGHT 502
#define TFT_WIDTH 410
#define TFT_OFFSET_X 22
#define TFT_OFFSET_Y 0
#define TFT_OFFSET_ROTATION 0
#define SCREEN_TRANSITION_FRAMERATE 5 // fps
#define HAS_TOUCHSCREEN 1
#define SCREEN_TOUCH_INT 12
#define TOUCH_I2C_PORT 0
#define TOUCH_SLAVE_ADDRESS 0x1A
#define WAKE_ON_TOUCH
#define BUTTON_PIN 0
#define USE_POWERSAVE
#define SLEEP_TIME 120
// External expansion chip XL9555
#define USE_XL9555
// MAX98357A
#define HAS_I2S
#define DAC_I2S_BCK 9
#define DAC_I2S_WS 10
#define DAC_I2S_DOUT 11
#define DAC_I2S_MCLK 0 // TODO
#define HAS_AXP2101
// #define PMU_IRQ 7
#define HAS_RTC 1
#define HAS_DRV2605 1
#define I2C_SDA 3
#define I2C_SCL 2
#define I2C_NO_RESCAN
#define HAS_GPS 1
#define GPS_BAUDRATE 38400
#define GPS_RX_PIN 44
#define GPS_TX_PIN 43
#define PIN_GPS_PPS 13
// SPI interface SD card slot
#define SPI_MOSI MOSI
#define SPI_SCK SCK
#define SPI_MISO MISO
#define SPI_CS 21
#define SD_SPI_FREQUENCY 75000000U
#define USE_SX1262
// #define USE_SX1280
#define LORA_SCK 35
#define LORA_MISO 33
#define LORA_MOSI 34
#define LORA_CS 36
#define LORA_DIO0 -1 // a No connect on the SX1262 module
#define LORA_RESET 47
#define LORA_DIO1 14 // SX1262 IRQ
#define LORA_DIO2 48 // SX1262 BUSY
#define LORA_DIO3
#define SX126X_CS LORA_CS
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#define USE_VIRTUAL_KEYBOARD 1
#define DISPLAY_CLOCK_FRAME 1

View File

@ -70,6 +70,9 @@
#define DAC_I2S_DIN 17 #define DAC_I2S_DIN 17
#define DAC_I2S_MCLK 10 #define DAC_I2S_MCLK 10
// haptic driver
#define HAS_DRV2605 1
// gyroscope BHI260AP // gyroscope BHI260AP
#define HAS_BHI260AP #define HAS_BHI260AP