diff --git a/.github/workflows/build_native.yml b/.github/workflows/build_native.yml index a57da5dfb..74bc074aa 100644 --- a/.github/workflows/build_native.yml +++ b/.github/workflows/build_native.yml @@ -14,7 +14,7 @@ jobs: shell: bash run: | sudo apt-get update --fix-missing - sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev + sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev libi2c-dev - name: Checkout code uses: actions/checkout@v4 diff --git a/.github/workflows/build_raspbian.yml b/.github/workflows/build_raspbian.yml index 1826504f0..ac63dfea4 100644 --- a/.github/workflows/build_raspbian.yml +++ b/.github/workflows/build_raspbian.yml @@ -14,7 +14,7 @@ jobs: shell: bash run: | sudo apt-get update -y --fix-missing - sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev + sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev libi2c-dev - name: Checkout code uses: actions/checkout@v4 diff --git a/.github/workflows/build_raspbian_armv7l.yml b/.github/workflows/build_raspbian_armv7l.yml index fd53585a5..565d9a0dc 100644 --- a/.github/workflows/build_raspbian_armv7l.yml +++ b/.github/workflows/build_raspbian_armv7l.yml @@ -14,7 +14,7 @@ jobs: shell: bash run: | sudo apt-get update -y --fix-missing - sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev + sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev libi2c-dev - name: Checkout code uses: actions/checkout@v4 diff --git a/.github/workflows/package_amd64.yml b/.github/workflows/package_amd64.yml index 782ef479b..c6e82e1be 100644 --- a/.github/workflows/package_amd64.yml +++ b/.github/workflows/package_amd64.yml @@ -79,7 +79,7 @@ jobs: maintainer: Jonathan Bennett version: ${{ steps.version.outputs.version }} # refs/tags/v*.*.* arch: amd64 - depends: libyaml-cpp0.7, openssl, libulfius2.7 + depends: libyaml-cpp0.7, openssl, libulfius2.7, libi2c0 desc: Native Linux Meshtastic binary. - uses: actions/upload-artifact@v4 @@ -87,4 +87,4 @@ jobs: name: meshtasticd_${{ steps.version.outputs.version }}_amd64.deb overwrite: true path: | - ./*.deb \ No newline at end of file + ./*.deb diff --git a/.github/workflows/package_raspbian.yml b/.github/workflows/package_raspbian.yml index aef8905f8..a4cd49573 100644 --- a/.github/workflows/package_raspbian.yml +++ b/.github/workflows/package_raspbian.yml @@ -79,7 +79,7 @@ jobs: maintainer: Jonathan Bennett version: ${{ steps.version.outputs.version }} # refs/tags/v*.*.* arch: arm64 - depends: libyaml-cpp0.7, openssl, libulfius2.7 + depends: libyaml-cpp0.7, openssl, libulfius2.7, libi2c0 desc: Native Linux Meshtastic binary. - uses: actions/upload-artifact@v4 @@ -87,4 +87,4 @@ jobs: name: meshtasticd_${{ steps.version.outputs.version }}_arm64.deb overwrite: true path: | - ./*.deb \ No newline at end of file + ./*.deb diff --git a/.github/workflows/package_raspbian_armv7l.yml b/.github/workflows/package_raspbian_armv7l.yml index ddb84d4a7..c4cc5c673 100644 --- a/.github/workflows/package_raspbian_armv7l.yml +++ b/.github/workflows/package_raspbian_armv7l.yml @@ -79,7 +79,7 @@ jobs: maintainer: Jonathan Bennett version: ${{ steps.version.outputs.version }} # refs/tags/v*.*.* arch: armhf - depends: libyaml-cpp0.7, openssl, libulfius2.7 + depends: libyaml-cpp0.7, openssl, libulfius2.7, libi2c0 desc: Native Linux Meshtastic binary. - uses: actions/upload-artifact@v4 @@ -87,4 +87,4 @@ jobs: name: meshtasticd_${{ steps.version.outputs.version }}_armhf.deb overwrite: true path: | - ./*.deb \ No newline at end of file + ./*.deb diff --git a/Dockerfile b/Dockerfile index fc34fbd4c..ca216e04b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,7 @@ USER root # trunk-ignore(hadolint/DL3008): Use latest version of packages for buildchain RUN apt-get update && apt-get install --no-install-recommends -y wget python3 python3-pip python3-wheel python3-venv g++ zip git \ ca-certificates libgpiod-dev libyaml-cpp-dev libbluetooth-dev \ - libulfius-dev liborcania-dev libssl-dev pkg-config && \ + libusb-1.0-0-dev libulfius-dev liborcania-dev libssl-dev pkg-config && \ apt-get clean && rm -rf /var/lib/apt/lists/* && mkdir /tmp/firmware RUN groupadd -g 1000 mesh && useradd -ml -u 1000 -g 1000 mesh && chown mesh:mesh /tmp/firmware @@ -37,7 +37,7 @@ ENV TZ=Etc/UTC # trunk-ignore(terrascan/AC_DOCKER_0002): Known terrascan issue # trunk-ignore(hadolint/DL3008): Use latest version of packages for buildchain -RUN apt-get update && apt-get --no-install-recommends -y install libc-bin libc6 libgpiod2 libyaml-cpp0.7 libulfius2.7 liborcania2.3 libssl3 && \ +RUN apt-get update && apt-get --no-install-recommends -y install libc-bin libc6 libgpiod2 libyaml-cpp0.7 libulfius2.7 libusb-1.0-0-dev liborcania2.3 libssl3 && \ apt-get clean && rm -rf /var/lib/apt/lists/* RUN groupadd -g 1000 mesh && useradd -ml -u 1000 -g 1000 mesh @@ -51,4 +51,4 @@ VOLUME /home/mesh/data CMD [ "sh", "-cx", "./meshtasticd -d /home/mesh/data --hwid=${HWID:-$RANDOM}" ] -HEALTHCHECK NONE +HEALTHCHECK NONE \ No newline at end of file diff --git a/arch/portduino/portduino.ini b/arch/portduino/portduino.ini index 34f0dd8c9..777ce1e02 100644 --- a/arch/portduino/portduino.ini +++ b/arch/portduino/portduino.ini @@ -1,6 +1,6 @@ ; The Portduino based 'native' environment. Currently supported on Linux targets with real LoRa hardware (or simulated). [portduino_base] -platform = https://github.com/meshtastic/platform-native.git#73bd1a21183ca8b00c4ea58bb21315df31a50dff +platform = https://github.com/meshtastic/platform-native.git#562d189828f09fbf4c4093b3c0104bae9d8e9ff9 framework = arduino build_src_filter = @@ -34,7 +34,10 @@ build_flags = -Isrc/platform/portduino -DRADIOLIB_EEPROM_UNSUPPORTED -DPORTDUINO_LINUX_HARDWARE + -lpthread -lstdc++fs -lbluetooth -lgpiod - -lyaml-cpp \ No newline at end of file + -lyaml-cpp + -li2c + -std=c++17 \ No newline at end of file diff --git a/bin/config.d/femtofox/femtofox_EByte-E22-900M30S_Ebyte-E22-900M22S.yaml b/bin/config.d/femtofox/femtofox_EByte-E22-900M30S_Ebyte-E22-900M22S.yaml deleted file mode 100644 index 6c88b1eb2..000000000 --- a/bin/config.d/femtofox/femtofox_EByte-E22-900M30S_Ebyte-E22-900M22S.yaml +++ /dev/null @@ -1,16 +0,0 @@ ---- -Lora: -## Ebyte E22-900M30S, E22-900M22S with no external RF switching setup -## Will work with any module without RF switching, and with TCXO - Module: sx1262 - gpiochip: 1 # subtract 32 from the gpio numbers - DIO2_AS_RF_SWITCH: true - DIO3_TCXO_VOLTAGE: true - CS: 16 #pin6 / GPIO48 1C0 - IRQ: 23 #pin17 / GPIO55 1C7 - Busy: 22 #pin16 / GPIO54 1C6 - Reset: 25 #pin13 / GPIO57 1D1 - RXen: 24 #pin12 / GPIO56 1D0 - #TXen: bridge to DIO2 on E22 module - spidev: spidev0.0 - spiSpeed: 2000000 \ No newline at end of file diff --git a/bin/config.d/femtofox/femtofox_EByte-E22-900MM22S.yaml b/bin/config.d/femtofox/femtofox_EByte-E22-900MM22S.yaml deleted file mode 100644 index 451d5d3f4..000000000 --- a/bin/config.d/femtofox/femtofox_EByte-E22-900MM22S.yaml +++ /dev/null @@ -1,16 +0,0 @@ ---- -Lora: -## Ebyte E22-900MM22S with no external RF switching setup -## Will work with any module without RF switching and no TCXO - Module: sx1262 - gpiochip: 1 # subtract 32 from the gpio numbers - DIO2_AS_RF_SWITCH: true - DIO3_TCXO_VOLTAGE: true - CS: 16 #pin6 / GPIO48 1C0 - IRQ: 23 #pin17 / GPIO55 1C7 - Busy: 22 #pin16 / GPIO54 1C6 - Reset: 25 #pin13 / GPIO57 1D1 - RXen: 24 #pin12 / GPIO56 1D0 - #TXen: bridge to DIO2 on E22 module - spidev: spidev0.0 - spiSpeed: 2000000 \ No newline at end of file diff --git a/bin/config.d/femtofox/femtofox_Heltec-HT-RA62_Seeed-WIO-SX1262.yaml b/bin/config.d/femtofox/femtofox_Heltec-HT-RA62_Seeed-WIO-SX1262.yaml deleted file mode 100644 index d5f02b42c..000000000 --- a/bin/config.d/femtofox/femtofox_Heltec-HT-RA62_Seeed-WIO-SX1262.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -Lora: -## Heltec HT-RA62, Seeed WIO SX1262 -## Will work with any module with automatic RF switching, and with TCXO - Module: sx1262 - gpiochip: 1 # subtract 32 from the gpio numbers - DIO2_AS_RF_SWITCH: true - DIO3_TCXO_VOLTAGE: true - CS: 16 #pin6 (GPIO pin 48 1C0) - IRQ: 23 #pin17 (GPIO pin 55 1C7) - Reset: 25 #pin13 (GPIO pin 57 1D1) - Busy: 22 #pin16 (GPIO pin 54 1C6) - spidev: spidev0.0 #pins are (CS=6, CLK=7, MOSI=8, MISO=9) - spiSpeed: 2000000 \ No newline at end of file diff --git a/bin/config.d/femtofox/femtofox_LR1121_TCXO.yaml b/bin/config.d/femtofox/femtofox_LR1121_TCXO.yaml new file mode 100644 index 000000000..7aa860f61 --- /dev/null +++ b/bin/config.d/femtofox/femtofox_LR1121_TCXO.yaml @@ -0,0 +1,20 @@ +--- +Lora: +## Ebyte E80-900M22S +## This is a bit experimental +## +## + Module: lr1121 + gpiochip: 1 # subtract 32 from the gpio numbers + DIO3_TCXO_VOLTAGE: 1.8 + CS: 16 #pin6 / GPIO48 1C0 + IRQ: 23 #pin17 / GPIO55 1C7 + Busy: 22 #pin16 / GPIO54 1C6 + Reset: 25 #pin13 / GPIO57 1D1 + + + spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19) + spiSpeed: 2000000 + +General: + MACAddressSource: eth0 diff --git a/bin/config.d/femtofox/femtofox_SX1262_TCXO.yaml b/bin/config.d/femtofox/femtofox_SX1262_TCXO.yaml new file mode 100644 index 000000000..a4dec870a --- /dev/null +++ b/bin/config.d/femtofox/femtofox_SX1262_TCXO.yaml @@ -0,0 +1,21 @@ +--- +Lora: +## Ebyte E22-900M30S, E22-900M22S with or without external RF switching setup +## HT-RA62 (Has internal switching, but whatever) +## Seeed WIO SX1262 (already has TXEN-DIO2 link, but needs RXEN) +## Will work with any module with or without RF switching, and with TCXO + Module: sx1262 + gpiochip: 1 # subtract 32 from the gpio numbers + DIO2_AS_RF_SWITCH: true + DIO3_TCXO_VOLTAGE: true + CS: 16 #pin6 / GPIO48 1C0 + IRQ: 23 #pin17 / GPIO55 1C7 + Busy: 22 #pin16 / GPIO54 1C6 + Reset: 25 #pin13 / GPIO57 1D1 + RXen: 24 #pin12 / GPIO56 1D0 # Not strictly needed for auto-switching, but why complicate things? +# TXen: bridge to DIO2 on E22 module + spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19) + spiSpeed: 2000000 + +General: + MACAddressSource: eth0 diff --git a/bin/config.d/femtofox/femtofox_SX1262_XTAL.yaml b/bin/config.d/femtofox/femtofox_SX1262_XTAL.yaml new file mode 100644 index 000000000..6b956f3e3 --- /dev/null +++ b/bin/config.d/femtofox/femtofox_SX1262_XTAL.yaml @@ -0,0 +1,21 @@ +--- +Lora: +## Ebyte E22-900MM22S with no external RF switching setup +## Waveshare SX126X XXXM, AI Thinker RA-01SH +## Will work with any module with or without RF switching and no TCXO + + Module: sx1262 + gpiochip: 1 # subtract 32 from the gpio numbers + DIO2_AS_RF_SWITCH: true + DIO3_TCXO_VOLTAGE: false + CS: 16 #pin6 / GPIO48 1C0 + IRQ: 23 #pin17 / GPIO55 1C7 + Busy: 22 #pin16 / GPIO54 1C6 + Reset: 25 #pin13 / GPIO57 1D1 + RXen: 24 #pin12 / GPIO56 1D0 # Not strictly needed for auto-switching, but why complicate things? +# TXen: bridge to DIO2 on E22 module + spidev: spidev0.0 #pins are (CS=16, CLK=17, MOSI=18, MISO=19) + spiSpeed: 2000000 + +General: + MACAddressSource: eth0 diff --git a/bin/config.d/femtofox/femtofox_Waveshare-SX126X-XXXM_AI-Thinker-RA-01SH.yaml b/bin/config.d/femtofox/femtofox_Waveshare-SX126X-XXXM_AI-Thinker-RA-01SH.yaml deleted file mode 100644 index 23834adec..000000000 --- a/bin/config.d/femtofox/femtofox_Waveshare-SX126X-XXXM_AI-Thinker-RA-01SH.yaml +++ /dev/null @@ -1,13 +0,0 @@ ---- -Lora: -## Waveshare SX126X XXXM, AI Thinker RA-01SH -## Will work with any module with automatic RF switching, and with no TCXO - Module: sx1262 - gpiochip: 1 # subtract 32 from the gpio numbers - DIO2_AS_RF_SWITCH: true - CS: 16 #pin6 (GPIO pin 48 1C0) - IRQ: 23 #pin17 (GPIO pin 55 1C7) - Reset: 25 #pin13 (GPIO pin 57 1D1) - Busy: 22 #pin16 (GPIO pin 54 1C6) - spidev: spidev0.0 #pins are (CS=6, CLK=7, MOSI=8, MISO=9) - spiSpeed: 2000000 diff --git a/boards/esp32-s3-zero.json b/boards/esp32-s3-zero.json new file mode 100644 index 000000000..76cb34fa0 --- /dev/null +++ b/boards/esp32-s3-zero.json @@ -0,0 +1,41 @@ +{ + "build": { + "arduino": { + "partitions": "default.csv", + "memory_type": "qio_qspi" + }, + "core": "esp32", + "extra_flags": [ + "-DARDUINO_ESP32S3_DEV", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "psram_type": "qio", + "hwids": [["0x303A", "0x1001"]], + "mcu": "esp32s3", + "variant": "esp32s3" + }, + "connectivity": ["wifi", "bluetooth"], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": ["esp-builtin"], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": ["arduino", "espidf"], + "platforms": ["espressif32"], + "name": "Espressif ESP32-S3-FH4R2 (4 MB QD, 2MB PSRAM)", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 921600 + }, + "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/user-guide-devkitc-1.html", + "vendor": "Espressif" +} diff --git a/platformio.ini b/platformio.ini index 08d21665f..41f1ca764 100644 --- a/platformio.ini +++ b/platformio.ini @@ -160,4 +160,5 @@ lib_deps = https://github.com/KodinLanewave/INA3221@1.0.1 mprograms/QMC5883LCompass@1.2.3 dfrobot/DFRobot_RTU@1.0.3 - https://github.com/meshtastic/DFRobot_LarkWeatherStation#4de3a9cadef0f6a5220a8a906cf9775b02b0040d \ No newline at end of file + https://github.com/meshtastic/DFRobot_LarkWeatherStation#4de3a9cadef0f6a5220a8a906cf9775b02b0040d + robtillaart/INA226@0.6.0 diff --git a/src/Power.cpp b/src/Power.cpp index a354b74e2..ae0908ec6 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -72,8 +72,9 @@ static const uint8_t ext_chrg_detect_value = EXT_CHRG_DETECT_VALUE; #endif #if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO) -INA260Sensor ina260Sensor; INA219Sensor ina219Sensor; +INA226Sensor ina226Sensor; +INA260Sensor ina260Sensor; INA3221Sensor ina3221Sensor; #endif @@ -413,7 +414,20 @@ class AnalogBatteryLevel : public HasBatteryLevel #ifdef EXT_CHRG_DETECT return digitalRead(EXT_CHRG_DETECT) == ext_chrg_detect_value; #else +#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && \ + !defined(DISABLE_INA_CHARGING_DETECTION) + if (hasINA()) { + // get current flow from INA sensor - negative value means power flowing into the battery + // default assuming BATTERY+ <--> INA_VIN+ <--> SHUNT RESISTOR <--> INA_VIN- <--> LOAD + LOG_DEBUG("Using INA on I2C addr 0x%x for charging detection", config.power.device_battery_ina_address); +#if defined(INA_CHARGING_DETECTION_INVERT) + return getINACurrent() > 0; +#else + return getINACurrent() < 0; +#endif + } return isBatteryConnect() && isVbusIn(); +#endif #endif } @@ -450,6 +464,9 @@ class AnalogBatteryLevel : public HasBatteryLevel { if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) { return ina219Sensor.getBusVoltageMv(); + } else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA226].first == + config.power.device_battery_ina_address) { + return ina226Sensor.getBusVoltageMv(); } else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260].first == config.power.device_battery_ina_address) { return ina260Sensor.getBusVoltageMv(); @@ -460,6 +477,20 @@ class AnalogBatteryLevel : public HasBatteryLevel return 0; } + int16_t getINACurrent() + { + if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) { + return ina219Sensor.getCurrentMa(); + } else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA226].first == + config.power.device_battery_ina_address) { + return ina226Sensor.getCurrentMa(); + } else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA3221].first == + config.power.device_battery_ina_address) { + return ina3221Sensor.getCurrentMa(); + } + return 0; + } + bool hasINA() { if (!config.power.device_battery_ina_address) { @@ -469,6 +500,10 @@ class AnalogBatteryLevel : public HasBatteryLevel if (!ina219Sensor.isInitialized()) return ina219Sensor.runOnce() > 0; return ina219Sensor.isRunning(); + } else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA226].first == + config.power.device_battery_ina_address) { + if (!ina226Sensor.isInitialized()) + return ina226Sensor.runOnce() > 0; } else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260].first == config.power.device_battery_ina_address) { if (!ina260Sensor.isInitialized()) @@ -1154,4 +1189,4 @@ bool Power::lipoInit() { return false; } -#endif \ No newline at end of file +#endif diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h index 2473a6573..2561a8e17 100644 --- a/src/detect/ScanI2C.h +++ b/src/detect/ScanI2C.h @@ -64,7 +64,8 @@ class ScanI2C TPS65233, MPR121KB, CGRADSENS, - INA226 + INA226, + NXP_SE050, } DeviceType; // typedef uint8_t DeviceAddress; diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index 79c0deccf..6e695c22f 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -154,9 +154,14 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) } i2cBus->beginTransmission(addr.address); #ifdef ARCH_PORTDUINO - if (i2cBus->read() != -1) - err = 0; - else + err = 2; + if ((addr.address >= 0x30 && addr.address <= 0x37) || (addr.address >= 0x50 && addr.address <= 0x5F)) { + if (i2cBus->read() != -1) + err = 0; + } else { + err = i2cBus->writeQuick((uint8_t)0); + } + if (err != 0) err = 2; #else err = i2cBus->endTransmission(); @@ -396,7 +401,6 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) SCAN_SIMPLE_CASE(OPT3001_ADDR, OPT3001, "OPT3001", (uint8_t)addr.address); SCAN_SIMPLE_CASE(MLX90632_ADDR, MLX90632, "MLX90632", (uint8_t)addr.address); SCAN_SIMPLE_CASE(NAU7802_ADDR, NAU7802, "NAU7802", (uint8_t)addr.address); - SCAN_SIMPLE_CASE(FT6336U_ADDR, FT6336U, "FT6336U", (uint8_t)addr.address); SCAN_SIMPLE_CASE(MAX1704X_ADDR, MAX17048, "MAX17048", (uint8_t)addr.address); #ifdef HAS_TPS65233 SCAN_SIMPLE_CASE(TPS65233_ADDR, TPS65233, "TPS65233", (uint8_t)addr.address); @@ -444,6 +448,26 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) } break; + case 0x48: { + i2cBus->beginTransmission(addr.address); + uint8_t getInfo[] = {0x5A, 0xC0, 0x00, 0xFF, 0xFC}; + uint8_t expectedInfo[] = {0xa5, 0xE0, 0x00, 0x3F, 0x19}; + uint8_t info[5]; + size_t len = 0; + i2cBus->write(getInfo, 5); + i2cBus->endTransmission(); + len = i2cBus->readBytes(info, 5); + if (len == 5 && memcmp(expectedInfo, info, len) == 0) { + LOG_INFO("NXP SE050 crypto chip found\n"); + type = NXP_SE050; + + } else { + LOG_INFO("FT6336U touchscreen found\n"); + type = FT6336U; + } + break; + } + default: LOG_INFO("Device found at address 0x%x was not able to be enumerated", (uint8_t)addr.address); } diff --git a/src/modules/Telemetry/PowerTelemetry.cpp b/src/modules/Telemetry/PowerTelemetry.cpp index 367643849..10133fca5 100644 --- a/src/modules/Telemetry/PowerTelemetry.cpp +++ b/src/modules/Telemetry/PowerTelemetry.cpp @@ -56,6 +56,8 @@ int32_t PowerTelemetryModule::runOnce() // therefore, we should only enable the sensor loop if measurement is also enabled if (ina219Sensor.hasSensor() && !ina219Sensor.isInitialized()) result = ina219Sensor.runOnce(); + if (ina226Sensor.hasSensor() && !ina226Sensor.isInitialized()) + result = ina226Sensor.runOnce(); if (ina260Sensor.hasSensor() && !ina260Sensor.isInitialized()) result = ina260Sensor.runOnce(); if (ina3221Sensor.hasSensor() && !ina3221Sensor.isInitialized()) @@ -170,6 +172,8 @@ bool PowerTelemetryModule::getPowerTelemetry(meshtastic_Telemetry *m) #if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) if (ina219Sensor.hasSensor()) valid = ina219Sensor.getMetrics(m); + if (ina226Sensor.hasSensor()) + valid = ina226Sensor.getMetrics(m); if (ina260Sensor.hasSensor()) valid = ina260Sensor.getMetrics(m); if (ina3221Sensor.hasSensor()) @@ -253,4 +257,4 @@ bool PowerTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) return false; } -#endif +#endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/CurrentSensor.h b/src/modules/Telemetry/Sensor/CurrentSensor.h new file mode 100644 index 000000000..9827a9aa4 --- /dev/null +++ b/src/modules/Telemetry/Sensor/CurrentSensor.h @@ -0,0 +1,13 @@ +#include "configuration.h" + +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + +#pragma once + +class CurrentSensor +{ + public: + virtual int16_t getCurrentMa() = 0; +}; + +#endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/INA219Sensor.cpp b/src/modules/Telemetry/Sensor/INA219Sensor.cpp index de69163b4..ea47e265d 100644 --- a/src/modules/Telemetry/Sensor/INA219Sensor.cpp +++ b/src/modules/Telemetry/Sensor/INA219Sensor.cpp @@ -45,4 +45,9 @@ uint16_t INA219Sensor::getBusVoltageMv() return lround(ina219.getBusVoltage_V() * 1000); } +int16_t INA219Sensor::getCurrentMa() +{ + return lround(ina219.getCurrent_mA()); +} + #endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/INA219Sensor.h b/src/modules/Telemetry/Sensor/INA219Sensor.h index 9dded067b..9b6a2fcca 100644 --- a/src/modules/Telemetry/Sensor/INA219Sensor.h +++ b/src/modules/Telemetry/Sensor/INA219Sensor.h @@ -3,11 +3,12 @@ #if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR #include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "CurrentSensor.h" #include "TelemetrySensor.h" #include "VoltageSensor.h" #include -class INA219Sensor : public TelemetrySensor, VoltageSensor +class INA219Sensor : public TelemetrySensor, VoltageSensor, CurrentSensor { private: Adafruit_INA219 ina219; @@ -20,6 +21,7 @@ class INA219Sensor : public TelemetrySensor, VoltageSensor virtual int32_t runOnce() override; virtual bool getMetrics(meshtastic_Telemetry *measurement) override; virtual uint16_t getBusVoltageMv() override; + virtual int16_t getCurrentMa() override; }; #endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/INA226Sensor.cpp b/src/modules/Telemetry/Sensor/INA226Sensor.cpp new file mode 100644 index 000000000..1ee7cd92e --- /dev/null +++ b/src/modules/Telemetry/Sensor/INA226Sensor.cpp @@ -0,0 +1,58 @@ +#include "configuration.h" + +#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "INA226.h" +#include "INA226Sensor.h" +#include "TelemetrySensor.h" + +INA226Sensor::INA226Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_INA226, "INA226") {} + +int32_t INA226Sensor::runOnce() +{ + LOG_INFO("Init sensor: %s", sensorName); + if (!hasSensor()) { + return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; + } + + begin(nodeTelemetrySensorsMap[sensorType].second, nodeTelemetrySensorsMap[sensorType].first); + + if (!status) { + status = ina226.begin(); + } + return initI2CSensor(); +} + +void INA226Sensor::setup() {} + +void INA226Sensor::begin(TwoWire *wire, uint8_t addr) +{ + _wire = wire; + _addr = addr; + ina226 = INA226(_addr, _wire); + _wire->begin(); +} + +bool INA226Sensor::getMetrics(meshtastic_Telemetry *measurement) +{ + measurement->variant.environment_metrics.has_voltage = true; + measurement->variant.environment_metrics.has_current = true; + + // mV conversion to V + measurement->variant.environment_metrics.voltage = ina226.getBusVoltage() / 1000; + measurement->variant.environment_metrics.current = ina226.getCurrent_mA(); + return true; +} + +uint16_t INA226Sensor::getBusVoltageMv() +{ + return lround(ina226.getBusVoltage()); +} + +int16_t INA226Sensor::getCurrentMa() +{ + return lround(ina226.getCurrent_mA()); +} + +#endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/INA226Sensor.h b/src/modules/Telemetry/Sensor/INA226Sensor.h new file mode 100644 index 000000000..2f71c5b86 --- /dev/null +++ b/src/modules/Telemetry/Sensor/INA226Sensor.h @@ -0,0 +1,30 @@ +#include "configuration.h" + +#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "CurrentSensor.h" +#include "TelemetrySensor.h" +#include "VoltageSensor.h" +#include + +class INA226Sensor : public TelemetrySensor, VoltageSensor, CurrentSensor +{ + private: + uint8_t _addr = INA_ADDR; + TwoWire *_wire = &Wire; + INA226 ina226 = INA226(_addr, _wire); + + protected: + virtual void setup() override; + void begin(TwoWire *wire = &Wire, uint8_t addr = INA_ADDR); + + public: + INA226Sensor(); + virtual int32_t runOnce() override; + virtual bool getMetrics(meshtastic_Telemetry *measurement) override; + virtual uint16_t getBusVoltageMv() override; + virtual int16_t getCurrentMa() override; +}; + +#endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/INA3221Sensor.cpp b/src/modules/Telemetry/Sensor/INA3221Sensor.cpp index ed09856e2..7ac11dfde 100644 --- a/src/modules/Telemetry/Sensor/INA3221Sensor.cpp +++ b/src/modules/Telemetry/Sensor/INA3221Sensor.cpp @@ -102,4 +102,9 @@ uint16_t INA3221Sensor::getBusVoltageMv() return lround(ina3221.getVoltage(BAT_CH) * 1000); } +int16_t INA3221Sensor::getCurrentMa() +{ + return lround(ina3221.getCurrent(BAT_CH)); +} + #endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/INA3221Sensor.h b/src/modules/Telemetry/Sensor/INA3221Sensor.h index d5121aab6..8eeda3e02 100644 --- a/src/modules/Telemetry/Sensor/INA3221Sensor.h +++ b/src/modules/Telemetry/Sensor/INA3221Sensor.h @@ -3,11 +3,12 @@ #if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR #include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "CurrentSensor.h" #include "TelemetrySensor.h" #include "VoltageSensor.h" #include -class INA3221Sensor : public TelemetrySensor, VoltageSensor +class INA3221Sensor : public TelemetrySensor, VoltageSensor, CurrentSensor { private: INA3221 ina3221 = INA3221(INA3221_ADDR42_SDA); @@ -35,6 +36,7 @@ class INA3221Sensor : public TelemetrySensor, VoltageSensor int32_t runOnce() override; bool getMetrics(meshtastic_Telemetry *measurement) override; virtual uint16_t getBusVoltageMv() override; + virtual int16_t getCurrentMa() override; }; struct _INA3221Measurement { diff --git a/src/motion/LIS3DHSensor.cpp b/src/motion/LIS3DHSensor.cpp index f3f5a62d1..995f74abe 100755 --- a/src/motion/LIS3DHSensor.cpp +++ b/src/motion/LIS3DHSensor.cpp @@ -22,7 +22,7 @@ int32_t LIS3DHSensor::runOnce() { if (sensor.getClick() > 0) { uint8_t click = sensor.getClick(); - if (!config.device.double_tap_as_button_press) { + if (!config.device.double_tap_as_button_press && config.display.wake_on_tap_or_motion) { wakeScreen(); } @@ -34,4 +34,4 @@ int32_t LIS3DHSensor::runOnce() return MOTION_SENSOR_CHECK_INTERVAL_MS; } -#endif \ No newline at end of file +#endif diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 74a3f357d..ba47e26e3 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -232,14 +232,21 @@ bool isPrivateIpAddress(const IPAddress &ip) return false; } -std::pair parseHostAndPort(std::string address, uint16_t port = 0) +// Separate a [:] string. Returns a pair containing the parsed host and port. If the port is +// not present in the input string, or is invalid, the value of the `port` argument will be returned. +std::pair parseHostAndPort(String server, uint16_t port = 0) { - const size_t delimIndex = address.find_first_of(':'); + const int delimIndex = server.indexOf(':'); if (delimIndex > 0) { - port = std::stoul(address.substr(delimIndex + 1, address.length())); - address.resize(delimIndex); + const long parsedPort = server.substring(delimIndex + 1, server.length()).toInt(); + if (parsedPort < 1 || parsedPort > UINT16_MAX) { + LOG_WARN("Invalid MQTT port %d: %s", parsedPort, server.c_str()); + } else { + port = parsedPort; + } + server[delimIndex] = 0; } - return std::make_pair(std::move(address), port); + return std::make_pair(std::move(server), port); } } // namespace @@ -435,7 +442,7 @@ void MQTT::reconnect() pubSub.setClient(mqttClient); #endif - std::pair hostAndPort = parseHostAndPort(serverAddr, serverPort); + std::pair hostAndPort = parseHostAndPort(serverAddr, serverPort); serverAddr = hostAndPort.first.c_str(); serverPort = hostAndPort.second; pubSub.setServer(serverAddr, serverPort); @@ -450,9 +457,7 @@ void MQTT::reconnect() enabled = true; // Start running background process again runASAP = true; reconnectCount = 0; -#if !defined(ARCH_PORTDUINO) isMqttServerAddressPrivate = isPrivateIpAddress(mqttClient.remoteIP()); -#endif publishNodeInfo(); sendSubscriptions(); diff --git a/src/platform/rp2xx0/architecture.h b/src/platform/rp2xx0/architecture.h index 8c7dfc0cd..506c19c83 100644 --- a/src/platform/rp2xx0/architecture.h +++ b/src/platform/rp2xx0/architecture.h @@ -33,4 +33,6 @@ #define HW_VENDOR meshtastic_HardwareModel_RP2040_LORA #elif defined(RP2040_FEATHER_RFM95) #define HW_VENDOR meshtastic_HardwareModel_RP2040_FEATHER_RFM95 +#elif defined(PRIVATE_HW) +#define HW_VENDOR meshtastic_HardwareModel_PRIVATE_HW #endif \ No newline at end of file diff --git a/src/power.h b/src/power.h index 63335104b..ab55fc7e1 100644 --- a/src/power.h +++ b/src/power.h @@ -42,10 +42,12 @@ extern RTC_NOINIT_ATTR uint64_t RTC_reg_b; #if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO) #include "modules/Telemetry/Sensor/INA219Sensor.h" +#include "modules/Telemetry/Sensor/INA226Sensor.h" #include "modules/Telemetry/Sensor/INA260Sensor.h" #include "modules/Telemetry/Sensor/INA3221Sensor.h" -extern INA260Sensor ina260Sensor; extern INA219Sensor ina219Sensor; +extern INA226Sensor ina226Sensor; +extern INA260Sensor ina260Sensor; extern INA3221Sensor ina3221Sensor; #endif @@ -99,4 +101,4 @@ class Power : private concurrency::OSThread #endif }; -extern Power *power; \ No newline at end of file +extern Power *power; diff --git a/variants/nibble_esp32/platformio.ini b/variants/nibble_esp32/platformio.ini new file mode 100644 index 000000000..24d2ee2a5 --- /dev/null +++ b/variants/nibble_esp32/platformio.ini @@ -0,0 +1,6 @@ +[env:nibble-esp32] +extends = esp32s3_base +board = esp32-s3-zero +board_level = extra +build_flags = + ${esp32_base.build_flags} -D PRIVATE_HW -I variants/nibble_esp32 \ No newline at end of file diff --git a/variants/nibble_esp32/variant.h b/variants/nibble_esp32/variant.h new file mode 100644 index 000000000..8ffbd9d59 --- /dev/null +++ b/variants/nibble_esp32/variant.h @@ -0,0 +1,18 @@ +#define I2C_SDA 11 // I2C pins for this board +#define I2C_SCL 10 + +#define LED_PIN 1 // If defined we will blink this LED + +#define BUTTON_PIN 0 // If defined, this will be used for user button presses +#define BUTTON_NEED_PULLUP + +#define USE_RF95 +#define LORA_SCK 6 +#define LORA_MISO 7 +#define LORA_MOSI 8 +#define LORA_CS 9 +#define LORA_DIO0 5 // a No connect on the SX1262 module +#define LORA_RESET 4 + +#define LORA_DIO1 RADIOLIB_NC +#define LORA_DIO2 RADIOLIB_NC \ No newline at end of file diff --git a/variants/nibble_rp2040/platformio.ini b/variants/nibble_rp2040/platformio.ini new file mode 100644 index 000000000..ad987895f --- /dev/null +++ b/variants/nibble_rp2040/platformio.ini @@ -0,0 +1,17 @@ +[env:nibble-rp2040] +extends = rp2040_base +board = rpipico +board_level = extra +upload_protocol = picotool + +# add our variants files to the include and src paths +build_flags = ${rp2040_base.build_flags} + -DPRIVATE_HW + -Ivariants/nibble_rp2040 + -DDEBUG_RP2040_PORT=Serial + -DHW_SPI1_DEVICE + -L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m0plus" +lib_deps = + ${rp2040_base.lib_deps} +debug_build_flags = ${rp2040_base.build_flags}, -g +debug_tool = cmsis-dap ; for e.g. Picotool \ No newline at end of file diff --git a/variants/nibble_rp2040/variant.h b/variants/nibble_rp2040/variant.h new file mode 100644 index 000000000..0f71b98e9 --- /dev/null +++ b/variants/nibble_rp2040/variant.h @@ -0,0 +1,18 @@ +#define ARDUINO_ARCH_AVR + +#define BUTTON_PIN -1 // Pin 17 used for antenna switching via DIO4 + +#define LED_PIN 1 + +#define HAS_CPU_SHUTDOWN 1 + +#define USE_RF95 +#define LORA_SCK 10 +#define LORA_MISO 12 +#define LORA_MOSI 11 +#define LORA_CS 13 + +#define LORA_DIO0 14 +#define LORA_RESET 15 +#define LORA_DIO1 RADIOLIB_NC +#define LORA_DIO2 RADIOLIB_NC diff --git a/variants/nugget_s2_lora/platformio.ini b/variants/nugget_s2_lora/platformio.ini new file mode 100644 index 000000000..2a7ff1013 --- /dev/null +++ b/variants/nugget_s2_lora/platformio.ini @@ -0,0 +1,6 @@ +[env:nugget-s2-lora] +extends = esp32s2_base +board = lolin_s2_mini +board_level = extra +build_flags = + ${esp32s2_base.build_flags} -D PRIVATE_HW -I variants/nugget_s2_lora \ No newline at end of file diff --git a/variants/nugget_s2_lora/variant.h b/variants/nugget_s2_lora/variant.h new file mode 100644 index 000000000..2d123d603 --- /dev/null +++ b/variants/nugget_s2_lora/variant.h @@ -0,0 +1,23 @@ +#define I2C_SDA 34 // I2C pins for this board +#define I2C_SCL 36 + +#define LED_PIN 15 // If defined we will blink this LED + +#define HAS_NEOPIXEL // Enable the use of neopixels +#define NEOPIXEL_COUNT 3 // How many neopixels are connected +#define NEOPIXEL_DATA 12 // 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 // If defined, this will be used for user button presses +#define BUTTON_NEED_PULLUP + +#define USE_RF95 +#define LORA_SCK 6 +#define LORA_MISO 8 +#define LORA_MOSI 10 +#define LORA_CS 13 +#define LORA_DIO0 16 +#define LORA_RESET 5 + +#define LORA_DIO1 RADIOLIB_NC +#define LORA_DIO2 RADIOLIB_NC \ No newline at end of file diff --git a/variants/nugget_s3_lora/platformio.ini b/variants/nugget_s3_lora/platformio.ini new file mode 100644 index 000000000..729a3ef23 --- /dev/null +++ b/variants/nugget_s3_lora/platformio.ini @@ -0,0 +1,6 @@ +[env:nugget-s3-lora] +extends = esp32s3_base +board = lolin_s3_mini +board_level = extra +build_flags = + ${esp32s3_base.build_flags} -D PRIVATE_HW -I variants/nugget_s3_lora \ No newline at end of file diff --git a/variants/nugget_s3_lora/variant.h b/variants/nugget_s3_lora/variant.h new file mode 100644 index 000000000..488fe4e44 --- /dev/null +++ b/variants/nugget_s3_lora/variant.h @@ -0,0 +1,23 @@ +#define I2C_SDA 34 // I2C pins for this board +#define I2C_SCL 38 + +#define LED_PIN 15 // If defined we will blink this LED + +#define HAS_NEOPIXEL // Enable the use of neopixels +#define NEOPIXEL_COUNT 3 // How many neopixels are connected +#define NEOPIXEL_DATA 10 // 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 // If defined, this will be used for user button presses +#define BUTTON_NEED_PULLUP + +#define USE_RF95 +#define LORA_SCK 6 +#define LORA_MISO 7 +#define LORA_MOSI 8 +#define LORA_CS 9 +#define LORA_DIO0 16 // a No connect on the SX1262 module +#define LORA_RESET 4 + +#define LORA_DIO1 RADIOLIB_NC +#define LORA_DIO2 RADIOLIB_NC \ No newline at end of file diff --git a/variants/portduino-buildroot/platformio.ini b/variants/portduino-buildroot/platformio.ini index 683a3cecc..3fbd26910 100644 --- a/variants/portduino-buildroot/platformio.ini +++ b/variants/portduino-buildroot/platformio.ini @@ -3,7 +3,6 @@ extends = portduino_base ; Optional libraries should be appended to `PLATFORMIO_BUILD_FLAGS` ; environment variable in the buildroot environment. build_flags = ${portduino_base.build_flags} -O0 -I variants/portduino-buildroot - -std=c++17 board = buildroot lib_deps = ${portduino_base.lib_deps} -build_src_filter = ${portduino_base.build_src_filter} +build_src_filter = ${portduino_base.build_src_filter} \ No newline at end of file