Compare commits
42
Commits
develop
...
t-watch-ultra
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7de19ae1fd | ||
|
|
7dbf7ed32d | ||
|
|
da5ed9f6e9 | ||
|
|
7808c81649 | ||
|
|
352a97d81c | ||
|
|
519bd4994d | ||
|
|
7980dd2cdb | ||
|
|
2be14eb6c7 | ||
|
|
31b38630f7 | ||
|
|
2d37a58959 | ||
|
|
293b86013f | ||
|
|
97824c6ba0 | ||
|
|
fe45e5fde6 | ||
|
|
d4514cff62 | ||
|
|
db4a097303 | ||
|
|
dc212b08ac | ||
|
|
93f05406c4 | ||
|
|
147299e44f | ||
|
|
bd7ebd946a | ||
|
|
e4314904be | ||
|
|
42a20016d9 | ||
|
|
6015b05c09 | ||
|
|
083c65e42b | ||
|
|
b38cbf9a40 | ||
|
|
ad819321f7 | ||
|
|
3529c0bce2 | ||
|
|
8ee5407db5 | ||
|
|
65d4adb7c2 | ||
|
|
0cda4eb675 | ||
|
|
7763469c62 | ||
|
|
f158964d5e | ||
|
|
a8af68844c | ||
|
|
e8153ca6c2 | ||
|
|
b905766c6a | ||
|
|
9f8311ffd5 | ||
|
|
efd2ca9c06 | ||
|
|
19e62b8686 | ||
|
|
fb46938582 | ||
|
|
4776631ba8 | ||
|
|
295b8b6db5 | ||
|
|
82123b1519 | ||
|
|
d5bb3db4ed |
@@ -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=1",
|
||||
"-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"
|
||||
}
|
||||
+46
-2
@@ -1063,8 +1063,10 @@ int32_t Power::runOnce()
|
||||
// cancel action also turns the screen on and off.
|
||||
if (PMU->isPekeyShortPressIrq()) {
|
||||
LOG_INFO("Input: Corona Button Click");
|
||||
InputEvent event = {.inputEvent = (input_broker_event)INPUT_BROKER_CANCEL, .kbchar = 0, .touchX = 0, .touchY = 0};
|
||||
inputBroker->injectInputEvent(&event);
|
||||
if (inputBroker) {
|
||||
InputEvent event = {.inputEvent = (input_broker_event)INPUT_BROKER_CANCEL, .kbchar = 0, .touchX = 0, .touchY = 0};
|
||||
inputBroker->injectInputEvent(&event);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
@@ -1367,6 +1369,48 @@ bool Power::axpChipInit()
|
||||
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_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();
|
||||
}
|
||||
|
||||
// disable all axp chip interrupt
|
||||
|
||||
@@ -37,9 +37,9 @@ ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
|
||||
|
||||
ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
|
||||
{
|
||||
ScanI2C::DeviceType types[] = {MPU6050, LIS3DH, BMA423, LSM6DS3, BMX160, STK8BAXX,
|
||||
ICM20948, QMA6100P, BMM150, BMI270, ICM42607P, ISM330DHCX};
|
||||
return firstOfOrNONE(12, types);
|
||||
ScanI2C::DeviceType types[] = {MPU6050, LIS3DH, BMA423, LSM6DS3, BMX160, STK8BAXX, ICM20948,
|
||||
QMA6100P, BHI260AP, BMM150, BMI270, ICM42607P, ISM330DHCX};
|
||||
return firstOfOrNONE(13, types);
|
||||
}
|
||||
|
||||
ScanI2C::FoundDevice ScanI2C::firstMagnetometer() const
|
||||
|
||||
+2
-2
@@ -1279,8 +1279,8 @@ void GPS::setPowerPMU(bool on)
|
||||
} else if (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE) {
|
||||
// t-beam-s3-core GNSS power channel
|
||||
on ? PMU->enablePowerOutput(XPOWERS_ALDO4) : PMU->disablePowerOutput(XPOWERS_ALDO4);
|
||||
} else if (HW_VENDOR == meshtastic_HardwareModel_T_WATCH_S3) {
|
||||
// t-watch-s3-plus GNSS power channel
|
||||
} else if (HW_VENDOR == meshtastic_HardwareModel_T_WATCH_ULTRA || HW_VENDOR == meshtastic_HardwareModel_T_WATCH_S3) {
|
||||
// t-watch-ultra / t-watch-s3-plus GNSS power channel
|
||||
on ? PMU->enablePowerOutput(XPOWERS_BLDO1) : PMU->disablePowerOutput(XPOWERS_BLDO1);
|
||||
}
|
||||
} else if (model == XPOWERS_AXP192) {
|
||||
|
||||
@@ -512,7 +512,8 @@ Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_O
|
||||
LOG_INFO("SSD1306 init success");
|
||||
}
|
||||
#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(HACKADAY_COMMUNICATOR)
|
||||
defined(RAK14014) || defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST7796_CS) || defined(CO5300_CS) || \
|
||||
defined(HACKADAY_COMMUNICATOR)
|
||||
dispdev = new TFTDisplay(address.address, -1, -1, geometry,
|
||||
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
|
||||
#elif defined(USE_EINK) && !defined(USE_EINK_DYNAMICDISPLAY) && !defined(USE_EINK_PARALLELDISPLAY)
|
||||
@@ -586,12 +587,12 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver)
|
||||
if (on) {
|
||||
LOG_INFO("Turn on screen");
|
||||
powerMon->setState(meshtastic_PowerMon_State_Screen_On);
|
||||
#ifdef T_WATCH_S3
|
||||
#if defined(T_WATCH_S3) || defined(T_WATCH_ULTRA)
|
||||
PMU->enablePowerOutput(XPOWERS_ALDO2);
|
||||
#endif
|
||||
|
||||
// some screens seem to need a kick in the pants to turn back on
|
||||
#if defined(MUZI_BASE) || defined(M5STACK_CARDPUTER_ADV)
|
||||
#if defined(MUZI_BASE) || defined(M5STACK_CARDPUTER_ADV) || defined(TFT_RESET_AFTER_SLEEP)
|
||||
dispdev->init();
|
||||
dispdev->setBrightness(brightness);
|
||||
dispdev->flipScreenVertically();
|
||||
@@ -716,7 +717,7 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef T_WATCH_S3
|
||||
#if defined(T_WATCH_S3) // on T_WATCH_ULTRA, powering down this pin seems to goober the i2c bus.
|
||||
PMU->disablePowerOutput(XPOWERS_ALDO2);
|
||||
#endif
|
||||
enabled = false;
|
||||
@@ -848,7 +849,8 @@ void Screen::setup()
|
||||
#else
|
||||
if (!config.display.flip_screen) {
|
||||
#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(HACKADAY_COMMUNICATOR)
|
||||
defined(RAK14014) || defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST7796_CS) || defined(CO5300_CS) || \
|
||||
defined(HACKADAY_COMMUNICATOR)
|
||||
static_cast<TFTDisplay *>(dispdev)->flipScreenVertically();
|
||||
#elif defined(USE_ST7789)
|
||||
static_cast<ST7789Spi *>(dispdev)->flipScreenVertically();
|
||||
@@ -886,7 +888,7 @@ void Screen::setup()
|
||||
touchScreenImpl1->init();
|
||||
}
|
||||
}
|
||||
#elif HAS_TOUCHSCREEN && !defined(USE_EINK) && !HAS_CST226SE
|
||||
#elif HAS_TOUCHSCREEN && !defined(USE_EINK) && !HAS_CST226SE && !VARIANT_TOUCHSCREEN
|
||||
touchScreenImpl1 =
|
||||
new TouchScreenImpl1(dispdev->getWidth(), dispdev->getHeight(), static_cast<TFTDisplay *>(dispdev)->getTouch);
|
||||
touchScreenImpl1->init();
|
||||
|
||||
@@ -271,6 +271,9 @@ class Screen : public concurrency::OSThread
|
||||
// FIXME: Needs refactoring and getMacAddr needs to be moved to a utility class
|
||||
char ourId[5];
|
||||
|
||||
// if we have a step counter, this stores the number of steps.
|
||||
uint32_t steps = 0;
|
||||
|
||||
/// Initializes the UI, turns on the display, starts showing boot screen.
|
||||
//
|
||||
// Not thread safe - must be called before any other methods are called.
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
|
||||
#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(USE_ST7796) || defined(HACKADAY_COMMUNICATOR)) && \
|
||||
defined(CO5300_CS) || defined(HACKADAY_COMMUNICATOR) || defined(USE_ST7796)) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
// The screen is bigger so use bigger fonts
|
||||
#define FONT_SMALL FONT_MEDIUM_LOCAL // Height: 19
|
||||
|
||||
+141
-5
@@ -16,6 +16,92 @@
|
||||
extern SX1509 gpioExtender;
|
||||
#endif
|
||||
|
||||
#ifdef TFT_MESH_OVERRIDE
|
||||
uint16_t TFT_MESH = TFT_MESH_OVERRIDE;
|
||||
#else
|
||||
uint16_t TFT_MESH = COLOR565(0x67, 0xEA, 0x94);
|
||||
#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 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(20);
|
||||
lgfx::gpio_lo(CO5300_RESET);
|
||||
delay(30);
|
||||
lgfx::gpio_hi(CO5300_RESET);
|
||||
delay(20);
|
||||
#endif
|
||||
return lgfx::LGFX_Device::init();
|
||||
}
|
||||
};
|
||||
|
||||
static LGFX *tft = nullptr;
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(ST7735S)
|
||||
#include <LovyanGFX.hpp> // Graphics and font library for ST7735 driver chip
|
||||
|
||||
@@ -1362,6 +1448,7 @@ void TFTDisplay::display(bool fromBlank)
|
||||
x_LastPixelUpdate = displayWidth - 1;
|
||||
}
|
||||
|
||||
int y_offset = 0;
|
||||
// Step 3: Copy only the changed span into the pixel line buffer.
|
||||
for (x = x_FirstPixelUpdate; x <= x_LastPixelUpdate; x++) {
|
||||
isset = buffer[x + y_byteIndex] & y_byteMask;
|
||||
@@ -1376,13 +1463,58 @@ void TFTDisplay::display(bool fromBlank)
|
||||
linePixelBuffer[x] = isset ? colorTftWhite : colorTftBlack;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(CO5300_CS)
|
||||
uint8_t lines_updated = 2;
|
||||
if (y % 2 == 0) {
|
||||
y_byteIndex = ((y + 1) / 8) * displayWidth;
|
||||
y_byteMask = (1 << ((y + 1) & 7));
|
||||
uint32_t bufferIndex = 1;
|
||||
for (x = x_FirstPixelUpdate; x < x_LastPixelUpdate; x++) {
|
||||
isset = buffer[x + y_byteIndex] & y_byteMask;
|
||||
#if GRAPHICS_TFT_COLORING_ENABLED
|
||||
if (hasColorRegions) {
|
||||
linePixelBuffer[bufferIndex++ + x_LastPixelUpdate] = graphics::resolveTFTColorPixel(
|
||||
static_cast<int16_t>(x), static_cast<int16_t>(y), isset, colorTftWhite, colorTftBlack);
|
||||
} else {
|
||||
linePixelBuffer[bufferIndex++ + x_LastPixelUpdate] = isset ? colorTftWhite : colorTftBlack;
|
||||
}
|
||||
#else
|
||||
linePixelBuffer[bufferIndex++ + x_LastPixelUpdate] = isset ? colorTftWhite : colorTftBlack;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
y_offset = -1;
|
||||
memcpy(&linePixelBuffer[x_LastPixelUpdate + 1], &linePixelBuffer[x_FirstPixelUpdate],
|
||||
2 * (x_LastPixelUpdate - x_FirstPixelUpdate + 1));
|
||||
y_byteIndex = ((y - 1) / 8) * displayWidth;
|
||||
y_byteMask = (1 << ((y - 1) & 7));
|
||||
uint32_t bufferIndex = 0;
|
||||
for (x = x_FirstPixelUpdate; x < x_LastPixelUpdate; x++) {
|
||||
isset = buffer[x + y_byteIndex] & y_byteMask;
|
||||
#if GRAPHICS_TFT_COLORING_ENABLED
|
||||
if (hasColorRegions) {
|
||||
linePixelBuffer[bufferIndex++ + x_FirstPixelUpdate] = graphics::resolveTFTColorPixel(
|
||||
static_cast<int16_t>(x), static_cast<int16_t>(y), isset, colorTftWhite, colorTftBlack);
|
||||
} else {
|
||||
linePixelBuffer[bufferIndex++ + x_FirstPixelUpdate] = isset ? colorTftWhite : colorTftBlack;
|
||||
}
|
||||
#else
|
||||
linePixelBuffer[bufferIndex++ + x_FirstPixelUpdate] = isset ? colorTftWhite : colorTftBlack;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#else
|
||||
uint8_t lines_updated = 1;
|
||||
#endif
|
||||
|
||||
#if defined(HACKADAY_COMMUNICATOR)
|
||||
tft->draw16bitBeRGBBitmap(x_FirstPixelUpdate, y, &linePixelBuffer[x_FirstPixelUpdate],
|
||||
(x_LastPixelUpdate - x_FirstPixelUpdate + 1), 1);
|
||||
#else
|
||||
// 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.
|
||||
tft->pushImage(x_FirstPixelUpdate, y, (x_LastPixelUpdate - x_FirstPixelUpdate + 1), 1,
|
||||
tft->pushImage(x_FirstPixelUpdate, y + y_offset, (x_LastPixelUpdate - x_FirstPixelUpdate + 1), lines_updated,
|
||||
&linePixelBuffer[x_FirstPixelUpdate]);
|
||||
#endif
|
||||
somethingChanged = true;
|
||||
@@ -1450,7 +1582,7 @@ void TFTDisplay::sendCommand(uint8_t com)
|
||||
// handle display on/off directly
|
||||
switch (com) {
|
||||
case DISPLAYON: {
|
||||
// LOG_DEBUG("Display on");
|
||||
LOG_DEBUG("Display on");
|
||||
backlightEnable->set(true);
|
||||
#if ARCH_PORTDUINO
|
||||
display(true);
|
||||
@@ -1478,7 +1610,7 @@ void TFTDisplay::sendCommand(uint8_t com)
|
||||
break;
|
||||
}
|
||||
case DISPLAYOFF: {
|
||||
// LOG_DEBUG("Display off");
|
||||
LOG_DEBUG("Display off");
|
||||
backlightEnable->set(false);
|
||||
#if ARCH_PORTDUINO
|
||||
tft->clear();
|
||||
@@ -1581,8 +1713,8 @@ bool TFTDisplay::connect()
|
||||
tft = new LGFX;
|
||||
#endif
|
||||
|
||||
backlightEnable->set(true);
|
||||
LOG_INFO("Power to TFT Backlight");
|
||||
backlightEnable->set(true);
|
||||
|
||||
#ifdef UNPHONE
|
||||
unphone.backlight(true); // using unPhone library
|
||||
@@ -1610,7 +1742,7 @@ bool TFTDisplay::connect()
|
||||
tft->setRotation(1); // T-Deck has the TFT in landscape
|
||||
#elif defined(T_WATCH_S3)
|
||||
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
|
||||
#else
|
||||
tft->setRotation(3); // Orient horizontal and wide underneath the silkscreen name label
|
||||
@@ -1618,7 +1750,11 @@ bool TFTDisplay::connect()
|
||||
tft->fillScreen(getThemeDefaultOffColor());
|
||||
|
||||
if (this->linePixelBuffer == NULL) {
|
||||
#if defined(CO5300_CS)
|
||||
this->linePixelBuffer = (uint16_t *)malloc(sizeof(uint16_t) * displayWidth * 2);
|
||||
#else
|
||||
this->linePixelBuffer = (uint16_t *)malloc(sizeof(uint16_t) * displayWidth);
|
||||
#endif
|
||||
|
||||
if (!this->linePixelBuffer) {
|
||||
LOG_ERROR("Not enough memory to create TFT line buffer\n");
|
||||
|
||||
@@ -99,7 +99,7 @@ void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16
|
||||
(storeForwardModule->heartbeatInterval * 1200))) { // no heartbeat, overlap a bit
|
||||
#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(HACKADAY_COMMUNICATOR) || defined(USE_ST7796) || ARCH_PORTDUINO) && \
|
||||
defined(CO5300_CS) || defined(HACKADAY_COMMUNICATOR) || defined(USE_ST7796) || ARCH_PORTDUINO) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(screen->ourId), y + 3 + FONT_HEIGHT_SMALL, 12,
|
||||
8, imgQuestionL1);
|
||||
@@ -112,7 +112,7 @@ void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16
|
||||
} else {
|
||||
#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(HACKADAY_COMMUNICATOR) || defined(USE_ST7796)) && \
|
||||
defined(CO5300_CS) || defined(HACKADAY_COMMUNICATOR) || defined(USE_ST7796)) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(screen->ourId), y + 3 + FONT_HEIGHT_SMALL, 16,
|
||||
8, imgSFL1);
|
||||
@@ -128,7 +128,7 @@ void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16
|
||||
// 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) || \
|
||||
defined(ST7789_CS) || defined(USE_ST7789) || defined(ILI9488_CS) || defined(HX8357_CS) || defined(ST7796_CS) || \
|
||||
defined(HACKADAY_COMMUNICATOR) || defined(USE_ST7796) || ARCH_PORTDUINO) && \
|
||||
defined(CO5300_CS) || defined(HACKADAY_COMMUNICATOR) || defined(USE_ST7796) || ARCH_PORTDUINO) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(screen->ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
|
||||
imgInfoL1);
|
||||
|
||||
@@ -719,7 +719,7 @@ 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) || \
|
||||
defined(ST7789_CS) || defined(USE_ST7789) || defined(ILI9488_CS) || defined(HX8357_CS) || defined(ST7796_CS) || \
|
||||
defined(HACKADAY_COMMUNICATOR) || defined(USE_ST7796)) && \
|
||||
defined(CO5300_CS) || defined(HACKADAY_COMMUNICATOR) || defined(USE_ST7796)) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
|
||||
if (currentResolution == ScreenResolution::High) {
|
||||
@@ -1304,6 +1304,13 @@ void UIRenderer::drawDeviceFocused(OLEDDisplay *display, OLEDDisplayUiState *sta
|
||||
UIRenderer::drawStringWithEmotes(display, nameX, getTextPositions(display)[line++], shortName, FONT_HEIGHT_SMALL, 1,
|
||||
false);
|
||||
}
|
||||
#ifdef SHOW_STEP_COUNTER
|
||||
std::string stepsLine = "Steps: " + std::to_string(screen->steps);
|
||||
textWidth = UIRenderer::measureStringWithEmotes(display, stepsLine.c_str());
|
||||
nameX = (SCREEN_WIDTH - textWidth) / 2;
|
||||
UIRenderer::drawStringWithEmotes(display, nameX, getTextPositions(display)[line++], stepsLine.c_str(), FONT_HEIGHT_SMALL, 1,
|
||||
false);
|
||||
#endif
|
||||
#endif
|
||||
graphics::drawCommonFooter(display, x, y);
|
||||
}
|
||||
|
||||
@@ -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) || \
|
||||
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST7796_CS) || \
|
||||
defined(USE_ST7796) || defined(HACKADAY_COMMUNICATOR) || ARCH_PORTDUINO) && \
|
||||
defined(USE_ST7796) || defined(CO5300_CS) || defined(HACKADAY_COMMUNICATOR) || ARCH_PORTDUINO) && \
|
||||
!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 imgQuestionL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f};
|
||||
|
||||
@@ -66,8 +66,14 @@ void TouchScreenBase::init(bool hasTouch)
|
||||
|
||||
int32_t TouchScreenBase::runOnce()
|
||||
{
|
||||
uint32_t nowMs = millis();
|
||||
if (nowMs - _lastRun < 20) { // suppress too fast consecutive runOnce() executions
|
||||
return 20;
|
||||
}
|
||||
_lastRun = nowMs;
|
||||
TouchEvent e;
|
||||
e.touchEvent = static_cast<char>(TOUCH_ACTION_NONE);
|
||||
this->setInterval(TOUCH_POLL_INTERVAL_IDLE);
|
||||
const bool fastTapMode = fastTapModeEnabled();
|
||||
const bool allowLongPress = longPressEnabled();
|
||||
|
||||
@@ -186,7 +192,7 @@ int32_t TouchScreenBase::runOnce()
|
||||
|
||||
void TouchScreenBase::hapticFeedback()
|
||||
{
|
||||
#ifdef T_WATCH_S3
|
||||
#if defined(T_WATCH_S3) || defined(T_WATCH_ULTRA)
|
||||
drv.setWaveform(0, 75);
|
||||
drv.setWaveform(1, 0); // end waveform
|
||||
drv.go();
|
||||
|
||||
@@ -53,6 +53,7 @@ class TouchScreenBase : public Observable<const InputEvent *>, public concurrenc
|
||||
time_t _start; // for LONG_PRESS
|
||||
uint32_t _lastTouchSeenMs; // helps suppress brief touch-controller dropouts
|
||||
bool _tapped; // for DOUBLE_TAP
|
||||
uint32_t _lastRun = 0; // helps suppress too fast consecutive runOnce() executions
|
||||
|
||||
const char *_originName;
|
||||
};
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
#include "InputBroker.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include "modules/ExternalNotificationModule.h"
|
||||
#include "sleep.h"
|
||||
#include <cstring>
|
||||
|
||||
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
@@ -16,6 +18,27 @@
|
||||
|
||||
TouchScreenImpl1 *touchScreenImpl1;
|
||||
|
||||
// Hardware-interrupt wake on the touch IRQ line. Scoped to T-Watch Ultra: other touch boards
|
||||
// either drive this pin differently (RAK14014 already owns this interrupt in TFTDisplay) or
|
||||
// route it through an IO expander, which can't be used with attachInterrupt().
|
||||
#if defined(SCREEN_TOUCH_INT) && defined(T_WATCH_ULTRA)
|
||||
#define TOUCHSCREEN_HAS_INTERRUPT 1
|
||||
|
||||
// The touch controller pulls SCREEN_TOUCH_INT low when a new touch begins. Wake the polling
|
||||
// thread immediately so the touch is handled without waiting for the next idle poll. The
|
||||
// periodic poll in TouchScreenBase::runOnce() remains as a fallback. Mirrors the button
|
||||
// interrupt handling in ButtonThread/InputBroker.
|
||||
static void touchScreenInterruptHandler()
|
||||
{
|
||||
if (touchScreenImpl1) {
|
||||
touchScreenImpl1->setIntervalFromNow(0);
|
||||
runASAP = true;
|
||||
BaseType_t higherWake = 0;
|
||||
concurrency::mainDelay.interruptFromISR(&higherWake);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TouchScreenImpl1::TouchScreenImpl1(uint16_t width, uint16_t height, bool (*getTouch)(int16_t *, int16_t *))
|
||||
: TouchScreenBase("touchscreen1", width, height), _getTouch(getTouch)
|
||||
{
|
||||
@@ -27,6 +50,7 @@ void TouchScreenImpl1::init()
|
||||
if (portduino_config.touchscreenModule) {
|
||||
TouchScreenBase::init(true);
|
||||
inputBroker->registerSource(this);
|
||||
attachTouchInterrupt();
|
||||
} else {
|
||||
TouchScreenBase::init(false);
|
||||
}
|
||||
@@ -37,9 +61,46 @@ void TouchScreenImpl1::init()
|
||||
TouchScreenBase::init(true);
|
||||
if (inputBroker)
|
||||
inputBroker->registerSource(this);
|
||||
attachTouchInterrupt();
|
||||
#endif
|
||||
|
||||
#if defined(TOUCHSCREEN_HAS_INTERRUPT) && defined(ARCH_ESP32)
|
||||
// Detach/reattach our interrupt around light sleep, so sleep.cpp can configure the touch
|
||||
// pin as a wake source without our handler interfering.
|
||||
lsObserver.observe(¬ifyLightSleep);
|
||||
lsEndObserver.observe(¬ifyLightSleepEnd);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Attach the touch-controller IRQ so a new touch wakes the polling thread immediately.
|
||||
// No-op on boards without a usable touch interrupt line.
|
||||
void TouchScreenImpl1::attachTouchInterrupt()
|
||||
{
|
||||
#ifdef TOUCHSCREEN_HAS_INTERRUPT
|
||||
pinMode(SCREEN_TOUCH_INT, INPUT_PULLUP);
|
||||
attachInterrupt(SCREEN_TOUCH_INT, touchScreenInterruptHandler, FALLING);
|
||||
LOG_INFO("TouchScreen interrupt attached on pin %d", SCREEN_TOUCH_INT);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
// Detach our interrupt before light sleep; sleep.cpp configures its own wake-on-touch.
|
||||
int TouchScreenImpl1::beforeLightSleep(void *unused)
|
||||
{
|
||||
#ifdef TOUCHSCREEN_HAS_INTERRUPT
|
||||
detachInterrupt(SCREEN_TOUCH_INT);
|
||||
#endif
|
||||
return 0; // Indicates success
|
||||
}
|
||||
|
||||
// Reattach our interrupt after waking from light sleep.
|
||||
int TouchScreenImpl1::afterLightSleep(esp_sleep_wakeup_cause_t cause)
|
||||
{
|
||||
attachTouchInterrupt();
|
||||
return 0; // Indicates success
|
||||
}
|
||||
#endif
|
||||
|
||||
bool TouchScreenImpl1::getTouch(int16_t &x, int16_t &y)
|
||||
{
|
||||
return _getTouch(&x, &y);
|
||||
|
||||
@@ -13,7 +13,23 @@ class TouchScreenImpl1 : public TouchScreenBase
|
||||
bool fastTapModeEnabled() const override;
|
||||
bool longPressEnabled() const override;
|
||||
|
||||
// Attach/detach a hardware interrupt on the touch IRQ pin (SCREEN_TOUCH_INT) so a new touch
|
||||
// wakes the polling thread immediately. No-op on boards without a usable touch interrupt line.
|
||||
void attachTouchInterrupt();
|
||||
|
||||
bool (*_getTouch)(int16_t *, int16_t *);
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
// Detach the touch interrupt before light sleep (so sleep.cpp can own the wake config),
|
||||
// and reattach it afterwards. Mirrors ButtonThread's interrupt handling.
|
||||
int beforeLightSleep(void *unused);
|
||||
int afterLightSleep(esp_sleep_wakeup_cause_t cause);
|
||||
|
||||
CallbackObserver<TouchScreenImpl1, void *> lsObserver =
|
||||
CallbackObserver<TouchScreenImpl1, void *>(this, &TouchScreenImpl1::beforeLightSleep);
|
||||
CallbackObserver<TouchScreenImpl1, esp_sleep_wakeup_cause_t> lsEndObserver =
|
||||
CallbackObserver<TouchScreenImpl1, esp_sleep_wakeup_cause_t>(this, &TouchScreenImpl1::afterLightSleep);
|
||||
#endif
|
||||
};
|
||||
|
||||
extern TouchScreenImpl1 *touchScreenImpl1;
|
||||
|
||||
+5
-2
@@ -290,6 +290,9 @@ __attribute__((weak, noinline)) bool loopCanSleep()
|
||||
void lateInitVariant() __attribute__((weak));
|
||||
void lateInitVariant() {}
|
||||
|
||||
// NOTE: earlyInitVariant() runs before consoleInit(), so the logging subsystem isn't set
|
||||
// up yet. Calling a LOG_* macro here CRASHES the device -- it is not a silent no-op. Do
|
||||
// not use them in earlyInitVariant(); defer any logging to lateInitVariant() or later.
|
||||
void earlyInitVariant() __attribute__((weak));
|
||||
void earlyInitVariant() {}
|
||||
|
||||
@@ -916,7 +919,7 @@ void setup()
|
||||
|
||||
#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(USE_SPISSD1306) || defined(USE_ST7796) || defined(HACKADAY_COMMUNICATOR)
|
||||
defined(USE_SPISSD1306) || defined(USE_ST7796) || defined(CO5300_CS) || defined(HACKADAY_COMMUNICATOR)
|
||||
screen = new graphics::Screen(screen_found, screen_model, screen_geometry);
|
||||
#elif defined(ARCH_PORTDUINO)
|
||||
if ((screen_found.port != ScanI2C::I2CPort::NO_I2C || portduino_config.displayPanel) &&
|
||||
@@ -1042,7 +1045,7 @@ void setup()
|
||||
// the current region name)
|
||||
#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(USE_ST7796) || defined(USE_SPISSD1306) || defined(HACKADAY_COMMUNICATOR)
|
||||
defined(USE_ST7796) || defined(USE_SPISSD1306) || defined(CO5300_CS) || defined(HACKADAY_COMMUNICATOR)
|
||||
if (screen)
|
||||
screen->setup();
|
||||
#elif defined(ARCH_PORTDUINO)
|
||||
|
||||
+2
-2
@@ -1006,7 +1006,7 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
|
||||
strncpy(config.network.ntp_server, "meshtastic.pool.ntp.org", 32);
|
||||
|
||||
#if (defined(T_DECK) || defined(T_WATCH_S3) || defined(UNPHONE) || defined(PICOMPUTER_S3) || defined(SENSECAP_INDICATOR) || \
|
||||
defined(ELECROW_PANEL) || defined(HELTEC_V4_TFT) || defined(HELTEC_V4_R8_TFT)) && \
|
||||
defined(ELECROW_PANEL) || defined(HELTEC_V4_TFT) || defined(T_WATCH_ULTRA) || defined(HELTEC_V4_R8_TFT)) && \
|
||||
HAS_TFT
|
||||
// switch BT off by default; use TFT programming mode or hotkey to enable
|
||||
config.bluetooth.enabled = false;
|
||||
@@ -1092,7 +1092,7 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
|
||||
config.display.wake_on_tap_or_motion = true;
|
||||
#endif
|
||||
|
||||
#if defined(T_WATCH_S3) || defined(SENSECAP_INDICATOR)
|
||||
#if defined(T_WATCH_S3) || defined(SENSECAP_INDICATOR) || defined(T_WATCH_ULTRA)
|
||||
config.display.screen_on_secs = 30;
|
||||
config.display.wake_on_tap_or_motion = true;
|
||||
#endif
|
||||
|
||||
@@ -70,7 +70,7 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
|
||||
if (config.position.fixed_position) {
|
||||
LOG_DEBUG("Ignore incoming position update from myself except for time, because position.fixed_position is true");
|
||||
|
||||
#ifdef T_WATCH_S3
|
||||
#if defined(T_WATCH_S3) || defined(T_WATCH_ULTRA)
|
||||
// Since we return early if position.fixed_position is true, set the T-Watch's RTC to the time received from the
|
||||
// client device here
|
||||
if (p.time && channels.getByIndex(mp.channel).role == meshtastic_Channel_Role_PRIMARY) {
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
#ifdef HAS_STK8XXX
|
||||
#include "STK8XXXSensor.h"
|
||||
#endif
|
||||
#ifdef HAS_BHI260AP
|
||||
#include "BHI260APSensor.h"
|
||||
#endif
|
||||
|
||||
extern ScanI2C::DeviceAddress accelerometer_found;
|
||||
|
||||
@@ -139,6 +142,11 @@ class AccelerometerThread : public concurrency::OSThread
|
||||
case ScanI2C::DeviceType::QMA6100P:
|
||||
sensor = new QMA6100PSensor(device);
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAS_BHI260AP
|
||||
case ScanI2C::DeviceType::BHI260AP:
|
||||
sensor = new BHI260APSensor(device);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
disable();
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
#include "BHI260APSensor.h"
|
||||
|
||||
#if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && defined(HAS_BHI260AP) && __has_include(<SensorBHI260AP.hpp>)
|
||||
#define BOSCH_BHI260_KLIO
|
||||
#define USING_DATA_HELPER
|
||||
|
||||
#include <BoschFirmware.h>
|
||||
BHI260APSensor::BHI260APSensor(ScanI2C::FoundDevice foundDevice) : MotionSensor::MotionSensor(foundDevice) {}
|
||||
// https://github.com/lewisxhe/SensorLib/blob/master/examples/Sensors/IMU/BHI260AP_InterruptSettings/BHI260AP_InterruptSettings.ino
|
||||
|
||||
bool BHI260APSensor::init()
|
||||
{
|
||||
LOG_WARN("Initializing BHI260AP sensor %u", deviceAddress());
|
||||
sensor.setFirmware(bosch_firmware_image, bosch_firmware_size, bosch_firmware_type);
|
||||
sensor.setBootFromFlash(bosch_firmware_type);
|
||||
if (sensor.begin(Wire, deviceAddress())) {
|
||||
sensor.setRemapAxes(SensorBHI260AP::TOP_LAYER_BOTTOM_RIGHT_CORNER);
|
||||
BoschSensorInfo info = sensor.getSensorInfo();
|
||||
|
||||
LOG_INFO("Product ID : %02x\n", info.product_id);
|
||||
LOG_INFO("Kernel version : %04u\n", info.kernel_version);
|
||||
LOG_INFO("User version : %04u\n", info.user_version);
|
||||
LOG_INFO("ROM version : %04u\n", info.rom_version);
|
||||
LOG_INFO("Power state : %s\n", (info.host_status & BHY2_HST_POWER_STATE) ? "sleeping" : "active");
|
||||
LOG_INFO("Host interface : %s\n", (info.host_status & BHY2_HST_HOST_PROTOCOL) ? "SPI" : "I2C");
|
||||
LOG_INFO("Feature status : 0x%02x\n", info.feat_status);
|
||||
|
||||
stepCounter = new SensorStepCounter(sensor);
|
||||
// stepDetector = new SensorStepDetector(sensor);
|
||||
|
||||
// sensor.configAccelerometer(sensor.RANGE_2G, sensor.ODR_100HZ, sensor.BW_NORMAL_AVG4, sensor.PERF_CONTINUOUS_MODE);
|
||||
// sensor.enableAccelerometer();
|
||||
// sensor.configInterrupt();
|
||||
|
||||
#ifdef BHI260AP_INT
|
||||
pinMode(BHI260AP_INT, INPUT);
|
||||
attachInterrupt(
|
||||
BHI260AP_INT,
|
||||
[] {
|
||||
// Set interrupt to set irq value to true
|
||||
},
|
||||
RISING); // Select the interrupt mode according to the actual circuit
|
||||
#endif
|
||||
|
||||
#ifdef T_WATCH_S3
|
||||
// Need to raise the wrist function, need to set the correct axis
|
||||
sensor.setRemapAxes(sensor.REMAP_TOP_LAYER_RIGHT_CORNER);
|
||||
#else
|
||||
// sensor.setRemapAxes(sensor.REMAP_BOTTOM_LAYER_BOTTOM_LEFT_CORNER);
|
||||
#endif
|
||||
|
||||
// stepDetector->enable(1.0, 0);
|
||||
stepCounter->enable(1.0, 0);
|
||||
LOG_DEBUG("BHI260AP init ok");
|
||||
return true;
|
||||
}
|
||||
LOG_DEBUG("BHI260AP init failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t BHI260APSensor::runOnce()
|
||||
{
|
||||
sensor.update();
|
||||
if (stepCounter->hasUpdated()) {
|
||||
steps = stepCounter->getStepCount();
|
||||
LOG_WARN("Step count updated: %u", steps);
|
||||
if (screen)
|
||||
screen->steps = steps;
|
||||
}
|
||||
// LOG_WARN("Step count: %u", stepCounter->getStepCount());
|
||||
// if (sensor.readIrqStatus()) {
|
||||
// if (sensor.isTilt() || sensor.isDoubleTap()) {
|
||||
// wakeScreen();
|
||||
// return 500;
|
||||
// }
|
||||
//}
|
||||
return 1000;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
#ifndef _BHI260AP_SENSOR_H_
|
||||
#define _BHI260AP_SENSOR_H_
|
||||
|
||||
#include "MotionSensor.h"
|
||||
|
||||
#if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && defined(HAS_BHI260AP) && __has_include(<SensorBHI260AP.hpp>)
|
||||
|
||||
// Sensor lib
|
||||
#include <SensorBHI260AP.hpp>
|
||||
#include <Wire.h>
|
||||
#include <bosch/BoschSensorDataHelper.hpp>
|
||||
|
||||
class BHI260APSensor : public MotionSensor
|
||||
{
|
||||
private:
|
||||
SensorBHI260AP sensor;
|
||||
volatile bool BHI_IRQ = false;
|
||||
SensorStepCounter *stepCounter;
|
||||
SensorStepDetector *stepDetector;
|
||||
uint32_t steps = 0;
|
||||
|
||||
public:
|
||||
explicit BHI260APSensor(ScanI2C::FoundDevice foundDevice);
|
||||
virtual bool init() override;
|
||||
virtual int32_t runOnce() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -206,6 +206,8 @@
|
||||
#define HW_VENDOR meshtastic_HardwareModel_M5STACK_C6L
|
||||
#elif defined(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
|
||||
#elif defined(M5STACK_CARDPUTER_ADV)
|
||||
#define HW_VENDOR meshtastic_HardwareModel_M5STACK_CARDPUTER_ADV
|
||||
#else
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
// Workaround for the IDF 5.5 manual esp_flash read regression on t-watch-ultra.
|
||||
//
|
||||
// On this board (Winbond W25Q128JW, ef:8018), the IDF 5.5 *direct* flash read path
|
||||
// (esp_flash_read / esp_partition_read) returns 0x00 for data that is physically
|
||||
// correct on flash. We proved the *memory-mapped* (cache) read returns the right
|
||||
// data, writes work, and it's not read-mode/HPM/timing-tuning/PSRAM. So route every
|
||||
// esp_partition_read through esp_partition_mmap + memcpy, which uses the working
|
||||
// cache path. Activated by `-Wl,--wrap=esp_partition_read` (t-watch-ultra only).
|
||||
#if defined(T_WATCH_ULTRA)
|
||||
|
||||
#include "esp_partition.h"
|
||||
#include <string.h>
|
||||
|
||||
extern esp_err_t __real_esp_partition_read(const esp_partition_t *partition, size_t src_offset, void *dst, size_t size);
|
||||
|
||||
esp_err_t __wrap_esp_partition_read(const esp_partition_t *partition, size_t src_offset, void *dst, size_t size)
|
||||
{
|
||||
if (partition == NULL || dst == NULL)
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
if (size == 0)
|
||||
return ESP_OK;
|
||||
|
||||
// mmap requires a 64KB-aligned start; map the containing page span and copy
|
||||
// out from the requested offset.
|
||||
const size_t PAGE = 0x10000;
|
||||
size_t aligned = src_offset & ~(PAGE - 1);
|
||||
size_t delta = src_offset - aligned;
|
||||
|
||||
const void *ptr = NULL;
|
||||
esp_partition_mmap_handle_t handle;
|
||||
esp_err_t err = esp_partition_mmap(partition, aligned, delta + size, ESP_PARTITION_MMAP_DATA, &ptr, &handle);
|
||||
if (err != ESP_OK) {
|
||||
// Encrypted partitions / regions mmap can't serve: fall back to the real
|
||||
// read (may be wrong on this board, but better than failing the call).
|
||||
return __real_esp_partition_read(partition, src_offset, dst, size);
|
||||
}
|
||||
memcpy(dst, (const uint8_t *)ptr + delta, size);
|
||||
esp_partition_munmap(handle);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#endif // T_WATCH_ULTRA
|
||||
@@ -7,6 +7,8 @@ This directory tree is designed to solve two problems.
|
||||
|
||||
So we are borrowing the initVariant() ideas here (by using weak gcc references). You can now define earlyInitVariant() and lateInitVariant() if your board needs them. earlyInitVariant() runs at the beginning of setup() directly after waitUntilPowerLevelSafe(); while lateInitVariant() runs after the LoRa radio is initialized.
|
||||
|
||||
**Important:** earlyInitVariant() runs _before_ consoleInit(), so the logging subsystem isn't set up yet. Calling a `LOG_*` macro there **crashes the device** — it is not a silent no-op. Never use `LOG_*` in earlyInitVariant(); defer any logging to lateInitVariant() or later.
|
||||
|
||||
If you'd like a board specific variant to be run, add the variant.cpp file to an appropriately named
|
||||
subdirectory and check for \_VARIANT_boardname in the cpp file (so that your code is only built for your board).
|
||||
You'll need to define \_VARIANT_boardname in your corresponding variant.h file.
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
#include "configuration.h"
|
||||
|
||||
#ifdef T_WATCH_ULTRA
|
||||
|
||||
// Board-specific init lives here (rather than in variants/esp32s3/t-watch-ultra/variant.cpp)
|
||||
// so that PlatformIO's library dependency finder can resolve headers such as
|
||||
// input/TouchScreenImpl1.h (which transitively pulls in the ArduinoThread "Thread.h"),
|
||||
// ExtensionIOXL9555.hpp and TouchDrvCSTXXX.hpp. Files compiled from outside src/ only get
|
||||
// include paths for libraries they reference directly, so the transitive Thread.h include
|
||||
// is not found there. See src/platform/extra_variants/README.md.
|
||||
|
||||
#include "TouchDrvCSTXXX.hpp"
|
||||
#include "input/TouchScreenImpl1.h"
|
||||
#include <ExtensionIOXL9555.hpp>
|
||||
#include <Wire.h>
|
||||
|
||||
static ExtensionIOXL9555 io;
|
||||
static TouchDrvCST92xx touchDrv;
|
||||
|
||||
void earlyInitVariant()
|
||||
{
|
||||
pinMode(LORA_CS, OUTPUT);
|
||||
digitalWrite(LORA_CS, HIGH);
|
||||
pinMode(DISP_CS, OUTPUT);
|
||||
digitalWrite(DISP_CS, HIGH);
|
||||
pinMode(SDCARD_CS, OUTPUT);
|
||||
digitalWrite(SDCARD_CS, HIGH);
|
||||
pinMode(NFC_CS, OUTPUT);
|
||||
digitalWrite(NFC_CS, HIGH);
|
||||
pinMode(I2C_SDA, INPUT_PULLUP);
|
||||
pinMode(I2C_SCL, INPUT_PULLUP);
|
||||
|
||||
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, LOW);
|
||||
delay(20);
|
||||
io.digitalWrite(EXPANDS_TOUCH_RST, HIGH);
|
||||
delay(60);
|
||||
io.pinMode(EXPANDS_LORA_RF_SW, OUTPUT);
|
||||
io.digitalWrite(EXPANDS_LORA_RF_SW, HIGH); // set RF switch to built-in LoRa antenna
|
||||
// io.pinMode(EXPANDS_SD_DET, INPUT);
|
||||
}
|
||||
// NOTE: deliberately no LOG_* on the io.begin() failure path. earlyInitVariant() runs
|
||||
// before consoleInit(), where calling a LOG_* macro crashes the device (see
|
||||
// extra_variants/README.md). On failure the EXPANDS_* pins stay on their defaults.
|
||||
}
|
||||
|
||||
static bool readTouch(int16_t *x, int16_t *y)
|
||||
{
|
||||
int16_t x_array[1], y_array[1];
|
||||
uint8_t touched = touchDrv.getPoint(x_array, y_array, 1);
|
||||
if (touched > 0) {
|
||||
*x = (x_array[0]);
|
||||
*y = (y_array[0]);
|
||||
// Check bounds
|
||||
if (*x < 0 || *x >= TFT_WIDTH || *y < 0 || *y >= TFT_HEIGHT) {
|
||||
return false;
|
||||
}
|
||||
return true; // Valid touch detected
|
||||
}
|
||||
return false; // No valid touch data
|
||||
}
|
||||
|
||||
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, -1, -1)) {
|
||||
touchScreenImpl1 = new TouchScreenImpl1(TFT_WIDTH, TFT_HEIGHT, readTouch);
|
||||
touchScreenImpl1->init();
|
||||
} else {
|
||||
LOG_ERROR("failed to initialize CST92xx");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+1
-1
@@ -361,7 +361,7 @@ void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false, bool skipSaveN
|
||||
// t-beam v1.2 radio power channel
|
||||
PMU->disablePowerOutput(XPOWERS_ALDO2); // lora radio power channel
|
||||
} else if (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE ||
|
||||
HW_VENDOR == meshtastic_HardwareModel_T_WATCH_S3) {
|
||||
HW_VENDOR == meshtastic_HardwareModel_T_WATCH_S3 || HW_VENDOR == meshtastic_HardwareModel_T_WATCH_ULTRA) {
|
||||
PMU->disablePowerOutput(XPOWERS_ALDO3); // lora radio power channel
|
||||
}
|
||||
} else if (model == XPOWERS_AXP192) {
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
// vibration motor
|
||||
#define PIN_VIBRATION 2
|
||||
#define HAS_DRV2605 1
|
||||
|
||||
// Have SPI interface SD card slot
|
||||
#define HAS_SDCARD
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
#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)
|
||||
#define EXPANDS_LORA_RF_SW (11)
|
||||
|
||||
// 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 */
|
||||
@@ -0,0 +1,77 @@
|
||||
; 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
|
||||
|
||||
custom_sdkconfig =
|
||||
${esp32s3_base.custom_sdkconfig}
|
||||
; Keep esp_littlefs buffers in internal RAM (off the shared-bus PSRAM).
|
||||
CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL=y
|
||||
CONFIG_SPI_FLASH_SHARE_SPI1_BUS=y
|
||||
|
||||
build_flags = ${esp32_base.build_flags} -Ivariants/esp32s3/t-watch-ultra
|
||||
; Route flash reads through the cache/mmap path (esp_partition_read_mmap_wrap.c)
|
||||
; to dodge the IDF 5.5 manual-read regression on this board's flash.
|
||||
-Wl,--wrap=esp_partition_read
|
||||
-D T_WATCH_ULTRA
|
||||
-D RADIOLIB_EXCLUDE_SX128X=1
|
||||
-D RADIOLIB_EXCLUDE_SX127X=1
|
||||
-D RADIOLIB_EXCLUDE_LR11X0=1
|
||||
-UMESHTASTIC_EXCLUDE_ACCELEROMETER
|
||||
; -D HAS_SDCARD
|
||||
-D SDCARD_CS=21
|
||||
; -DHAS_BMA423=1
|
||||
|
||||
build_src_filter =
|
||||
${esp32s3_base.build_src_filter}
|
||||
+<../variants/esp32s3/t-watch-ultra>
|
||||
|
||||
lib_deps = ${esp32s3_base.lib_deps}
|
||||
https://github.com/lovyan03/LovyanGFX/archive/tags/1.2.19.zip
|
||||
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 LGFX_AMOLED_ROUNDER=1
|
||||
-D LGFX_BUFSIZE=308732
|
||||
-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 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}
|
||||
@@ -0,0 +1,100 @@
|
||||
|
||||
// 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 USE_TFTDISPLAY 1
|
||||
#define HAS_SCREEN 1
|
||||
#define TFT_RESET_AFTER_SLEEP
|
||||
|
||||
#define HAS_TOUCHSCREEN 1
|
||||
#define VARIANT_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
|
||||
|
||||
// PCF85063 RTC Module
|
||||
#define PCF85063_RTC 0x51
|
||||
#define HAS_RTC 1
|
||||
|
||||
// MAX98357A
|
||||
#define HAS_I2S
|
||||
#define DAC_I2S_BCK 9
|
||||
#define DAC_I2S_WS 10
|
||||
#define DAC_I2S_DOUT 11
|
||||
#define DAC_I2S_MCLK -1 // TODO
|
||||
|
||||
#define HAS_AXP2101
|
||||
#define PMU_IRQ 7
|
||||
#define PMU_POWER_BUTTON_IS_CANCEL
|
||||
#define HAS_DRV2605 1
|
||||
|
||||
#define HAS_BHI260AP
|
||||
#define BHI260AP_INT 8
|
||||
#undef MESHTASTIC_EXCLUDE_ACCELEROMETER
|
||||
#define SHOW_STEP_COUNTER
|
||||
|
||||
#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 HW_SPI1_DEVICE
|
||||
|
||||
#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
|
||||
@@ -69,6 +69,9 @@
|
||||
#define DAC_I2S_DIN 17
|
||||
#define DAC_I2S_MCLK 10
|
||||
|
||||
// haptic driver
|
||||
#define HAS_DRV2605 1
|
||||
|
||||
// gyroscope BHI260AP
|
||||
#define HAS_BHI260AP
|
||||
|
||||
|
||||
Reference in New Issue
Block a user