diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index c923a22a6..4f7cbf194 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -8,7 +8,9 @@ on: branches: - master - develop + - pioarduino # Remove when merged // use `feature/` in the future. - event/* + - feature/* paths-ignore: - "**.md" - version.properties @@ -18,7 +20,9 @@ on: branches: - master - develop + - pioarduino # Remove when merged // use `feature/` in the future. - event/* + - feature/* paths-ignore: - "**.md" #- "**.yml" diff --git a/bin/build-esp32.sh b/bin/build-esp32.sh index 4e799b30a..d07a09a16 100755 --- a/bin/build-esp32.sh +++ b/bin/build-esp32.sh @@ -38,4 +38,4 @@ cp bin/device-install.* $OUTDIR/ cp bin/device-update.* $OUTDIR/ echo "Copying manifest" -cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json +cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json || true diff --git a/bin/build-nrf52.sh b/bin/build-nrf52.sh index edcc2add2..99187ba0d 100755 --- a/bin/build-nrf52.sh +++ b/bin/build-nrf52.sh @@ -49,4 +49,4 @@ if (echo $1 | grep -q "rak4631"); then fi echo "Copying manifest" -cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json +cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json || true diff --git a/bin/build-rp2xx0.sh b/bin/build-rp2xx0.sh index 3ef1c1e34..992a39be7 100755 --- a/bin/build-rp2xx0.sh +++ b/bin/build-rp2xx0.sh @@ -30,4 +30,4 @@ echo "Copying uf2 file" cp $BUILDDIR/$basename.uf2 $OUTDIR/$basename.uf2 echo "Copying manifest" -cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json +cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json || true diff --git a/bin/build-stm32wl.sh b/bin/build-stm32wl.sh index 023f3603c..64eb36586 100755 --- a/bin/build-stm32wl.sh +++ b/bin/build-stm32wl.sh @@ -30,4 +30,4 @@ echo "Copying STM32 bin file" cp $BUILDDIR/$basename.bin $OUTDIR/$basename.bin echo "Copying manifest" -cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json +cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json || true diff --git a/bin/platformio-custom.py b/bin/platformio-custom.py index b6560f35b..90d733ca7 100644 --- a/bin/platformio-custom.py +++ b/bin/platformio-custom.py @@ -2,11 +2,12 @@ # trunk-ignore-all(ruff/F821) # trunk-ignore-all(flake8/F821): For SConstruct imports import sys -from os.path import join, basename, isfile +from os.path import join import subprocess import json import re from datetime import datetime +from typing import Dict from readprops import readProps @@ -14,8 +15,47 @@ Import("env") platform = env.PioPlatform() progname = env.get("PROGNAME") lfsbin = f"{progname.replace('firmware-', 'littlefs-')}.bin" +manifest_ran = False + +def infer_architecture(board_cfg): + try: + mcu = board_cfg.get("build.mcu") if board_cfg else None + except KeyError: + mcu = None + except Exception: + mcu = None + if not mcu: + return None + mcu_l = str(mcu).lower() + if "esp32s3" in mcu_l: + return "esp32-s3" + if "esp32c6" in mcu_l: + return "esp32-c6" + if "esp32c3" in mcu_l: + return "esp32-c3" + if "esp32" in mcu_l: + return "esp32" + if "rp2040" in mcu_l: + return "rp2040" + if "rp2350" in mcu_l: + return "rp2350" + if "nrf52" in mcu_l or "nrf52840" in mcu_l: + return "nrf52840" + if "stm32" in mcu_l: + return "stm32" + return None def manifest_gather(source, target, env): + global manifest_ran + if manifest_ran: + return + # Skip manifest generation if we cannot determine architecture (host/native builds) + board_arch = infer_architecture(env.BoardConfig()) + if not board_arch: + print(f"Skipping mtjson generation for unknown architecture (env={env.get('PIOENV')})") + manifest_ran = True + return + manifest_ran = True out = [] board_platform = env.BoardConfig().get("platform") needs_ota_suffix = board_platform == "nordicnrf52" @@ -47,14 +87,39 @@ def manifest_gather(source, target, env): manifest_write(out, env) def manifest_write(files, env): + # Defensive: also skip manifest writing if we cannot determine architecture + def get_project_option(name): + try: + return env.GetProjectOption(name) + except Exception: + return None + + def get_project_option_any(names): + for name in names: + val = get_project_option(name) + if val is not None: + return val + return None + + def as_bool(val): + return str(val).strip().lower() in ("1", "true", "yes", "on") + + def as_int(val): + try: + return int(str(val), 10) + except (TypeError, ValueError): + return None + + def as_list(val): + return [item.strip() for item in str(val).split(",") if item.strip()] + manifest = { "version": verObj["long"], "build_epoch": build_epoch, - "board": env.get("PIOENV"), + "platformioTarget": env.get("PIOENV"), "mcu": env.get("BOARD_MCU"), "repo": repo_owner, "files": files, - "part": None, "has_mui": False, "has_inkhud": False, } @@ -69,6 +134,51 @@ def manifest_write(files, env): if "MESHTASTIC_INCLUDE_INKHUD" in env.get("CPPDEFINES", []): manifest["has_inkhud"] = True + pioenv = env.get("PIOENV") + device_meta = {} + device_meta_fields = [ + ("hwModel", ["custom_meshtastic_hw_model"], as_int), + ("hwModelSlug", ["custom_meshtastic_hw_model_slug"], str), + ("architecture", ["custom_meshtastic_architecture"], str), + ("activelySupported", ["custom_meshtastic_actively_supported"], as_bool), + ("displayName", ["custom_meshtastic_display_name"], str), + ("supportLevel", ["custom_meshtastic_support_level"], as_int), + ("images", ["custom_meshtastic_images"], as_list), + ("tags", ["custom_meshtastic_tags"], as_list), + ("requiresDfu", ["custom_meshtastic_requires_dfu"], as_bool), + ("partitionScheme", ["custom_meshtastic_partition_scheme"], str), + ("url", ["custom_meshtastic_url"], str), + ("key", ["custom_meshtastic_key"], str), + ("variant", ["custom_meshtastic_variant"], str), + ] + + + for manifest_key, option_keys, caster in device_meta_fields: + raw_val = get_project_option_any(option_keys) + if raw_val is None: + continue + parsed = caster(raw_val) if callable(caster) else raw_val + if parsed is not None and parsed != "": + device_meta[manifest_key] = parsed + + # Determine architecture once; if we can't infer it, skip manifest generation + board_arch = device_meta.get("architecture") or infer_architecture(env.BoardConfig()) + if not board_arch: + print(f"Skipping mtjson write for unknown architecture (env={env.get('PIOENV')})") + return + + device_meta["architecture"] = board_arch + + # Always set requiresDfu: true for nrf52840 targets + if board_arch == "nrf52840": + device_meta["requiresDfu"] = True + + device_meta.setdefault("displayName", pioenv) + device_meta.setdefault("activelySupported", False) + + if device_meta: + manifest.update(device_meta) + # Write the manifest to the build directory with open(env.subst("$BUILD_DIR/${PROGNAME}.mt.json"), "w") as f: json.dump(manifest, f, indent=2) @@ -166,8 +276,12 @@ def load_boot_logo(source, target, env): if ("HAS_TFT", 1) in env.get("CPPDEFINES", []): env.AddPreAction(f"$BUILD_DIR/{lfsbin}", load_boot_logo) -mtjson_deps = ["buildprog"] -if platform.name == "espressif32": +board_arch = infer_architecture(env.BoardConfig()) +should_skip_manifest = board_arch is None + +# For host/native envs, avoid depending on 'buildprog' (some targets don't define it) +mtjson_deps = [] if should_skip_manifest else ["buildprog"] +if not should_skip_manifest and platform.name == "espressif32": # Build littlefs image as part of mtjson target # Equivalent to `pio run -t buildfs` target_lfs = env.DataToBin( @@ -175,11 +289,27 @@ if platform.name == "espressif32": ) mtjson_deps.append(target_lfs) -env.AddCustomTarget( - name="mtjson", - dependencies=mtjson_deps, - actions=[manifest_gather], - title="Meshtastic Manifest", - description="Generating Meshtastic manifest JSON + Checksums", - always_build=False, -) +if should_skip_manifest: + def skip_manifest(source, target, env): + print(f"mtjson: skipped for native environment: {env.get('PIOENV')}") + + env.AddCustomTarget( + name="mtjson", + dependencies=mtjson_deps, + actions=[skip_manifest], + title="Meshtastic Manifest (skipped)", + description="mtjson generation is skipped for native environments", + always_build=True, + ) +else: + env.AddCustomTarget( + name="mtjson", + dependencies=mtjson_deps, + actions=[manifest_gather], + title="Meshtastic Manifest", + description="Generating Meshtastic manifest JSON + Checksums", + always_build=True, + ) + + # Run manifest generation as part of the default build pipeline for non-native builds. + env.Default("mtjson") diff --git a/bin/readprops.py b/bin/readprops.py index 731a3d0d3..4b92d63dd 100644 --- a/bin/readprops.py +++ b/bin/readprops.py @@ -18,8 +18,9 @@ def readProps(prefsLoc): # Try to find current build SHA if if the workspace is clean. This could fail if git is not installed try: + # Pin abbreviation length to keep local builds and CI matching (avoid auto-shortening) sha = ( - subprocess.check_output(["git", "rev-parse", "--short", "HEAD"]) + subprocess.check_output(["git", "rev-parse", "--short=7", "HEAD"]) .decode("utf-8") .strip() ) diff --git a/boards/t-beam-1w.json b/boards/t-beam-1w.json new file mode 100644 index 000000000..ac1d1f15e --- /dev/null +++ b/boards/t-beam-1w.json @@ -0,0 +1,50 @@ +{ + "build": { + "arduino": { + "ldscript": "esp32s3_out.ld", + "memory_type": "qio_opi" + }, + "core": "esp32", + "extra_flags": [ + "-DBOARD_HAS_PSRAM", + "-DLILYGO_TBEAM_1W", + "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DARDUINO_USB_MODE=0", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "psram_type": "opi", + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "t-beam-1w" + }, + "connectivity": [ + "wifi", + "bluetooth", + "lora" + ], + "debug": { + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino" + ], + "name": "LilyGo TBeam-1W", + "upload": { + "flash_size": "16MB", + "maximum_ram_size": 327680, + "maximum_size": 16777216, + "require_upload_port": true, + "speed": 921600 + }, + "url": "http://www.lilygo.cn/", + "vendor": "LilyGo" +} \ No newline at end of file diff --git a/src/configuration.h b/src/configuration.h index 650e1cc71..ec1b9acc2 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -444,6 +444,18 @@ along with this program. If not, see . #endif #endif +// BME680 BSEC2 support detection +#if !defined(MESHTASTIC_BME680_BSEC2_SUPPORTED) +#if defined(RAK_4631) || defined(TBEAM_V10) + +#define MESHTASTIC_BME680_BSEC2_SUPPORTED 1 +#define MESHTASTIC_BME680_HEADER +#else +#define MESHTASTIC_BME680_BSEC2_SUPPORTED 0 +#define MESHTASTIC_BME680_HEADER +#endif // defined(RAK_4631) +#endif // !defined(MESHTASTIC_BME680_BSEC2_SUPPORTED) + // ----------------------------------------------------------------------------- // Global switches to turn off features for a minimized build // ----------------------------------------------------------------------------- diff --git a/src/graphics/draw/MenuHandler.cpp b/src/graphics/draw/MenuHandler.cpp index 5687c8620..138995ebe 100644 --- a/src/graphics/draw/MenuHandler.cpp +++ b/src/graphics/draw/MenuHandler.cpp @@ -449,13 +449,14 @@ void menuHandler::clockMenu() } void menuHandler::messageResponseMenu() { - enum optionsNumbers { Back = 0, ViewMode, DeleteAll, DeleteOldest, ReplyMenu, Aloud, enumEnd }; + enum optionsNumbers { Back = 0, ViewMode, DeleteAll, DeleteOldest, ReplyMenu, MuteChannel, Aloud, enumEnd }; static const char *optionsArray[enumEnd]; static int optionsEnumArray[enumEnd]; int options = 0; auto mode = graphics::MessageRenderer::getThreadMode(); + int threadChannel = graphics::MessageRenderer::getThreadChannel(); optionsArray[options] = "Back"; optionsEnumArray[options++] = Back; @@ -467,6 +468,15 @@ void menuHandler::messageResponseMenu() optionsArray[options] = "View Chats"; optionsEnumArray[options++] = ViewMode; + // If viewing ALL chats, hide “Mute Chat” + if (mode != graphics::MessageRenderer::ThreadMode::ALL && mode != graphics::MessageRenderer::ThreadMode::DIRECT) { + const uint8_t chIndex = (threadChannel != 0) ? (uint8_t)threadChannel : channels.getPrimaryIndex(); + auto &chan = channels.getByIndex(chIndex); + + optionsArray[options] = chan.settings.module_settings.is_muted ? "Unmute Channel" : "Mute Channel"; + optionsEnumArray[options++] = MuteChannel; + } + // Delete submenu optionsArray[options] = "Delete"; optionsEnumArray[options++] = 900; @@ -502,6 +512,14 @@ void menuHandler::messageResponseMenu() menuHandler::menuQueue = menuHandler::reply_menu; screen->runNow(); + } else if (selected == MuteChannel) { + const uint8_t chIndex = (ch != 0) ? (uint8_t)ch : channels.getPrimaryIndex(); + auto &chan = channels.getByIndex(chIndex); + if (chan.settings.has_module_settings) { + chan.settings.module_settings.is_muted = !chan.settings.module_settings.is_muted; + nodeDB->saveToDisk(); + } + // Delete submenu } else if (selected == 900) { menuHandler::menuQueue = menuHandler::delete_messages_menu; diff --git a/src/mesh/FloodingRouter.cpp b/src/mesh/FloodingRouter.cpp index b7459abe0..78602a9ec 100644 --- a/src/mesh/FloodingRouter.cpp +++ b/src/mesh/FloodingRouter.cpp @@ -4,6 +4,7 @@ #include "configuration.h" #include "mesh-pb-constants.h" #include "meshUtils.h" +#include "modules/TextMessageModule.h" #if !MESHTASTIC_EXCLUDE_TRACEROUTE #include "modules/TraceRouteModule.h" #endif @@ -35,6 +36,10 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p) return true; // we handled it, so stop processing } + if (!seenRecently && !wasUpgraded && textMessageModule) { + seenRecently = textMessageModule->recentlySeen(p->id); + } + if (seenRecently) { printPacket("Ignore dupe incoming msg", p); rxDupe++; diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index a74b33abf..22e3bd1e3 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -246,7 +246,8 @@ uint32_t RadioInterface::getPacketTime(const meshtastic_MeshPacket *p, bool rece /** The delay to use for retransmitting dropped packets */ uint32_t RadioInterface::getRetransmissionMsec(const meshtastic_MeshPacket *p) { - size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded); + size_t numbytes =p->which_payload_variant == meshtastic_MeshPacket_decoded_tag ? + pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded) : p->encrypted.size+MESHTASTIC_HEADER_LENGTH; uint32_t packetAirtime = getPacketTime(numbytes + sizeof(PacketHeader)); // Make sure enough time has elapsed for this packet to be sent and an ACK is received. // LOG_DEBUG("Waiting for flooding message with airtime %d and slotTime is %d", packetAirtime, slotTimeMsec); diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp index e1f07a32b..2d7996a13 100644 --- a/src/mesh/SX126xInterface.cpp +++ b/src/mesh/SX126xInterface.cpp @@ -62,6 +62,11 @@ template bool SX126xInterface::init() digitalWrite(LORA_PA_TX_EN, LOW); #endif +#ifdef RF95_FAN_EN + digitalWrite(RF95_FAN_EN, HIGH); + pinMode(RF95_FAN_EN, OUTPUT); +#endif + #if ARCH_PORTDUINO tcxoVoltage = (float)portduino_config.dio3_tcxo_voltage / 1000; if (portduino_config.lora_sx126x_ant_sw_pin.pin != RADIOLIB_NC) { @@ -85,6 +90,13 @@ template bool SX126xInterface::init() power = -9; int res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage, useRegulatorLDO); + +#ifdef SX126X_PA_RAMP_US + // Set custom PA ramp time for boards requiring longer stabilization (e.g., T-Beam 1W needs >800us) + if (res == RADIOLIB_ERR_NONE) { + lora.setPaRampTime(SX126X_PA_RAMP_US); + } +#endif // \todo Display actual typename of the adapter, not just `SX126x` LOG_INFO("SX126x init result %d", res); if (res == RADIOLIB_ERR_CHIP_NOT_FOUND || res == RADIOLIB_ERR_SPI_CMD_FAILED) diff --git a/src/modules/SystemCommandsModule.cpp b/src/modules/SystemCommandsModule.cpp index 51543eab6..1da756366 100644 --- a/src/modules/SystemCommandsModule.cpp +++ b/src/modules/SystemCommandsModule.cpp @@ -45,9 +45,9 @@ int SystemCommandsModule::handleInputEvent(const InputEvent *event) // Mute case INPUT_BROKER_MSG_MUTE_TOGGLE: if (moduleConfig.external_notification.enabled && externalNotificationModule) { - externalNotificationModule->setMute(externalNotificationModule->getMute()); + externalNotificationModule->setMute(!externalNotificationModule->getMute()); IF_SCREEN(if (!externalNotificationModule->getMute()) externalNotificationModule->stopNow(); screen->showSimpleBanner( - externalNotificationModule->getMute() ? "Notifications\nEnabled" : "Notifications\nDisabled", 3000);) + externalNotificationModule->getMute() ? "Notifications\nDisabled" : "Notifications\nEnabled", 3000);) } return 0; // Bluetooth diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index 41062662b..843d7b8d5 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -53,7 +53,7 @@ extern void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const c #include "Sensor/LTR390UVSensor.h" #endif -#if __has_include() +#if __has_include(MESHTASTIC_BME680_HEADER) #include "Sensor/BME680Sensor.h" #endif @@ -214,7 +214,7 @@ void EnvironmentTelemetryModule::i2cScanFinished(ScanI2C *i2cScanner) #if __has_include() addSensor(i2cScanner, ScanI2C::DeviceType::LTR390UV); #endif -#if __has_include() +#if __has_include(MESHTASTIC_BME680_HEADER) addSensor(i2cScanner, ScanI2C::DeviceType::BME_680); #endif #if __has_include() diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.cpp b/src/modules/Telemetry/Sensor/BME680Sensor.cpp index 95f3dc5f0..22330ca75 100644 --- a/src/modules/Telemetry/Sensor/BME680Sensor.cpp +++ b/src/modules/Telemetry/Sensor/BME680Sensor.cpp @@ -1,6 +1,6 @@ #include "configuration.h" -#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include() +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include(MESHTASTIC_BME680_HEADER) #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "BME680Sensor.h" @@ -10,6 +10,7 @@ BME680Sensor::BME680Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BME680, "BME680") {} +#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1 int32_t BME680Sensor::runOnce() { if (!bme680.run()) { @@ -17,10 +18,13 @@ int32_t BME680Sensor::runOnce() } return 35; } +#endif // defined(MESHTASTIC_BME680_BSEC2_SUPPORTED) bool BME680Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) { status = 0; + +#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1 if (!bme680.begin(dev->address.address, *bus)) checkStatus("begin"); @@ -42,12 +46,25 @@ bool BME680Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) if (status == 0) LOG_DEBUG("BME680Sensor::runOnce: bme680.status %d", bme680.status); +#else + bme680 = makeBME680(bus); + + if (!bme680->begin(dev->address.address)) { + LOG_ERROR("Init sensor: %s failed at begin()", sensorName); + return status; + } + + status = 1; + +#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED + initI2CSensor(); return status; } bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement) { +#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1 if (bme680.getData(BSEC_OUTPUT_RAW_PRESSURE).signal == 0) return false; @@ -65,9 +82,27 @@ bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement) // Check if we need to save state to filesystem (every STATE_SAVE_PERIOD ms) measurement->variant.environment_metrics.iaq = bme680.getData(BSEC_OUTPUT_IAQ).signal; updateState(); +#else + if (!bme680->performReading()) { + LOG_ERROR("BME680Sensor::getMetrics: performReading failed"); + return false; + } + + measurement->variant.environment_metrics.has_temperature = true; + measurement->variant.environment_metrics.has_relative_humidity = true; + measurement->variant.environment_metrics.has_barometric_pressure = true; + measurement->variant.environment_metrics.has_gas_resistance = true; + + measurement->variant.environment_metrics.temperature = bme680->readTemperature(); + measurement->variant.environment_metrics.relative_humidity = bme680->readHumidity(); + measurement->variant.environment_metrics.barometric_pressure = bme680->readPressure() / 100.0F; + measurement->variant.environment_metrics.gas_resistance = bme680->readGas() / 1000.0; + +#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED return true; } +#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1 void BME680Sensor::loadState() { #ifdef FSCom @@ -144,5 +179,6 @@ void BME680Sensor::checkStatus(const char *functionName) else if (bme680.sensor.status > BME68X_OK) LOG_WARN("%s BME68X code: %d", functionName, bme680.sensor.status); } +#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED #endif diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.h b/src/modules/Telemetry/Sensor/BME680Sensor.h index f4ead95f7..9bef56e1e 100644 --- a/src/modules/Telemetry/Sensor/BME680Sensor.h +++ b/src/modules/Telemetry/Sensor/BME680Sensor.h @@ -1,23 +1,40 @@ #include "configuration.h" -#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include() +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include(MESHTASTIC_BME680_HEADER) #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "TelemetrySensor.h" + +#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1 +#include #include +#else +#include +#include +#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED #define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) // That's 6 hours worth of millis() +#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1 const uint8_t bsec_config[] = { #include "config/bme680/bme680_iaq_33v_3s_4d/bsec_iaq.txt" }; - +#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED class BME680Sensor : public TelemetrySensor { private: +#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1 Bsec2 bme680; +#else + using BME680Ptr = std::unique_ptr; + + static BME680Ptr makeBME680(TwoWire *bus) { return std::make_unique(bus); } + + BME680Ptr bme680; +#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED protected: +#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1 const char *bsecConfigFileName = "/prefs/bsec.dat"; uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE] = {0}; uint8_t accuracy = 0; @@ -34,10 +51,13 @@ class BME680Sensor : public TelemetrySensor void loadState(); void updateState(); void checkStatus(const char *functionName); +#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED public: BME680Sensor(); +#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1 virtual int32_t runOnce() override; +#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED virtual bool getMetrics(meshtastic_Telemetry *measurement) override; virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override; }; diff --git a/src/modules/TextMessageModule.cpp b/src/modules/TextMessageModule.cpp index 7f889e087..d94701c6b 100644 --- a/src/modules/TextMessageModule.cpp +++ b/src/modules/TextMessageModule.cpp @@ -17,6 +17,9 @@ ProcessMessage TextMessageModule::handleReceived(const meshtastic_MeshPacket &mp auto &p = mp.decoded; LOG_INFO("Received text msg from=0x%0x, id=0x%x, msg=%.*s", mp.from, mp.id, p.payload.size, p.payload.bytes); #endif + // add packet ID to the rolling list of packets + textPacketList[textPacketListIndex] = mp.id; + textPacketListIndex = (textPacketListIndex + 1) % TEXT_PACKET_LIST_SIZE; // We only store/display messages destined for us. devicestate.rx_text_message = mp; @@ -47,3 +50,13 @@ bool TextMessageModule::wantPacket(const meshtastic_MeshPacket *p) { return MeshService::isTextPayload(p); } + +bool TextMessageModule::recentlySeen(uint32_t id) +{ + for (size_t i = 0; i < TEXT_PACKET_LIST_SIZE; i++) { + if (textPacketList[i] != 0 && textPacketList[i] == id) { + return true; + } + } + return false; +} \ No newline at end of file diff --git a/src/modules/TextMessageModule.h b/src/modules/TextMessageModule.h index e719f1abc..42900a78e 100644 --- a/src/modules/TextMessageModule.h +++ b/src/modules/TextMessageModule.h @@ -1,6 +1,7 @@ #pragma once #include "Observer.h" #include "SinglePortModule.h" +#define TEXT_PACKET_LIST_SIZE 50 /** * Text message handling for Meshtastic. @@ -19,6 +20,8 @@ class TextMessageModule : public SinglePortModule, public Observable + +#define USB_VID 0x303a +#define USB_PID 0x1001 + +static const uint8_t TX = 43; +static const uint8_t RX = 44; + +// I2C for OLED and sensors +static const uint8_t SDA = 8; +static const uint8_t SCL = 9; + +// Default SPI mapped to Radio/SD +static const uint8_t SS = 15; // LoRa CS +static const uint8_t MOSI = 11; +static const uint8_t MISO = 12; +static const uint8_t SCK = 13; + +// SD Card CS +#define SDCARD_CS 10 + +#endif /* Pins_Arduino_h */ diff --git a/variants/esp32s3/t-beam-1w/platformio.ini b/variants/esp32s3/t-beam-1w/platformio.ini new file mode 100644 index 000000000..54ddb6c3e --- /dev/null +++ b/variants/esp32s3/t-beam-1w/platformio.ini @@ -0,0 +1,14 @@ +; LilyGo T-Beam-1W (1 Watt LoRa with external PA) +[env:t-beam-1w] +extends = esp32s3_base +board = t-beam-1w +board_build.partitions = default_8MB.csv +board_check = true + +lib_deps = + ${esp32s3_base.lib_deps} + +build_flags = + ${esp32s3_base.build_flags} + -I variants/esp32s3/t-beam-1w + -D T_BEAM_1W diff --git a/variants/esp32s3/t-beam-1w/variant.h b/variants/esp32s3/t-beam-1w/variant.h new file mode 100644 index 000000000..01404afcb --- /dev/null +++ b/variants/esp32s3/t-beam-1w/variant.h @@ -0,0 +1,97 @@ +// LilyGo T-Beam-1W variant.h +// Configuration based on LilyGO utilities.h and RF documentation + +// I2C for OLED display (SH1106 at 0x3C) +#define I2C_SDA 8 +#define I2C_SCL 9 + +// GPS - Quectel L76K +#define GPS_RX_PIN 5 +#define GPS_TX_PIN 6 +#define GPS_1PPS_PIN 7 +#define GPS_WAKEUP_PIN 16 // GPS_EN_PIN in LilyGO code +#define HAS_GPS 1 +#define GPS_BAUDRATE 9600 + +// Buttons +#define BUTTON_PIN 0 // BUTTON 1 +#define BUTTON_PIN_ALT 17 // BUTTON 2 + +// SPI (shared by LoRa and SD) +#define SPI_MOSI 11 +#define SPI_SCK 13 +#define SPI_MISO 12 +#define SPI_CS 10 + +// SD Card +#define HAS_SDCARD +#define SDCARD_USE_SPI1 +#define SDCARD_CS SPI_CS + +// LoRa Radio - SX1262 with 1W PA +#define USE_SX1262 + +#define LORA_SCK SPI_SCK +#define LORA_MISO SPI_MISO +#define LORA_MOSI SPI_MOSI +#define LORA_CS 15 +#define LORA_RESET 3 +#define LORA_DIO1 1 +#define LORA_BUSY 38 + +// CRITICAL: Radio power enable - MUST be HIGH before lora.begin()! +// GPIO 40 powers the SX1262 + PA module via LDO +#define SX126X_POWER_EN 40 + +// TX power offset for external PA (0 = no offset, full SX1262 power) +#define TX_GAIN_LORA 10 + +#ifdef USE_SX1262 +#define SX126X_CS LORA_CS +#define SX126X_DIO1 LORA_DIO1 +#define SX126X_BUSY LORA_BUSY +#define SX126X_RESET LORA_RESET + +// RF switching configuration for 1W PA module +// DIO2 controls PA (via SX126X_DIO2_AS_RF_SWITCH) +// CTRL PIN (GPIO 21) controls LNA - must be HIGH during RX +// Truth table: DIO2=1,CTRL=0 → TX (PA on, LNA off) +// DIO2=0,CTRL=1 → RX (PA off, LNA on) +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_RXEN 21 // LNA enable - HIGH during RX + +// TCXO voltage - required for radio init +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 + +#define SX126X_MAX_POWER 22 +#endif + +// LED +#define LED_PIN 18 +#define LED_STATE_ON 1 // HIGH = ON + +// Battery ADC +#define BATTERY_PIN 4 +#define ADC_CHANNEL ADC1_GPIO4_CHANNEL +#define BATTERY_SENSE_SAMPLES 30 +#define ADC_MULTIPLIER 2.9333 + +// NTC temperature sensor +#define NTC_PIN 14 + +// Fan control +#define FAN_CTRL_PIN 41 +// Meshtastic standard fan control pin macro +#define RF95_FAN_EN FAN_CTRL_PIN + +// PA Ramp Time - T-Beam 1W requires >800us stabilization (default is 200us) +// Value 0x05 = RADIOLIB_SX126X_PA_RAMP_800U +#define SX126X_PA_RAMP_US 0x05 + +// Display - SH1106 OLED (128x64) +#define USE_SH1106 +#define OLED_WIDTH 128 +#define OLED_HEIGHT 64 + +// 32768 Hz crystal present +#define HAS_32768HZ 1 diff --git a/variants/esp32s3/t-deck-pro/platformio.ini b/variants/esp32s3/t-deck-pro/platformio.ini index b97d7ac3f..28fef86ba 100644 --- a/variants/esp32s3/t-deck-pro/platformio.ini +++ b/variants/esp32s3/t-deck-pro/platformio.ini @@ -1,4 +1,15 @@ [env:t-deck-pro] +custom_meshtastic_hw_model = 102 +custom_meshtastic_hw_model_slug = T_DECK_PRO +custom_meshtastic_architecture = esp32-s3 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = LILYGO T-Deck Pro +custom_meshtastic_images = tdeck_pro.svg +custom_meshtastic_tags = LilyGo +custom_meshtastic_requires_dfu = true +custom_meshtastic_partition_scheme = 16MB + extends = esp32s3_base board = t-deck-pro board_check = true diff --git a/variants/esp32s3/t-deck/platformio.ini b/variants/esp32s3/t-deck/platformio.ini index c8f3c8d5e..58335796a 100644 --- a/variants/esp32s3/t-deck/platformio.ini +++ b/variants/esp32s3/t-deck/platformio.ini @@ -1,5 +1,16 @@ ; LilyGo T-Deck [env:t-deck] +custom_meshtastic_hw_model = 50 +custom_meshtastic_hw_model_slug = T_DECK +custom_meshtastic_architecture = esp32-s3 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = LILYGO T-Deck +custom_meshtastic_images = t-deck.svg +custom_meshtastic_tags = LilyGo +custom_meshtastic_requires_dfu = true +custom_meshtastic_partition_scheme = 16MB + extends = esp32s3_base board = t-deck board_check = true diff --git a/variants/esp32s3/t-watch-s3/platformio.ini b/variants/esp32s3/t-watch-s3/platformio.ini index 9785119b5..7d7b07ff6 100644 --- a/variants/esp32s3/t-watch-s3/platformio.ini +++ b/variants/esp32s3/t-watch-s3/platformio.ini @@ -1,5 +1,15 @@ ; LilyGo T-Watch S3 [env:t-watch-s3] +custom_meshtastic_hw_model = 51 +custom_meshtastic_hw_model_slug = T_WATCH_S3 +custom_meshtastic_architecture = esp32-s3 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 3 +custom_meshtastic_display_name = LILYGO T-Watch S3 +custom_meshtastic_images = t-watch-s3.svg +custom_meshtastic_tags = LilyGo +custom_meshtastic_partition_scheme = 8MB + extends = esp32s3_base board = t-watch-s3 board_check = true diff --git a/variants/esp32s3/tbeam-s3-core/platformio.ini b/variants/esp32s3/tbeam-s3-core/platformio.ini index 5522e1d37..c0a32c49c 100644 --- a/variants/esp32s3/tbeam-s3-core/platformio.ini +++ b/variants/esp32s3/tbeam-s3-core/platformio.ini @@ -1,5 +1,16 @@ ; The 1.0 release of the LilyGo TBEAM-S3-Core board [env:tbeam-s3-core] +custom_meshtastic_hw_model = 12 +custom_meshtastic_hw_model_slug = LILYGO_TBEAM_S3_CORE +custom_meshtastic_architecture = esp32-s3 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = LILYGO T-Beam Supreme +custom_meshtastic_images = tbeam-s3-core.svg +custom_meshtastic_tags = LilyGo +custom_meshtastic_requires_dfu = true +custom_meshtastic_partition_scheme = 8MB + extends = esp32s3_base board = tbeam-s3-core board_build.partitions = default_8MB.csv diff --git a/variants/esp32s3/tlora-pager/platformio.ini b/variants/esp32s3/tlora-pager/platformio.ini index 98b9f51f5..3a7afb016 100644 --- a/variants/esp32s3/tlora-pager/platformio.ini +++ b/variants/esp32s3/tlora-pager/platformio.ini @@ -1,5 +1,16 @@ ; LilyGo T-Lora-Pager [env:tlora-pager] +custom_meshtastic_hw_model = 103 +custom_meshtastic_hw_model_slug = T_LORA_PAGER +custom_meshtastic_architecture = esp32-s3 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = LILYGO T-LoRa Pager +custom_meshtastic_images = lilygo-tlora-pager.svg +custom_meshtastic_tags = LilyGo +custom_meshtastic_requires_dfu = true +custom_meshtastic_partition_scheme = 16MB + extends = esp32s3_base board = t-deck-pro ; same as T-Deck Pro board_check = true diff --git a/variants/esp32s3/tlora_t3s3_epaper/platformio.ini b/variants/esp32s3/tlora_t3s3_epaper/platformio.ini index 18b9e136e..fdf3f7814 100644 --- a/variants/esp32s3/tlora_t3s3_epaper/platformio.ini +++ b/variants/esp32s3/tlora_t3s3_epaper/platformio.ini @@ -1,4 +1,14 @@ [env:tlora-t3s3-epaper] +custom_meshtastic_hw_model = 16 +custom_meshtastic_hw_model_slug = TLORA_T3_S3 +custom_meshtastic_architecture = esp32-s3 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = LILYGO T-LoRa T3-S3 E-Ink +custom_meshtastic_images = tlora-t3s3-epaper.svg +custom_meshtastic_tags = LilyGo +custom_meshtastic_requires_dfu = true + extends = esp32s3_base board = tlora-t3s3-v1 board_check = true diff --git a/variants/esp32s3/tlora_t3s3_v1/platformio.ini b/variants/esp32s3/tlora_t3s3_v1/platformio.ini index 7a5e3df4b..95686e417 100644 --- a/variants/esp32s3/tlora_t3s3_v1/platformio.ini +++ b/variants/esp32s3/tlora_t3s3_v1/platformio.ini @@ -1,4 +1,14 @@ [env:tlora-t3s3-v1] +custom_meshtastic_hw_model = 16 +custom_meshtastic_hw_model_slug = TLORA_T3_S3 +custom_meshtastic_architecture = esp32-s3 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = LILYGO T-LoRa T3-S3 +custom_meshtastic_images = tlora-t3s3-v1.svg +custom_meshtastic_tags = LilyGo +custom_meshtastic_requires_dfu = true + extends = esp32s3_base board = tlora-t3s3-v1 board_check = true diff --git a/variants/esp32s3/tracksenger/platformio.ini b/variants/esp32s3/tracksenger/platformio.ini index 73212c546..419a3539b 100644 --- a/variants/esp32s3/tracksenger/platformio.ini +++ b/variants/esp32s3/tracksenger/platformio.ini @@ -1,4 +1,13 @@ [env:tracksenger] +custom_meshtastic_hw_model = 48 +custom_meshtastic_hw_model_slug = HELTEC_WIRELESS_TRACKER +custom_meshtastic_architecture = esp32-s3 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 3 +custom_meshtastic_display_name = TrackSenger (small TFT) +custom_meshtastic_requires_dfu = true +custom_meshtastic_partition_scheme = 8MB + extends = esp32s3_base board = heltec_wireless_tracker board_build.partitions = default_8MB.csv @@ -16,6 +25,15 @@ lib_deps = lovyan03/LovyanGFX@1.2.7 [env:tracksenger-lcd] +custom_meshtastic_hw_model = 48 +custom_meshtastic_hw_model_slug = HELTEC_WIRELESS_TRACKER +custom_meshtastic_architecture = esp32-s3 +custom_meshtastic_actively_supported = false +custom_meshtastic_support_level = 3 +custom_meshtastic_display_name = TrackSenger (big TFT) +custom_meshtastic_requires_dfu = true +custom_meshtastic_partition_scheme = 8MB + extends = esp32s3_base board = heltec_wireless_tracker board_build.partitions = default_8MB.csv @@ -33,6 +51,14 @@ lib_deps = lovyan03/LovyanGFX@1.2.7 [env:tracksenger-oled] +custom_meshtastic_hw_model = 48 +custom_meshtastic_hw_model_slug = HELTEC_WIRELESS_TRACKER +custom_meshtastic_architecture = esp32-s3 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 3 +custom_meshtastic_display_name = TrackSenger (big OLED) +custom_meshtastic_partition_scheme = 8MB + extends = esp32s3_base board = heltec_wireless_tracker board_build.partitions = default_8MB.csv diff --git a/variants/esp32s3/unphone/platformio.ini b/variants/esp32s3/unphone/platformio.ini index 6c638af29..28be1f3e1 100644 --- a/variants/esp32s3/unphone/platformio.ini +++ b/variants/esp32s3/unphone/platformio.ini @@ -1,6 +1,15 @@ ; platformio.ini for unphone meshtastic [env:unphone] +custom_meshtastic_hw_model = 59 +custom_meshtastic_hw_model_slug = UNPHONE +custom_meshtastic_architecture = esp32-s3 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 3 +custom_meshtastic_display_name = unPhone +custom_meshtastic_requires_dfu = true +custom_meshtastic_partition_scheme = 8MB + extends = esp32s3_base board = unphone board_build.partitions = partition-table-8MB.csv diff --git a/variants/native/portduino.ini b/variants/native/portduino.ini index 76520091c..cc6c39aa2 100644 --- a/variants/native/portduino.ini +++ b/variants/native/portduino.ini @@ -34,6 +34,8 @@ lib_deps = adafruit/Adafruit seesaw Library@1.7.9 # renovate: datasource=git-refs depName=RAK12034-BMX160 packageName=https://github.com/RAKWireless/RAK12034-BMX160 gitBranch=main https://github.com/RAKWireless/RAK12034-BMX160/archive/dcead07ffa267d3c906e9ca4a1330ab989e957e2.zip + # renovate: datasource=custom.pio depName=adafruit/Adafruit BME680 Library packageName=adafruit/library/Adafruit BME680 + adafruit/Adafruit BME680 Library@^2.0.5 build_flags = ${arduino_base.build_flags} diff --git a/variants/nrf52840/ELECROW-ThinkNode-M1/platformio.ini b/variants/nrf52840/ELECROW-ThinkNode-M1/platformio.ini index 25f1b78b2..041d3b76f 100644 --- a/variants/nrf52840/ELECROW-ThinkNode-M1/platformio.ini +++ b/variants/nrf52840/ELECROW-ThinkNode-M1/platformio.ini @@ -1,5 +1,14 @@ ; First prototype eink/nrf52840/sx1262 device [env:thinknode_m1] +custom_meshtastic_hw_model = 89 +custom_meshtastic_hw_model_slug = THINKNODE_M1 +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = ThinkNode M1 +custom_meshtastic_images = thinknode_m1.svg +custom_meshtastic_tags = Elecrow + extends = nrf52840_base board = ThinkNode-M1 board_check = true diff --git a/variants/nrf52840/ELECROW-ThinkNode-M3/platformio.ini b/variants/nrf52840/ELECROW-ThinkNode-M3/platformio.ini index 0ed46896f..bf9492075 100644 --- a/variants/nrf52840/ELECROW-ThinkNode-M3/platformio.ini +++ b/variants/nrf52840/ELECROW-ThinkNode-M3/platformio.ini @@ -1,8 +1,17 @@ [env:thinknode_m3] +custom_meshtastic_support_level = 1 +custom_meshtastic_images = thinknode_m3.svg +custom_meshtastic_tags = Elecrow + extends = nrf52840_base board = ThinkNode-M3 board_check = true debug_tool = jlink +custom_meshtastic_hw_model = 115 +custom_meshtastic_hw_model_slug = THINKNODE_M3 +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_display_name = Elecrow ThinkNode M3 +custom_meshtastic_actively_supported = true build_flags = ${nrf52840_base.build_flags} -Ivariants/nrf52840/ELECROW-ThinkNode-M3 diff --git a/variants/nrf52840/ELECROW-ThinkNode-M6/platformio.ini b/variants/nrf52840/ELECROW-ThinkNode-M6/platformio.ini index 18108df83..413eb4fab 100644 --- a/variants/nrf52840/ELECROW-ThinkNode-M6/platformio.ini +++ b/variants/nrf52840/ELECROW-ThinkNode-M6/platformio.ini @@ -1,5 +1,14 @@ ; ThinkNode M6 - Outdoor Solar Power nrf52840/sx1262 device [env:thinknode_m6] +custom_meshtastic_hw_model = 120 +custom_meshtastic_hw_model_slug = THINKNODE_M6 +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = false +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = ThinkNode M6 +custom_meshtastic_images = thinknode_m6.svg +custom_meshtastic_tags = Elecrow + extends = nrf52840_base board = ThinkNode-M6 board_check = true diff --git a/variants/nrf52840/canaryone/platformio.ini b/variants/nrf52840/canaryone/platformio.ini index 1be04c9aa..a2cf55972 100644 --- a/variants/nrf52840/canaryone/platformio.ini +++ b/variants/nrf52840/canaryone/platformio.ini @@ -1,5 +1,13 @@ ; Public Beta oled/nrf52840/sx1262 device [env:canaryone] +custom_meshtastic_hw_model = 29 +custom_meshtastic_hw_model_slug = CANARYONE +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 3 +custom_meshtastic_display_name = Canary One +custom_meshtastic_tags = Canary + extends = nrf52840_base board = canaryone debug_tool = jlink diff --git a/variants/nrf52840/diy/nrf52_promicro_diy_tcxo/platformio.ini b/variants/nrf52840/diy/nrf52_promicro_diy_tcxo/platformio.ini index ca8f1777e..006f5c875 100644 --- a/variants/nrf52840/diy/nrf52_promicro_diy_tcxo/platformio.ini +++ b/variants/nrf52840/diy/nrf52_promicro_diy_tcxo/platformio.ini @@ -1,5 +1,15 @@ ; Promicro + E22(0)-xxxM / HT-RA62 modules board variant - DIY - with TCXO [env:nrf52_promicro_diy_tcxo] +custom_meshtastic_hw_model = 63 +custom_meshtastic_hw_model_slug = NRF52_PROMICRO_DIY +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 3 +custom_meshtastic_display_name = NRF52 Pro-micro DIY +custom_meshtastic_images = promicro.svg +custom_meshtastic_tags = DIY +custom_meshtastic_requires_dfu = true + extends = nrf52840_base board = promicro-nrf52840 build_flags = ${nrf52840_base.build_flags} diff --git a/variants/nrf52840/heltec_mesh_node_t114/platformio.ini b/variants/nrf52840/heltec_mesh_node_t114/platformio.ini index 7971e33c6..a39872205 100644 --- a/variants/nrf52840/heltec_mesh_node_t114/platformio.ini +++ b/variants/nrf52840/heltec_mesh_node_t114/platformio.ini @@ -1,5 +1,14 @@ ; First prototype nrf52840/sx1262 device [env:heltec-mesh-node-t114] +custom_meshtastic_hw_model = 69 +custom_meshtastic_hw_model_slug = HELTEC_MESH_NODE_T114 +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = Heltec Mesh Node T114 +custom_meshtastic_images = heltec-mesh-node-t114.svg, heltec-mesh-node-t114-case.svg +custom_meshtastic_tags = Heltec + extends = nrf52840_base board = heltec_mesh_node_t114 board_level = pr diff --git a/variants/nrf52840/heltec_mesh_pocket/platformio.ini b/variants/nrf52840/heltec_mesh_pocket/platformio.ini index 4d3610fda..4dc8b78e7 100644 --- a/variants/nrf52840/heltec_mesh_pocket/platformio.ini +++ b/variants/nrf52840/heltec_mesh_pocket/platformio.ini @@ -1,8 +1,20 @@ ; First prototype nrf52840/sx1262 device [env:heltec-mesh-pocket-5000] +custom_meshtastic_support_level = 1 +custom_meshtastic_images = heltec_mesh_pocket.svg +custom_meshtastic_tags = Heltec + extends = nrf52840_base board = heltec_mesh_pocket debug_tool = jlink +custom_device_hw_model = 94 +custom_meshtastic_hw_model = 94 +custom_meshtastic_hw_model_slug = HELTEC_MESH_POCKET +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_display_name = Heltec Mesh Pocket +custom_meshtastic_actively_supported = true +custom_meshtastic_variant = 5000mAh +custom_meshtastic_key = heltec_mesh_pocket # add -DCFG_SYSVIEW if you want to use the Segger systemview tool for OS profiling. build_flags = ${nrf52840_base.build_flags} @@ -31,6 +43,13 @@ lib_deps = [env:heltec-mesh-pocket-5000-inkhud] extends = nrf52840_base, inkhud board = heltec_mesh_pocket +custom_meshtastic_hw_model = 94 +custom_meshtastic_hw_model_slug = HELTEC_MESH_POCKET +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_display_name = Heltec Mesh Pocket +custom_meshtastic_actively_supported = true +custom_meshtastic_variant = 5000mAh InkHUD +custom_meshtastic_key = heltec_mesh_pocket build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/heltec_mesh_pocket> ${inkhud.build_src_filter} build_flags = ${inkhud.build_flags} @@ -45,9 +64,20 @@ lib_deps = ; First prototype nrf52840/sx1262 device [env:heltec-mesh-pocket-10000] +custom_meshtastic_support_level = 1 +custom_meshtastic_images = heltec_mesh_pocket.svg +custom_meshtastic_tags = Heltec + extends = nrf52840_base board = heltec_mesh_pocket debug_tool = jlink +custom_meshtastic_hw_model = 94 +custom_meshtastic_hw_model_slug = HELTEC_MESH_POCKET +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_display_name = Heltec Mesh Pocket +custom_meshtastic_actively_supported = true +custom_meshtastic_variant = 10000mAh +custom_meshtastic_key = heltec_mesh_pocket # add -DCFG_SYSVIEW if you want to use the Segger systemview tool for OS profiling. build_flags = ${nrf52840_base.build_flags} @@ -76,6 +106,13 @@ lib_deps = [env:heltec-mesh-pocket-10000-inkhud] extends = nrf52840_base, inkhud board = heltec_mesh_pocket +custom_meshtastic_hw_model = 94 +custom_meshtastic_hw_model_slug = HELTEC_MESH_POCKET +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_display_name = Heltec Mesh Pocket +custom_meshtastic_actively_supported = true +custom_meshtastic_variant = 10000mAh InkHUD +custom_meshtastic_key = heltec_mesh_pocket build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/heltec_mesh_pocket> ${inkhud.build_src_filter} build_flags = ${inkhud.build_flags} diff --git a/variants/nrf52840/heltec_mesh_solar/platformio.ini b/variants/nrf52840/heltec_mesh_solar/platformio.ini index fa8965a64..2ad699544 100644 --- a/variants/nrf52840/heltec_mesh_solar/platformio.ini +++ b/variants/nrf52840/heltec_mesh_solar/platformio.ini @@ -19,6 +19,15 @@ lib_deps = bblanchon/ArduinoJson@6.21.4 [env:heltec-mesh-solar] +custom_meshtastic_hw_model = 108 +custom_meshtastic_hw_model_slug = HELTEC_MESH_SOLAR +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = false +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = Heltec MeshSolar +custom_meshtastic_images = heltec-mesh-solar.svg +custom_meshtastic_tags = Heltec + extends = heltec_mesh_solar_base build_flags = ${heltec_mesh_solar_base.build_flags} -DSPI_INTERFACES_COUNT=1 diff --git a/variants/nrf52840/muzi_base/platformio.ini b/variants/nrf52840/muzi_base/platformio.ini index 29d93d1cd..52c558ff1 100644 --- a/variants/nrf52840/muzi_base/platformio.ini +++ b/variants/nrf52840/muzi_base/platformio.ini @@ -1,4 +1,13 @@ [env:muzi-base] +custom_meshtastic_hw_model = 93 +custom_meshtastic_hw_model_slug = MUZI_BASE +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = muzi BASE +custom_meshtastic_images = muzi_base.svg +custom_meshtastic_tags = muzi + extends = nrf52840_base board = muzi-base build_flags = ${nrf52840_base.build_flags} diff --git a/variants/nrf52840/nano-g2-ultra/platformio.ini b/variants/nrf52840/nano-g2-ultra/platformio.ini index 5952029fd..0748b7e38 100644 --- a/variants/nrf52840/nano-g2-ultra/platformio.ini +++ b/variants/nrf52840/nano-g2-ultra/platformio.ini @@ -1,5 +1,14 @@ ; First prototype eink/nrf52840/sx1262 device [env:nano-g2-ultra] +custom_meshtastic_hw_model = 18 +custom_meshtastic_hw_model_slug = NANO_G2_ULTRA +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 2 +custom_meshtastic_display_name = Nano G2 Ultra +custom_meshtastic_images = nano-g2-ultra.svg +custom_meshtastic_tags = B&Q + extends = nrf52840_base board = nano-g2-ultra debug_tool = jlink diff --git a/variants/nrf52840/r1-neo/platformio.ini b/variants/nrf52840/r1-neo/platformio.ini index af3cd052d..85fe49cf1 100644 --- a/variants/nrf52840/r1-neo/platformio.ini +++ b/variants/nrf52840/r1-neo/platformio.ini @@ -1,5 +1,14 @@ ; The R1 Neo board [env:r1-neo] +custom_meshtastic_hw_model = 101 +custom_meshtastic_hw_model_slug = MUZI_R1_NEO +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = muzi R1 Neo +custom_meshtastic_images = muzi_r1_neo.svg +custom_meshtastic_tags = muzi + extends = nrf52840_base board = r1-neo board_check = true diff --git a/variants/nrf52840/rak2560/platformio.ini b/variants/nrf52840/rak2560/platformio.ini index 21b3776f8..1703a13ae 100644 --- a/variants/nrf52840/rak2560/platformio.ini +++ b/variants/nrf52840/rak2560/platformio.ini @@ -1,5 +1,14 @@ ; Firmware for the WisMesh HUB RAK2560, including a onewire module to talk to the RAK 9154 solar battery. [env:rak2560] +custom_meshtastic_hw_model = 22 +custom_meshtastic_hw_model_slug = WISMESH_HUB +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = RAK WisMesh Repeater +custom_meshtastic_images = rak2560.svg +custom_meshtastic_tags = RAK + extends = nrf52840_base board = wiscore_rak4631 board_check = true diff --git a/variants/nrf52840/rak3401_1watt/platformio.ini b/variants/nrf52840/rak3401_1watt/platformio.ini index 268274b13..bb8fa28df 100644 --- a/variants/nrf52840/rak3401_1watt/platformio.ini +++ b/variants/nrf52840/rak3401_1watt/platformio.ini @@ -1,5 +1,15 @@ ; The very slick RAK wireless RAK 4631 / 4630 board - Unified firmware for 5005/19003, with or without OLED RAK 1921 [env:rak3401-1watt] +custom_meshtastic_hw_model = 117 +custom_meshtastic_hw_model_slug = RAK3401 +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = RAK3401 1W +custom_meshtastic_images = rak3401.svg +custom_meshtastic_tags = RAK +custom_meshtastic_requires_dfu = true + extends = nrf52840_base board = wiscore_rak4631 board_check = true diff --git a/variants/nrf52840/rak4631/platformio.ini b/variants/nrf52840/rak4631/platformio.ini index ed30692be..4a96fc8d9 100644 --- a/variants/nrf52840/rak4631/platformio.ini +++ b/variants/nrf52840/rak4631/platformio.ini @@ -1,5 +1,14 @@ ; The very slick RAK wireless RAK 4631 / 4630 board - Unified firmware for 5005/19003, with or without OLED RAK 1921 [env:rak4631] +custom_meshtastic_hw_model = 9 +custom_meshtastic_hw_model_slug = RAK4631 +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = RAK WisBlock 4631 +custom_meshtastic_images = rak4631.svg, rak4631_case.svg +custom_meshtastic_tags = RAK + extends = nrf52840_base board = wiscore_rak4631 board_level = pr diff --git a/variants/nrf52840/rak4631_nomadstar_meteor_pro/platformio.ini b/variants/nrf52840/rak4631_nomadstar_meteor_pro/platformio.ini index 500242c24..07d763df3 100644 --- a/variants/nrf52840/rak4631_nomadstar_meteor_pro/platformio.ini +++ b/variants/nrf52840/rak4631_nomadstar_meteor_pro/platformio.ini @@ -1,5 +1,14 @@ ; NomadStar Meteor Pro based on RAK4631 with RGBW LED LP5562 support [env:rak4631_nomadstar_meteor_pro] +custom_meshtastic_hw_model = 96 +custom_meshtastic_hw_model_slug = NOMADSTAR_METEOR_PRO +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = NomadStar Meteor Pro +custom_meshtastic_images = meteor_pro.svg +custom_meshtastic_tags = NomadStar + extends = nrf52840_base board = wiscore_rak4631 board_check = true diff --git a/variants/nrf52840/rak_wismeshtag/platformio.ini b/variants/nrf52840/rak_wismeshtag/platformio.ini index 1cc00e253..1e6e63e60 100644 --- a/variants/nrf52840/rak_wismeshtag/platformio.ini +++ b/variants/nrf52840/rak_wismeshtag/platformio.ini @@ -1,8 +1,17 @@ ; The very slick RAK wireless RAK 4631 / 4630 board - Unified firmware for 5005/19003, with or without OLED RAK 1921 [env:rak_wismeshtag] +custom_meshtastic_support_level = 1 +custom_meshtastic_images = rak_wismesh_tag.svg +custom_meshtastic_tags = RAK + extends = nrf52840_base board = wiscore_rak4631 board_check = true +custom_meshtastic_hw_model = 105 +custom_meshtastic_hw_model_slug = WISMESH_TAG +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_display_name = RAK WisMesh Tag +custom_meshtastic_actively_supported = true build_flags = ${nrf52840_base.build_flags} -I variants/nrf52840/rak_wismeshtag -D WISMESH_TAG diff --git a/variants/nrf52840/rak_wismeshtap/platformio.ini b/variants/nrf52840/rak_wismeshtap/platformio.ini index 485b7174f..f058d9153 100644 --- a/variants/nrf52840/rak_wismeshtap/platformio.ini +++ b/variants/nrf52840/rak_wismeshtap/platformio.ini @@ -1,5 +1,14 @@ ; The very slick RAK wireless RAK10701 Field Tester device. Note you will have to flash to Arduino bootloader to use this firmware. Be aware touch is not currently working. [env:rak_wismeshtap] +custom_meshtastic_hw_model = 84 +custom_meshtastic_hw_model_slug = WISMESH_TAP +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = RAK WisMesh Tap +custom_meshtastic_images = rak-wismeshtap.svg +custom_meshtastic_tags = RAK + extends = nrf52840_base board = wiscore_rak4631 build_flags = ${nrf52840_base.build_flags} diff --git a/variants/nrf52840/seeed_solar_node/platformio.ini b/variants/nrf52840/seeed_solar_node/platformio.ini index 5a2518331..18894c049 100644 --- a/variants/nrf52840/seeed_solar_node/platformio.ini +++ b/variants/nrf52840/seeed_solar_node/platformio.ini @@ -1,4 +1,13 @@ [env:seeed_solar_node] +custom_meshtastic_hw_model = 95 +custom_meshtastic_hw_model_slug = SEEED_SOLAR_NODE +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = Seeed SenseCAP Solar Node +custom_meshtastic_images = seeed_solar.svg +custom_meshtastic_tags = Seeed + board = seeed_solar_node extends = nrf52840_base ;board_level = extra diff --git a/variants/nrf52840/seeed_wio_tracker_L1/platformio.ini b/variants/nrf52840/seeed_wio_tracker_L1/platformio.ini index d11ad0ab9..d5b56b7bf 100644 --- a/variants/nrf52840/seeed_wio_tracker_L1/platformio.ini +++ b/variants/nrf52840/seeed_wio_tracker_L1/platformio.ini @@ -1,4 +1,14 @@ [env:seeed_wio_tracker_L1] +custom_meshtastic_hw_model = 99 +custom_meshtastic_hw_model_slug = SEEED_WIO_TRACKER_L1 +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = Seeed Wio Tracker L1 +custom_meshtastic_images = wio_tracker_l1_case.svg +custom_meshtastic_tags = Seeed +custom_meshtastic_requires_dfu = true + board = seeed_wio_tracker_L1 extends = nrf52840_base build_flags = ${nrf52840_base.build_flags} diff --git a/variants/nrf52840/seeed_wio_tracker_L1_eink/platformio.ini b/variants/nrf52840/seeed_wio_tracker_L1_eink/platformio.ini index 3007a8c7b..6b36a79c3 100644 --- a/variants/nrf52840/seeed_wio_tracker_L1_eink/platformio.ini +++ b/variants/nrf52840/seeed_wio_tracker_L1_eink/platformio.ini @@ -1,4 +1,13 @@ [env:seeed_wio_tracker_L1_eink] +custom_meshtastic_hw_model = 100 +custom_meshtastic_hw_model_slug = SEEED_WIO_TRACKER_L1_EINK +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = Seeed Wio Tracker L1 E-Ink +custom_meshtastic_images = wio_tracker_l1_eink.svg +custom_meshtastic_tags = Seeed + board = seeed_wio_tracker_L1 extends = nrf52840_base ;board_level = extra diff --git a/variants/nrf52840/seeed_xiao_nrf52840_kit/platformio.ini b/variants/nrf52840/seeed_xiao_nrf52840_kit/platformio.ini index 079cd5c52..68be47622 100644 --- a/variants/nrf52840/seeed_xiao_nrf52840_kit/platformio.ini +++ b/variants/nrf52840/seeed_xiao_nrf52840_kit/platformio.ini @@ -1,5 +1,14 @@ ; Seeed Xiao BLE: https://wiki.seeedstudio.com/XIAO_BLE/ [env:seeed_xiao_nrf52840_kit] +custom_meshtastic_hw_model = 88 +custom_meshtastic_hw_model_slug = XIAO_NRF52_KIT +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = Seeed Xiao NRF52840 Kit +custom_meshtastic_images = seeed_xiao_nrf52_kit.svg +custom_meshtastic_tags = Seeed + extends = nrf52840_base board = xiao_ble_sense board_level = pr diff --git a/variants/nrf52840/t-echo-lite/platformio.ini b/variants/nrf52840/t-echo-lite/platformio.ini index 217b76a2d..c873dea37 100644 --- a/variants/nrf52840/t-echo-lite/platformio.ini +++ b/variants/nrf52840/t-echo-lite/platformio.ini @@ -1,5 +1,14 @@ ; Using original screen class [env:t-echo-lite] +custom_meshtastic_hw_model = 109 +custom_meshtastic_hw_model_slug = T_ECHO_LITE +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = false +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = LILYGO T-Echo Lite +custom_meshtastic_images = techo_lite.svg +custom_meshtastic_tags = LilyGo + extends = nrf52840_base board = t-echo board_check = true diff --git a/variants/nrf52840/t-echo/platformio.ini b/variants/nrf52840/t-echo/platformio.ini index 4244419b7..a8fc027c8 100644 --- a/variants/nrf52840/t-echo/platformio.ini +++ b/variants/nrf52840/t-echo/platformio.ini @@ -1,5 +1,14 @@ ; Using original screen class [env:t-echo] +custom_meshtastic_hw_model = 7 +custom_meshtastic_hw_model_slug = T_ECHO +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 1 +custom_meshtastic_display_name = LILYGO T-Echo +custom_meshtastic_images = t-echo.svg +custom_meshtastic_tags = LilyGo + extends = nrf52840_base board = t-echo board_level = pr diff --git a/variants/nrf52840/tracker-t1000-e/platformio.ini b/variants/nrf52840/tracker-t1000-e/platformio.ini index 86d74f68a..43ba7a8b4 100644 --- a/variants/nrf52840/tracker-t1000-e/platformio.ini +++ b/variants/nrf52840/tracker-t1000-e/platformio.ini @@ -1,7 +1,16 @@ [env:tracker-t1000-e] +custom_meshtastic_support_level = 1 +custom_meshtastic_images = tracker-t1000-e.svg +custom_meshtastic_tags = Seeed + extends = nrf52840_base board = tracker-t1000-e board_level = pr +custom_meshtastic_hw_model = 71 +custom_meshtastic_hw_model_slug = TRACKER_T1000_E +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_display_name = Seeed SenseCAP T1000-E +custom_meshtastic_actively_supported = true build_flags = ${nrf52840_base.build_flags} -Ivariants/nrf52840/tracker-t1000-e -Isrc/platform/nrf52/softdevice diff --git a/variants/nrf52840/wio-tracker-wm1110/platformio.ini b/variants/nrf52840/wio-tracker-wm1110/platformio.ini index b3513a242..515712062 100644 --- a/variants/nrf52840/wio-tracker-wm1110/platformio.ini +++ b/variants/nrf52840/wio-tracker-wm1110/platformio.ini @@ -1,5 +1,15 @@ ; The red tracker Dev Board with the WM1110 module [env:wio-tracker-wm1110] +custom_meshtastic_hw_model = 21 +custom_meshtastic_hw_model_slug = WIO_WM1110 +custom_meshtastic_architecture = nrf52840 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 3 +custom_meshtastic_display_name = Seeed Wio WM1110 Tracker +custom_meshtastic_images = wio-tracker-wm1110.svg +custom_meshtastic_tags = Seeed +custom_meshtastic_requires_dfu = true + extends = nrf52840_base board = wio-tracker-wm1110 build_flags = ${nrf52840_base.build_flags} diff --git a/variants/rp2040/rak11310/platformio.ini b/variants/rp2040/rak11310/platformio.ini index 3234d3b99..2c2b2a4bf 100644 --- a/variants/rp2040/rak11310/platformio.ini +++ b/variants/rp2040/rak11310/platformio.ini @@ -1,4 +1,14 @@ [env:rak11310] +custom_meshtastic_hw_model = 26 +custom_meshtastic_hw_model_slug = RAK11310 +custom_meshtastic_architecture = rp2040 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 2 +custom_meshtastic_display_name = RAK WisBlock 11310 +custom_meshtastic_images = rak11310.svg +custom_meshtastic_tags = RAK +custom_meshtastic_requires_dfu = true + extends = rp2040_base board = rakwireless_rak11300 board_level = pr diff --git a/variants/rp2040/rp2040-lora/platformio.ini b/variants/rp2040/rp2040-lora/platformio.ini index a85869260..f1e0b9af6 100644 --- a/variants/rp2040/rp2040-lora/platformio.ini +++ b/variants/rp2040/rp2040-lora/platformio.ini @@ -1,4 +1,13 @@ [env:rp2040-lora] +custom_meshtastic_hw_model = 30 +custom_meshtastic_hw_model_slug = RP2040_LORA +custom_meshtastic_architecture = rp2040 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 2 +custom_meshtastic_display_name = RP2040 LoRa +custom_meshtastic_tags = Waveshare +custom_meshtastic_requires_dfu = true + extends = rp2040_base board = rpipico upload_protocol = picotool diff --git a/variants/rp2040/rpipico/platformio.ini b/variants/rp2040/rpipico/platformio.ini index 953aee625..4ae134b28 100644 --- a/variants/rp2040/rpipico/platformio.ini +++ b/variants/rp2040/rpipico/platformio.ini @@ -1,4 +1,14 @@ [env:pico] +custom_meshtastic_hw_model = 47 +custom_meshtastic_hw_model_slug = RPI_PICO +custom_meshtastic_architecture = rp2040 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 3 +custom_meshtastic_display_name = Raspberry Pi Pico +custom_meshtastic_images = pico.svg +custom_meshtastic_tags = RPi, DIY +custom_meshtastic_requires_dfu = true + extends = rp2040_base board = rpipico board_level = pr diff --git a/variants/rp2040/rpipicow/platformio.ini b/variants/rp2040/rpipicow/platformio.ini index 00b7b1f01..99e02a1aa 100644 --- a/variants/rp2040/rpipicow/platformio.ini +++ b/variants/rp2040/rpipicow/platformio.ini @@ -1,4 +1,14 @@ [env:picow] +custom_meshtastic_hw_model = 47 +custom_meshtastic_hw_model_slug = RPI_PICO +custom_meshtastic_architecture = rp2040 +custom_meshtastic_actively_supported = true +custom_meshtastic_support_level = 3 +custom_meshtastic_display_name = Raspberry Pi Pico W +custom_meshtastic_images = rpipicow.svg +custom_meshtastic_tags = RPi, DIY +custom_meshtastic_requires_dfu = true + extends = rp2040_base board = rpipicow board_level = pr