diff --git a/examples/companion_radio/DataStore.cpp b/examples/companion_radio/DataStore.cpp index 4faac9754..936cf8a7e 100644 --- a/examples/companion_radio/DataStore.cpp +++ b/examples/companion_radio/DataStore.cpp @@ -267,42 +267,57 @@ void DataStore::savePrefs(const NodePrefs& _prefs, double node_lat, double node_ } void DataStore::loadContacts(DataStoreHost* host) { -File file = openRead(_getContactsChannelsFS(), "/contacts3"); - if (file) { - bool full = false; - while (!full) { - ContactInfo c; - uint8_t pub_key[32]; - uint8_t unused; - - bool success = (file.read(pub_key, 32) == 32); - success = success && (file.read((uint8_t *)&c.name, 32) == 32); - success = success && (file.read(&c.type, 1) == 1); - success = success && (file.read(&c.flags, 1) == 1); - success = success && (file.read(&unused, 1) == 1); - success = success && (file.read((uint8_t *)&c.sync_since, 4) == 4); // was 'reserved' - success = success && (file.read((uint8_t *)&c.out_path_len, 1) == 1); - success = success && (file.read((uint8_t *)&c.last_advert_timestamp, 4) == 4); - success = success && (file.read(c.out_path, 64) == 64); - success = success && (file.read((uint8_t *)&c.lastmod, 4) == 4); - success = success && (file.read((uint8_t *)&c.gps_lat, 4) == 4); - success = success && (file.read((uint8_t *)&c.gps_lon, 4) == 4); - - if (!success) break; // EOF + FILESYSTEM* fs = _getContactsChannelsFS(); + File file = openRead(fs, "/contacts3"); + + // If main file doesn't exist or is empty, try backup + if (!file || file.size() == 0) { + if (file) file.close(); + if (fs->exists("/contacts3.bak")) { + MESH_DEBUG_PRINTLN("WARN: contacts3 missing/empty, loading from backup"); + file = openRead(fs, "/contacts3.bak"); + } + } - c.id = mesh::Identity(pub_key); - if (!host->onContactLoaded(c)) full = true; - } - file.close(); + if (file) { + bool full = false; + while (!full) { + ContactInfo c; + uint8_t pub_key[32]; + uint8_t unused; + + bool success = (file.read(pub_key, 32) == 32); + success = success && (file.read((uint8_t *)&c.name, 32) == 32); + success = success && (file.read(&c.type, 1) == 1); + success = success && (file.read(&c.flags, 1) == 1); + success = success && (file.read(&unused, 1) == 1); + success = success && (file.read((uint8_t *)&c.sync_since, 4) == 4); // was 'reserved' + success = success && (file.read((uint8_t *)&c.out_path_len, 1) == 1); + success = success && (file.read((uint8_t *)&c.last_advert_timestamp, 4) == 4); + success = success && (file.read(c.out_path, 64) == 64); + success = success && (file.read((uint8_t *)&c.lastmod, 4) == 4); + success = success && (file.read((uint8_t *)&c.gps_lat, 4) == 4); + success = success && (file.read((uint8_t *)&c.gps_lon, 4) == 4); + + if (!success) break; // EOF + + c.id = mesh::Identity(pub_key); + if (!host->onContactLoaded(c)) full = true; } + file.close(); + } } void DataStore::saveContacts(DataStoreHost* host) { - File file = openWrite(_getContactsChannelsFS(), "/contacts3"); + FILESYSTEM* fs = _getContactsChannelsFS(); + + // Write to temp file first (atomic write pattern) + File file = openWrite(fs, "/contacts3.tmp"); if (file) { uint32_t idx = 0; ContactInfo c; uint8_t unused = 0; + bool write_success = true; while (host->getContactForSave(idx, c)) { bool success = (file.write(c.id.pub_key, 32) == 32); @@ -318,11 +333,26 @@ void DataStore::saveContacts(DataStoreHost* host) { success = success && (file.write((uint8_t *)&c.gps_lat, 4) == 4); success = success && (file.write((uint8_t *)&c.gps_lon, 4) == 4); - if (!success) break; // write failed + if (!success) { + write_success = false; + break; // write failed + } idx++; // advance to next contact } + file.flush(); file.close(); + + if (write_success) { + // Atomic swap: remove old backup, rename current to backup, rename temp to current + fs->remove("/contacts3.bak"); + fs->rename("/contacts3", "/contacts3.bak"); + fs->rename("/contacts3.tmp", "/contacts3"); + } else { + // Write failed, remove incomplete temp file + fs->remove("/contacts3.tmp"); + MESH_DEBUG_PRINTLN("ERROR: saveContacts write failed, temp file removed"); + } } } diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index 59a0078f4..ef9619801 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -299,6 +299,10 @@ void MyMesh::onDiscoveredContact(ContactInfo &contact, bool is_new, uint8_t path memcpy(p->path, path, p->path_len); } + // Don't save if this is a new contact but auto-add is off (contact not added to list) + if (is_new && !isAutoAddEnabled()) { + return; + } dirty_contacts_expiry = futureMillis(LAZY_CONTACTS_WRITE_DELAY); } @@ -778,7 +782,7 @@ void MyMesh::begin(bool has_display) { _prefs.bw = constrain(_prefs.bw, 7.8f, 500.0f); _prefs.sf = constrain(_prefs.sf, 5, 12); _prefs.cr = constrain(_prefs.cr, 5, 8); - _prefs.tx_power_dbm = constrain(_prefs.tx_power_dbm, 1, MAX_LORA_TX_POWER); + _prefs.tx_power_dbm = constrain(_prefs.tx_power_dbm, -9, MAX_LORA_TX_POWER); _prefs.gps_enabled = constrain(_prefs.gps_enabled, 0, 1); // Ensure boolean 0 or 1 _prefs.gps_interval = constrain(_prefs.gps_interval, 0, 86400); // Max 24 hours @@ -1004,13 +1008,8 @@ void MyMesh::handleCmdFrame(size_t len) { } else if (cmd_frame[0] == CMD_SET_DEVICE_TIME && len >= 5) { uint32_t secs; memcpy(&secs, &cmd_frame[1], 4); - uint32_t curr = getRTCClock()->getCurrentTime(); - if (secs >= curr) { - getRTCClock()->setCurrentTime(secs); - writeOKFrame(); - } else { - writeErrFrame(ERR_CODE_ILLEGAL_ARG); - } + getRTCClock()->setCurrentTime(secs); + writeOKFrame(); } else if (cmd_frame[0] == CMD_SEND_SELF_ADVERT) { mesh::Packet* pkt; if (_prefs.advert_loc_policy == ADVERT_LOC_NONE) { diff --git a/examples/companion_radio/NodePrefs.h b/examples/companion_radio/NodePrefs.h index e9db5444f..5eda67f4d 100644 --- a/examples/companion_radio/NodePrefs.h +++ b/examples/companion_radio/NodePrefs.h @@ -17,7 +17,7 @@ struct NodePrefs { // persisted to file uint8_t multi_acks; uint8_t manual_add_contacts; float bw; - uint8_t tx_power_dbm; + int8_t tx_power_dbm; uint8_t telemetry_mode_base; uint8_t telemetry_mode_loc; uint8_t telemetry_mode_env; diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index 82c8c21d9..c9a43b233 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -99,6 +99,11 @@ MyMesh the_mesh(radio_driver, fast_rng, rtc_clock, tables, store #endif ); +// Power saving timing variables +unsigned long lastActive = 0; // Last time there was activity +unsigned long nextSleepInSecs = 120; // Wait 2 minutes before first sleep +const unsigned long WORK_TIME_SECS = 5; // Stay awake 5 seconds after wake/activity + /* END GLOBAL OBJECTS */ void halt() { @@ -219,6 +224,9 @@ void setup() { #ifdef DISPLAY_CLASS ui_task.begin(disp, &sensors, the_mesh.getNodePrefs()); // still want to pass this in as dependency, as prefs might be moved #endif + + // Initialize power saving timer + lastActive = millis(); } void loop() { @@ -228,4 +236,25 @@ void loop() { ui_task.loop(); #endif rtc_clock.tick(); + + // Power saving when BLE/WiFi is disabled + // Don't sleep if GPS is enabled - it needs continuous operation to maintain fix + // Note: Disabling BLE/WiFi via UI actually turns off the radio to save power + if (!serial_interface.isEnabled() && !the_mesh.getNodePrefs()->gps_enabled) { + // Check for pending work and update activity timer + if (the_mesh.hasPendingWork()) { + lastActive = millis(); + if (nextSleepInSecs < 10) { + nextSleepInSecs += 5; // Extend work time by 5s if still busy + } + } + + // Only sleep if enough time has passed since last activity + if (millis() >= lastActive + (nextSleepInSecs * 1000)) { + board.sleep(1800); // Sleep for 30 minutes, wake on LoRa packet, timer, or button + // Just woke up - reset timers + lastActive = millis(); + nextSleepInSecs = WORK_TIME_SECS; // Stay awake for 5s after wake + } + } } diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index 8077627f8..cc26320cf 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -219,7 +219,7 @@ class HomeScreen : public UIScreen { for (int i = 0; i < UI_RECENT_LIST_SIZE; i++, y += 11) { auto a = &recent[i]; if (a->name[0] == 0) continue; // empty slot - int secs = _rtc->getCurrentTime() - a->recv_timestamp; + uint32_t secs = safeElapsedSecs(_rtc->getCurrentTime(), a->recv_timestamp); if (secs < 60) { sprintf(tmp, "%ds", secs); } else if (secs < 60*60) { @@ -480,7 +480,7 @@ class MsgPreviewScreen : public UIScreen { auto p = &unread[0]; - int secs = _rtc->getCurrentTime() - p->timestamp; + uint32_t secs = safeElapsedSecs(_rtc->getCurrentTime(), p->timestamp); if (secs < 60) { sprintf(tmp, "%ds", secs); } else if (secs < 60*60) { diff --git a/examples/simple_repeater/MyMesh.cpp b/examples/simple_repeater/MyMesh.cpp index d926148d6..180b229ed 100644 --- a/examples/simple_repeater/MyMesh.cpp +++ b/examples/simple_repeater/MyMesh.cpp @@ -343,7 +343,7 @@ int MyMesh::handleRequest(ClientInfo *sender, uint32_t sender_timestamp, uint8_t // add next neighbour to results auto neighbour = sorted_neighbours[index + offset]; - uint32_t heard_seconds_ago = getRTCClock()->getCurrentTime() - neighbour->heard_timestamp; + uint32_t heard_seconds_ago = safeElapsedSecs(getRTCClock()->getCurrentTime(), neighbour->heard_timestamp); memcpy(&results_buffer[results_offset], neighbour->id.pub_key, pubkey_prefix_length); results_offset += pubkey_prefix_length; memcpy(&results_buffer[results_offset], &heard_seconds_ago, 4); results_offset += 4; memcpy(&results_buffer[results_offset], &neighbour->snr, 1); results_offset += 1; @@ -895,7 +895,7 @@ void MyMesh::dumpLogFile() { } } -void MyMesh::setTxPower(uint8_t power_dbm) { +void MyMesh::setTxPower(int8_t power_dbm) { radio_set_tx_power(power_dbm); } @@ -930,7 +930,7 @@ void MyMesh::formatNeighborsReply(char *reply) { mesh::Utils::toHex(hex, neighbour->id.pub_key, 4); // add next neighbour - uint32_t secs_ago = getRTCClock()->getCurrentTime() - neighbour->heard_timestamp; + uint32_t secs_ago = safeElapsedSecs(getRTCClock()->getCurrentTime(), neighbour->heard_timestamp); sprintf(dp, "%s:%d:%d", hex, secs_ago, neighbour->snr); while (*dp) dp++; // find end of string @@ -1194,8 +1194,3 @@ void MyMesh::loop() { uptime_millis += now - last_millis; last_millis = now; } - -// To check if there is pending work -bool MyMesh::hasPendingWork() const { - return _mgr->getOutboundCount(0xFFFFFFFF) > 0; -} diff --git a/examples/simple_repeater/MyMesh.h b/examples/simple_repeater/MyMesh.h index f930ee7eb..72850eeed 100644 --- a/examples/simple_repeater/MyMesh.h +++ b/examples/simple_repeater/MyMesh.h @@ -197,7 +197,7 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks { } void dumpLogFile() override; - void setTxPower(uint8_t power_dbm) override; + void setTxPower(int8_t power_dbm) override; void formatNeighborsReply(char *reply) override; void removeNeighbor(const uint8_t* pubkey, int key_len) override; void formatStatsReply(char *reply) override; @@ -230,7 +230,4 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks { bridge.begin(); } #endif - - // To check if there is pending work - bool hasPendingWork() const; }; diff --git a/examples/simple_repeater/UITask.cpp b/examples/simple_repeater/UITask.cpp index d096d14b2..91bb53bb2 100644 --- a/examples/simple_repeater/UITask.cpp +++ b/examples/simple_repeater/UITask.cpp @@ -2,6 +2,12 @@ #include #include +// Default button polarity: Active-LOW (pressed = LOW) +// Override with -D USER_BTN_PRESSED=HIGH in platformio.ini for rare active-high devices. +#ifndef USER_BTN_PRESSED +#define USER_BTN_PRESSED LOW +#endif + #define AUTO_OFF_MILLIS 20000 // 20 seconds #define BOOT_SCREEN_MILLIS 4000 // 4 seconds @@ -85,7 +91,7 @@ void UITask::loop() { if (millis() >= _next_read) { int btnState = digitalRead(PIN_USER_BTN); if (btnState != _prevBtnState) { - if (btnState == LOW) { // pressed? + if (btnState == USER_BTN_PRESSED) { // pressed? if (_display->isOn()) { // TODO: any action ? } else { diff --git a/examples/simple_room_server/MyMesh.cpp b/examples/simple_room_server/MyMesh.cpp index 60dd18407..a5a191919 100644 --- a/examples/simple_room_server/MyMesh.cpp +++ b/examples/simple_room_server/MyMesh.cpp @@ -715,7 +715,7 @@ void MyMesh::dumpLogFile() { } } -void MyMesh::setTxPower(uint8_t power_dbm) { +void MyMesh::setTxPower(int8_t power_dbm) { radio_set_tx_power(power_dbm); } diff --git a/examples/simple_room_server/MyMesh.h b/examples/simple_room_server/MyMesh.h index e7f1fee83..36eb3b558 100644 --- a/examples/simple_room_server/MyMesh.h +++ b/examples/simple_room_server/MyMesh.h @@ -188,7 +188,7 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks { } void dumpLogFile() override; - void setTxPower(uint8_t power_dbm) override; + void setTxPower(int8_t power_dbm) override; void formatNeighborsReply(char *reply) override { strcpy(reply, "not supported"); diff --git a/examples/simple_room_server/UITask.cpp b/examples/simple_room_server/UITask.cpp index 46311c5eb..57ea1ee59 100644 --- a/examples/simple_room_server/UITask.cpp +++ b/examples/simple_room_server/UITask.cpp @@ -2,6 +2,12 @@ #include #include +// Default button polarity: Active-LOW (pressed = LOW) +// Override with -D USER_BTN_PRESSED=HIGH in platformio.ini for rare active-high devices. +#ifndef USER_BTN_PRESSED +#define USER_BTN_PRESSED LOW +#endif + #define AUTO_OFF_MILLIS 20000 // 20 seconds #define BOOT_SCREEN_MILLIS 4000 // 4 seconds @@ -85,7 +91,7 @@ void UITask::loop() { if (millis() >= _next_read) { int btnState = digitalRead(PIN_USER_BTN); if (btnState != _prevBtnState) { - if (btnState == LOW) { // pressed? + if (btnState == USER_BTN_PRESSED) { // pressed? if (_display->isOn()) { // TODO: any action ? } else { diff --git a/examples/simple_secure_chat/main.cpp b/examples/simple_secure_chat/main.cpp index da1bac5b3..57b8e8694 100644 --- a/examples/simple_secure_chat/main.cpp +++ b/examples/simple_secure_chat/main.cpp @@ -66,7 +66,7 @@ struct NodePrefs { // persisted to file char node_name[32]; double node_lat, node_lon; float freq; - uint8_t tx_power_dbm; + int8_t tx_power_dbm; uint8_t unused[3]; }; @@ -158,13 +158,8 @@ class MyMesh : public BaseChatMesh, ContactVisitor { } void setClock(uint32_t timestamp) { - uint32_t curr = getRTCClock()->getCurrentTime(); - if (timestamp > curr) { - getRTCClock()->setCurrentTime(timestamp); - Serial.println(" (OK - clock set!)"); - } else { - Serial.println(" (ERR: clock cannot go backwards)"); - } + getRTCClock()->setCurrentTime(timestamp); + Serial.println(" (OK - clock set!)"); } void importCard(const char* command) { @@ -290,7 +285,7 @@ class MyMesh : public BaseChatMesh, ContactVisitor { } float getFreqPref() const { return _prefs.freq; } - uint8_t getTxPowerPref() const { return _prefs.tx_power_dbm; } + int8_t getTxPowerPref() const { return _prefs.tx_power_dbm; } void begin(FILESYSTEM& fs) { _fs = &fs; diff --git a/examples/simple_sensor/SensorMesh.cpp b/examples/simple_sensor/SensorMesh.cpp index 4995c55fc..35e285b27 100644 --- a/examples/simple_sensor/SensorMesh.cpp +++ b/examples/simple_sensor/SensorMesh.cpp @@ -812,7 +812,7 @@ void SensorMesh::updateFloodAdvertTimer() { } } -void SensorMesh::setTxPower(uint8_t power_dbm) { +void SensorMesh::setTxPower(int8_t power_dbm) { radio_set_tx_power(power_dbm); } diff --git a/examples/simple_sensor/SensorMesh.h b/examples/simple_sensor/SensorMesh.h index c320eb447..bb9b6ed5a 100644 --- a/examples/simple_sensor/SensorMesh.h +++ b/examples/simple_sensor/SensorMesh.h @@ -66,7 +66,7 @@ class SensorMesh : public mesh::Mesh, public CommonCLICallbacks { void setLoggingOn(bool enable) override { } void eraseLogFile() override { } void dumpLogFile() override { } - void setTxPower(uint8_t power_dbm) override; + void setTxPower(int8_t power_dbm) override; void formatNeighborsReply(char *reply) override { strcpy(reply, "not supported"); } diff --git a/examples/simple_sensor/TimeSeriesData.cpp b/examples/simple_sensor/TimeSeriesData.cpp index f6157f9af..c780c7de2 100644 --- a/examples/simple_sensor/TimeSeriesData.cpp +++ b/examples/simple_sensor/TimeSeriesData.cpp @@ -1,4 +1,5 @@ #include "TimeSeriesData.h" +#include void TimeSeriesData::recordData(mesh::RTCClock* clock, float value) { uint32_t now = clock->getCurrentTime(); @@ -12,7 +13,7 @@ void TimeSeriesData::recordData(mesh::RTCClock* clock, float value) { void TimeSeriesData::calcMinMaxAvg(mesh::RTCClock* clock, uint32_t start_secs_ago, uint32_t end_secs_ago, MinMaxAvg* dest, uint8_t channel, uint8_t lpp_type) const { int i = next, n = num_slots; - uint32_t ago = clock->getCurrentTime() - last_timestamp; + uint32_t ago = safeElapsedSecs(clock->getCurrentTime(), last_timestamp); int num_values = 0; float total = 0.0f; diff --git a/examples/simple_sensor/UITask.cpp b/examples/simple_sensor/UITask.cpp index 0694bc3c1..b7fb05cf8 100644 --- a/examples/simple_sensor/UITask.cpp +++ b/examples/simple_sensor/UITask.cpp @@ -2,6 +2,12 @@ #include #include +// Default button polarity: Active-LOW (pressed = LOW) +// Override with -D USER_BTN_PRESSED=HIGH in platformio.ini for rare active-high devices. +#ifndef USER_BTN_PRESSED +#define USER_BTN_PRESSED LOW +#endif + #define AUTO_OFF_MILLIS 20000 // 20 seconds #define BOOT_SCREEN_MILLIS 4000 // 4 seconds @@ -85,7 +91,7 @@ void UITask::loop() { if (millis() >= _next_read) { int btnState = digitalRead(PIN_USER_BTN); if (btnState != _prevBtnState) { - if (btnState == LOW) { // pressed? + if (btnState == USER_BTN_PRESSED) { // pressed? if (_display->isOn()) { // TODO: any action ? } else { diff --git a/src/Mesh.h b/src/Mesh.h index 00f7ed00f..cb1762a5e 100644 --- a/src/Mesh.h +++ b/src/Mesh.h @@ -220,6 +220,12 @@ class Mesh : public Dispatcher { */ void sendZeroHop(Packet* packet, uint16_t* transport_codes, uint32_t delay_millis=0); + /** + * \brief Check if there is pending work (packets to send) + * \returns true if there are outbound packets waiting + */ + bool hasPendingWork() const { return _mgr->getOutboundCount(0xFFFFFFFF) > 0; } + }; } diff --git a/src/helpers/ArduinoHelpers.h b/src/helpers/ArduinoHelpers.h index 97596daa3..5f12e5b01 100644 --- a/src/helpers/ArduinoHelpers.h +++ b/src/helpers/ArduinoHelpers.h @@ -3,6 +3,15 @@ #include #include +// Safe elapsed time calculation that handles clock corrections (when RTC is set backwards). +// Returns 0 if recorded_timestamp is in the "future" relative to current_time. +inline uint32_t safeElapsedSecs(uint32_t current_time, uint32_t recorded_timestamp) { + if (recorded_timestamp > current_time) { + return 0; // Clock was corrected backwards; treat as "just now" + } + return current_time - recorded_timestamp; +} + class VolatileRTCClock : public mesh::RTCClock { uint32_t base_time; uint64_t accumulator; diff --git a/src/helpers/BaseChatMesh.cpp b/src/helpers/BaseChatMesh.cpp index 081856289..8f70a4878 100644 --- a/src/helpers/BaseChatMesh.cpp +++ b/src/helpers/BaseChatMesh.cpp @@ -573,7 +573,7 @@ bool BaseChatMesh::startConnection(const ContactInfo& contact, uint16_t keep_ali uint32_t interval = connections[use_idx].keep_alive_millis = ((uint32_t)keep_alive_secs)*1000; connections[use_idx].next_ping = futureMillis(interval); connections[use_idx].expected_ack = 0; - connections[use_idx].last_activity = getRTCClock()->getCurrentTime(); + connections[use_idx].last_activity = _ms->getMillis(); // use monotonic time for connection expiry return true; // success } @@ -599,7 +599,7 @@ bool BaseChatMesh::hasConnectionTo(const uint8_t* pub_key) { void BaseChatMesh::markConnectionActive(const ContactInfo& contact) { for (int i = 0; i < MAX_CONNECTIONS; i++) { if (connections[i].keep_alive_millis > 0 && connections[i].server_id.matches(contact.id)) { - connections[i].last_activity = getRTCClock()->getCurrentTime(); + connections[i].last_activity = _ms->getMillis(); // use monotonic time for connection expiry // re-schedule next KEEP_ALIVE, now that we have heard from server connections[i].next_ping = futureMillis(connections[i].keep_alive_millis); @@ -613,7 +613,7 @@ ContactInfo* BaseChatMesh::checkConnectionsAck(const uint8_t* data) { if (connections[i].keep_alive_millis > 0 && memcmp(&connections[i].expected_ack, data, 4) == 0) { // yes, got an ack for our keep_alive request! connections[i].expected_ack = 0; - connections[i].last_activity = getRTCClock()->getCurrentTime(); + connections[i].last_activity = _ms->getMillis(); // use monotonic time for connection expiry // re-schedule next KEEP_ALIVE, now that we have heard from server connections[i].next_ping = futureMillis(connections[i].keep_alive_millis); @@ -630,9 +630,13 @@ void BaseChatMesh::checkConnections() { for (int i = 0; i < MAX_CONNECTIONS; i++) { if (connections[i].keep_alive_millis == 0) continue; // unused slot - uint32_t now = getRTCClock()->getCurrentTime(); - uint32_t expire_secs = (connections[i].keep_alive_millis / 1000) * 5 / 2; // 2.5 x keep_alive interval - if (now >= connections[i].last_activity + expire_secs) { + // Use monotonic time (millis) for connection expiry - immune to RTC clock changes. + // Note: This assumes light sleep mode where millis() continues to increment. + // Deep sleep would reset millis(), but BaseChatMesh is only used by companion_radio + // which uses light sleep. + unsigned long now = _ms->getMillis(); + uint32_t expire_millis = (connections[i].keep_alive_millis * 5) / 2; // 2.5 x keep_alive interval + if ((now - connections[i].last_activity) >= expire_millis) { // connection now lost connections[i].keep_alive_millis = 0; connections[i].next_ping = 0; diff --git a/src/helpers/CommonCLI.cpp b/src/helpers/CommonCLI.cpp index 2fc93006b..e7a144291 100644 --- a/src/helpers/CommonCLI.cpp +++ b/src/helpers/CommonCLI.cpp @@ -92,7 +92,7 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) { _prefs->bw = constrain(_prefs->bw, 7.8f, 500.0f); _prefs->sf = constrain(_prefs->sf, 5, 12); _prefs->cr = constrain(_prefs->cr, 5, 8); - _prefs->tx_power_dbm = constrain(_prefs->tx_power_dbm, 1, 30); + _prefs->tx_power_dbm = constrain(_prefs->tx_power_dbm, -9, 30); _prefs->multi_acks = constrain(_prefs->multi_acks, 0, 1); _prefs->adc_multiplier = constrain(_prefs->adc_multiplier, 0.0f, 10.0f); @@ -200,15 +200,10 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch _callbacks->sendSelfAdvertisement(1500); // longer delay, give CLI response time to be sent first strcpy(reply, "OK - Advert sent"); } else if (memcmp(command, "clock sync", 10) == 0) { - uint32_t curr = getRTCClock()->getCurrentTime(); - if (sender_timestamp > curr) { - getRTCClock()->setCurrentTime(sender_timestamp + 1); - uint32_t now = getRTCClock()->getCurrentTime(); - DateTime dt = DateTime(now); - sprintf(reply, "OK - clock set: %02d:%02d - %d/%d/%d UTC", dt.hour(), dt.minute(), dt.day(), dt.month(), dt.year()); - } else { - strcpy(reply, "ERR: clock cannot go backwards"); - } + getRTCClock()->setCurrentTime(sender_timestamp + 1); + uint32_t now = getRTCClock()->getCurrentTime(); + DateTime dt = DateTime(now); + sprintf(reply, "OK - clock set: %02d:%02d - %d/%d/%d UTC", dt.hour(), dt.minute(), dt.day(), dt.month(), dt.year()); } else if (memcmp(command, "start ota", 9) == 0) { if (!_board->startOTAUpdate(_prefs->node_name, reply)) { strcpy(reply, "Error"); @@ -219,15 +214,10 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch sprintf(reply, "%02d:%02d - %d/%d/%d UTC", dt.hour(), dt.minute(), dt.day(), dt.month(), dt.year()); } else if (memcmp(command, "time ", 5) == 0) { // set time (to epoch seconds) uint32_t secs = _atoi(&command[5]); - uint32_t curr = getRTCClock()->getCurrentTime(); - if (secs > curr) { - getRTCClock()->setCurrentTime(secs); - uint32_t now = getRTCClock()->getCurrentTime(); - DateTime dt = DateTime(now); - sprintf(reply, "OK - clock set: %02d:%02d - %d/%d/%d UTC", dt.hour(), dt.minute(), dt.day(), dt.month(), dt.year()); - } else { - strcpy(reply, "(ERR: clock cannot go backwards)"); - } + getRTCClock()->setCurrentTime(secs); + uint32_t now = getRTCClock()->getCurrentTime(); + DateTime dt = DateTime(now); + sprintf(reply, "OK - clock set: %02d:%02d - %d/%d/%d UTC", dt.hour(), dt.minute(), dt.day(), dt.month(), dt.year()); } else if (memcmp(command, "neighbors", 9) == 0) { _callbacks->formatNeighborsReply(reply); } else if (memcmp(command, "neighbor.remove ", 16) == 0) { @@ -321,7 +311,7 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch } *reply = 0; // set null terminator } else if (memcmp(config, "tx", 2) == 0 && (config[2] == 0 || config[2] == ' ')) { - sprintf(reply, "> %d", (uint32_t) _prefs->tx_power_dbm); + sprintf(reply, "> %d", (int32_t) _prefs->tx_power_dbm); } else if (memcmp(config, "freq", 4) == 0) { sprintf(reply, "> %s", StrHelper::ftoa(_prefs->freq)); } else if (memcmp(config, "public.key", 10) == 0) { diff --git a/src/helpers/CommonCLI.h b/src/helpers/CommonCLI.h index 3b1d05f96..4be8a7ac0 100644 --- a/src/helpers/CommonCLI.h +++ b/src/helpers/CommonCLI.h @@ -18,7 +18,7 @@ struct NodePrefs { // persisted to file double node_lat, node_lon; char password[16]; float freq; - uint8_t tx_power_dbm; + int8_t tx_power_dbm; uint8_t disable_fwd; uint8_t advert_interval; // minutes / 2 uint8_t flood_advert_interval; // hours @@ -66,7 +66,7 @@ class CommonCLICallbacks { virtual void setLoggingOn(bool enable) = 0; virtual void eraseLogFile() = 0; virtual void dumpLogFile() = 0; - virtual void setTxPower(uint8_t power_dbm) = 0; + virtual void setTxPower(int8_t power_dbm) = 0; virtual void formatNeighborsReply(char *reply) = 0; virtual void removeNeighbor(const uint8_t* pubkey, int key_len) { // no op by default diff --git a/src/helpers/ESP32Board.h b/src/helpers/ESP32Board.h index 01b4c980c..f21ef29ab 100644 --- a/src/helpers/ESP32Board.h +++ b/src/helpers/ESP32Board.h @@ -3,6 +3,13 @@ #include #include +// Default button polarity: Active-LOW (pressed = LOW) +// Most LoRa boards use GPIO as a boot button that pulls to GND when pressed. +// Override with -D USER_BTN_PRESSED=HIGH in platformio.ini for rare active-high devices. +#ifndef USER_BTN_PRESSED +#define USER_BTN_PRESSED LOW +#endif + #if defined(ESP_PLATFORM) #include @@ -56,14 +63,26 @@ class ESP32Board : public mesh::MainBoard { return raw / 4; } - void enterLightSleep(uint32_t secs) { + void enterLightSleep(uint32_t secs, int pin_wake_btn = -1, bool btn_active_high = true) { #if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(P_LORA_DIO_1) // Supported ESP32 variants if (rtc_gpio_is_valid_gpio((gpio_num_t)P_LORA_DIO_1)) { // Only enter sleep mode if P_LORA_DIO_1 is RTC pin esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); - esp_sleep_enable_ext1_wakeup((1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // To wake up when receiving a LoRa packet + + // Configure wakeup sources: LoRa packet (always active-high) and optionally button + if (pin_wake_btn < 0) { + // No button - just wake on LoRa packet + esp_sleep_enable_ext1_wakeup((1ULL << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); + } else if (btn_active_high) { + // Button is active-high (same as LoRa) - can use single ext1 source + esp_sleep_enable_ext1_wakeup((1ULL << P_LORA_DIO_1) | (1ULL << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); + } else { + // Button is active-low (different from LoRa) - use ext0 for button, ext1 for LoRa + esp_sleep_enable_ext0_wakeup((gpio_num_t)pin_wake_btn, 0); // Wake when button goes LOW + esp_sleep_enable_ext1_wakeup((1ULL << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // Wake on LoRa packet + } if (secs > 0) { - esp_sleep_enable_timer_wakeup(secs * 1000000); // To wake up every hour to do periodically jobs + esp_sleep_enable_timer_wakeup(secs * 1000000); // To wake up after specified seconds } esp_light_sleep_start(); // CPU enters light sleep @@ -75,9 +94,18 @@ class ESP32Board : public mesh::MainBoard { // To check for WiFi status to see if there is active OTA wifi_mode_t mode; esp_err_t err = esp_wifi_get_mode(&mode); - + if (err != ESP_OK) { // WiFi is off ~ No active OTA, safe to go to sleep - enterLightSleep(secs); // To wake up after "secs" seconds or when receiving a LoRa packet +#ifdef PIN_USER_BTN + // Sleep with button wake support (USER_BTN_PRESSED defaults to LOW if not defined) + #if USER_BTN_PRESSED == LOW + enterLightSleep(secs, PIN_USER_BTN, false); // Button is active-low + #else + enterLightSleep(secs, PIN_USER_BTN, true); // Button is active-high + #endif +#else + enterLightSleep(secs); +#endif } } diff --git a/src/helpers/esp32/SerialBLEInterface.cpp b/src/helpers/esp32/SerialBLEInterface.cpp index 7ec937238..5cae0ab59 100644 --- a/src/helpers/esp32/SerialBLEInterface.cpp +++ b/src/helpers/esp32/SerialBLEInterface.cpp @@ -21,7 +21,7 @@ void SerialBLEInterface::begin(const char* device_name, uint32_t pin_code) { sec.setStaticPIN(pin_code); sec.setAuthenticationMode(ESP_LE_AUTH_REQ_SC_MITM_BOND); - //BLEDevice::setPower(ESP_PWR_LVL_N8); + BLEDevice::setPower(ESP_PWR_LVL_P9); // Create the BLE Server pServer = BLEDevice::createServer(); @@ -118,7 +118,7 @@ void SerialBLEInterface::onWrite(BLECharacteristic* pCharacteristic, esp_ble_gat // ---------- public methods -void SerialBLEInterface::enable() { +void SerialBLEInterface::enable() { if (_isEnabled) return; _isEnabled = true; diff --git a/src/helpers/esp32/SerialWifiInterface.cpp b/src/helpers/esp32/SerialWifiInterface.cpp index 462e3ecc3..f4ebf5d69 100644 --- a/src/helpers/esp32/SerialWifiInterface.cpp +++ b/src/helpers/esp32/SerialWifiInterface.cpp @@ -4,18 +4,38 @@ void SerialWifiInterface::begin(int port) { // wifi setup is handled outside of this class, only starts the server server.begin(port); + + // Store WiFi credentials for re-enable +#ifdef WIFI_SSID + _ssid = WIFI_SSID; + _password = WIFI_PWD; + _isEnabled = true; // WiFi starts enabled +#else + _ssid = nullptr; + _password = nullptr; +#endif } // ---------- public methods -void SerialWifiInterface::enable() { +void SerialWifiInterface::enable() { if (_isEnabled) return; _isEnabled = true; clearBuffers(); + + // Re-enable WiFi with stored credentials + if (_ssid != nullptr && _password != nullptr) { + WiFi.mode(WIFI_STA); + WiFi.begin(_ssid, _password); + } } void SerialWifiInterface::disable() { _isEnabled = false; + + // Actually turn off WiFi to save power + WiFi.disconnect(true); // Disconnect and clear config + WiFi.mode(WIFI_OFF); // Turn off WiFi radio } size_t SerialWifiInterface::writeFrame(const uint8_t src[], size_t len) { diff --git a/src/helpers/esp32/SerialWifiInterface.h b/src/helpers/esp32/SerialWifiInterface.h index 19291497f..f900d18bc 100644 --- a/src/helpers/esp32/SerialWifiInterface.h +++ b/src/helpers/esp32/SerialWifiInterface.h @@ -8,6 +8,8 @@ class SerialWifiInterface : public BaseSerialInterface { bool _isEnabled; unsigned long _last_write; unsigned long adv_restart_time; + const char* _ssid; + const char* _password; WiFiServer server; WiFiClient client; @@ -39,6 +41,8 @@ class SerialWifiInterface : public BaseSerialInterface { deviceConnected = false; _isEnabled = false; _last_write = 0; + _ssid = nullptr; + _password = nullptr; send_queue_len = recv_queue_len = 0; received_frame_header.type = 0; received_frame_header.length = 0; diff --git a/src/helpers/sensors/MicroNMEALocationProvider.h b/src/helpers/sensors/MicroNMEALocationProvider.h index 574570a35..754cdf140 100644 --- a/src/helpers/sensors/MicroNMEALocationProvider.h +++ b/src/helpers/sensors/MicroNMEALocationProvider.h @@ -43,6 +43,8 @@ class MicroNMEALocationProvider : public LocationProvider { int _pin_en; long next_check = 0; long time_valid = 0; + unsigned long _last_time_sync = 0; + static const unsigned long TIME_SYNC_INTERVAL = 1800000; // Re-sync every 30 minutes public : MicroNMEALocationProvider(Stream& ser, mesh::RTCClock* clock = NULL, int pin_reset = GPS_RESET, int pin_en = GPS_EN,RefCountedDigitalPin* peripher_power=NULL) : @@ -126,10 +128,15 @@ public : if (millis() > next_check) { next_check = millis() + 1000; + // Re-enable time sync periodically when GPS has valid fix + if (!_time_sync_needed && _clock != NULL && (millis() - _last_time_sync) > TIME_SYNC_INTERVAL) { + _time_sync_needed = true; + } if (_time_sync_needed && time_valid > 2) { if (_clock != NULL) { _clock->setCurrentTime(getTimestamp()); _time_sync_needed = false; + _last_time_sync = millis(); } } if (isValid()) { diff --git a/variants/ebyte_eora_s3/target.cpp b/variants/ebyte_eora_s3/target.cpp index 647f59972..501f560be 100644 --- a/variants/ebyte_eora_s3/target.cpp +++ b/variants/ebyte_eora_s3/target.cpp @@ -75,7 +75,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/ebyte_eora_s3/target.h b/variants/ebyte_eora_s3/target.h index f184c7575..892c3de3f 100644 --- a/variants/ebyte_eora_s3/target.h +++ b/variants/ebyte_eora_s3/target.h @@ -25,5 +25,5 @@ extern SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/generic-e22/target.cpp b/variants/generic-e22/target.cpp index e02537798..f76bb979a 100644 --- a/variants/generic-e22/target.cpp +++ b/variants/generic-e22/target.cpp @@ -38,7 +38,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/generic-e22/target.h b/variants/generic-e22/target.h index 442706f33..5ad13054f 100644 --- a/variants/generic-e22/target.h +++ b/variants/generic-e22/target.h @@ -17,5 +17,5 @@ extern SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/generic_espnow/target.cpp b/variants/generic_espnow/target.cpp index 6b5d4e444..f42085c04 100644 --- a/variants/generic_espnow/target.cpp +++ b/variants/generic_espnow/target.cpp @@ -25,7 +25,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { // no-op } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio_driver.setTxPower(dbm); } diff --git a/variants/generic_espnow/target.h b/variants/generic_espnow/target.h index 99b6f5778..1ebd0837b 100644 --- a/variants/generic_espnow/target.h +++ b/variants/generic_espnow/target.h @@ -12,5 +12,5 @@ extern SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/heltec_ct62/target.cpp b/variants/heltec_ct62/target.cpp index a8c15f5ff..5cc621a13 100644 --- a/variants/heltec_ct62/target.cpp +++ b/variants/heltec_ct62/target.cpp @@ -27,7 +27,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/heltec_ct62/target.h b/variants/heltec_ct62/target.h index 9639ab2df..34130ae77 100644 --- a/variants/heltec_ct62/target.h +++ b/variants/heltec_ct62/target.h @@ -16,5 +16,5 @@ extern SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); \ No newline at end of file diff --git a/variants/heltec_e213/target.cpp b/variants/heltec_e213/target.cpp index 23561850e..c9233431c 100644 --- a/variants/heltec_e213/target.cpp +++ b/variants/heltec_e213/target.cpp @@ -44,7 +44,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/heltec_e213/target.h b/variants/heltec_e213/target.h index 9ecdc212a..14969c0f4 100644 --- a/variants/heltec_e213/target.h +++ b/variants/heltec_e213/target.h @@ -25,5 +25,5 @@ extern MomentaryButton user_btn; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); \ No newline at end of file diff --git a/variants/heltec_e290/target.cpp b/variants/heltec_e290/target.cpp index 92b02092e..b0c9630cf 100644 --- a/variants/heltec_e290/target.cpp +++ b/variants/heltec_e290/target.cpp @@ -44,7 +44,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/heltec_e290/target.h b/variants/heltec_e290/target.h index 607701127..5d423fc0d 100644 --- a/variants/heltec_e290/target.h +++ b/variants/heltec_e290/target.h @@ -25,5 +25,5 @@ extern MomentaryButton user_btn; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); \ No newline at end of file diff --git a/variants/heltec_mesh_solar/target.cpp b/variants/heltec_mesh_solar/target.cpp index ad79f7171..1ea33e1f2 100644 --- a/variants/heltec_mesh_solar/target.cpp +++ b/variants/heltec_mesh_solar/target.cpp @@ -11,7 +11,7 @@ WRAPPER_CLASS radio_driver(radio, board); VolatileRTCClock fallback_clock; AutoDiscoverRTCClock rtc_clock(fallback_clock); -MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); +MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock); SolarSensorManager sensors = SolarSensorManager(nmea); #ifdef DISPLAY_CLASS @@ -34,7 +34,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/heltec_mesh_solar/target.h b/variants/heltec_mesh_solar/target.h index e301a2735..f1921abfa 100644 --- a/variants/heltec_mesh_solar/target.h +++ b/variants/heltec_mesh_solar/target.h @@ -42,5 +42,5 @@ extern SolarSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/heltec_t114/target.cpp b/variants/heltec_t114/target.cpp index c3341103a..160d00b6a 100644 --- a/variants/heltec_t114/target.cpp +++ b/variants/heltec_t114/target.cpp @@ -36,7 +36,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/heltec_t114/target.h b/variants/heltec_t114/target.h index 6306cd699..187675e97 100644 --- a/variants/heltec_t114/target.h +++ b/variants/heltec_t114/target.h @@ -50,5 +50,5 @@ extern T114SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/heltec_t190/target.cpp b/variants/heltec_t190/target.cpp index b93575943..d22f8b8cf 100644 --- a/variants/heltec_t190/target.cpp +++ b/variants/heltec_t190/target.cpp @@ -44,7 +44,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/heltec_t190/target.h b/variants/heltec_t190/target.h index 8a5fc716f..83e035707 100644 --- a/variants/heltec_t190/target.h +++ b/variants/heltec_t190/target.h @@ -25,5 +25,5 @@ extern MomentaryButton user_btn; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); \ No newline at end of file diff --git a/variants/heltec_tracker/platformio.ini b/variants/heltec_tracker/platformio.ini index 797eafdca..21e5c0c50 100644 --- a/variants/heltec_tracker/platformio.ini +++ b/variants/heltec_tracker/platformio.ini @@ -32,6 +32,8 @@ build_flags = -D PIN_TFT_LEDA_CTL=21 ; LEDK (switches on/off via mosfet to create the ground) -D PIN_GPS_RX=33 -D PIN_GPS_TX=34 + -D GPS_BAUD_RATE=115200 + -D ENV_INCLUDE_GPS=1 -D SX126X_DIO2_AS_RF_SWITCH=true -D SX126X_DIO3_TCXO_VOLTAGE=1.8 -D SX126X_CURRENT_LIMIT=140 diff --git a/variants/heltec_tracker/target.cpp b/variants/heltec_tracker/target.cpp index 5ba9a8fb4..fc14dee41 100644 --- a/variants/heltec_tracker/target.cpp +++ b/variants/heltec_tracker/target.cpp @@ -16,7 +16,8 @@ WRAPPER_CLASS radio_driver(radio, board); ESP32RTCClock fallback_clock; AutoDiscoverRTCClock rtc_clock(fallback_clock); -MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); +// v1 has no dedicated GPS reset/enable pins - power is shared via VEXT with display +MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock, -1, -1, &board.periph_power); HWTSensorManager sensors = HWTSensorManager(nmea); #ifdef DISPLAY_CLASS @@ -47,7 +48,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } @@ -58,18 +59,16 @@ mesh::LocalIdentity radio_new_identity() { void HWTSensorManager::start_gps() { if (!gps_active) { - board.periph_power.claim(); - + _location->begin(); // Claims periph_power via RefCountedDigitalPin gps_active = true; - Serial1.println("$CFGSYS,h35155*68"); + Serial1.println("$CFGSYS,h35155*68"); // Configure GPS for all constellations } } void HWTSensorManager::stop_gps() { if (gps_active) { gps_active = false; - - board.periph_power.release(); + _location->stop(); // Releases periph_power via RefCountedDigitalPin } } diff --git a/variants/heltec_tracker/target.h b/variants/heltec_tracker/target.h index 23fab16e1..29099f46a 100644 --- a/variants/heltec_tracker/target.h +++ b/variants/heltec_tracker/target.h @@ -28,6 +28,7 @@ class HWTSensorManager : public SensorManager { const char* getSettingName(int i) const override; const char* getSettingValue(int i) const override; bool setSettingValue(const char* name, const char* value) override; + LocationProvider* getLocationProvider() override { return _location; } }; extern HeltecV3Board board; @@ -43,5 +44,5 @@ extern HWTSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/heltec_tracker_v2/HeltecTrackerV2Board.cpp b/variants/heltec_tracker_v2/HeltecTrackerV2Board.cpp index 4975d5cde..159e87625 100644 --- a/variants/heltec_tracker_v2/HeltecTrackerV2Board.cpp +++ b/variants/heltec_tracker_v2/HeltecTrackerV2Board.cpp @@ -6,17 +6,7 @@ void HeltecTrackerV2Board::begin() { pinMode(PIN_ADC_CTRL, OUTPUT); digitalWrite(PIN_ADC_CTRL, LOW); // Initially inactive - pinMode(P_LORA_PA_POWER, OUTPUT); - digitalWrite(P_LORA_PA_POWER,HIGH); - - rtc_gpio_hold_dis((gpio_num_t)P_LORA_PA_EN); - pinMode(P_LORA_PA_EN, OUTPUT); - digitalWrite(P_LORA_PA_EN,HIGH); - pinMode(P_LORA_PA_TX_EN, OUTPUT); - digitalWrite(P_LORA_PA_TX_EN,LOW); - - periph_power.begin(); - + // Check if waking from deep sleep esp_reset_reason_t reason = esp_reset_reason(); if (reason == ESP_RST_DEEPSLEEP) { long wakeup_source = esp_sleep_get_ext1_wakeup_status(); @@ -24,19 +14,44 @@ void HeltecTrackerV2Board::begin() { startup_reason = BD_STARTUP_RX_PACKET; } + // Release RTC holds - pins retain their state, no need to reconfigure rtc_gpio_hold_dis((gpio_num_t)P_LORA_NSS); + rtc_gpio_hold_dis((gpio_num_t)P_LORA_PA_POWER); + rtc_gpio_hold_dis((gpio_num_t)P_LORA_PA_EN); rtc_gpio_deinit((gpio_num_t)P_LORA_DIO_1); + } else { + // Cold boot: Configure GC1109 FEM pins + // Control logic (from GC1109 datasheet): + // Receive LNA: CSD=1, CTX=0, CPS=X (17dB gain, 2dB NF) + // Transmit PA: CSD=1, CTX=1, CPS=1 (full PA enabled) + // Pin mapping: CTX->DIO2 (auto), CSD->GPIO4, CPS->GPIO46, VFEM->GPIO7 + + // VFEM_Ctrl (GPIO7): Power enable for GC1109 LDO + pinMode(P_LORA_PA_POWER, OUTPUT); + digitalWrite(P_LORA_PA_POWER, HIGH); + + // CSD (GPIO4): Chip enable - must be HIGH for GC1109 to work + pinMode(P_LORA_PA_EN, OUTPUT); + digitalWrite(P_LORA_PA_EN, HIGH); } + + periph_power.begin(); + + // Note: GPIO46 (CPS) is a strapping pin - do NOT configure it here. + // TX handlers are fully responsible for GPIO46 (see onBeforeTransmit/onAfterTransmit) } void HeltecTrackerV2Board::onBeforeTransmit(void) { - digitalWrite(P_LORA_TX_LED, HIGH); // turn TX LED on - digitalWrite(P_LORA_PA_TX_EN,HIGH); + // GPIO46 is a strapping pin - only drive it when actively transmitting + pinMode(P_LORA_PA_TX_EN, OUTPUT); + digitalWrite(P_LORA_PA_TX_EN, HIGH); // CPS=1: Enable full PA mode + digitalWrite(P_LORA_TX_LED, HIGH); } void HeltecTrackerV2Board::onAfterTransmit(void) { - digitalWrite(P_LORA_TX_LED, LOW); // turn TX LED off - digitalWrite(P_LORA_PA_TX_EN,LOW); + digitalWrite(P_LORA_PA_TX_EN, LOW); + pinMode(P_LORA_PA_TX_EN, INPUT); // Release strapping pin + digitalWrite(P_LORA_TX_LED, LOW); } void HeltecTrackerV2Board::enterDeepSleep(uint32_t secs, int pin_wake_btn) { @@ -48,7 +63,11 @@ void HeltecTrackerV2Board::begin() { rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS); - rtc_gpio_hold_en((gpio_num_t)P_LORA_PA_EN); //It also needs to be enabled in receive mode + // Hold GC1109 FEM pins during sleep for RX wake capability + // State: CSD=1, CTX=0 (DIO2), CPS=X -> Receive LNA mode + rtc_gpio_hold_en((gpio_num_t)P_LORA_PA_POWER); // VFEM_Ctrl - keep LDO powered + rtc_gpio_hold_en((gpio_num_t)P_LORA_PA_EN); // CSD=1 - chip enabled + // Note: GPIO46 (CPS) is NOT an RTC GPIO, cannot hold - but CPS is don't care for RX if (pin_wake_btn < 0) { esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet diff --git a/variants/heltec_tracker_v2/platformio.ini b/variants/heltec_tracker_v2/platformio.ini index 36de671e2..f23899a71 100644 --- a/variants/heltec_tracker_v2/platformio.ini +++ b/variants/heltec_tracker_v2/platformio.ini @@ -17,15 +17,17 @@ build_flags = -D P_LORA_SCLK=9 -D P_LORA_MISO=11 -D P_LORA_MOSI=10 - -D P_LORA_PA_POWER=7 ;power en - -D P_LORA_PA_EN=4 - -D P_LORA_PA_TX_EN=46 ;enable tx - -D LORA_TX_POWER=10 ;If it is configured as 10 here, the final output will be 22 dbm. - -D MAX_LORA_TX_POWER=22 ;Max SX1262 output + -D P_LORA_PA_POWER=7 ; VFEM_Ctrl - GC1109 LDO power enable + -D P_LORA_PA_EN=4 ; CSD - GC1109 chip enable (HIGH=on) + -D P_LORA_PA_TX_EN=46 ; CPS - GC1109 PA mode (HIGH=full PA, LOW=bypass) + -D LORA_TX_POWER=10 ; 10dBm + 11dB gain = ~21dBm output (see gain curve above) + -D MAX_LORA_TX_POWER=22 ; Max SX1262 output -> ~28dBm at antenna -D SX126X_DIO2_AS_RF_SWITCH=true -D SX126X_DIO3_TCXO_VOLTAGE=1.8 -D SX126X_CURRENT_LIMIT=140 -D SX126X_RX_BOOSTED_GAIN=1 + ; GC1109 FEM: TX/RX switching is handled by DIO2 -> CTX pin (via SX126X_DIO2_AS_RF_SWITCH) + ; GPIO46 is CPS (PA mode), not TX control - do not use for RF switching -D PIN_BOARD_SDA=5 -D PIN_BOARD_SCL=6 -D PIN_USER_BTN=0 diff --git a/variants/heltec_tracker_v2/target.cpp b/variants/heltec_tracker_v2/target.cpp index da397fb74..0b349231c 100644 --- a/variants/heltec_tracker_v2/target.cpp +++ b/variants/heltec_tracker_v2/target.cpp @@ -17,7 +17,7 @@ AutoDiscoverRTCClock rtc_clock(fallback_clock); #if ENV_INCLUDE_GPS #include - MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, NULL, GPS_RESET, GPS_EN, &board.periph_power); + MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock, GPS_RESET, GPS_EN, &board.periph_power); EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); #else EnvironmentSensorManager sensors; @@ -50,7 +50,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/heltec_tracker_v2/target.h b/variants/heltec_tracker_v2/target.h index 190404ef9..5b799e780 100644 --- a/variants/heltec_tracker_v2/target.h +++ b/variants/heltec_tracker_v2/target.h @@ -26,5 +26,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/heltec_v2/target.cpp b/variants/heltec_v2/target.cpp index df71d3f4b..c5a047528 100644 --- a/variants/heltec_v2/target.cpp +++ b/variants/heltec_v2/target.cpp @@ -43,7 +43,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/heltec_v2/target.h b/variants/heltec_v2/target.h index 48d750be4..788dac723 100644 --- a/variants/heltec_v2/target.h +++ b/variants/heltec_v2/target.h @@ -25,5 +25,5 @@ extern SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/heltec_v3/target.cpp b/variants/heltec_v3/target.cpp index 78b881972..460c3c9b7 100644 --- a/variants/heltec_v3/target.cpp +++ b/variants/heltec_v3/target.cpp @@ -17,7 +17,7 @@ AutoDiscoverRTCClock rtc_clock(fallback_clock); #if ENV_INCLUDE_GPS #include - MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); + MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock); EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); #else EnvironmentSensorManager sensors; @@ -50,7 +50,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/heltec_v3/target.h b/variants/heltec_v3/target.h index 739aecfe0..21a209f99 100644 --- a/variants/heltec_v3/target.h +++ b/variants/heltec_v3/target.h @@ -26,5 +26,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/heltec_v4/HeltecV4Board.cpp b/variants/heltec_v4/HeltecV4Board.cpp index f143db36f..18caeca15 100644 --- a/variants/heltec_v4/HeltecV4Board.cpp +++ b/variants/heltec_v4/HeltecV4Board.cpp @@ -3,22 +3,10 @@ void HeltecV4Board::begin() { ESP32Board::begin(); - pinMode(PIN_ADC_CTRL, OUTPUT); digitalWrite(PIN_ADC_CTRL, LOW); // Initially inactive - pinMode(P_LORA_PA_POWER, OUTPUT); - digitalWrite(P_LORA_PA_POWER,HIGH); - - rtc_gpio_hold_dis((gpio_num_t)P_LORA_PA_EN); - pinMode(P_LORA_PA_EN, OUTPUT); - digitalWrite(P_LORA_PA_EN,HIGH); - pinMode(P_LORA_PA_TX_EN, OUTPUT); - digitalWrite(P_LORA_PA_TX_EN,LOW); - - - periph_power.begin(); - + // Check if waking from deep sleep esp_reset_reason_t reason = esp_reset_reason(); if (reason == ESP_RST_DEEPSLEEP) { long wakeup_source = esp_sleep_get_ext1_wakeup_status(); @@ -26,19 +14,44 @@ void HeltecV4Board::begin() { startup_reason = BD_STARTUP_RX_PACKET; } + // Release RTC holds - pins retain their state, no need to reconfigure rtc_gpio_hold_dis((gpio_num_t)P_LORA_NSS); + rtc_gpio_hold_dis((gpio_num_t)P_LORA_PA_POWER); + rtc_gpio_hold_dis((gpio_num_t)P_LORA_PA_EN); rtc_gpio_deinit((gpio_num_t)P_LORA_DIO_1); + } else { + // Cold boot: Configure GC1109 FEM pins + // Control logic (from GC1109 datasheet): + // Receive LNA: CSD=1, CTX=0, CPS=X (17dB gain, 2dB NF) + // Transmit PA: CSD=1, CTX=1, CPS=1 (full PA enabled) + // Pin mapping: CTX->DIO2 (auto), CSD->GPIO2, CPS->GPIO46, VFEM->GPIO7 + + // VFEM_Ctrl (GPIO7): Power enable for GC1109 LDO + pinMode(P_LORA_PA_POWER, OUTPUT); + digitalWrite(P_LORA_PA_POWER, HIGH); + + // CSD (GPIO2): Chip enable - must be HIGH for GC1109 to work + pinMode(P_LORA_PA_EN, OUTPUT); + digitalWrite(P_LORA_PA_EN, HIGH); } + + periph_power.begin(); + + // Note: GPIO46 (CPS) is a strapping pin - do NOT configure it here. + // TX handlers are fully responsible for GPIO46 (see onBeforeTransmit/onAfterTransmit) } void HeltecV4Board::onBeforeTransmit(void) { - digitalWrite(P_LORA_TX_LED, HIGH); // turn TX LED on - digitalWrite(P_LORA_PA_TX_EN,HIGH); + // GPIO46 is a strapping pin - only drive it when actively transmitting + pinMode(P_LORA_PA_TX_EN, OUTPUT); + digitalWrite(P_LORA_PA_TX_EN, HIGH); // CPS=1: Enable full PA mode + digitalWrite(P_LORA_TX_LED, HIGH); } void HeltecV4Board::onAfterTransmit(void) { - digitalWrite(P_LORA_TX_LED, LOW); // turn TX LED off - digitalWrite(P_LORA_PA_TX_EN,LOW); + digitalWrite(P_LORA_PA_TX_EN, LOW); + pinMode(P_LORA_PA_TX_EN, INPUT); // Release strapping pin + digitalWrite(P_LORA_TX_LED, LOW); } void HeltecV4Board::enterDeepSleep(uint32_t secs, int pin_wake_btn) { @@ -50,7 +63,11 @@ void HeltecV4Board::begin() { rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS); - rtc_gpio_hold_en((gpio_num_t)P_LORA_PA_EN); //It also needs to be enabled in receive mode + // Hold GC1109 FEM pins during sleep for RX wake capability + // State: CSD=1, CTX=0 (DIO2), CPS=X -> Receive LNA mode + rtc_gpio_hold_en((gpio_num_t)P_LORA_PA_POWER); // VFEM_Ctrl - keep LDO powered + rtc_gpio_hold_en((gpio_num_t)P_LORA_PA_EN); // CSD=1 - chip enabled + // Note: GPIO46 (CPS) is NOT an RTC GPIO, cannot hold - but CPS is don't care for RX if (pin_wake_btn < 0) { esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet diff --git a/variants/heltec_v4/platformio.ini b/variants/heltec_v4/platformio.ini index ecfd7889b..e86480fec 100644 --- a/variants/heltec_v4/platformio.ini +++ b/variants/heltec_v4/platformio.ini @@ -17,9 +17,9 @@ build_flags = -D P_LORA_SCLK=9 -D P_LORA_MISO=11 -D P_LORA_MOSI=10 - -D P_LORA_PA_POWER=7 ;power en - -D P_LORA_PA_EN=2 - -D P_LORA_PA_TX_EN=46 ;enable tx + -D P_LORA_PA_POWER=7 ; VFEM_Ctrl - GC1109 LDO power enable + -D P_LORA_PA_EN=2 ; CSD - GC1109 chip enable (HIGH=on) + -D P_LORA_PA_TX_EN=46 ; CPS - GC1109 PA mode (HIGH=full PA, LOW=bypass) -D PIN_BOARD_SDA=17 -D PIN_BOARD_SCL=18 -D PIN_USER_BTN=0 @@ -31,6 +31,8 @@ build_flags = -D SX126X_DIO3_TCXO_VOLTAGE=1.8 -D SX126X_CURRENT_LIMIT=140 -D SX126X_RX_BOOSTED_GAIN=1 + ; GC1109 FEM: TX/RX switching is handled by DIO2 -> CTX pin (via SX126X_DIO2_AS_RF_SWITCH) + ; GPIO46 is CPS (power save), not TX control - do not use for RF switching -D PIN_GPS_RX=38 -D PIN_GPS_TX=39 -D PIN_GPS_RESET=42 diff --git a/variants/heltec_v4/target.cpp b/variants/heltec_v4/target.cpp index 015c3a8e7..d8a3efe54 100644 --- a/variants/heltec_v4/target.cpp +++ b/variants/heltec_v4/target.cpp @@ -17,7 +17,7 @@ AutoDiscoverRTCClock rtc_clock(fallback_clock); #if ENV_INCLUDE_GPS #include - MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); + MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock); EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); #else EnvironmentSensorManager sensors; @@ -50,7 +50,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/heltec_v4/target.h b/variants/heltec_v4/target.h index a153b2af3..75f94c153 100644 --- a/variants/heltec_v4/target.h +++ b/variants/heltec_v4/target.h @@ -26,5 +26,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/heltec_wireless_paper/target.cpp b/variants/heltec_wireless_paper/target.cpp index dd2d51c0f..06f548fc0 100644 --- a/variants/heltec_wireless_paper/target.cpp +++ b/variants/heltec_wireless_paper/target.cpp @@ -43,7 +43,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/heltec_wireless_paper/target.h b/variants/heltec_wireless_paper/target.h index b89c486fb..65739e773 100644 --- a/variants/heltec_wireless_paper/target.h +++ b/variants/heltec_wireless_paper/target.h @@ -25,5 +25,5 @@ extern MomentaryButton user_btn; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); \ No newline at end of file diff --git a/variants/ikoka_handheld_nrf/target.cpp b/variants/ikoka_handheld_nrf/target.cpp index efa6669f1..48244e172 100644 --- a/variants/ikoka_handheld_nrf/target.cpp +++ b/variants/ikoka_handheld_nrf/target.cpp @@ -36,7 +36,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/ikoka_handheld_nrf/target.h b/variants/ikoka_handheld_nrf/target.h index a28ca81a5..d4af956e1 100644 --- a/variants/ikoka_handheld_nrf/target.h +++ b/variants/ikoka_handheld_nrf/target.h @@ -25,5 +25,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/ikoka_nano_nrf/target.cpp b/variants/ikoka_nano_nrf/target.cpp index aed591823..be20cfb43 100644 --- a/variants/ikoka_nano_nrf/target.cpp +++ b/variants/ikoka_nano_nrf/target.cpp @@ -34,7 +34,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/ikoka_nano_nrf/target.h b/variants/ikoka_nano_nrf/target.h index 9b4e908ec..7949ab638 100644 --- a/variants/ikoka_nano_nrf/target.h +++ b/variants/ikoka_nano_nrf/target.h @@ -24,5 +24,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/ikoka_stick_nrf/target.cpp b/variants/ikoka_stick_nrf/target.cpp index bd803399b..4f6befc60 100644 --- a/variants/ikoka_stick_nrf/target.cpp +++ b/variants/ikoka_stick_nrf/target.cpp @@ -34,7 +34,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/ikoka_stick_nrf/target.h b/variants/ikoka_stick_nrf/target.h index c276e89f2..fab825926 100644 --- a/variants/ikoka_stick_nrf/target.h +++ b/variants/ikoka_stick_nrf/target.h @@ -24,5 +24,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/keepteen_lt1/target.cpp b/variants/keepteen_lt1/target.cpp index e72abf08b..85f11232a 100644 --- a/variants/keepteen_lt1/target.cpp +++ b/variants/keepteen_lt1/target.cpp @@ -12,7 +12,7 @@ VolatileRTCClock fallback_clock; AutoDiscoverRTCClock rtc_clock(fallback_clock); #if ENV_INCLUDE_GPS #include - MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); + MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock); EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); #else EnvironmentSensorManager sensors; @@ -40,7 +40,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/keepteen_lt1/target.h b/variants/keepteen_lt1/target.h index 0f1aa756c..f2468d34e 100644 --- a/variants/keepteen_lt1/target.h +++ b/variants/keepteen_lt1/target.h @@ -26,5 +26,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/lilygo_t3s3/target.cpp b/variants/lilygo_t3s3/target.cpp index 1c7b3b094..284811881 100644 --- a/variants/lilygo_t3s3/target.cpp +++ b/variants/lilygo_t3s3/target.cpp @@ -38,7 +38,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/lilygo_t3s3/target.h b/variants/lilygo_t3s3/target.h index f184c7575..892c3de3f 100644 --- a/variants/lilygo_t3s3/target.h +++ b/variants/lilygo_t3s3/target.h @@ -25,5 +25,5 @@ extern SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/lilygo_t3s3_sx1276/platformio.ini b/variants/lilygo_t3s3_sx1276/platformio.ini index f544be113..5a7ece2cb 100644 --- a/variants/lilygo_t3s3_sx1276/platformio.ini +++ b/variants/lilygo_t3s3_sx1276/platformio.ini @@ -138,8 +138,6 @@ build_flags = -D DISPLAY_CLASS=SSD1306Display -D MAX_CONTACTS=350 -D MAX_GROUP_CHANNELS=40 - -D MESH_PACKET_LOGGING=1 - -D MESH_DEBUG=1 build_src_filter = ${LilyGo_T3S3_sx1276.build_src_filter} + + diff --git a/variants/lilygo_t3s3_sx1276/target.cpp b/variants/lilygo_t3s3_sx1276/target.cpp index 042ff2062..e7fe07a0c 100644 --- a/variants/lilygo_t3s3_sx1276/target.cpp +++ b/variants/lilygo_t3s3_sx1276/target.cpp @@ -44,7 +44,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/lilygo_t3s3_sx1276/target.h b/variants/lilygo_t3s3_sx1276/target.h index 98a0fe359..2df4b3edb 100644 --- a/variants/lilygo_t3s3_sx1276/target.h +++ b/variants/lilygo_t3s3_sx1276/target.h @@ -25,5 +25,5 @@ extern SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); \ No newline at end of file diff --git a/variants/lilygo_tbeam_SX1262/target.cpp b/variants/lilygo_tbeam_SX1262/target.cpp index a8caecb36..a851fd25c 100644 --- a/variants/lilygo_tbeam_SX1262/target.cpp +++ b/variants/lilygo_tbeam_SX1262/target.cpp @@ -17,7 +17,7 @@ AutoDiscoverRTCClock rtc_clock(fallback_clock); #if ENV_INCLUDE_GPS #include - MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); + MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock); EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); #else EnvironmentSensorManager sensors; @@ -45,7 +45,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/lilygo_tbeam_SX1262/target.h b/variants/lilygo_tbeam_SX1262/target.h index 5f33abb87..e5b3e445e 100644 --- a/variants/lilygo_tbeam_SX1262/target.h +++ b/variants/lilygo_tbeam_SX1262/target.h @@ -25,5 +25,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/lilygo_tbeam_SX1276/target.cpp b/variants/lilygo_tbeam_SX1276/target.cpp index 0a7517a21..5865faa39 100644 --- a/variants/lilygo_tbeam_SX1276/target.cpp +++ b/variants/lilygo_tbeam_SX1276/target.cpp @@ -17,7 +17,7 @@ AutoDiscoverRTCClock rtc_clock(fallback_clock); #if ENV_INCLUDE_GPS #include - MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); + MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock); EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); #else EnvironmentSensorManager sensors; @@ -50,7 +50,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/lilygo_tbeam_SX1276/target.h b/variants/lilygo_tbeam_SX1276/target.h index b382b652d..cd4480dce 100644 --- a/variants/lilygo_tbeam_SX1276/target.h +++ b/variants/lilygo_tbeam_SX1276/target.h @@ -25,5 +25,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/lilygo_tbeam_supreme_SX1262/target.cpp b/variants/lilygo_tbeam_supreme_SX1262/target.cpp index 8ad306f1b..23983bd36 100644 --- a/variants/lilygo_tbeam_supreme_SX1262/target.cpp +++ b/variants/lilygo_tbeam_supreme_SX1262/target.cpp @@ -19,7 +19,7 @@ AutoDiscoverRTCClock rtc_clock(fallback_clock); #if ENV_INCLUDE_GPS #include - MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); + MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock); EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); #else EnvironmentSensorManager sensors; @@ -42,7 +42,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/lilygo_tbeam_supreme_SX1262/target.h b/variants/lilygo_tbeam_supreme_SX1262/target.h index c6ffa0a66..200a56905 100644 --- a/variants/lilygo_tbeam_supreme_SX1262/target.h +++ b/variants/lilygo_tbeam_supreme_SX1262/target.h @@ -23,5 +23,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); \ No newline at end of file diff --git a/variants/lilygo_tdeck/target.cpp b/variants/lilygo_tdeck/target.cpp index 50ffa7359..731ecfd86 100644 --- a/variants/lilygo_tdeck/target.cpp +++ b/variants/lilygo_tdeck/target.cpp @@ -45,7 +45,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/lilygo_tdeck/target.h b/variants/lilygo_tdeck/target.h index 4640925f1..c31d0d0ff 100644 --- a/variants/lilygo_tdeck/target.h +++ b/variants/lilygo_tdeck/target.h @@ -27,5 +27,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); \ No newline at end of file diff --git a/variants/lilygo_techo/target.cpp b/variants/lilygo_techo/target.cpp index 2ebc0641f..12d222ff7 100644 --- a/variants/lilygo_techo/target.cpp +++ b/variants/lilygo_techo/target.cpp @@ -42,7 +42,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/lilygo_techo/target.h b/variants/lilygo_techo/target.h index 2b6ed45fc..d978d5224 100644 --- a/variants/lilygo_techo/target.h +++ b/variants/lilygo_techo/target.h @@ -27,5 +27,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/lilygo_techo_lite/target.cpp b/variants/lilygo_techo_lite/target.cpp index 6979e3478..40a94526e 100644 --- a/variants/lilygo_techo_lite/target.cpp +++ b/variants/lilygo_techo_lite/target.cpp @@ -41,7 +41,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/lilygo_techo_lite/target.h b/variants/lilygo_techo_lite/target.h index 2b6ed45fc..d978d5224 100644 --- a/variants/lilygo_techo_lite/target.h +++ b/variants/lilygo_techo_lite/target.h @@ -27,5 +27,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/lilygo_tlora_c6/target.cpp b/variants/lilygo_tlora_c6/target.cpp index e12c58b5a..3566fbe48 100644 --- a/variants/lilygo_tlora_c6/target.cpp +++ b/variants/lilygo_tlora_c6/target.cpp @@ -38,7 +38,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/lilygo_tlora_c6/target.h b/variants/lilygo_tlora_c6/target.h index c26d59586..1cb52fbc7 100644 --- a/variants/lilygo_tlora_c6/target.h +++ b/variants/lilygo_tlora_c6/target.h @@ -16,5 +16,5 @@ extern SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/lilygo_tlora_v2_1/target.cpp b/variants/lilygo_tlora_v2_1/target.cpp index 65a78c194..ead62e797 100644 --- a/variants/lilygo_tlora_v2_1/target.cpp +++ b/variants/lilygo_tlora_v2_1/target.cpp @@ -39,7 +39,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/lilygo_tlora_v2_1/target.h b/variants/lilygo_tlora_v2_1/target.h index 326a0dee7..cb7d861dd 100644 --- a/variants/lilygo_tlora_v2_1/target.h +++ b/variants/lilygo_tlora_v2_1/target.h @@ -25,5 +25,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/mesh_pocket/target.cpp b/variants/mesh_pocket/target.cpp index a7f6c7fb1..6fabb3174 100644 --- a/variants/mesh_pocket/target.cpp +++ b/variants/mesh_pocket/target.cpp @@ -34,7 +34,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/mesh_pocket/target.h b/variants/mesh_pocket/target.h index 2aa956693..6ab5d9c2f 100644 --- a/variants/mesh_pocket/target.h +++ b/variants/mesh_pocket/target.h @@ -26,7 +26,7 @@ extern AutoDiscoverRTCClock rtc_clock; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); extern SensorManager sensors; diff --git a/variants/meshadventurer/target.cpp b/variants/meshadventurer/target.cpp index 0e3b03f2b..9ef58d0e3 100644 --- a/variants/meshadventurer/target.cpp +++ b/variants/meshadventurer/target.cpp @@ -11,7 +11,7 @@ WRAPPER_CLASS radio_driver(radio, board); ESP32RTCClock fallback_clock; AutoDiscoverRTCClock rtc_clock(fallback_clock); -MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); +MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock); MASensorManager sensors = MASensorManager(nmea); #ifdef DISPLAY_CLASS @@ -41,7 +41,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/meshadventurer/target.h b/variants/meshadventurer/target.h index 31bc40663..9d1ffca8d 100644 --- a/variants/meshadventurer/target.h +++ b/variants/meshadventurer/target.h @@ -45,5 +45,5 @@ extern MASensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/minewsemi_me25ls01/MinewsemiME25LS01Board.h b/variants/minewsemi_me25ls01/MinewsemiME25LS01Board.h index 805f9dfa8..64210bd75 100644 --- a/variants/minewsemi_me25ls01/MinewsemiME25LS01Board.h +++ b/variants/minewsemi_me25ls01/MinewsemiME25LS01Board.h @@ -63,7 +63,8 @@ class MinewsemiME25LS01Board : public NRF52BoardOTA { digitalWrite(LED_PIN, LOW); #endif #ifdef BUTTON_PIN - nrf_gpio_cfg_sense_input(digitalPinToInterrupt(BUTTON_PIN), NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_HIGH); + // Wake on button press (active-LOW: pressed = LOW) + nrf_gpio_cfg_sense_input(digitalPinToInterrupt(BUTTON_PIN), NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW); #endif sd_power_system_off(); } diff --git a/variants/minewsemi_me25ls01/platformio.ini b/variants/minewsemi_me25ls01/platformio.ini index fd9c3819f..dacd8d34e 100644 --- a/variants/minewsemi_me25ls01/platformio.ini +++ b/variants/minewsemi_me25ls01/platformio.ini @@ -21,7 +21,6 @@ build_flags = ${nrf52840_me25ls01.build_flags} -I variants/minewsemi_me25ls01 -D me25ls01 -D PIN_USER_BTN=27 - -D USER_BTN_PRESSED=HIGH -D PIN_STATUS_LED=39 -D P_LORA_TX_LED=22 -D RADIO_CLASS=CustomLR1110 diff --git a/variants/minewsemi_me25ls01/target.cpp b/variants/minewsemi_me25ls01/target.cpp index 13306762a..fcec19419 100644 --- a/variants/minewsemi_me25ls01/target.cpp +++ b/variants/minewsemi_me25ls01/target.cpp @@ -88,7 +88,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/minewsemi_me25ls01/target.h b/variants/minewsemi_me25ls01/target.h index a5da58234..ea7383e25 100644 --- a/variants/minewsemi_me25ls01/target.h +++ b/variants/minewsemi_me25ls01/target.h @@ -25,5 +25,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/nano_g2_ultra/target.cpp b/variants/nano_g2_ultra/target.cpp index 81e7744fc..bd4e9b480 100644 --- a/variants/nano_g2_ultra/target.cpp +++ b/variants/nano_g2_ultra/target.cpp @@ -12,7 +12,7 @@ WRAPPER_CLASS radio_driver(radio, board); VolatileRTCClock fallback_clock; AutoDiscoverRTCClock rtc_clock(fallback_clock); -MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); +MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock); NanoG2UltraSensorManager sensors = NanoG2UltraSensorManager(nmea); #ifdef DISPLAY_CLASS @@ -36,7 +36,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/nano_g2_ultra/target.h b/variants/nano_g2_ultra/target.h index 3e58b9007..6e3541275 100644 --- a/variants/nano_g2_ultra/target.h +++ b/variants/nano_g2_ultra/target.h @@ -45,5 +45,5 @@ extern MomentaryButton user_btn; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/nibble_screen_connect/target.cpp b/variants/nibble_screen_connect/target.cpp index 1980e0394..6edaaad7a 100644 --- a/variants/nibble_screen_connect/target.cpp +++ b/variants/nibble_screen_connect/target.cpp @@ -38,7 +38,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/nibble_screen_connect/target.h b/variants/nibble_screen_connect/target.h index 66e69901a..f31efb8da 100644 --- a/variants/nibble_screen_connect/target.h +++ b/variants/nibble_screen_connect/target.h @@ -25,6 +25,6 @@ extern SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/promicro/target.cpp b/variants/promicro/target.cpp index b26320e47..e4a4442ab 100644 --- a/variants/promicro/target.cpp +++ b/variants/promicro/target.cpp @@ -12,7 +12,7 @@ VolatileRTCClock fallback_clock; AutoDiscoverRTCClock rtc_clock(fallback_clock); #if ENV_INCLUDE_GPS #include - MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); + MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock); EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); #else EnvironmentSensorManager sensors; @@ -40,7 +40,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/promicro/target.h b/variants/promicro/target.h index 38c4b4e88..d379927ec 100644 --- a/variants/promicro/target.h +++ b/variants/promicro/target.h @@ -26,5 +26,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/rak11310/target.cpp b/variants/rak11310/target.cpp index dba5bff2c..67432998a 100644 --- a/variants/rak11310/target.cpp +++ b/variants/rak11310/target.cpp @@ -29,7 +29,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/rak11310/target.h b/variants/rak11310/target.h index fe45c3f2c..7c25cd901 100644 --- a/variants/rak11310/target.h +++ b/variants/rak11310/target.h @@ -16,5 +16,5 @@ extern SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/rak3x72/target.cpp b/variants/rak3x72/target.cpp index 446783aa4..48e7f4228 100644 --- a/variants/rak3x72/target.cpp +++ b/variants/rak3x72/target.cpp @@ -66,7 +66,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/rak3x72/target.h b/variants/rak3x72/target.h index e0c1441e7..3ba1cf421 100644 --- a/variants/rak3x72/target.h +++ b/variants/rak3x72/target.h @@ -52,5 +52,5 @@ extern SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/rak4631/target.cpp b/variants/rak4631/target.cpp index bc7465fda..ac1ac7cac 100644 --- a/variants/rak4631/target.cpp +++ b/variants/rak4631/target.cpp @@ -26,7 +26,7 @@ AutoDiscoverRTCClock rtc_clock(fallback_clock); #if ENV_INCLUDE_GPS #include - MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); + MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock); EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); #else EnvironmentSensorManager sensors; @@ -48,7 +48,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/rak4631/target.h b/variants/rak4631/target.h index aa6be664b..eeb3e0947 100644 --- a/variants/rak4631/target.h +++ b/variants/rak4631/target.h @@ -26,5 +26,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/rak_wismesh_tag/target.cpp b/variants/rak_wismesh_tag/target.cpp index 2bd30864b..d42c0d58e 100644 --- a/variants/rak_wismesh_tag/target.cpp +++ b/variants/rak_wismesh_tag/target.cpp @@ -22,7 +22,7 @@ AutoDiscoverRTCClock rtc_clock(fallback_clock); #if ENV_INCLUDE_GPS #include - MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); + MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock); EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); #else EnvironmentSensorManager sensors; @@ -44,7 +44,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/rak_wismesh_tag/target.h b/variants/rak_wismesh_tag/target.h index 150d08319..a51b30924 100644 --- a/variants/rak_wismesh_tag/target.h +++ b/variants/rak_wismesh_tag/target.h @@ -23,5 +23,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/rpi_picow/target.cpp b/variants/rpi_picow/target.cpp index abb1485df..e3d4bf090 100644 --- a/variants/rpi_picow/target.cpp +++ b/variants/rpi_picow/target.cpp @@ -29,7 +29,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/rpi_picow/target.h b/variants/rpi_picow/target.h index 17dbb35fd..706578a40 100644 --- a/variants/rpi_picow/target.h +++ b/variants/rpi_picow/target.h @@ -16,5 +16,5 @@ extern SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/sensecap_indicator-espnow/target.cpp b/variants/sensecap_indicator-espnow/target.cpp index efdaac610..6674c180d 100644 --- a/variants/sensecap_indicator-espnow/target.cpp +++ b/variants/sensecap_indicator-espnow/target.cpp @@ -37,7 +37,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { // no-op } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio_driver.setTxPower(dbm); } diff --git a/variants/sensecap_indicator-espnow/target.h b/variants/sensecap_indicator-espnow/target.h index bb78e9233..a56dec7bd 100644 --- a/variants/sensecap_indicator-espnow/target.h +++ b/variants/sensecap_indicator-espnow/target.h @@ -25,5 +25,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/sensecap_solar/target.cpp b/variants/sensecap_solar/target.cpp index 6bd7d31a7..2c2ff0dc7 100644 --- a/variants/sensecap_solar/target.cpp +++ b/variants/sensecap_solar/target.cpp @@ -29,7 +29,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/sensecap_solar/target.h b/variants/sensecap_solar/target.h index 90d60ba52..f4a988013 100644 --- a/variants/sensecap_solar/target.h +++ b/variants/sensecap_solar/target.h @@ -17,5 +17,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/station_g2/target.cpp b/variants/station_g2/target.cpp index 3f0c1404d..026b25de7 100644 --- a/variants/station_g2/target.cpp +++ b/variants/station_g2/target.cpp @@ -51,7 +51,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/station_g2/target.h b/variants/station_g2/target.h index 2bf7016d4..01428d586 100644 --- a/variants/station_g2/target.h +++ b/variants/station_g2/target.h @@ -26,5 +26,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/t1000-e/T1000eBoard.h b/variants/t1000-e/T1000eBoard.h index f26bdf02e..7bd9b293d 100644 --- a/variants/t1000-e/T1000eBoard.h +++ b/variants/t1000-e/T1000eBoard.h @@ -77,14 +77,15 @@ class T1000eBoard : public NRF52BoardDCDC { digitalWrite(LED_PIN, HIGH); #endif #ifdef BUTTON_PIN - while(digitalRead(BUTTON_PIN)); + while(digitalRead(BUTTON_PIN) == LOW); // wait for button release #endif #ifdef LED_PIN digitalWrite(LED_PIN, LOW); #endif #ifdef BUTTON_PIN - nrf_gpio_cfg_sense_input(BUTTON_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_HIGH); + // Wake on button press (active-LOW: pressed = LOW) + nrf_gpio_cfg_sense_input(BUTTON_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_LOW); #endif sd_power_system_off(); diff --git a/variants/t1000-e/platformio.ini b/variants/t1000-e/platformio.ini index 555b182fb..7d165876a 100644 --- a/variants/t1000-e/platformio.ini +++ b/variants/t1000-e/platformio.ini @@ -10,7 +10,6 @@ build_flags = ${nrf52_base.build_flags} -I src/helpers/ui -D T1000_E -D PIN_USER_BTN=6 - -D USER_BTN_PRESSED=HIGH -D PIN_STATUS_LED=24 -D RADIO_CLASS=CustomLR1110 -D WRAPPER_CLASS=CustomLR1110Wrapper diff --git a/variants/t1000-e/target.cpp b/variants/t1000-e/target.cpp index 82d958b5d..da8fa48bb 100644 --- a/variants/t1000-e/target.cpp +++ b/variants/t1000-e/target.cpp @@ -85,7 +85,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/t1000-e/target.h b/variants/t1000-e/target.h index 27351b945..d4e3c02c5 100644 --- a/variants/t1000-e/target.h +++ b/variants/t1000-e/target.h @@ -43,5 +43,5 @@ extern T1000SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/tenstar_c3/target.cpp b/variants/tenstar_c3/target.cpp index a29780f09..d4f189b52 100644 --- a/variants/tenstar_c3/target.cpp +++ b/variants/tenstar_c3/target.cpp @@ -38,7 +38,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/tenstar_c3/target.h b/variants/tenstar_c3/target.h index fa29e52bd..e503564b3 100644 --- a/variants/tenstar_c3/target.h +++ b/variants/tenstar_c3/target.h @@ -17,5 +17,5 @@ extern SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/thinknode_m1/target.cpp b/variants/thinknode_m1/target.cpp index 2b04d7c6e..ec2438d40 100644 --- a/variants/thinknode_m1/target.cpp +++ b/variants/thinknode_m1/target.cpp @@ -11,7 +11,7 @@ WRAPPER_CLASS radio_driver(radio, board); VolatileRTCClock fallback_clock; AutoDiscoverRTCClock rtc_clock(fallback_clock); -MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); +MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock); ThinkNodeM1SensorManager sensors = ThinkNodeM1SensorManager(nmea); #ifdef DISPLAY_CLASS @@ -35,7 +35,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/thinknode_m1/target.h b/variants/thinknode_m1/target.h index 1e4e1381f..454bf2bad 100644 --- a/variants/thinknode_m1/target.h +++ b/variants/thinknode_m1/target.h @@ -44,5 +44,5 @@ extern ThinkNodeM1SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/thinknode_m2/target.cpp b/variants/thinknode_m2/target.cpp index cb3c1624d..e7e36d05f 100644 --- a/variants/thinknode_m2/target.cpp +++ b/variants/thinknode_m2/target.cpp @@ -46,7 +46,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/thinknode_m2/target.h b/variants/thinknode_m2/target.h index b05def8aa..77ebbfde8 100644 --- a/variants/thinknode_m2/target.h +++ b/variants/thinknode_m2/target.h @@ -26,7 +26,7 @@ extern SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); \ No newline at end of file diff --git a/variants/thinknode_m3/platformio.ini b/variants/thinknode_m3/platformio.ini index 8ef2ba54a..88fd487aa 100644 --- a/variants/thinknode_m3/platformio.ini +++ b/variants/thinknode_m3/platformio.ini @@ -10,7 +10,6 @@ build_flags = ${nrf52_base.build_flags} -I src/helpers/ui -D THINKNODE_M3 -D PIN_USER_BTN=12 - -D USER_BTN_PRESSED=LOW -D PIN_STATUS_LED=35 -D RADIO_CLASS=CustomLR1110 -D WRAPPER_CLASS=CustomLR1110Wrapper diff --git a/variants/thinknode_m3/target.cpp b/variants/thinknode_m3/target.cpp index c6708e4d1..322bbc7ae 100644 --- a/variants/thinknode_m3/target.cpp +++ b/variants/thinknode_m3/target.cpp @@ -11,7 +11,7 @@ WRAPPER_CLASS radio_driver(radio, board); VolatileRTCClock fallback_clock; AutoDiscoverRTCClock rtc_clock(fallback_clock); #ifdef ENV_INCLUDE_GPS -MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); +MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock); EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); #else EnvironmentSensorManager sensors = EnvironmentSensorManager(); @@ -89,7 +89,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/thinknode_m3/target.h b/variants/thinknode_m3/target.h index f60a85b03..fee7620ea 100644 --- a/variants/thinknode_m3/target.h +++ b/variants/thinknode_m3/target.h @@ -25,5 +25,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/thinknode_m5/target.cpp b/variants/thinknode_m5/target.cpp index 8208d2c43..a7a049ef4 100644 --- a/variants/thinknode_m5/target.cpp +++ b/variants/thinknode_m5/target.cpp @@ -53,7 +53,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/thinknode_m5/target.h b/variants/thinknode_m5/target.h index 2af42095c..a228cc9f5 100644 --- a/variants/thinknode_m5/target.h +++ b/variants/thinknode_m5/target.h @@ -29,7 +29,7 @@ extern PCA9557 expander; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); \ No newline at end of file diff --git a/variants/thinknode_m6/target.cpp b/variants/thinknode_m6/target.cpp index c14dd300f..36ca86180 100644 --- a/variants/thinknode_m6/target.cpp +++ b/variants/thinknode_m6/target.cpp @@ -39,7 +39,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/thinknode_m6/target.h b/variants/thinknode_m6/target.h index 38b1fed1b..fb129988f 100644 --- a/variants/thinknode_m6/target.h +++ b/variants/thinknode_m6/target.h @@ -27,5 +27,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/tiny_relay/target.cpp b/variants/tiny_relay/target.cpp index f738ac179..313dfaa94 100644 --- a/variants/tiny_relay/target.cpp +++ b/variants/tiny_relay/target.cpp @@ -70,7 +70,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/tiny_relay/target.h b/variants/tiny_relay/target.h index 82747cdcc..d15837121 100644 --- a/variants/tiny_relay/target.h +++ b/variants/tiny_relay/target.h @@ -55,5 +55,5 @@ extern SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/waveshare_rp2040_lora/target.cpp b/variants/waveshare_rp2040_lora/target.cpp index 7bc1d0430..a9121b0c3 100644 --- a/variants/waveshare_rp2040_lora/target.cpp +++ b/variants/waveshare_rp2040_lora/target.cpp @@ -39,7 +39,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/waveshare_rp2040_lora/target.h b/variants/waveshare_rp2040_lora/target.h index aed558939..fe1903de1 100644 --- a/variants/waveshare_rp2040_lora/target.h +++ b/variants/waveshare_rp2040_lora/target.h @@ -17,5 +17,5 @@ extern SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/wio-e5-dev/target.cpp b/variants/wio-e5-dev/target.cpp index 42e900e40..3e59b6cee 100644 --- a/variants/wio-e5-dev/target.cpp +++ b/variants/wio-e5-dev/target.cpp @@ -63,7 +63,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/wio-e5-dev/target.h b/variants/wio-e5-dev/target.h index 5fdd0abaf..1d1fc5cb9 100644 --- a/variants/wio-e5-dev/target.h +++ b/variants/wio-e5-dev/target.h @@ -29,5 +29,5 @@ extern SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/wio-e5-mini/platformio.ini b/variants/wio-e5-mini/platformio.ini index 837844437..f589ea032 100644 --- a/variants/wio-e5-mini/platformio.ini +++ b/variants/wio-e5-mini/platformio.ini @@ -9,7 +9,6 @@ build_flags = ${stm32_base.build_flags} -D RX_BOOSTED_GAIN=true -D P_LORA_TX_LED=LED_RED -D PIN_USER_BTN=USER_BTN - -D USER_BTN_PRESSED=LOW -I variants/wio-e5-mini build_src_filter = ${stm32_base.build_src_filter} +<../variants/wio-e5-mini> diff --git a/variants/wio-e5-mini/target.cpp b/variants/wio-e5-mini/target.cpp index 0e2358b82..2e95ad6d1 100644 --- a/variants/wio-e5-mini/target.cpp +++ b/variants/wio-e5-mini/target.cpp @@ -61,7 +61,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/wio-e5-mini/target.h b/variants/wio-e5-mini/target.h index 921c38d34..a4e5fb60c 100644 --- a/variants/wio-e5-mini/target.h +++ b/variants/wio-e5-mini/target.h @@ -60,5 +60,5 @@ extern WIOE5SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/wio-tracker-l1/target.cpp b/variants/wio-tracker-l1/target.cpp index 64866de00..4575a76c8 100644 --- a/variants/wio-tracker-l1/target.cpp +++ b/variants/wio-tracker-l1/target.cpp @@ -44,7 +44,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/wio-tracker-l1/target.h b/variants/wio-tracker-l1/target.h index 97e575d89..e23476473 100644 --- a/variants/wio-tracker-l1/target.h +++ b/variants/wio-tracker-l1/target.h @@ -33,5 +33,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/wio_wm1110/target.cpp b/variants/wio_wm1110/target.cpp index c659d708b..457d5bda2 100644 --- a/variants/wio_wm1110/target.cpp +++ b/variants/wio_wm1110/target.cpp @@ -81,7 +81,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/wio_wm1110/target.h b/variants/wio_wm1110/target.h index 9bd4a22b8..8712a0ef0 100644 --- a/variants/wio_wm1110/target.h +++ b/variants/wio_wm1110/target.h @@ -16,6 +16,6 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/xiao_c3/target.cpp b/variants/xiao_c3/target.cpp index fe3f7196a..09461d10a 100644 --- a/variants/xiao_c3/target.cpp +++ b/variants/xiao_c3/target.cpp @@ -17,7 +17,7 @@ AutoDiscoverRTCClock rtc_clock(fallback_clock); #if ENV_INCLUDE_GPS #include - MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); + MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock); EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); #else EnvironmentSensorManager sensors; @@ -46,7 +46,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/xiao_c3/target.h b/variants/xiao_c3/target.h index a7ef44218..57e3b81ca 100644 --- a/variants/xiao_c3/target.h +++ b/variants/xiao_c3/target.h @@ -16,5 +16,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/xiao_c6/XiaoC6Board.cpp b/variants/xiao_c6/XiaoC6Board.cpp index 555fed629..5710c4ccb 100644 --- a/variants/xiao_c6/XiaoC6Board.cpp +++ b/variants/xiao_c6/XiaoC6Board.cpp @@ -39,7 +39,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/xiao_c6/target.h b/variants/xiao_c6/target.h index 0fbb0bb2e..28b465383 100644 --- a/variants/xiao_c6/target.h +++ b/variants/xiao_c6/target.h @@ -17,5 +17,5 @@ extern SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/xiao_nrf52/XiaoNrf52Board.h b/variants/xiao_nrf52/XiaoNrf52Board.h index 1c46dfeee..fdd7a4fa6 100644 --- a/variants/xiao_nrf52/XiaoNrf52Board.h +++ b/variants/xiao_nrf52/XiaoNrf52Board.h @@ -4,6 +4,12 @@ #include #include +// Default button polarity: Active-LOW (pressed = LOW) +// Override with -D USER_BTN_PRESSED=HIGH in platformio.ini for rare active-high devices. +#ifndef USER_BTN_PRESSED +#define USER_BTN_PRESSED LOW +#endif + #ifdef XIAO_NRF52 class XiaoNrf52Board : public NRF52BoardDCDC, public NRF52BoardOTA { @@ -44,7 +50,7 @@ class XiaoNrf52Board : public NRF52BoardDCDC, public NRF52BoardOTA { // set led on and wait for button release before poweroff digitalWrite(PIN_LED, LOW); #ifdef PIN_USER_BTN - while(digitalRead(PIN_USER_BTN) == LOW); + while(digitalRead(PIN_USER_BTN) == USER_BTN_PRESSED); // wait for button release #endif digitalWrite(LED_GREEN, HIGH); digitalWrite(LED_BLUE, HIGH); @@ -52,7 +58,11 @@ class XiaoNrf52Board : public NRF52BoardDCDC, public NRF52BoardOTA { #ifdef PIN_USER_BTN // configure button press to wake up when in powered off state + #if USER_BTN_PRESSED == LOW nrf_gpio_cfg_sense_input(digitalPinToInterrupt(g_ADigitalPinMap[PIN_USER_BTN]), NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_LOW); + #else + nrf_gpio_cfg_sense_input(digitalPinToInterrupt(g_ADigitalPinMap[PIN_USER_BTN]), NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_HIGH); + #endif #endif sd_power_system_off(); diff --git a/variants/xiao_nrf52/target.cpp b/variants/xiao_nrf52/target.cpp index c9c02d215..a8f4162ea 100644 --- a/variants/xiao_nrf52/target.cpp +++ b/variants/xiao_nrf52/target.cpp @@ -34,7 +34,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/xiao_nrf52/target.h b/variants/xiao_nrf52/target.h index e1ea2a6b8..f4076c349 100644 --- a/variants/xiao_nrf52/target.h +++ b/variants/xiao_nrf52/target.h @@ -22,5 +22,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/xiao_rp2040/target.cpp b/variants/xiao_rp2040/target.cpp index b7c199758..6c9a91434 100644 --- a/variants/xiao_rp2040/target.cpp +++ b/variants/xiao_rp2040/target.cpp @@ -39,7 +39,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/xiao_rp2040/target.h b/variants/xiao_rp2040/target.h index 33b3766c2..528c44414 100644 --- a/variants/xiao_rp2040/target.h +++ b/variants/xiao_rp2040/target.h @@ -17,5 +17,5 @@ extern SensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity(); diff --git a/variants/xiao_s3_wio/target.cpp b/variants/xiao_s3_wio/target.cpp index 26cd27ac2..50981ab64 100644 --- a/variants/xiao_s3_wio/target.cpp +++ b/variants/xiao_s3_wio/target.cpp @@ -46,7 +46,7 @@ void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { radio.setCodingRate(cr); } -void radio_set_tx_power(uint8_t dbm) { +void radio_set_tx_power(int8_t dbm) { radio.setOutputPower(dbm); } diff --git a/variants/xiao_s3_wio/target.h b/variants/xiao_s3_wio/target.h index c3227368c..fffd16833 100644 --- a/variants/xiao_s3_wio/target.h +++ b/variants/xiao_s3_wio/target.h @@ -26,5 +26,5 @@ extern EnvironmentSensorManager sensors; bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); -void radio_set_tx_power(uint8_t dbm); +void radio_set_tx_power(int8_t dbm); mesh::LocalIdentity radio_new_identity();