diff --git a/boards/tlora-t3s3-v1.json b/boards/tlora-t3s3-v1.json index 5af53084f..d073fc7c1 100644 --- a/boards/tlora-t3s3-v1.json +++ b/boards/tlora-t3s3-v1.json @@ -14,7 +14,7 @@ "f_cpu": "240000000L", "f_flash": "80000000L", "flash_mode": "dio", - "hwids": [["0X303A", "0x1001"]], + "hwids": [["0x303A", "0x1001"]], "mcu": "esp32s3", "variant": "tlora-t3s3-v1" }, diff --git a/platformio.ini b/platformio.ini index 4f8f53d0c..af18a6f8b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,6 +13,7 @@ default_envs = tbeam ;default_envs = tlora_v1_3 ;default_envs = tlora-v2 ;default_envs = tlora-v2-1-1.6 +;default_envs = tlora-t3s3-v1 ;default_envs = lora-relay-v1 # nrf board ;default_envs = t-echo ;default_envs = nrf52840dk-geeksville diff --git a/protobufs b/protobufs index 275ddfd2d..b3d05ec99 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 275ddfd2d017c5a806f2de2975892d197e404c27 +Subproject commit b3d05ec995844ae888e1d43d6e5c770b7d654309 diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index c935c354f..12d08cd17 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -518,18 +518,12 @@ static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus // Draw status when gps is disabled by PMU static void drawGPSpowerstat(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps) { -#ifdef HAS_PMU String displayLine = "GPS disabled"; int16_t xPos = display->getStringWidth(displayLine); if (!config.position.gps_enabled) { display->drawString(x + xPos, y, displayLine); -#ifdef GPS_POWER_TOGGLE - display->drawString(x + xPos, y - 2 + FONT_HEIGHT_SMALL, " by button"); -#endif - // display->drawString(x + xPos, y + 2, displayLine); } -#endif } static void drawGPSAltitude(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps) @@ -1440,11 +1434,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16 } // Display GPS status if (!config.position.gps_enabled) { - int16_t yPos = y + 2; -#ifdef GPS_POWER_TOGGLE - yPos = (y + 10 + FONT_HEIGHT_SMALL); -#endif - drawGPSpowerstat(display, x, yPos, gpsStatus); + drawGPSpowerstat(display, x, y + 2, gpsStatus); } else { if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) { drawGPS(display, x + (SCREEN_WIDTH * 0.63), y + 2, gpsStatus); @@ -1761,6 +1751,9 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat drawGPScoordinates(display, x, y + FONT_HEIGHT_SMALL * 3, gpsStatus); } else { drawGPSpowerstat(display, x - (SCREEN_WIDTH / 4), y + FONT_HEIGHT_SMALL * 2, gpsStatus); +#ifdef GPS_POWER_TOGGLE + display->drawString(x + 30, (y + FONT_HEIGHT_SMALL * 3), " by button"); +#endif } /* Display a heartbeat pixel that blinks every time the frame is redrawn */ #ifdef SHOW_REDRAWS diff --git a/src/main.cpp b/src/main.cpp index e2e39ebd2..c1afb5c18 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -420,19 +420,6 @@ void setup() } #endif -#if defined(USE_SX1280) - if (!rIf) { - rIf = new SX1280Interface(SX128X_CS, SX128X_DIO1, SX128X_RESET, SX128X_BUSY, SPI); - if (!rIf->init()) { - LOG_WARN("Failed to find SX1280 radio\n"); - delete rIf; - rIf = NULL; - } else { - LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio\n"); - } - } -#endif - #if defined(USE_SX1262) if (!rIf) { rIf = new SX1262Interface(SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY, SPI); @@ -472,6 +459,19 @@ void setup() } #endif +#if defined(USE_SX1280) + if (!rIf) { + rIf = new SX1280Interface(SX128X_CS, SX128X_DIO1, SX128X_RESET, SX128X_BUSY, SPI); + if (!rIf->init()) { + LOG_WARN("Failed to find SX1280 radio\n"); + delete rIf; + rIf = NULL; + } else { + LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio\n"); + } + } +#endif + // check if the radio chip matches the selected region if ((config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_LORA_24) && (!rIf->wideLora())) { diff --git a/src/mesh/FloodingRouter.cpp b/src/mesh/FloodingRouter.cpp index d0925d0a1..d8861943e 100644 --- a/src/mesh/FloodingRouter.cpp +++ b/src/mesh/FloodingRouter.cpp @@ -44,7 +44,8 @@ void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas tosend->hop_limit--; // bump down the hop count // If it is a traceRoute request, update the route that it went via me - if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag && traceRouteModule->wantPacket(p)) { + if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag && traceRouteModule && + traceRouteModule->wantPacket(p)) { traceRouteModule->updateRoute(tosend); } diff --git a/src/mesh/MeshService.cpp b/src/mesh/MeshService.cpp index 80fea011b..650f6882b 100644 --- a/src/mesh/MeshService.cpp +++ b/src/mesh/MeshService.cpp @@ -76,7 +76,7 @@ int MeshService::handleFromRadio(const meshtastic_MeshPacket *mp) powerFSM.trigger(EVENT_PACKET_FOR_PHONE); // Possibly keep the node from sleeping nodeDB.updateFrom(*mp); // update our DB state based off sniffing every RX packet from the radio - if (!nodeDB.getNode(mp->from)->has_user && nodeInfoModule) { + if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag && !nodeDB.getNode(mp->from)->has_user && nodeInfoModule) { LOG_INFO("Heard a node we don't know, sending NodeInfo and asking for a response.\n"); nodeInfoModule->sendOurNodeInfo(mp->from, true); } diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index ebf214316..0748f50aa 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -239,6 +239,9 @@ void NodeDB::installRoleDefaults(meshtastic_Config_DeviceConfig_Role role) config.position.position_broadcast_smart_enabled = false; config.position.position_broadcast_secs = 120; config.position.gps_update_interval = 60; + } else if (role == meshtastic_Config_DeviceConfig_Role_SENSOR) { + moduleConfig.telemetry.environment_measurement_enabled = true; + moduleConfig.telemetry.environment_update_interval = 300; } } diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 94dab0bcd..118aab5a6 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -175,7 +175,7 @@ uint32_t RadioInterface::getPacketTime(uint32_t pl) return msecs; } -uint32_t RadioInterface::getPacketTime(meshtastic_MeshPacket *p) +uint32_t RadioInterface::getPacketTime(const meshtastic_MeshPacket *p) { uint32_t pl = 0; if (p->which_payload_variant == meshtastic_MeshPacket_encrypted_tag) { diff --git a/src/mesh/RadioInterface.h b/src/mesh/RadioInterface.h index b9511fd5d..68dbf3522 100644 --- a/src/mesh/RadioInterface.h +++ b/src/mesh/RadioInterface.h @@ -154,7 +154,7 @@ class RadioInterface * * @return num msecs for the packet */ - uint32_t getPacketTime(meshtastic_MeshPacket *p); + uint32_t getPacketTime(const meshtastic_MeshPacket *p); uint32_t getPacketTime(uint32_t totalPacketLen); /** diff --git a/src/mesh/ReliableRouter.cpp b/src/mesh/ReliableRouter.cpp index 3d07ff77e..774be9c17 100644 --- a/src/mesh/ReliableRouter.cpp +++ b/src/mesh/ReliableRouter.cpp @@ -24,6 +24,15 @@ ErrorCode ReliableRouter::send(meshtastic_MeshPacket *p) startRetransmission(copy); } + /* If we have pending retransmissions, add the airtime of this packet to it, because during that time we cannot receive an + (implicit) ACK. Otherwise, we might retransmit too early. + */ + for (auto i = pending.begin(); i != pending.end(); i++) { + if (i->first.id != p->id) { + i->second.nextTxMsec += iface->getPacketTime(p); + } + } + return FloodingRouter::send(p); } @@ -53,6 +62,15 @@ bool ReliableRouter::shouldFilterReceived(const meshtastic_MeshPacket *p) } } + /* At this point we have already deleted the pending retransmission if this packet was an (implicit) ACK to it. + Now for all other pending retransmissions, we have to add the airtime of this received packet to the retransmission timer, + because while receiving this packet, we could not have received an (implicit) ACK for it. + If we don't add this, we will likely retransmit too early. + */ + for (auto i = pending.begin(); i != pending.end(); i++) { + i->second.nextTxMsec += iface->getPacketTime(p); + } + /* Resend implicit ACKs for repeated packets (assuming the original packet was sent with HOP_RELIABLE) * this way if an implicit ACK is dropped and a packet is resent we'll rebroadcast again. * Resending real ACKs is omitted, as you might receive a packet multiple times due to flooding and diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h index 0ffb4ccec..fcb129bef 100644 --- a/src/mesh/generated/meshtastic/config.pb.h +++ b/src/mesh/generated/meshtastic/config.pb.h @@ -31,7 +31,10 @@ typedef enum _meshtastic_Config_DeviceConfig_Role { meshtastic_Config_DeviceConfig_Role_REPEATER = 4, /* Tracker device role Position Mesh packets will be prioritized higher and sent more frequently by default. */ - meshtastic_Config_DeviceConfig_Role_TRACKER = 5 + meshtastic_Config_DeviceConfig_Role_TRACKER = 5, + /* Sensor device role + Telemetry Mesh packets will be prioritized higher and sent more frequently by default. */ + meshtastic_Config_DeviceConfig_Role_SENSOR = 6 } meshtastic_Config_DeviceConfig_Role; /* Defines the device's behavior for how messages are rebroadcast */ @@ -453,8 +456,8 @@ extern "C" { /* Helper constants for enums */ #define _meshtastic_Config_DeviceConfig_Role_MIN meshtastic_Config_DeviceConfig_Role_CLIENT -#define _meshtastic_Config_DeviceConfig_Role_MAX meshtastic_Config_DeviceConfig_Role_TRACKER -#define _meshtastic_Config_DeviceConfig_Role_ARRAYSIZE ((meshtastic_Config_DeviceConfig_Role)(meshtastic_Config_DeviceConfig_Role_TRACKER+1)) +#define _meshtastic_Config_DeviceConfig_Role_MAX meshtastic_Config_DeviceConfig_Role_SENSOR +#define _meshtastic_Config_DeviceConfig_Role_ARRAYSIZE ((meshtastic_Config_DeviceConfig_Role)(meshtastic_Config_DeviceConfig_Role_SENSOR+1)) #define _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN meshtastic_Config_DeviceConfig_RebroadcastMode_ALL #define _meshtastic_Config_DeviceConfig_RebroadcastMode_MAX meshtastic_Config_DeviceConfig_RebroadcastMode_LOCAL_ONLY diff --git a/src/modules/Telemetry/AirQualityTelemetry.cpp b/src/modules/Telemetry/AirQualityTelemetry.cpp index c300e1f96..de74c0bf9 100644 --- a/src/modules/Telemetry/AirQualityTelemetry.cpp +++ b/src/modules/Telemetry/AirQualityTelemetry.cpp @@ -108,7 +108,10 @@ bool AirQualityTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) meshtastic_MeshPacket *p = allocDataProtobuf(m); p->to = dest; p->decoded.want_response = false; - p->priority = meshtastic_MeshPacket_Priority_MIN; + if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR) + p->priority = meshtastic_MeshPacket_Priority_RELIABLE; + else + p->priority = meshtastic_MeshPacket_Priority_MIN; // release previous packet before occupying a new spot if (lastMeasurementPacket != nullptr) diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index bd7ed539a..3b8a7dda1 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -244,8 +244,10 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) meshtastic_MeshPacket *p = allocDataProtobuf(m); p->to = dest; p->decoded.want_response = false; - p->priority = meshtastic_MeshPacket_Priority_MIN; - + if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR) + p->priority = meshtastic_MeshPacket_Priority_RELIABLE; + else + p->priority = meshtastic_MeshPacket_Priority_MIN; // release previous packet before occupying a new spot if (lastMeasurementPacket != nullptr) packetPool.release(lastMeasurementPacket); diff --git a/src/platform/esp32/architecture.h b/src/platform/esp32/architecture.h index edd16ebbd..45ee7e6d4 100644 --- a/src/platform/esp32/architecture.h +++ b/src/platform/esp32/architecture.h @@ -97,6 +97,8 @@ #define HW_VENDOR meshtastic_HardwareModel_BETAFPV_2400_TX #elif defined(NANO_G1_EXPLORER) #define HW_VENDOR meshtastic_HardwareModel_NANO_G1_EXPLORER +#elif defined(BETAFPV_900_TX_NANO) +#define HW_VENDOR meshtastic_HardwareModel_BETAFPV_900_NANO_TX #endif // diff --git a/src/platform/nrf52/NRF52Bluetooth.cpp b/src/platform/nrf52/NRF52Bluetooth.cpp index 044b57ae6..59d11717a 100644 --- a/src/platform/nrf52/NRF52Bluetooth.cpp +++ b/src/platform/nrf52/NRF52Bluetooth.cpp @@ -92,12 +92,12 @@ void startAdv(void) Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); // IncludeService UUID - // Bluefruit.ScanResponse.addService(meshBleService); + Bluefruit.ScanResponse.addService(meshBleService); Bluefruit.ScanResponse.addTxPower(); Bluefruit.ScanResponse.addName(); // Include Name - // Bluefruit.Advertising.addName(); + Bluefruit.Advertising.addName(); Bluefruit.Advertising.addService(meshBleService); /* Start Advertising diff --git a/variants/betafpv_900_tx_nano/platformio.ini b/variants/betafpv_900_tx_nano/platformio.ini new file mode 100644 index 000000000..e4c945cab --- /dev/null +++ b/variants/betafpv_900_tx_nano/platformio.ini @@ -0,0 +1,16 @@ +[env:betafpv_900_tx_nano] +extends = esp32_base +board = esp32doit-devkit-v1 +build_flags = + ${esp32_base.build_flags} + -D BETAFPV_900_TX_NANO + -D VTABLES_IN_FLASH=1 + -D CONFIG_DISABLE_HAL_LOCKS=1 + -O2 + -I variants/betafpv_900_tx_nano +board_build.f_cpu = 240000000L +upload_protocol = esptool +upload_port = /dev/ttyUSB0 +upload_speed = 460800 +lib_deps = + ${esp32_base.lib_deps} diff --git a/variants/betafpv_900_tx_nano/variant.h b/variants/betafpv_900_tx_nano/variant.h new file mode 100644 index 000000000..01961d92d --- /dev/null +++ b/variants/betafpv_900_tx_nano/variant.h @@ -0,0 +1,28 @@ +// https://betafpv.com/products/elrs-nano-tx-module + +// no screen +#define HAS_SCREEN 0 + +// NO GPS +#undef GPS_RX_PIN +#undef GPS_TX_PIN + +#define USE_RF95 + +#define RF95_SCK 18 +#define RF95_MISO 19 +#define RF95_MOSI 23 +#define RF95_NSS 5 + +#define LORA_DIO0 4 +#define LORA_RESET 14 +#define LORA_DIO1 2 +#define LORA_DIO2 +#define LORA_DIO3 + +#define LED_PIN 16 // green - blue is at 17 + +#define BUTTON_PIN 25 +#define BUTTON_NEED_PULLUP + +#undef EXT_NOTIFY_OUT diff --git a/variants/tlora_t3s3_v1/platformio.ini b/variants/tlora_t3s3_v1/platformio.ini index aa8189199..568e8af42 100644 --- a/variants/tlora_t3s3_v1/platformio.ini +++ b/variants/tlora_t3s3_v1/platformio.ini @@ -1,6 +1,7 @@ [env:tlora-t3s3-v1] extends = esp32s3_base board = tlora-t3s3-v1 +upload_protocol = esp-builtin lib_deps = ${esp32_base.lib_deps} caveman99/ESP32 Codec2@^1.0.1 diff --git a/variants/tlora_t3s3_v1/variant.h b/variants/tlora_t3s3_v1/variant.h index 116911ae0..68eb18e31 100644 --- a/variants/tlora_t3s3_v1/variant.h +++ b/variants/tlora_t3s3_v1/variant.h @@ -37,11 +37,12 @@ #ifdef USE_SX1262 #define SX126X_CS RF95_NSS // FIXME - we really should define LORA_CS instead -#define SX126X_DIO1 LORA_DIO1 -#define SX126X_BUSY 36 +#define SX126X_DIO1 33 +#define SX126X_BUSY 34 #define SX126X_RESET LORA_RESET -#define SX126X_RXEN 21 -#define SX126X_TXEN 10 +//#define SX126X_RXEN 21 +//#define SX126X_TXEN 10 +#define SX126X_E22 #endif #ifdef USE_SX1280 diff --git a/version.properties b/version.properties index d0805fbbf..dca62c699 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 0 -build = 22 +build = 24