diff --git a/.github/workflows/package_raspbian.yml b/.github/workflows/package_raspbian.yml
index dd4133dab..81ff6ee25 100644
--- a/.github/workflows/package_raspbian.yml
+++ b/.github/workflows/package_raspbian.yml
@@ -45,6 +45,7 @@ jobs:
- name: build .debpkg
run: |
+ mkdir -p .debpkg/debian
mkdir -p .debpkg/usr/share/doc/meshtasticd/web
mkdir -p .debpkg/usr/sbin
mkdir -p .debpkg/etc/meshtasticd
@@ -55,6 +56,7 @@ jobs:
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
chmod +x .debpkg/usr/sbin/meshtasticd
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
+ echo "etc/meshtasticd/config.yaml" > .debpkg/debian/conffiles
- uses: jiro4989/build-deb-action@v3
with:
diff --git a/arch/esp32/esp32s2.ini b/arch/esp32/esp32s2.ini
index 5de0fa549..df66de2ed 100644
--- a/arch/esp32/esp32s2.ini
+++ b/arch/esp32/esp32s2.ini
@@ -2,14 +2,17 @@
extends = esp32_base
build_src_filter =
- ${esp32_base.build_src_filter} - -
+ ${esp32_base.build_src_filter} - - -
monitor_speed = 115200
build_flags =
${esp32_base.build_flags}
-DHAS_BLUETOOTH=0
+ -DMESHTASTIC_EXCLUDE_PAXCOUNTER
+ -DMESHTASTIC_EXCLUDE_BLUETOOTH
lib_ignore =
${esp32_base.lib_ignore}
- NimBLE-Arduino
\ No newline at end of file
+ NimBLE-Arduino
+ libpax
\ No newline at end of file
diff --git a/arch/portduino/portduino.ini b/arch/portduino/portduino.ini
index 53f06c9f3..4857933ec 100644
--- a/arch/portduino/portduino.ini
+++ b/arch/portduino/portduino.ini
@@ -1,6 +1,6 @@
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
[portduino_base]
-platform = https://github.com/meshtastic/platform-native.git#6fb39b6f94ece9c042141edb4afb91aca94dcaab
+platform = https://github.com/meshtastic/platform-native.git#659e49346aa33008b150dfb206b1817ddabc7132
framework = arduino
build_src_filter =
@@ -24,7 +24,7 @@ lib_deps =
${env.lib_deps}
${networking_base.lib_deps}
rweather/Crypto@^0.4.0
- lovyan03/LovyanGFX@^1.1.12
+ https://github.com/lovyan03/LovyanGFX.git#d35e60f269dfecbb18a8cb0fd07d594c2fb7e7a8
build_flags =
${arduino_base.build_flags}
@@ -34,4 +34,4 @@ build_flags =
-DPORTDUINO_LINUX_HARDWARE
-lbluetooth
-lgpiod
- -lyaml-cpp
+ -lyaml-cpp
\ No newline at end of file
diff --git a/bin/config-dist.yaml b/bin/config-dist.yaml
index f729f1ac7..05b4a7b0a 100644
--- a/bin/config-dist.yaml
+++ b/bin/config-dist.yaml
@@ -38,6 +38,15 @@ Lora:
# Busy: 20
# Reset: 18
+# Module: sx1268 # SX1268-based modules, tested with Ebyte E22 400M33S
+# CS: 21
+# IRQ: 16
+# Busy: 20
+# Reset: 18
+# TXen: 6
+# RXen: 12
+# DIO3_TCXO_VOLTAGE: true
+
# DIO3_TCXO_VOLTAGE: true # the Waveshare Core1262 and others are known to need this setting
# TXen: x # TX and RX enable pins
@@ -96,17 +105,21 @@ Display:
# Panel: ILI9341
# CS: 8
# DC: 25
-# Backlight: 2
-# Width: 320
-# Height: 240
+# Width: 240
+# Height: 320
+# Rotate: true
Touchscreen:
### Note, at least for now, the touchscreen must have a CS pin defined, even if you let Linux manage the CS switching.
-# Module: STMPE610
+# Module: STMPE610 # Option 1 for Adafruit PiTFT 2.8
# CS: 7
# IRQ: 24
+# Module: FT5x06 # Option 2 for Adafruit PiTFT 2.8
+# IRQ: 24
+# I2CAddr: 0x38
+
# Module: XPT2046 # Waveshare 2.8inch
# CS: 7
# IRQ: 17
diff --git a/platformio.ini b/platformio.ini
index a1082a84a..e178fdb16 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -78,7 +78,7 @@ lib_deps =
https://github.com/meshtastic/esp8266-oled-ssd1306.git#ee628ee6c9588d4c56c9e3da35f0fc9448ad54a8 ; ESP8266_SSD1306
mathertel/OneButton@^2.5.0 ; OneButton library for non-blocking button debounce
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
- https://github.com/meshtastic/TinyGPSPlus.git#964f75a72cccd6b53cd74e4add1f7a42c6f7344d
+ https://github.com/meshtastic/TinyGPSPlus.git#71a82db35f3b973440044c476d4bcdc673b104f4
https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0
nanopb/Nanopb@^0.4.7
erriez/ErriezCRC32@^1.0.1
diff --git a/protobufs b/protobufs
index eade2c6be..e21899aa6 160000
--- a/protobufs
+++ b/protobufs
@@ -1 +1 @@
-Subproject commit eade2c6befb65a9c46c5d28ae1e8e24c37a1a3d0
+Subproject commit e21899aa6b2b49863cfa2758e5e3b6faacf04bba
diff --git a/src/AmbientLightingThread.h b/src/AmbientLightingThread.h
index 98ccedde4..6b3360b1f 100644
--- a/src/AmbientLightingThread.h
+++ b/src/AmbientLightingThread.h
@@ -5,6 +5,16 @@
NCP5623 rgb;
#endif
+#ifdef HAS_NEOPIXEL
+#include
+Adafruit_NeoPixel pixels(NEOPIXEL_COUNT, NEOPIXEL_DATA, NEOPIXEL_TYPE);
+#endif
+
+#ifdef UNPHONE
+#include "unPhone.h"
+extern unPhone unphone;
+#endif
+
namespace concurrency
{
class AmbientLightingThread : public concurrency::OSThread
@@ -27,15 +37,31 @@ class AmbientLightingThread : public concurrency::OSThread
disable();
return;
}
+#endif
+#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
if (!moduleConfig.ambient_lighting.led_state) {
LOG_DEBUG("AmbientLightingThread disabling due to moduleConfig.ambient_lighting.led_state OFF\n");
disable();
return;
}
LOG_DEBUG("AmbientLightingThread initializing\n");
+#ifdef HAS_NCP5623
if (_type == ScanI2C::NCP5623) {
rgb.begin();
+#endif
+#ifdef RGBLED_RED
+ pinMode(RGBLED_RED, OUTPUT);
+ pinMode(RGBLED_GREEN, OUTPUT);
+ pinMode(RGBLED_BLUE, OUTPUT);
+#endif
+#ifdef HAS_NEOPIXEL
+ pixels.begin(); // Initialise the pixel(s)
+ pixels.clear(); // Set all pixel colors to 'off'
+ pixels.setBrightness(moduleConfig.ambient_lighting.current);
+#endif
setLighting();
+#endif
+#ifdef HAS_NCP5623
}
#endif
}
@@ -43,16 +69,17 @@ class AmbientLightingThread : public concurrency::OSThread
protected:
int32_t runOnce() override
{
+#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
#ifdef HAS_NCP5623
if (_type == ScanI2C::NCP5623 && moduleConfig.ambient_lighting.led_state) {
+#endif
setLighting();
return 30000; // 30 seconds to reset from any animations that may have been running from Ext. Notification
- } else {
- return disable();
+#ifdef HAS_NCP5623
}
-#else
- return disable();
#endif
+#endif
+ return disable();
}
private:
@@ -65,9 +92,36 @@ class AmbientLightingThread : public concurrency::OSThread
rgb.setRed(moduleConfig.ambient_lighting.red);
rgb.setGreen(moduleConfig.ambient_lighting.green);
rgb.setBlue(moduleConfig.ambient_lighting.blue);
- LOG_DEBUG("Initializing Ambient lighting w/ current=%d, red=%d, green=%d, blue=%d\n",
+ LOG_DEBUG("Initializing NCP5623 Ambient lighting w/ current=%d, red=%d, green=%d, blue=%d\n",
moduleConfig.ambient_lighting.current, moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
moduleConfig.ambient_lighting.blue);
+#endif
+#ifdef HAS_NEOPIXEL
+ pixels.fill(pixels.Color(moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
+ moduleConfig.ambient_lighting.blue),
+ 0, NEOPIXEL_COUNT);
+ pixels.show();
+ LOG_DEBUG("Initializing NeoPixel Ambient lighting w/ brightness(current)=%d, red=%d, green=%d, blue=%d\n",
+ moduleConfig.ambient_lighting.current, moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
+ moduleConfig.ambient_lighting.blue);
+#endif
+#ifdef RGBLED_CA
+ analogWrite(RGBLED_RED, 255 - moduleConfig.ambient_lighting.red);
+ analogWrite(RGBLED_GREEN, 255 - moduleConfig.ambient_lighting.green);
+ analogWrite(RGBLED_BLUE, 255 - moduleConfig.ambient_lighting.blue);
+ LOG_DEBUG("Initializing Ambient lighting RGB Common Anode w/ red=%d, green=%d, blue=%d\n",
+ moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
+#elif defined(RGBLED_RED)
+ analogWrite(RGBLED_RED, moduleConfig.ambient_lighting.red);
+ analogWrite(RGBLED_GREEN, moduleConfig.ambient_lighting.green);
+ analogWrite(RGBLED_BLUE, moduleConfig.ambient_lighting.blue);
+ LOG_DEBUG("Initializing Ambient lighting RGB Common Cathode w/ red=%d, green=%d, blue=%d\n",
+ moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
+#endif
+#ifdef UNPHONE
+ unphone.rgb(moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
+ LOG_DEBUG("Initializing unPhone Ambient lighting w/ red=%d, green=%d, blue=%d\n", moduleConfig.ambient_lighting.red,
+ moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
#endif
}
};
diff --git a/src/ButtonThread.cpp b/src/ButtonThread.cpp
index 206bb7239..4566de924 100644
--- a/src/ButtonThread.cpp
+++ b/src/ButtonThread.cpp
@@ -136,9 +136,12 @@ int32_t ButtonThread::runOnce()
case BUTTON_EVENT_DOUBLE_PRESSED: {
LOG_BUTTON("Double press!\n");
service.refreshLocalMeshNode();
- service.sendNetworkPing(NODENUM_BROADCAST, true);
+ auto sentPosition = service.trySendPosition(NODENUM_BROADCAST, true);
if (screen) {
- screen->print("Sent ad-hoc ping\n");
+ if (sentPosition)
+ screen->print("Sent ad-hoc position\n");
+ else
+ screen->print("Sent ad-hoc nodeinfo\n");
screen->forceDisplay(true); // Force a new UI frame, then force an EInk update
}
break;
@@ -193,15 +196,13 @@ int32_t ButtonThread::runOnce()
#ifdef BUTTON_PIN_TOUCH
case BUTTON_EVENT_TOUCH_LONG_PRESSED: {
LOG_BUTTON("Touch press!\n");
- if (config.display.wake_on_tap_or_motion) {
- if (screen) {
- // Wake if asleep
- if (powerFSM.getState() == &stateDARK)
- powerFSM.trigger(EVENT_PRESS);
+ if (screen) {
+ // Wake if asleep
+ if (powerFSM.getState() == &stateDARK)
+ powerFSM.trigger(EVENT_PRESS);
- // Update display (legacy behaviour)
- screen->forceDisplay();
- }
+ // Update display (legacy behaviour)
+ screen->forceDisplay();
}
break;
}
diff --git a/src/Power.cpp b/src/Power.cpp
index d13fd6891..2658b74a4 100644
--- a/src/Power.cpp
+++ b/src/Power.cpp
@@ -184,7 +184,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
virtual uint16_t getBattVoltage() override
{
-#if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
+#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
if (hasINA()) {
LOG_DEBUG("Using INA on I2C addr 0x%x for device battery voltage\n", config.power.device_battery_ina_address);
return getINAVoltage();
@@ -360,7 +360,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
float last_read_value = (OCV[NUM_OCV_POINTS - 1] * NUM_CELLS);
uint32_t last_read_time_ms = 0;
-#if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO)
+#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
uint16_t getINAVoltage()
{
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {
diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h
index c8fcfee10..05a5cb2ea 100644
--- a/src/detect/ScanI2C.h
+++ b/src/detect/ScanI2C.h
@@ -41,9 +41,7 @@ class ScanI2C
BQ24295,
LSM6DS3,
TCA9555,
-#ifdef HAS_NCP5623
NCP5623,
-#endif
} DeviceType;
// typedef uint8_t DeviceAddress;
diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp
index e2e2188b6..ba2820a77 100644
--- a/src/detect/ScanI2CTwoWire.cpp
+++ b/src/detect/ScanI2CTwoWire.cpp
@@ -279,6 +279,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
} else { // Unknown device
LOG_INFO("No INA3221 found at address 0x%x\n", (uint8_t)addr.address);
}
+ break;
case MCP9808_ADDR:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2);
if (registerValue == 0x0400) {
diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp
index 0d0bfd9a2..17e35a4b3 100644
--- a/src/gps/GPS.cpp
+++ b/src/gps/GPS.cpp
@@ -452,7 +452,7 @@ bool GPS::setup()
// Set the NEMA output messages
// Ask for only RMC and GGA
uint8_t fields[] = {CAS_NEMA_RMC, CAS_NEMA_GGA};
- for (int i = 0; i < sizeof(fields); i++) {
+ for (uint i = 0; i < sizeof(fields); i++) {
// Construct a CAS-CFG-MSG packet
uint8_t cas_cfg_msg_packet[] = {0x4e, fields[i], 0x01, 0x00};
msglen = makeCASPacket(0x06, 0x01, sizeof(cas_cfg_msg_packet), cas_cfg_msg_packet);
@@ -1584,7 +1584,7 @@ bool GPS::hasFlow()
bool GPS::whileIdle()
{
- int charsInBuf = 0;
+ uint charsInBuf = 0;
bool isValid = false;
if (!isAwake) {
clearBuffer();
diff --git a/src/gps/RTC.cpp b/src/gps/RTC.cpp
index 26af7cac2..a2cdb5b30 100644
--- a/src/gps/RTC.cpp
+++ b/src/gps/RTC.cpp
@@ -104,13 +104,15 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
bool shouldSet;
if (q > currentQuality) {
shouldSet = true;
- LOG_DEBUG("Upgrading time to quality %d\n", q);
- } else if (q == RTCQualityGPS && (now - lastSetMsec) > (12 * 60 * 60 * 1000UL)) {
- // Every 12 hrs we will slam in a new GPS time, to correct for local RTC clock drift
+ LOG_DEBUG("Upgrading time to quality %s\n", RtcName(q));
+ } else if (q >= RTCQualityNTP && (now - lastSetMsec) > (12 * 60 * 60 * 1000UL)) {
+ // Every 12 hrs we will slam in a new GPS or Phone GPS / NTP time, to correct for local RTC clock drift
shouldSet = true;
LOG_DEBUG("Reapplying external time to correct clock drift %ld secs\n", tv->tv_sec);
- } else
+ } else {
shouldSet = false;
+ LOG_DEBUG("Current RTC quality: %s. Ignoring time of RTC quality of %s\n", RtcName(currentQuality), RtcName(q));
+ }
if (shouldSet) {
currentQuality = q;
@@ -162,6 +164,24 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
}
}
+const char *RtcName(RTCQuality quality)
+{
+ switch (quality) {
+ case RTCQualityNone:
+ return "None";
+ case RTCQualityDevice:
+ return "Device";
+ case RTCQualityFromNet:
+ return "Net";
+ case RTCQualityNTP:
+ return "NTP";
+ case RTCQualityGPS:
+ return "GPS";
+ default:
+ return "Unknown";
+ }
+}
+
/**
* Sets the RTC time if the provided time is of higher quality than the current RTC time.
*
@@ -203,7 +223,7 @@ int32_t getTZOffset()
now = time(NULL);
gmt = gmtime(&now);
gmt->tm_isdst = -1;
- return (int16_t)difftime(now, mktime(gmt));
+ return (int32_t)difftime(now, mktime(gmt));
}
/**
diff --git a/src/gps/RTC.h b/src/gps/RTC.h
index 0561819bd..1d609f136 100644
--- a/src/gps/RTC.h
+++ b/src/gps/RTC.h
@@ -28,6 +28,9 @@ RTCQuality getRTCQuality();
bool perhapsSetRTC(RTCQuality q, const struct timeval *tv);
bool perhapsSetRTC(RTCQuality q, struct tm &t);
+/// Return a string name for the quality
+const char *RtcName(RTCQuality quality);
+
/// Return time since 1970 in secs. While quality is RTCQualityNone we will be returning time based at zero
uint32_t getTime(bool local = false);
diff --git a/src/graphics/EInkDynamicDisplay.cpp b/src/graphics/EInkDynamicDisplay.cpp
index b396446fa..5b97b8d48 100644
--- a/src/graphics/EInkDynamicDisplay.cpp
+++ b/src/graphics/EInkDynamicDisplay.cpp
@@ -534,6 +534,10 @@ void EInkDynamicDisplay::checkBusyAsyncRefresh()
return;
}
+
+ // Async refresh appears to have stopped, but wasn't caught by onNotify()
+ else
+ pollAsyncRefresh(); // Check (and terminate) the async refresh manually
}
// Hold control while an async refresh runs
diff --git a/src/graphics/NeoPixel.h b/src/graphics/NeoPixel.h
new file mode 100644
index 000000000..dde74366e
--- /dev/null
+++ b/src/graphics/NeoPixel.h
@@ -0,0 +1,4 @@
+#ifdef HAS_NEOPIXEL
+#include
+extern Adafruit_NeoPixel pixels;
+#endif
\ No newline at end of file
diff --git a/src/graphics/TFTDisplay.cpp b/src/graphics/TFTDisplay.cpp
index 12e549424..b529bf0e4 100644
--- a/src/graphics/TFTDisplay.cpp
+++ b/src/graphics/TFTDisplay.cpp
@@ -1,7 +1,6 @@
#include "configuration.h"
#include "main.h"
#if ARCH_PORTDUINO
-#include "mesh_bus_spi.h"
#include "platform/portduino/PortduinoGlue.h"
#endif
@@ -340,7 +339,7 @@ static TFT_eSPI *tft = nullptr; // Invoke library, pins defined in User_Setup.h
class LGFX : public lgfx::LGFX_Device
{
lgfx::Panel_LCD *_panel_instance;
- lgfx::Mesh_Bus_SPI _bus_instance;
+ lgfx::Bus_SPI _bus_instance;
lgfx::ITouch *_touch_instance;
@@ -357,7 +356,7 @@ class LGFX : public lgfx::LGFX_Device
_panel_instance = new lgfx::Panel_ILI9341;
auto buscfg = _bus_instance.config();
buscfg.spi_mode = 0;
- _bus_instance.spi_device(DisplaySPI, settingsStrings[displayspidev]);
+ _bus_instance.spi_device(DisplaySPI);
buscfg.pin_dc = settingsMap[displayDC]; // Set SPI DC pin number (-1 = disable)
@@ -383,6 +382,8 @@ class LGFX : public lgfx::LGFX_Device
_touch_instance = new lgfx::Touch_XPT2046;
} else if (settingsMap[touchscreenModule] == stmpe610) {
_touch_instance = new lgfx::Touch_STMPE610;
+ } else if (settingsMap[touchscreenModule] == ft5x06) {
+ _touch_instance = new lgfx::Touch_FT5x06;
}
auto touch_cfg = _touch_instance->config();
@@ -394,6 +395,9 @@ class LGFX : public lgfx::LGFX_Device
touch_cfg.pin_int = settingsMap[touchscreenIRQ];
touch_cfg.bus_shared = true;
touch_cfg.offset_rotation = 1;
+ if (settingsMap[touchscreenI2CAddr] != -1) {
+ touch_cfg.i2c_addr = settingsMap[touchscreenI2CAddr];
+ }
_touch_instance->config(touch_cfg);
_panel_instance->setTouch(_touch_instance);
@@ -711,4 +715,4 @@ bool TFTDisplay::connect()
return true;
}
-#endif
+#endif
\ No newline at end of file
diff --git a/src/graphics/mesh_bus_spi.cpp b/src/graphics/mesh_bus_spi.cpp
deleted file mode 100644
index a9536d490..000000000
--- a/src/graphics/mesh_bus_spi.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-// This code has been copied from LovyanGFX to make the SPI device selectable for touchscreens.
-// Ideally this could eventually be an inherited class from BUS_SPI,
-// but currently too many internal objects are set private.
-
-#include "configuration.h"
-#if ARCH_PORTDUINO
-#include "lgfx/v1/misc/pixelcopy.hpp"
-#include "main.h"
-#include "mesh_bus_spi.h"
-#include
-#include
-
-namespace lgfx
-{
-inline namespace v1
-{
-//----------------------------------------------------------------------------
-
-void Mesh_Bus_SPI::config(const config_t &config)
-{
- _cfg = config;
-
- if (_cfg.pin_dc >= 0) {
- pinMode(_cfg.pin_dc, pin_mode_t::output);
- gpio_hi(_cfg.pin_dc);
- }
-}
-
-bool Mesh_Bus_SPI::init(void)
-{
- dc_h();
- pinMode(_cfg.pin_dc, pin_mode_t::output);
- if (SPIName != "")
- PrivateSPI->begin(SPIName.c_str());
- else
- PrivateSPI->begin();
- return true;
-}
-
-void Mesh_Bus_SPI::release(void)
-{
- PrivateSPI->end();
-}
-
-void Mesh_Bus_SPI::spi_device(HardwareSPI *newSPI, std::string newSPIName)
-{
- PrivateSPI = newSPI;
- SPIName = newSPIName;
-}
-void Mesh_Bus_SPI::beginTransaction(void)
-{
- dc_h();
- SPISettings setting(_cfg.freq_write, MSBFIRST, _cfg.spi_mode);
- PrivateSPI->beginTransaction(setting);
-}
-
-void Mesh_Bus_SPI::endTransaction(void)
-{
- PrivateSPI->endTransaction();
- dc_h();
-}
-
-void Mesh_Bus_SPI::beginRead(void)
-{
- PrivateSPI->endTransaction();
- // SPISettings setting(_cfg.freq_read, BitOrder::MSBFIRST, _cfg.spi_mode, false);
- SPISettings setting(_cfg.freq_read, MSBFIRST, _cfg.spi_mode);
- PrivateSPI->beginTransaction(setting);
-}
-
-void Mesh_Bus_SPI::endRead(void)
-{
- PrivateSPI->endTransaction();
- beginTransaction();
-}
-
-void Mesh_Bus_SPI::wait(void) {}
-
-bool Mesh_Bus_SPI::busy(void) const
-{
- return false;
-}
-
-bool Mesh_Bus_SPI::writeCommand(uint32_t data, uint_fast8_t bit_length)
-{
- dc_l();
- PrivateSPI->transfer((uint8_t *)&data, bit_length >> 3);
- dc_h();
- return true;
-}
-
-void Mesh_Bus_SPI::writeData(uint32_t data, uint_fast8_t bit_length)
-{
- PrivateSPI->transfer((uint8_t *)&data, bit_length >> 3);
-}
-
-void Mesh_Bus_SPI::writeDataRepeat(uint32_t data, uint_fast8_t bit_length, uint32_t length)
-{
- const uint8_t dst_bytes = bit_length >> 3;
- uint32_t limit = (dst_bytes == 3) ? 12 : 16;
- auto buf = _flip_buffer.getBuffer(512);
- size_t fillpos = 0;
- reinterpret_cast(buf)[0] = data;
- fillpos += dst_bytes;
- uint32_t len;
- do {
- len = ((length - 1) % limit) + 1;
- if (limit <= 64)
- limit <<= 1;
-
- while (fillpos < len * dst_bytes) {
- memcpy(&buf[fillpos], buf, fillpos);
- fillpos += fillpos;
- }
-
- PrivateSPI->transfer(buf, len * dst_bytes);
- } while (length -= len);
-}
-
-void Mesh_Bus_SPI::writePixels(pixelcopy_t *param, uint32_t length)
-{
- const uint8_t dst_bytes = param->dst_bits >> 3;
- uint32_t limit = (dst_bytes == 3) ? 12 : 16;
- uint32_t len;
- do {
- len = ((length - 1) % limit) + 1;
- if (limit <= 32)
- limit <<= 1;
- auto buf = _flip_buffer.getBuffer(len * dst_bytes);
- param->fp_copy(buf, 0, len, param);
- PrivateSPI->transfer(buf, len * dst_bytes);
- } while (length -= len);
-}
-
-void Mesh_Bus_SPI::writeBytes(const uint8_t *data, uint32_t length, bool dc, bool use_dma)
-{
- if (dc)
- dc_h();
- else
- dc_l();
- PrivateSPI->transfer(const_cast(data), length);
- if (!dc)
- dc_h();
-}
-
-uint32_t Mesh_Bus_SPI::readData(uint_fast8_t bit_length)
-{
- uint32_t res = 0;
- bit_length >>= 3;
- if (!bit_length)
- return res;
- int idx = 0;
- do {
- res |= PrivateSPI->transfer(0) << idx;
- idx += 8;
- } while (--bit_length);
- return res;
-}
-
-bool Mesh_Bus_SPI::readBytes(uint8_t *dst, uint32_t length, bool use_dma)
-{
- do {
- dst[0] = PrivateSPI->transfer(0);
- ++dst;
- } while (--length);
- return true;
-}
-
-void Mesh_Bus_SPI::readPixels(void *dst, pixelcopy_t *param, uint32_t length)
-{
- uint32_t bytes = param->src_bits >> 3;
- uint32_t dstindex = 0;
- uint32_t len = 4;
- uint8_t buf[24];
- param->src_data = buf;
- do {
- if (len > length)
- len = length;
- readBytes((uint8_t *)buf, len * bytes, true);
- param->src_x = 0;
- dstindex = param->fp_copy(dst, dstindex, dstindex + len, param);
- length -= len;
- } while (length);
-}
-
-} // namespace v1
-} // namespace lgfx
-#endif
\ No newline at end of file
diff --git a/src/graphics/mesh_bus_spi.h b/src/graphics/mesh_bus_spi.h
deleted file mode 100644
index 903f7ad9d..000000000
--- a/src/graphics/mesh_bus_spi.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#if ARCH_PORTDUINO
-/*----------------------------------------------------------------------------/
- Lovyan GFX - Graphics library for embedded devices.
-
-Original Source:
- https://github.com/lovyan03/LovyanGFX/
-
-Licence:
- [FreeBSD](https://github.com/lovyan03/LovyanGFX/blob/master/license.txt)
-
-Author:
- [lovyan03](https://twitter.com/lovyan03)
-
-Contributors:
- [ciniml](https://github.com/ciniml)
- [mongonta0716](https://github.com/mongonta0716)
- [tobozo](https://github.com/tobozo)
-/----------------------------------------------------------------------------*/
-#pragma once
-
-#include
-
-#include "lgfx/v1/Bus.hpp"
-#include "lgfx/v1/platforms/common.hpp"
-
-namespace lgfx
-{
-inline namespace v1
-{
-//----------------------------------------------------------------------------
-
-class Mesh_Bus_SPI : public IBus
-{
- public:
- struct config_t {
- uint32_t freq_write = 16000000;
- uint32_t freq_read = 8000000;
- // bool spi_3wire = true;
- // bool use_lock = true;
- int16_t pin_sclk = -1;
- int16_t pin_miso = -1;
- int16_t pin_mosi = -1;
- int16_t pin_dc = -1;
- uint8_t spi_mode = 0;
- };
-
- const config_t &config(void) const { return _cfg; }
-
- void config(const config_t &config);
-
- bus_type_t busType(void) const override { return bus_type_t::bus_spi; }
-
- bool init(void) override;
- void release(void) override;
- void spi_device(HardwareSPI *newSPI, std::string newSPIName);
-
- void beginTransaction(void) override;
- void endTransaction(void) override;
- void wait(void) override;
- bool busy(void) const override;
-
- bool writeCommand(uint32_t data, uint_fast8_t bit_length) override;
- void writeData(uint32_t data, uint_fast8_t bit_length) override;
- void writeDataRepeat(uint32_t data, uint_fast8_t bit_length, uint32_t count) override;
- void writePixels(pixelcopy_t *param, uint32_t length) override;
- void writeBytes(const uint8_t *data, uint32_t length, bool dc, bool use_dma) override;
-
- void initDMA(void) {}
- void flush(void) {}
- void addDMAQueue(const uint8_t *data, uint32_t length) override { writeBytes(data, length, true, true); }
- void execDMAQueue(void) {}
- uint8_t *getDMABuffer(uint32_t length) override { return _flip_buffer.getBuffer(length); }
-
- void beginRead(void) override;
- void endRead(void) override;
- uint32_t readData(uint_fast8_t bit_length) override;
- bool readBytes(uint8_t *dst, uint32_t length, bool use_dma) override;
- void readPixels(void *dst, pixelcopy_t *param, uint32_t length) override;
-
- private:
- HardwareSPI *PrivateSPI;
- std::string SPIName;
- __attribute__((always_inline)) inline void dc_h(void) { gpio_hi(_cfg.pin_dc); }
- __attribute__((always_inline)) inline void dc_l(void) { gpio_lo(_cfg.pin_dc); }
-
- config_t _cfg;
- FlipBuffer _flip_buffer;
- bool _need_wait;
- uint32_t _mask_reg_dc;
- uint32_t _last_apb_freq = -1;
- uint32_t _clkdiv_write;
- uint32_t _clkdiv_read;
- volatile uint32_t *_gpio_reg_dc_h;
- volatile uint32_t *_gpio_reg_dc_l;
-};
-
-//----------------------------------------------------------------------------
-} // namespace v1
-} // namespace lgfx
-#endif
\ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
index b1a15634f..4a663a8a0 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -179,6 +179,11 @@ const char *getDeviceName()
static int32_t ledBlinker()
{
+ // Still set up the blinking (heartbeat) interval but skip code path below, so LED will blink if
+ // config.device.led_heartbeat_disabled is changed
+ if (config.device.led_heartbeat_disabled)
+ return 1000;
+
static bool ledOn;
ledOn ^= 1;
@@ -607,7 +612,9 @@ void setup()
}
#endif
-#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
+#if defined(HAS_NEOPIXEL) || defined(UNPHONE) || defined(RGBLED_RED)
+ ambientLightingThread = new AmbientLightingThread(ScanI2C::DeviceType::NONE);
+#elif !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
if (rgb_found.type != ScanI2C::DeviceType::NONE) {
ambientLightingThread = new AmbientLightingThread(rgb_found.type);
}
@@ -763,6 +770,21 @@ void setup()
LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio\n");
}
}
+ } else if (settingsMap[use_sx1268]) {
+ if (!rIf) {
+ LOG_DEBUG("Attempting to activate sx1268 radio on SPI port %s\n", settingsStrings[spidev].c_str());
+ LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(*LoraSPI, spiSettings);
+ rIf = new SX1268Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
+ settingsMap[busy]);
+ if (!rIf->init()) {
+ LOG_ERROR("Failed to find SX1268 radio\n");
+ delete rIf;
+ rIf = NULL;
+ exit(EXIT_FAILURE);
+ } else {
+ LOG_INFO("SX1268 Radio init succeeded, using SX1268 radio\n");
+ }
+ }
}
#elif defined(HW_SPI1_DEVICE)
@@ -1001,4 +1023,4 @@ void loop()
mainDelay.delay(delayMsec);
}
// if (didWake) LOG_DEBUG("wake!\n");
-}
\ No newline at end of file
+}
diff --git a/src/mesh/FloodingRouter.cpp b/src/mesh/FloodingRouter.cpp
index 4cfe982d8..dd547a6f1 100644
--- a/src/mesh/FloodingRouter.cpp
+++ b/src/mesh/FloodingRouter.cpp
@@ -35,11 +35,10 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c)
{
- bool isAck =
- ((c && c->error_reason == meshtastic_Routing_Error_NONE)); // consider only ROUTING_APP message without error as ACK
- if (isAck && p->to != getNodeNum()) {
- // do not flood direct message that is ACKed
- LOG_DEBUG("Receiving an ACK not for me, but don't need to rebroadcast this direct message anymore.\n");
+ bool isAckorReply = (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) && (p->decoded.request_id != 0);
+ if (isAckorReply && p->to != getNodeNum() && p->to != NODENUM_BROADCAST) {
+ // do not flood direct message that is ACKed or replied to
+ LOG_DEBUG("Receiving an ACK or reply not for me, but don't need to rebroadcast this direct message anymore.\n");
Router::cancelSending(p->to, p->decoded.request_id); // cancel rebroadcast for this DM
}
if ((p->to != getNodeNum()) && (p->hop_limit > 0) && (getFrom(p) != getNodeNum())) {
diff --git a/src/mesh/MeshService.cpp b/src/mesh/MeshService.cpp
index 2c1969e30..66a2e6952 100644
--- a/src/mesh/MeshService.cpp
+++ b/src/mesh/MeshService.cpp
@@ -193,10 +193,7 @@ void MeshService::handleToRadio(meshtastic_MeshPacket &p)
}
#endif
if (p.from != 0) { // We don't let phones assign nodenums to their sent messages
- LOG_WARN("phone tried to pick a nodenum, we don't allow that.\n");
p.from = 0;
- } else {
- // p.from = nodeDB->getNodeNum();
}
if (p.id == 0)
@@ -267,7 +264,7 @@ void MeshService::sendToMesh(meshtastic_MeshPacket *p, RxSource src, bool ccToPh
}
}
-void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
+bool MeshService::trySendPosition(NodeNum dest, bool wantReplies)
{
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());
@@ -278,6 +275,7 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
if (positionModule) {
LOG_INFO("Sending position ping to 0x%x, wantReplies=%d, channel=%d\n", dest, wantReplies, node->channel);
positionModule->sendOurPosition(dest, wantReplies, node->channel);
+ return true;
}
} else {
#endif
@@ -286,6 +284,7 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
nodeInfoModule->sendOurNodeInfo(dest, wantReplies, node->channel);
}
}
+ return false;
}
void MeshService::sendToPhone(meshtastic_MeshPacket *p)
diff --git a/src/mesh/MeshService.h b/src/mesh/MeshService.h
index 8d1434030..d777b7a01 100644
--- a/src/mesh/MeshService.h
+++ b/src/mesh/MeshService.h
@@ -108,8 +108,9 @@ class MeshService
void reloadOwner(bool shouldSave = true);
/// Called when the user wakes up our GUI, normally sends our latest location to the mesh (if we have it), otherwise at least
- /// sends our owner
- void sendNetworkPing(NodeNum dest, bool wantReplies = false);
+ /// sends our nodeinfo
+ /// returns true if we sent a position
+ bool trySendPosition(NodeNum dest, bool wantReplies = false);
/// Send a packet into the mesh - note p must have been allocated from packetPool. We will return it to that pool after
/// sending. This is the ONLY function you should use for sending messages into the mesh, because it also updates the nodedb
diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp
index 39422b454..249db627e 100644
--- a/src/mesh/NodeDB.cpp
+++ b/src/mesh/NodeDB.cpp
@@ -352,9 +352,6 @@ void NodeDB::installDefaultModuleConfig()
moduleConfig.external_notification.alert_message = true;
moduleConfig.external_notification.output_ms = 100;
moduleConfig.external_notification.active = true;
-#endif
-#ifdef TTGO_T_ECHO
- config.display.wake_on_tap_or_motion = true; // Enable touch button for screen-on / refresh
#endif
moduleConfig.has_canned_message = true;
diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp
index 63912a03e..f5eb35cbe 100644
--- a/src/mesh/RadioInterface.cpp
+++ b/src/mesh/RadioInterface.cpp
@@ -76,9 +76,12 @@ const RegionInfo regions[] = {
RDEF(KR, 920.0f, 923.0f, 100, 0, 0, true, false, false),
/*
- ???
+ Taiwan, 920-925Mhz, limited to 0.5W indoor or coastal, 1.0W outdoor.
+ 5.8.1 in the Low-power Radio-frequency Devices Technical Regulations
+ https://www.ncc.gov.tw/english/files/23070/102_5190_230703_1_doc_C.PDF
+ https://gazette.nat.gov.tw/egFront/e_detail.do?metaid=147283
*/
- RDEF(TW, 920.0f, 925.0f, 100, 0, 0, true, false, false),
+ RDEF(TW, 920.0f, 925.0f, 100, 0, 27, true, false, false),
/*
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
@@ -492,7 +495,7 @@ void RadioInterface::applyModemConfig()
// If user has manually specified a channel num, then use that, otherwise generate one by hashing the name
const char *channelName = channels.getName(channels.getPrimaryIndex());
// channel_num is actually (channel_num - 1), since modulus (%) returns values from 0 to (numChannels - 1)
- int channel_num = (loraConfig.channel_num ? loraConfig.channel_num - 1 : hash(channelName)) % numChannels;
+ uint channel_num = (loraConfig.channel_num ? loraConfig.channel_num - 1 : hash(channelName)) % numChannels;
// Check if we use the default frequency slot
RadioInterface::uses_default_frequency_slot =
@@ -586,4 +589,4 @@ size_t RadioInterface::beginSending(meshtastic_MeshPacket *p)
sendingPacket = p;
return p->encrypted.size + sizeof(PacketHeader);
-}
\ No newline at end of file
+}
diff --git a/src/mesh/generated/meshtastic/apponly.pb.h b/src/mesh/generated/meshtastic/apponly.pb.h
index 54629f522..ba9f90873 100644
--- a/src/mesh/generated/meshtastic/apponly.pb.h
+++ b/src/mesh/generated/meshtastic/apponly.pb.h
@@ -55,7 +55,7 @@ extern const pb_msgdesc_t meshtastic_ChannelSet_msg;
/* Maximum encoded size of messages (where known) */
#define MESHTASTIC_MESHTASTIC_APPONLY_PB_H_MAX_SIZE meshtastic_ChannelSet_size
-#define meshtastic_ChannelSet_size 658
+#define meshtastic_ChannelSet_size 674
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/mesh/generated/meshtastic/channel.pb.h b/src/mesh/generated/meshtastic/channel.pb.h
index 185a47a98..d9c7d4ffa 100644
--- a/src/mesh/generated/meshtastic/channel.pb.h
+++ b/src/mesh/generated/meshtastic/channel.pb.h
@@ -34,6 +34,9 @@ typedef enum _meshtastic_Channel_Role {
typedef struct _meshtastic_ModuleSettings {
/* Bits of precision for the location sent in position packets. */
uint32_t position_precision;
+ /* Controls whether or not the phone / clients should mute the current channel
+ Useful for noisy public channels you don't necessarily want to disable */
+ bool is_client_muted;
} meshtastic_ModuleSettings;
typedef PB_BYTES_ARRAY_T(32) meshtastic_ChannelSettings_psk_t;
@@ -126,14 +129,15 @@ extern "C" {
/* Initializer values for message structs */
#define meshtastic_ChannelSettings_init_default {0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_default}
-#define meshtastic_ModuleSettings_init_default {0}
+#define meshtastic_ModuleSettings_init_default {0, 0}
#define meshtastic_Channel_init_default {0, false, meshtastic_ChannelSettings_init_default, _meshtastic_Channel_Role_MIN}
#define meshtastic_ChannelSettings_init_zero {0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_zero}
-#define meshtastic_ModuleSettings_init_zero {0}
+#define meshtastic_ModuleSettings_init_zero {0, 0}
#define meshtastic_Channel_init_zero {0, false, meshtastic_ChannelSettings_init_zero, _meshtastic_Channel_Role_MIN}
/* Field tags (for use in manual encoding/decoding) */
#define meshtastic_ModuleSettings_position_precision_tag 1
+#define meshtastic_ModuleSettings_is_client_muted_tag 2
#define meshtastic_ChannelSettings_channel_num_tag 1
#define meshtastic_ChannelSettings_psk_tag 2
#define meshtastic_ChannelSettings_name_tag 3
@@ -159,7 +163,8 @@ X(a, STATIC, OPTIONAL, MESSAGE, module_settings, 7)
#define meshtastic_ChannelSettings_module_settings_MSGTYPE meshtastic_ModuleSettings
#define meshtastic_ModuleSettings_FIELDLIST(X, a) \
-X(a, STATIC, SINGULAR, UINT32, position_precision, 1)
+X(a, STATIC, SINGULAR, UINT32, position_precision, 1) \
+X(a, STATIC, SINGULAR, BOOL, is_client_muted, 2)
#define meshtastic_ModuleSettings_CALLBACK NULL
#define meshtastic_ModuleSettings_DEFAULT NULL
@@ -182,9 +187,9 @@ extern const pb_msgdesc_t meshtastic_Channel_msg;
/* Maximum encoded size of messages (where known) */
#define MESHTASTIC_MESHTASTIC_CHANNEL_PB_H_MAX_SIZE meshtastic_Channel_size
-#define meshtastic_ChannelSettings_size 70
-#define meshtastic_Channel_size 85
-#define meshtastic_ModuleSettings_size 6
+#define meshtastic_ChannelSettings_size 72
+#define meshtastic_Channel_size 87
+#define meshtastic_ModuleSettings_size 8
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/mesh/generated/meshtastic/deviceonly.pb.h b/src/mesh/generated/meshtastic/deviceonly.pb.h
index 2506ec647..b8cc80633 100644
--- a/src/mesh/generated/meshtastic/deviceonly.pb.h
+++ b/src/mesh/generated/meshtastic/deviceonly.pb.h
@@ -306,7 +306,7 @@ extern const pb_msgdesc_t meshtastic_OEMStore_msg;
/* Maximum encoded size of messages (where known) */
/* meshtastic_DeviceState_size depends on runtime parameters */
#define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_OEMStore_size
-#define meshtastic_ChannelFile_size 702
+#define meshtastic_ChannelFile_size 718
#define meshtastic_NodeInfoLite_size 166
#define meshtastic_OEMStore_size 3346
#define meshtastic_PositionLite_size 28
diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h
index 67b2edd15..68d9b4707 100644
--- a/src/mesh/generated/meshtastic/mesh.pb.h
+++ b/src/mesh/generated/meshtastic/mesh.pb.h
@@ -148,6 +148,9 @@ typedef enum _meshtastic_HardwareModel {
meshtastic_HardwareModel_TD_LORAC = 60,
/* CDEBYTE EoRa-S3 board using their own MM modules, clone of LILYGO T3S3 */
meshtastic_HardwareModel_CDEBYTE_EORA_S3 = 61,
+ /* TWC_MESH_V4
+ Adafruit NRF52840 feather express with SX1262, SSD1306 OLED and NEO6M GPS */
+ meshtastic_HardwareModel_TWC_MESH_V4 = 62,
/* ------------------------------------------------------------------------------------------------------------------------------------------
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
------------------------------------------------------------------------------------------------------------------------------------------ */
diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp
index cbd6fee72..a8b1b994b 100644
--- a/src/modules/CannedMessageModule.cpp
+++ b/src/modules/CannedMessageModule.cpp
@@ -161,10 +161,10 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
if (!event->kbchar) {
if (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
this->payload = 0xb4;
- this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE;
+ // this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE;
} else if (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) {
this->payload = 0xb7;
- this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE;
+ // this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE;
}
} else {
// pass the pressed key
@@ -233,14 +233,16 @@ int32_t CannedMessageModule::runOnce()
{
if (((!moduleConfig.canned_message.enabled) && !CANNED_MESSAGE_MODULE_ENABLE) ||
(this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED) || (this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE)) {
+ temporaryMessage = "";
return INT32_MAX;
}
// LOG_DEBUG("Check status\n");
UIFrameEvent e = {false, true};
if ((this->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) ||
- (this->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED)) {
- // TODO: might have some feedback of sendig state
+ (this->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED) || (this->runState == CANNED_MESSAGE_RUN_STATE_MESSAGE)) {
+ // TODO: might have some feedback of sending state
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
+ temporaryMessage = "";
e.frameChanged = true;
this->currentMessageIndex = -1;
this->freetext = ""; // clear freetext
@@ -434,7 +436,7 @@ int32_t CannedMessageModule::runOnce()
}
if (screen)
screen->forceDisplay();
- runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
+ showTemporaryMessage("GPS Toggled");
break;
// mute (switch off/toggle) external notifications on fn+m
@@ -442,18 +444,21 @@ int32_t CannedMessageModule::runOnce()
if (moduleConfig.external_notification.enabled == true) {
if (externalNotificationModule->getMute()) {
externalNotificationModule->setMute(false);
- runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
+ showTemporaryMessage("Notifications \nEnabled");
} else {
externalNotificationModule->stopNow(); // this will turn off all GPIO and sounds and idle the loop
externalNotificationModule->setMute(true);
- runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
+ showTemporaryMessage("Notifications \nDisabled");
}
}
break;
case 0xaf: // fn+space send network ping like double press does
service.refreshLocalMeshNode();
- service.sendNetworkPing(NODENUM_BROADCAST, true);
- runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
+ if (service.trySendPosition(NODENUM_BROADCAST, true)) {
+ showTemporaryMessage("Position \nUpdate Sent");
+ } else {
+ showTemporaryMessage("Node Info \nUpdate Sent");
+ }
break;
default:
if (this->cursor == this->freetext.length()) {
@@ -542,12 +547,27 @@ int CannedMessageModule::getPrevIndex()
return this->currentMessageIndex - 1;
}
}
+void CannedMessageModule::showTemporaryMessage(const String &message)
+{
+ temporaryMessage = message;
+ UIFrameEvent e = {false, true};
+ e.frameChanged = true;
+ notifyObservers(&e);
+ runState = CANNED_MESSAGE_RUN_STATE_MESSAGE;
+ // run this loop again in 2 seconds, next iteration will clear the display
+ setIntervalFromNow(2000);
+}
void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
char buffer[50];
- if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED) {
+ if (temporaryMessage.length() != 0) {
+ LOG_DEBUG("Drawing temporary message: %s", temporaryMessage.c_str());
+ display->setTextAlignment(TEXT_ALIGN_CENTER);
+ display->setFont(FONT_MEDIUM);
+ display->drawString(display->getWidth() / 2 + x, 0 + y + 12, temporaryMessage);
+ } else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED) {
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(FONT_MEDIUM);
String displayString;
@@ -766,4 +786,4 @@ String CannedMessageModule::drawWithCursor(String text, int cursor)
return result;
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/modules/CannedMessageModule.h b/src/modules/CannedMessageModule.h
index 4802be078..faf1d80f3 100644
--- a/src/modules/CannedMessageModule.h
+++ b/src/modules/CannedMessageModule.h
@@ -10,6 +10,7 @@ enum cannedMessageModuleRunState {
CANNED_MESSAGE_RUN_STATE_FREETEXT,
CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE,
CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED,
+ CANNED_MESSAGE_RUN_STATE_MESSAGE,
CANNED_MESSAGE_RUN_STATE_ACTION_SELECT,
CANNED_MESSAGE_RUN_STATE_ACTION_UP,
CANNED_MESSAGE_RUN_STATE_ACTION_DOWN,
@@ -51,6 +52,8 @@ class CannedMessageModule : public SinglePortModule, public Observable
+#endif
+#ifdef HAS_NEOPIXEL
+#include
+#endif
+
+#ifdef UNPHONE
+#include "unPhone.h"
+extern unPhone unphone;
+#endif
+
+#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
uint8_t red = 0;
uint8_t green = 0;
uint8_t blue = 0;
@@ -108,27 +119,44 @@ int32_t ExternalNotificationModule::runOnce()
millis()) {
getExternal(2) ? setExternalOff(2) : setExternalOn(2);
}
+#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
+ red = (colorState & 4) ? brightnessValues[brightnessIndex] : 0; // Red enabled on colorState = 4,5,6,7
+ green = (colorState & 2) ? brightnessValues[brightnessIndex] : 0; // Green enabled on colorState = 2,3,6,7
+ blue = (colorState & 1) ? (brightnessValues[brightnessIndex] * 1.5) : 0; // Blue enabled on colorState = 1,3,5,7
#ifdef HAS_NCP5623
if (rgb_found.type == ScanI2C::NCP5623) {
- red = (colorState & 4) ? brightnessValues[brightnessIndex] : 0; // Red enabled on colorState = 4,5,6,7
- green = (colorState & 2) ? brightnessValues[brightnessIndex] : 0; // Green enabled on colorState = 2,3,6,7
- blue = (colorState & 1) ? (brightnessValues[brightnessIndex] * 1.5) : 0; // Blue enabled on colorState = 1,3,5,7
rgb.setColor(red, green, blue);
-
- if (ascending) { // fade in
- brightnessIndex++;
- if (brightnessIndex == (sizeof(brightnessValues) - 1)) {
- ascending = false;
- }
- } else {
- brightnessIndex--; // fade out
+ }
+#endif
+#ifdef RGBLED_CA
+ analogWrite(RGBLED_RED, 255 - red); // CA type needs reverse logic
+ analogWrite(RGBLED_GREEN, 255 - green);
+ analogWrite(RGBLED_BLUE, 255 - blue);
+#elif defined(RGBLED_RED)
+ analogWrite(RGBLED_RED, red);
+ analogWrite(RGBLED_GREEN, green);
+ analogWrite(RGBLED_BLUE, blue);
+#endif
+#ifdef HAS_NEOPIXEL
+ pixels.fill(pixels.Color(red, green, blue), 0, NEOPIXEL_COUNT);
+ pixels.show();
+#endif
+#ifdef UNPHONE
+ unphone.rgb(red, green, blue);
+#endif
+ if (ascending) { // fade in
+ brightnessIndex++;
+ if (brightnessIndex == (sizeof(brightnessValues) - 1)) {
+ ascending = false;
}
- if (brightnessIndex == 0) {
- ascending = true;
- colorState++; // next color
- if (colorState > 7) {
- colorState = 1;
- }
+ } else {
+ brightnessIndex--; // fade out
+ }
+ if (brightnessIndex == 0) {
+ ascending = true;
+ colorState++; // next color
+ if (colorState > 7) {
+ colorState = 1;
}
}
#endif
@@ -179,6 +207,9 @@ void ExternalNotificationModule::setExternalOn(uint8_t index)
switch (index) {
case 1:
+#ifdef UNPHONE
+ unphone.vibe(true); // the unPhone's vibration motor is on a i2c GPIO expander
+#endif
if (moduleConfig.external_notification.output_vibra)
digitalWrite(moduleConfig.external_notification.output_vibra, true);
break;
@@ -197,6 +228,22 @@ void ExternalNotificationModule::setExternalOn(uint8_t index)
rgb.setColor(red, green, blue);
}
#endif
+#ifdef RGBLED_CA
+ analogWrite(RGBLED_RED, 255 - red); // CA type needs reverse logic
+ analogWrite(RGBLED_GREEN, 255 - green);
+ analogWrite(RGBLED_BLUE, 255 - blue);
+#elif defined(RGBLED_RED)
+ analogWrite(RGBLED_RED, red);
+ analogWrite(RGBLED_GREEN, green);
+ analogWrite(RGBLED_BLUE, blue);
+#endif
+#ifdef HAS_NEOPIXEL
+ pixels.fill(pixels.Color(red, green, blue), 0, NEOPIXEL_COUNT);
+ pixels.show();
+#endif
+#ifdef UNPHONE
+ unphone.rgb(red, green, blue);
+#endif
#ifdef T_WATCH_S3
drv.go();
#endif
@@ -209,6 +256,9 @@ void ExternalNotificationModule::setExternalOff(uint8_t index)
switch (index) {
case 1:
+#ifdef UNPHONE
+ unphone.vibe(false); // the unPhone's vibration motor is on a i2c GPIO expander
+#endif
if (moduleConfig.external_notification.output_vibra)
digitalWrite(moduleConfig.external_notification.output_vibra, false);
break;
@@ -222,14 +272,33 @@ void ExternalNotificationModule::setExternalOff(uint8_t index)
break;
}
+#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
+ red = 0;
+ green = 0;
+ blue = 0;
#ifdef HAS_NCP5623
if (rgb_found.type == ScanI2C::NCP5623) {
- red = 0;
- green = 0;
- blue = 0;
rgb.setColor(red, green, blue);
}
#endif
+#ifdef RGBLED_CA
+ analogWrite(RGBLED_RED, 255 - red); // CA type needs reverse logic
+ analogWrite(RGBLED_GREEN, 255 - green);
+ analogWrite(RGBLED_BLUE, 255 - blue);
+#elif defined(RGBLED_RED)
+ analogWrite(RGBLED_RED, red);
+ analogWrite(RGBLED_GREEN, green);
+ analogWrite(RGBLED_BLUE, blue);
+#endif
+#ifdef HAS_NEOPIXEL
+ pixels.fill(pixels.Color(red, green, blue), 0, NEOPIXEL_COUNT);
+ pixels.show();
+#endif
+#ifdef UNPHONE
+ unphone.rgb(red, green, blue);
+#endif
+#endif
+
#ifdef T_WATCH_S3
drv.stop();
#endif
@@ -244,7 +313,8 @@ void ExternalNotificationModule::stopNow()
{
rtttl::stop();
#ifdef HAS_I2S
- audioThread->stop();
+ if (audioThread->isPlaying())
+ audioThread->stop();
#endif
nagCycleCutoff = 1; // small value
isNagging = false;
@@ -327,6 +397,21 @@ ExternalNotificationModule::ExternalNotificationModule()
rgb.begin();
rgb.setCurrent(10);
}
+#endif
+#ifdef RGBLED_RED
+ pinMode(RGBLED_RED, OUTPUT); // set up the RGB led pins
+ pinMode(RGBLED_GREEN, OUTPUT);
+ pinMode(RGBLED_BLUE, OUTPUT);
+#endif
+#ifdef RGBLED_CA
+ analogWrite(RGBLED_RED, 255); // with a common anode type, logic is reversed
+ analogWrite(RGBLED_GREEN, 255); // so we want to initialise with lights off
+ analogWrite(RGBLED_BLUE, 255);
+#endif
+#ifdef HAS_NEOPIXEL
+ pixels.begin(); // Initialise the pixel(s)
+ pixels.clear(); // Set all pixel colors to 'off'
+ pixels.setBrightness(moduleConfig.ambient_lighting.current);
#endif
} else {
LOG_INFO("External Notification Module Disabled\n");
@@ -508,4 +593,4 @@ void ExternalNotificationModule::handleSetRingtone(const char *from_msg)
if (changed) {
nodeDB->saveProto(rtttlConfigFile, meshtastic_RTTTLConfig_size, &meshtastic_RTTTLConfig_msg, &rtttlConfig);
}
-}
\ No newline at end of file
+}
diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp
index 250daec57..7c459dc35 100644
--- a/src/modules/PositionModule.cpp
+++ b/src/modules/PositionModule.cpp
@@ -71,14 +71,8 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
p.time);
if (p.time && channels.getByIndex(mp.channel).role == meshtastic_Channel_Role_PRIMARY) {
- struct timeval tv;
- uint32_t secs = p.time;
-
- tv.tv_sec = secs;
- tv.tv_usec = 0;
-
// Set from phone RTC Quality to RTCQualityNTP since it should be approximately so
- perhapsSetRTC(isLocal ? RTCQualityNTP : RTCQualityFromNet, &tv);
+ trySetRtc(p, isLocal);
}
nodeDB->updatePosition(getFrom(&mp), p);
@@ -93,6 +87,33 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
return false; // Let others look at this message also if they want
}
+void PositionModule::alterReceivedProtobuf(meshtastic_MeshPacket &mp, meshtastic_Position *p)
+{
+ // Phone position packets need to be truncated to the channel precision
+ if (nodeDB->getNodeNum() == getFrom(&mp) && (precision < 32 && precision > 0)) {
+ LOG_DEBUG("Truncating phone position to channel precision %i\n", precision);
+ p->latitude_i = p->latitude_i & (UINT32_MAX << (32 - precision));
+ p->longitude_i = p->longitude_i & (UINT32_MAX << (32 - precision));
+
+ // We want the imprecise position to be the middle of the possible location, not
+ p->latitude_i += (1 << (31 - precision));
+ p->longitude_i += (1 << (31 - precision));
+
+ mp.decoded.payload.size =
+ pb_encode_to_bytes(mp.decoded.payload.bytes, sizeof(mp.decoded.payload.bytes), &meshtastic_Position_msg, p);
+ }
+}
+
+void PositionModule::trySetRtc(meshtastic_Position p, bool isLocal)
+{
+ struct timeval tv;
+ uint32_t secs = p.time;
+
+ tv.tv_sec = secs;
+ tv.tv_usec = 0;
+ perhapsSetRTC(isLocal ? RTCQualityNTP : RTCQualityFromNet, &tv);
+}
+
meshtastic_MeshPacket *PositionModule::allocReply()
{
if (precision == 0) {
diff --git a/src/modules/PositionModule.h b/src/modules/PositionModule.h
index 0e24e3a9e..1161159f7 100644
--- a/src/modules/PositionModule.h
+++ b/src/modules/PositionModule.h
@@ -42,6 +42,8 @@ class PositionModule : public ProtobufModule, private concu
*/
virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Position *p) override;
+ virtual void alterReceivedProtobuf(meshtastic_MeshPacket &mp, meshtastic_Position *p) override;
+
/** Messages can be received that have the want_response bit set. If set, this callback will be invoked
* so that subclasses can (optionally) send a response back to the original sender. */
virtual meshtastic_MeshPacket *allocReply() override;
@@ -52,6 +54,7 @@ class PositionModule : public ProtobufModule, private concu
private:
struct SmartPosition getDistanceTraveledSinceLastSend(meshtastic_PositionLite currentPosition);
meshtastic_MeshPacket *allocAtakPli();
+ void trySetRtc(meshtastic_Position p, bool isLocal);
uint32_t precision;
void sendLostAndFoundText();
diff --git a/src/modules/RoutingModule.cpp b/src/modules/RoutingModule.cpp
index a52328ca4..fe1abab05 100644
--- a/src/modules/RoutingModule.cpp
+++ b/src/modules/RoutingModule.cpp
@@ -51,7 +51,7 @@ uint8_t RoutingModule::getHopLimitForResponse(uint8_t hopStart, uint8_t hopLimit
uint8_t hopsUsed = hopStart < hopLimit ? config.lora.hop_limit : hopStart - hopLimit;
if (hopsUsed > config.lora.hop_limit) {
return hopsUsed; // If the request used more hops than the limit, use the same amount of hops
- } else if (hopsUsed + 2 < config.lora.hop_limit) {
+ } else if ((uint8_t)(hopsUsed + 2) < config.lora.hop_limit) {
return hopsUsed + 2; // Use only the amount of hops needed with some margin as the way back may be different
}
}
diff --git a/src/modules/esp32/PaxcounterModule.cpp b/src/modules/esp32/PaxcounterModule.cpp
index aad7b5d63..b9fdfcb63 100644
--- a/src/modules/esp32/PaxcounterModule.cpp
+++ b/src/modules/esp32/PaxcounterModule.cpp
@@ -1,5 +1,5 @@
#include "configuration.h"
-#if defined(ARCH_ESP32)
+#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_PAXCOUNTER
#include "Default.h"
#include "MeshService.h"
#include "PaxcounterModule.h"
diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp
index da1c204b8..508830203 100644
--- a/src/mqtt/MQTT.cpp
+++ b/src/mqtt/MQTT.cpp
@@ -54,9 +54,9 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
JSONObject json;
json = json_value->AsObject();
- // parse the channel name from the topic string by looking for "json/"
- const char *jsonSlash = "json/";
- char *ptr = strstr(topic, jsonSlash) + sizeof(jsonSlash) + 1; // set pointer to after "json/"
+ // parse the channel name from the topic string
+ // the topic has been checked above for having jsonTopic prefix, so just move past it
+ char *ptr = topic + jsonTopic.length();
ptr = strtok(ptr, "/") ? strtok(ptr, "/") : ptr; // if another "/" was added, parse string up to that character
meshtastic_Channel sendChannel = channels.getByName(ptr);
// We allow downlink JSON packets only on a channel named "mqtt"
@@ -76,6 +76,8 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
p->channel = json["channel"]->AsNumber();
if (json.find("to") != json.end() && json["to"]->IsNumber())
p->to = json["to"]->AsNumber();
+ if (json.find("hopLimit") != json.end() && json["hopLimit"]->IsNumber())
+ p->hop_limit = json["hopLimit"]->AsNumber();
if (jsonPayloadStr.length() <= sizeof(p->decoded.payload.bytes)) {
memcpy(p->decoded.payload.bytes, jsonPayloadStr.c_str(), jsonPayloadStr.length());
p->decoded.payload.size = jsonPayloadStr.length();
@@ -105,6 +107,8 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
p->channel = json["channel"]->AsNumber();
if (json.find("to") != json.end() && json["to"]->IsNumber())
p->to = json["to"]->AsNumber();
+ if (json.find("hopLimit") != json.end() && json["hopLimit"]->IsNumber())
+ p->hop_limit = json["hopLimit"]->AsNumber();
p->decoded.payload.size =
pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes),
&meshtastic_Position_msg, &pos); // make the Data protobuf from position
@@ -548,7 +552,10 @@ void MQTT::perhapsReportToMap()
} else {
if (map_position_precision == 0 || (localPosition.latitude_i == 0 && localPosition.longitude_i == 0)) {
last_report_to_map = millis();
- LOG_WARN("MQTT Map reporting is enabled, but precision is 0 or no position available.\n");
+ if (map_position_precision == 0)
+ LOG_WARN("MQTT Map reporting is enabled, but precision is 0\n");
+ if (localPosition.latitude_i == 0 && localPosition.longitude_i == 0)
+ LOG_WARN("MQTT Map reporting is enabled, but no position available.\n");
return;
}
@@ -904,6 +911,7 @@ bool MQTT::isValidJsonEnvelope(JSONObject &json)
{
// if "sender" is provided, avoid processing packets we uplinked
return (json.find("sender") != json.end() ? (json["sender"]->AsString().compare(owner.id) != 0) : true) &&
+ (json.find("hopLimit") != json.end() ? json["hopLimit"]->IsNumber() : true) && // hop limit should be a number
(json.find("from") != json.end()) && json["from"]->IsNumber() &&
(json["from"]->AsNumber() == nodeDB->getNodeNum()) && // only accept message if the "from" is us
(json.find("type") != json.end()) && json["type"]->IsString() && // should specify a type
diff --git a/src/platform/nrf52/architecture.h b/src/platform/nrf52/architecture.h
index 35cd4fd84..3be3e7e55 100644
--- a/src/platform/nrf52/architecture.h
+++ b/src/platform/nrf52/architecture.h
@@ -52,6 +52,8 @@
#define HW_VENDOR meshtastic_HardwareModel_CANARYONE
#elif defined(NORDIC_PCA10059)
#define HW_VENDOR meshtastic_HardwareModel_NRF52840_PCA10059
+#elif defined(TWC_MESH_V4)
+#define HW_VENDOR meshtastic_HardwareModel_TWC_MESH_V4
#elif defined(PRIVATE_HW) || defined(FEATHER_DIY)
#define HW_VENDOR meshtastic_HardwareModel_PRIVATE_HW
#else
@@ -110,4 +112,4 @@
#if !defined(PIN_SERIAL_RX) && !defined(NRF52840_XXAA)
// No serial ports on this board - ONLY use segger in memory console
#define USE_SEGGER
-#endif
+#endif
\ No newline at end of file
diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp
index a04c9c12c..d86ac6677 100644
--- a/src/platform/portduino/PortduinoGlue.cpp
+++ b/src/platform/portduino/PortduinoGlue.cpp
@@ -136,6 +136,7 @@ void portduinoSetup()
settingsMap[use_sx1262] = false;
settingsMap[use_rf95] = false;
settingsMap[use_sx1280] = false;
+ settingsMap[use_sx1268] = false;
if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as("") == "sx1262") {
settingsMap[use_sx1262] = true;
@@ -143,6 +144,8 @@ void portduinoSetup()
settingsMap[use_rf95] = true;
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as("") == "sx1280") {
settingsMap[use_sx1280] = true;
+ } else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as("") == "sx1268") {
+ settingsMap[use_sx1268] = true;
}
settingsMap[dio2_as_rf_switch] = yamlConfig["Lora"]["DIO2_AS_RF_SWITCH"].as(false);
settingsMap[dio3_tcxo_voltage] = yamlConfig["Lora"]["DIO3_TCXO_VOLTAGE"].as(false);
@@ -221,6 +224,7 @@ void portduinoSetup()
settingsMap[touchscreenIRQ] = yamlConfig["Touchscreen"]["IRQ"].as(-1);
settingsMap[touchscreenBusFrequency] = yamlConfig["Touchscreen"]["BusFrequency"].as(1000000);
settingsMap[touchscreenRotate] = yamlConfig["Touchscreen"]["Rotate"].as(-1);
+ settingsMap[touchscreenI2CAddr] = yamlConfig["Touchscreen"]["I2CAddr"].as(-1);
if (yamlConfig["Touchscreen"]["spidev"]) {
settingsStrings[touchscreenspidev] = "/dev/" + yamlConfig["Touchscreen"]["spidev"].as("");
}
@@ -332,4 +336,4 @@ int initGPIOPin(int pinNum, std::string gpioChipName)
std::cout << "Warning, cannot claim pin " << gpio_name << (p ? p.__cxa_exception_type()->name() : "null") << std::endl;
return ERRNO_DISABLED;
}
-}
+}
\ No newline at end of file
diff --git a/src/platform/portduino/PortduinoGlue.h b/src/platform/portduino/PortduinoGlue.h
index ed2954eef..94cdbf2f8 100644
--- a/src/platform/portduino/PortduinoGlue.h
+++ b/src/platform/portduino/PortduinoGlue.h
@@ -13,6 +13,7 @@ enum configNames {
dio3_tcxo_voltage,
use_rf95,
use_sx1280,
+ use_sx1268,
user,
gpiochip,
spidev,
@@ -21,6 +22,7 @@ enum configNames {
touchscreenModule,
touchscreenCS,
touchscreenIRQ,
+ touchscreenI2CAddr,
touchscreenBusFrequency,
touchscreenRotate,
touchscreenspidev,
diff --git a/src/sleep.cpp b/src/sleep.cpp
index e58c3872a..fe73a755c 100644
--- a/src/sleep.cpp
+++ b/src/sleep.cpp
@@ -211,7 +211,7 @@ void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false)
// esp_wifi_stop();
waitEnterSleep(skipPreflight);
-#ifdef ARCH_ESP32
+#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_BLUETOOTH
// Full shutdown of bluetooth hardware
if (nimbleBluetooth)
nimbleBluetooth->deinit();
diff --git a/variants/Dongle_nRF52840-pca10059-v1/variant.cpp b/variants/Dongle_nRF52840-pca10059-v1/variant.cpp
index 8c6bf039c..2fc87c718 100644
--- a/variants/Dongle_nRF52840-pca10059-v1/variant.cpp
+++ b/variants/Dongle_nRF52840-pca10059-v1/variant.cpp
@@ -29,10 +29,7 @@ const uint32_t g_ADigitalPinMap[] = {
void initVariant()
{
- // LED1 & LED2
+ // LED1
pinMode(PIN_LED1, OUTPUT);
ledOff(PIN_LED1);
-
- pinMode(PIN_LED2, OUTPUT);
- ledOff(PIN_LED2);
-}
+}
\ No newline at end of file
diff --git a/variants/Dongle_nRF52840-pca10059-v1/variant.h b/variants/Dongle_nRF52840-pca10059-v1/variant.h
index 533367a30..2318450eb 100644
--- a/variants/Dongle_nRF52840-pca10059-v1/variant.h
+++ b/variants/Dongle_nRF52840-pca10059-v1/variant.h
@@ -43,16 +43,12 @@ extern "C" {
#define NUM_ANALOG_OUTPUTS (0)
// LEDs
-#define PIN_LED1 (0 + 12) // Blue LED P1.12
-#define PIN_LED2 (0 + 6) // Built in Green P0.06
-
-// Green Built in LED1
-// #define PIN_LED1 (0 + 6) // LED1 P1.15
-
-// RGB NeoPixel LED2
-// #define PIN_LED1 (0 + 8) Red
-// #define PIN_LED1 (32 + 9) Green
-// #define PIN_LED1 (0 + 12) Blue
+#define PIN_LED1 (0 + 6) // Built in Green P0.06
+#define PIN_LED2 (0 + 6) // Just here for completeness
+#define RGBLED_RED (0 + 8) // Red of RGB P0.08
+#define RGBLED_GREEN (32 + 9) // Green of RGB P1.09
+#define RGBLED_BLUE (0 + 12) // Blue of RGB P0.12
+#define RGBLED_CA // comment out this line if you have a common cathode type, as defined use common anode logic
#define LED_BUILTIN PIN_LED1
#define LED_CONN PIN_LED2
@@ -168,4 +164,4 @@ static const uint8_t SCK = PIN_SPI_SCK;
* Arduino objects - C++ only
*----------------------------------------------------------------------------*/
-#endif
\ No newline at end of file
+#endif
diff --git a/variants/TWC_mesh_v4/platformio.ini b/variants/TWC_mesh_v4/platformio.ini
new file mode 100644
index 000000000..9cf25c685
--- /dev/null
+++ b/variants/TWC_mesh_v4/platformio.ini
@@ -0,0 +1,10 @@
+[env:TWC_mesh_v4]
+extends = nrf52840_base
+board = TWC_mesh_v4
+board_level = extra
+build_flags = ${nrf52840_base.build_flags} -I variants/TWC_mesh_v4 -D TWC_mesh_v4 -L".pio\libdeps\TWC_mesh_v4\BSEC2 Software Library\src\cortex-m4\fpv4-sp-d16-hard"
+build_src_filter = ${nrf52_base.build_src_filter} +<../variants/TWC_mesh_v4>
+lib_deps =
+ ${nrf52840_base.lib_deps}
+ zinggjm/GxEPD2@^1.4.9
+debug_tool = jlink
\ No newline at end of file
diff --git a/variants/TWC_mesh_v4/variant.cpp b/variants/TWC_mesh_v4/variant.cpp
new file mode 100644
index 000000000..b3712346d
--- /dev/null
+++ b/variants/TWC_mesh_v4/variant.cpp
@@ -0,0 +1,38 @@
+/*
+ Copyright (c) 2014-2015 Arduino LLC. All right reserved.
+ Copyright (c) 2016 Sandeep Mistry All right reserved.
+ Copyright (c) 2018, Adafruit Industries (adafruit.com)
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Lesser General Public License for more details.
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "variant.h"
+#include "nrf.h"
+#include "wiring_constants.h"
+#include "wiring_digital.h"
+
+const uint32_t g_ADigitalPinMap[] = {
+ // P0
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+
+ // P1
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47};
+
+void initVariant()
+{
+ // LED1 & LED2
+ pinMode(PIN_LED1, OUTPUT);
+ ledOff(PIN_LED1);
+
+ pinMode(PIN_LED2, OUTPUT);
+ ledOff(PIN_LED2);
+}
\ No newline at end of file
diff --git a/variants/TWC_mesh_v4/variant.h b/variants/TWC_mesh_v4/variant.h
new file mode 100644
index 000000000..6a6f541e6
--- /dev/null
+++ b/variants/TWC_mesh_v4/variant.h
@@ -0,0 +1,133 @@
+#ifndef _VARIANT_TWC_MESH_V4_
+#define _VARIANT_TWC_MESH_V4_
+
+#define PCA10059
+
+/** Master clock frequency */
+#define VARIANT_MCK (64000000ul)
+
+#define USE_LFXO // Board uses 32khz crystal for LF
+// define USE_LFRC // Board uses RC for LF
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+
+#include "WVariant.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+// Number of pins defined in PinDescription array
+#define PINS_COUNT (48)
+#define NUM_DIGITAL_PINS (48)
+#define NUM_ANALOG_INPUTS (6)
+#define NUM_ANALOG_OUTPUTS (0)
+
+// LEDs
+#define PIN_LED1 (32 + 10) // Blue LED P1.10
+#define PIN_LED2 (32 + 15) // Built in Green P1.15
+
+// RGB NeoPixel LED2
+// #define PIN_LED1 (0 + 8) Red
+// #define PIN_LED1 (32 + 9) Green
+// #define PIN_LED1 (0 + 12) Blue
+
+#define LED_BUILTIN PIN_LED1
+#define LED_CONN PIN_LED2
+
+#define LED_GREEN PIN_LED1
+#define LED_BLUE PIN_LED2
+
+#define LED_STATE_ON 0 // State when LED is litted
+
+/*
+ * Buttons
+ */
+#define PIN_BUTTON1 (32 + 2) // BTN_DN P1.02 Built in button
+
+/*
+ * Analog pins
+ */
+#define PIN_A0 (0 + 29) // using VDIV (A6 / P0.29)
+
+static const uint8_t A0 = PIN_A0;
+#define ADC_RESOLUTION 14
+
+// Other pins
+#define PIN_AREF (-1) // AREF Not yet used
+
+static const uint8_t AREF = PIN_AREF;
+
+/*
+ * Serial interfaces
+ */
+#define PIN_SERIAL1_RX (0 + 24)
+#define PIN_SERIAL1_TX (0 + 25)
+
+// Connected to Jlink CDC
+#define PIN_SERIAL2_RX (-1)
+#define PIN_SERIAL2_TX (-1)
+
+/*
+ * SPI Interfaces
+ */
+#define SPI_INTERFACES_COUNT 1
+
+#define PIN_SPI_MISO (0 + 15) // MISO P0.15
+#define PIN_SPI_MOSI (0 + 13) // MOSI P0.13
+#define PIN_SPI_SCK (0 + 14) // SCK P0.14
+
+static const uint8_t SS = (0 + 6); // LORA_CS P0.6
+static const uint8_t MOSI = PIN_SPI_MOSI;
+static const uint8_t MISO = PIN_SPI_MISO;
+static const uint8_t SCK = PIN_SPI_SCK;
+
+////#define USE_EINK
+#define USE_SSD1306
+
+/*
+ * Wire Interfaces
+ */
+#define WIRE_INTERFACES_COUNT 1
+
+#define PIN_WIRE_SDA (0 + 12) // SDA P0.12
+#define PIN_WIRE_SCL (0 + 11) // SCL P0.11
+
+// NiceRF 868 LoRa module
+#define USE_SX1262
+#define USE_LLCC68
+
+#define SX126X_CS (0 + 6) // LORA_CS P0.06
+#define SX126X_DIO1 (0 + 7) // DIO1 P0.07
+#define SX126X_BUSY (0 + 26) // LORA_BUSY P0.26
+#define SX126X_RESET (0 + 27) // LORA_RESET P0.27
+#define SX126X_DIO3_TCXO_VOLTAGE 1.8
+
+#define PIN_GPS_EN (-1)
+#define PIN_GPS_PPS (-1) // Pulse per second input from the GPS
+
+#define GPS_RX_PIN PIN_SERIAL1_RX
+#define GPS_TX_PIN PIN_SERIAL1_TX
+
+// Battery
+// The battery sense is hooked to pin A6 (0.29)
+#define BATTERY_PIN PIN_A0
+// and has 12 bit resolution
+#define BATTERY_SENSE_RESOLUTION_BITS 12
+#define BATTERY_SENSE_RESOLUTION 4096.0
+#undef AREF_VOLTAGE
+#define AREF_VOLTAGE 3.0
+#define VBAT_AR_INTERNAL AR_INTERNAL_3_0
+#define ADC_MULTIPLIER (2.0F)
+
+#ifdef __cplusplus
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * Arduino objects - C++ only
+ *----------------------------------------------------------------------------*/
+
+#endif
\ No newline at end of file
diff --git a/variants/betafpv_2400_tx_micro/platformio.ini b/variants/betafpv_2400_tx_micro/platformio.ini
index 82fe2a9e4..531e8532d 100644
--- a/variants/betafpv_2400_tx_micro/platformio.ini
+++ b/variants/betafpv_2400_tx_micro/platformio.ini
@@ -15,4 +15,4 @@ upload_protocol = esptool
upload_speed = 460800
lib_deps =
${esp32_base.lib_deps}
- makuna/NeoPixelBus@^2.7.1
+ adafruit/Adafruit NeoPixel @ ^1.12.0
\ No newline at end of file
diff --git a/variants/betafpv_2400_tx_micro/variant.h b/variants/betafpv_2400_tx_micro/variant.h
index 8c615d168..fd06183ee 100644
--- a/variants/betafpv_2400_tx_micro/variant.h
+++ b/variants/betafpv_2400_tx_micro/variant.h
@@ -1,5 +1,4 @@
// https://betafpv.com/products/elrs-micro-tx-module
-#include
// 0.96" OLED
#define I2C_SDA 22
@@ -15,7 +14,11 @@
#define LORA_CS 5
#define RF95_FAN_EN 17
-#define LED_PIN 16 // This is a LED_WS2812 not a standard LED
+// #define LED_PIN 16 // This is a LED_WS2812 not a standard LED
+#define HAS_NEOPIXEL // Enable the use of neopixels
+#define NEOPIXEL_COUNT 1 // How many neopixels are connected
+#define NEOPIXEL_DATA 16 // gpio pin used to send data to the neopixels
+#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) // type of neopixels in use
#define BUTTON_PIN 25
#define BUTTON_NEED_PULLUP
@@ -31,4 +34,4 @@
#define SX128X_TXEN 26
#define SX128X_RXEN 27
#define SX128X_RESET LORA_RESET
-#define SX128X_MAX_POWER 13
+#define SX128X_MAX_POWER 13
\ No newline at end of file
diff --git a/variants/esp32-s3-pico/platformio.ini b/variants/esp32-s3-pico/platformio.ini
index ef737d98a..ff77c30e0 100644
--- a/variants/esp32-s3-pico/platformio.ini
+++ b/variants/esp32-s3-pico/platformio.ini
@@ -22,4 +22,4 @@ build_flags = ${esp32_base.build_flags}
lib_deps = ${esp32s3_base.lib_deps}
zinggjm/GxEPD2@^1.5.3
- ;adafruit/Adafruit NeoPixel@^1.10.7
+ adafruit/Adafruit NeoPixel @ ^1.12.0
\ No newline at end of file
diff --git a/variants/esp32-s3-pico/variant.h b/variants/esp32-s3-pico/variant.h
index 87378d378..bfcb6059d 100644
--- a/variants/esp32-s3-pico/variant.h
+++ b/variants/esp32-s3-pico/variant.h
@@ -10,6 +10,10 @@
// #define LED_PIN PIN_LED
// Board has RGB LED 21
+#define HAS_NEOPIXEL // Enable the use of neopixels
+#define NEOPIXEL_COUNT 1 // How many neopixels are connected
+#define NEOPIXEL_DATA 21 // gpio pin used to send data to the neopixels
+#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) // type of neopixels in use
// The usbPower state is revered ?
// DEBUG | ??:??:?? 365 [Power] Battery: usbPower=0, isCharging=0, batMv=4116, batPct=90
diff --git a/variants/heltec_esp32c3/variant.h b/variants/heltec_esp32c3/variant.h
index 6641f9d21..360d9bf1f 100644
--- a/variants/heltec_esp32c3/variant.h
+++ b/variants/heltec_esp32c3/variant.h
@@ -1,24 +1,16 @@
-#define I2C_SDA 1
-#define I2C_SCL 0
-
#define BUTTON_PIN 9
-#define BUTTON_NEED_PULLUP
-// LED flashes brighter
+// LED pin on HT-DEV-ESP_V2 and HT-DEV-ESP_V3
// https://resource.heltec.cn/download/HT-CT62/HT-CT62_Reference_Design.pdf
-#define LED_PIN 18 // LED
-#define LED_INVERTED 1
+// https://resource.heltec.cn/download/HT-DEV-ESP/HT-DEV-ESP_V3_Sch.pdf
+#define LED_PIN 2 // LED
+#define LED_INVERTED 0
-#define HAS_SCREEN 1
+#define HAS_SCREEN 0
#define HAS_GPS 0
#undef GPS_RX_PIN
#undef GPS_TX_PIN
-#undef LORA_SCK
-#undef LORA_MISO
-#undef LORA_MOSI
-#undef LORA_CS
-
#define USE_SX1262
#define LORA_SCK 10
#define LORA_MISO 6
diff --git a/variants/lora_relay_v1/platformio.ini b/variants/lora_relay_v1/platformio.ini
index 77402aadc..8660bf64a 100644
--- a/variants/lora_relay_v1/platformio.ini
+++ b/variants/lora_relay_v1/platformio.ini
@@ -20,4 +20,5 @@ build_src_filter = ${nrf52_base.build_src_filter} +<../variants/lora_relay_v1>
lib_deps =
${nrf52840_base.lib_deps}
sparkfun/SparkFun BQ27441 LiPo Fuel Gauge Arduino Library@^1.1.0
- bodmer/TFT_eSPI@^2.4.76
\ No newline at end of file
+ bodmer/TFT_eSPI@^2.4.76
+ adafruit/Adafruit NeoPixel @ ^1.12.0
\ No newline at end of file
diff --git a/variants/lora_relay_v1/variant.h b/variants/lora_relay_v1/variant.h
index 9cfb69337..54bc87b68 100644
--- a/variants/lora_relay_v1/variant.h
+++ b/variants/lora_relay_v1/variant.h
@@ -44,7 +44,11 @@ extern "C" {
// LEDs
#define PIN_LED1 (3)
#define PIN_LED2 (4)
-#define PIN_NEOPIXEL (8)
+// #define PIN_NEOPIXEL (8)
+#define HAS_NEOPIXEL // Enable the use of neopixels
+#define NEOPIXEL_COUNT 1 // How many neopixels are connected
+#define NEOPIXEL_DATA 8 // gpio pin used to send data to the neopixels
+#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) // type of neopixels in use
#define LED_BUILTIN PIN_LED1
#define LED_CONN PIN_LED2
diff --git a/variants/lora_relay_v2/platformio.ini b/variants/lora_relay_v2/platformio.ini
index 4439d8a46..cd2109f00 100644
--- a/variants/lora_relay_v2/platformio.ini
+++ b/variants/lora_relay_v2/platformio.ini
@@ -23,3 +23,4 @@ lib_deps =
${nrf52840_base.lib_deps}
sparkfun/SparkFun BQ27441 LiPo Fuel Gauge Arduino Library@^1.1.0
bodmer/TFT_eSPI@^2.4.76
+ adafruit/Adafruit NeoPixel @ ^1.12.0
\ No newline at end of file
diff --git a/variants/lora_relay_v2/variant.h b/variants/lora_relay_v2/variant.h
index 3afe8620e..6ef7ad7d6 100644
--- a/variants/lora_relay_v2/variant.h
+++ b/variants/lora_relay_v2/variant.h
@@ -61,7 +61,12 @@ extern "C" {
// LEDs
#define PIN_LED1 (3)
#define PIN_LED2 (4)
-#define PIN_NEOPIXEL (8)
+// #define PIN_NEOPIXEL (8)
+#define HAS_NEOPIXEL // Enable the use of neopixels
+#define NEOPIXEL_COUNT 1 // How many neopixels are connected
+#define NEOPIXEL_DATA 8 // gpio pin used to send data to the neopixels
+#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) // type of neopixels in use
+
#define PIN_BUZZER (40)
#define LED_BUILTIN PIN_LED1
diff --git a/variants/my_esp32s3_diy_eink/platformio.ini b/variants/my_esp32s3_diy_eink/platformio.ini
index 966bc580e..e81f2c1ab 100644
--- a/variants/my_esp32s3_diy_eink/platformio.ini
+++ b/variants/my_esp32s3_diy_eink/platformio.ini
@@ -13,7 +13,7 @@ platform_packages =
lib_deps =
${esp32_base.lib_deps}
zinggjm/GxEPD2@^1.5.1
- adafruit/Adafruit NeoPixel@^1.10.7
+ adafruit/Adafruit NeoPixel @ ^1.12.0
build_unflags = -DARDUINO_USB_MODE=1
build_flags =
;${esp32_base.build_flags} -D MY_ESP32S3_DIY -I variants/my_esp32s3_diy_eink
@@ -24,4 +24,4 @@ build_flags =
-DEINK_HEIGHT=128
-DBOARD_HAS_PSRAM
-mfix-esp32-psram-cache-issue
- -DARDUINO_USB_MODE=0
+ -DARDUINO_USB_MODE=0
\ No newline at end of file
diff --git a/variants/my_esp32s3_diy_eink/variant.h b/variants/my_esp32s3_diy_eink/variant.h
index 516fa7f34..024f912dd 100644
--- a/variants/my_esp32s3_diy_eink/variant.h
+++ b/variants/my_esp32s3_diy_eink/variant.h
@@ -12,6 +12,10 @@
#define I2C_SCL 17 // 2
// #define LED_PIN 38 // This is a RGB LED not a standard LED
+#define HAS_NEOPIXEL // Enable the use of neopixels
+#define NEOPIXEL_COUNT 1 // How many neopixels are connected
+#define NEOPIXEL_DATA 38 // gpio pin used to send data to the neopixels
+#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) // type of neopixels in use
#define BUTTON_PIN 0 // This is the BOOT button
#define BUTTON_NEED_PULLUP
diff --git a/variants/my_esp32s3_diy_oled/platformio.ini b/variants/my_esp32s3_diy_oled/platformio.ini
index 9b8b09f7f..2d7a5cd91 100644
--- a/variants/my_esp32s3_diy_oled/platformio.ini
+++ b/variants/my_esp32s3_diy_oled/platformio.ini
@@ -12,11 +12,11 @@ platform_packages =
tool-esptoolpy@^1.40500.0
lib_deps =
${esp32_base.lib_deps}
- adafruit/Adafruit NeoPixel@^1.10.7
+ adafruit/Adafruit NeoPixel @ ^1.12.0
build_unflags = -DARDUINO_USB_MODE=1
build_flags =
;${esp32_base.build_flags} -D MY_ESP32S3_DIY -I variants/my_esp32s3_diy_oled
${esp32_base.build_flags} -D PRIVATE_HW -I variants/my_esp32s3_diy_oled
-DBOARD_HAS_PSRAM
-mfix-esp32-psram-cache-issue
- -DARDUINO_USB_MODE=0
+ -DARDUINO_USB_MODE=0
\ No newline at end of file
diff --git a/variants/my_esp32s3_diy_oled/variant.h b/variants/my_esp32s3_diy_oled/variant.h
index 6dd18c236..8a3a39003 100644
--- a/variants/my_esp32s3_diy_oled/variant.h
+++ b/variants/my_esp32s3_diy_oled/variant.h
@@ -12,6 +12,10 @@
#define I2C_SCL 17 // 2
// #define LED_PIN 38 // This is a RGB LED not a standard LED
+#define HAS_NEOPIXEL // Enable the use of neopixels
+#define NEOPIXEL_COUNT 1 // How many neopixels are connected
+#define NEOPIXEL_DATA 38 // gpio pin used to send data to the neopixels
+#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) // type of neopixels in use
#define BUTTON_PIN 0 // This is the BOOT button
#define BUTTON_NEED_PULLUP
@@ -53,4 +57,4 @@
// #define PIN_EINK_DC 1
// #define PIN_EINK_RES (-1)
// #define PIN_EINK_SCLK 5
-// #define PIN_EINK_MOSI 6
+// #define PIN_EINK_MOSI 6
\ No newline at end of file
diff --git a/variants/rak11310/variant.h b/variants/rak11310/variant.h
index ba3d4fed7..f9dcbd91a 100644
--- a/variants/rak11310/variant.h
+++ b/variants/rak11310/variant.h
@@ -14,7 +14,7 @@
#define BATTERY_PIN 26
#define BATTERY_SENSE_RESOLUTION_BITS ADC_RESOLUTION
// ratio of voltage divider = 3.0 (R17=200k, R18=100k)
-#define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic
+#define ADC_MULTIPLIER 1.84
#define DETECTION_SENSOR_EN 28
@@ -47,4 +47,4 @@
// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
-#endif
\ No newline at end of file
+#endif
diff --git a/variants/unphone/platformio.ini b/variants/unphone/platformio.ini
index dad9a7177..e4a92fe4c 100644
--- a/variants/unphone/platformio.ini
+++ b/variants/unphone/platformio.ini
@@ -13,6 +13,7 @@ build_unflags =
-D ARDUINO_USB_MODE
build_flags = ${esp32_base.build_flags}
+ ;-D BOARD_HAS_PSRAM // what's up with this - doesn't seem to be recognised at boot
-D UNPHONE
-I variants/unphone
-D ARDUINO_USB_MODE=0
@@ -27,4 +28,5 @@ build_src_filter = ${esp32_base.build_src_filter} +<../variants/unphone>
lib_deps = ${esp32s3_base.lib_deps}
lovyan03/LovyanGFX @ ^1.1.8
- https://gitlab.com/hamishcunningham/unphonelibrary#meshtastic @ ^9.0.0
\ No newline at end of file
+ https://gitlab.com/hamishcunningham/unphonelibrary#meshtastic @ ^9.0.0
+ adafruit/Adafruit NeoPixel @ ^1.12.0
\ No newline at end of file
diff --git a/variants/unphone/variant.cpp b/variants/unphone/variant.cpp
index 3f6d1c54d..7884f82e3 100644
--- a/variants/unphone/variant.cpp
+++ b/variants/unphone/variant.cpp
@@ -10,6 +10,7 @@ void initVariant()
unphone.printWakeupReason(); // what woke us up? (stored, not printed :|)
unphone.checkPowerSwitch(); // if power switch is off, shutdown
unphone.backlight(false); // setup backlight and make sure its off
+ unphone.expanderPower(true); // enable power to expander / hat / sheild
for (int i = 0; i < 3; i++) { // buzz a bit
unphone.vibe(true);
diff --git a/variants/unphone/variant.h b/variants/unphone/variant.h
index 180fdfe2c..7d5c30f79 100644
--- a/variants/unphone/variant.h
+++ b/variants/unphone/variant.h
@@ -48,7 +48,7 @@
#undef GPS_RX_PIN
#undef GPS_TX_PIN
-#define HAS_SDCARD 1
+// #define HAS_SDCARD 1 // causes hang if defined
#define SDCARD_CS 43
#define LED_PIN 13 // the red part of the RGB LED
diff --git a/variants/xiao_ble/variant.h b/variants/xiao_ble/variant.h
index e2b8eb613..77af08278 100644
--- a/variants/xiao_ble/variant.h
+++ b/variants/xiao_ble/variant.h
@@ -181,6 +181,7 @@ static const uint8_t SCL = PIN_WIRE_SCL;
#define BAT_READ \
14 // P0_14 = 14 Reads battery voltage from divider on signal board. (PIN_VBAT is reading voltage divider on XIAO and is
// program pin 32 / or P0.31)
+#define BATTERY_SENSE_RESOLUTION_BITS 10
#define CHARGE_LED 23 // P0_17 = 17 D23 YELLOW CHARGE LED
#define HICHG 22 // P0_13 = 13 D22 Charge-select pin for Lipo for 100 mA instead of default 50mA charge
diff --git a/version.properties b/version.properties
index 485f55130..36607a956 100644
--- a/version.properties
+++ b/version.properties
@@ -1,4 +1,4 @@
[VERSION]
major = 2
minor = 3
-build = 7
+build = 8