Merge remote-tracking branch 'upstream/dev' into keymindCascade
# Conflicts: # examples/companion_radio/ui-new/UITask.cpp # examples/companion_radio/ui-orig/UITask.cpp # examples/companion_radio/ui-tiny/UITask.cpp # examples/simple_repeater/MyMesh.cpp # src/Mesh.cpp # src/Mesh.h # src/helpers/ESP32Board.cpp # src/helpers/ESP32Board.h # src/helpers/SimpleMeshTables.h # variants/heltec_v3/HeltecV3Board.h # variants/tenstar_c3/target.h
This commit is contained in:
commit
84c166d5cc
53 files changed
+1057
-130
No files matched your search
+22
-11
@@ -318,7 +318,8 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
|
||||
onTraceRecv(pkt, trace_tag, auth_code, flags, pkt->path, &pkt->payload[i], len);
|
||||
} else if (hash_size > 0 && offset + hash_size <= len
|
||||
&& self_id.isHashMatch(&pkt->payload[i + offset], hash_size)
|
||||
&& allowPacketForward(pkt) && !_tables->hasSeen(pkt)) {
|
||||
&& allowPacketForward(pkt) && !_tables->wasSeen(pkt)) {
|
||||
_tables->markSeen(pkt);
|
||||
// append SNR (Not hash!)
|
||||
pkt->path[pkt->path_len++] = (int8_t) (pkt->getSNR()*4);
|
||||
|
||||
@@ -360,14 +361,16 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
|
||||
if (pkt->getPayloadType() == PAYLOAD_TYPE_MULTIPART) {
|
||||
return forwardMultipartDirect(pkt);
|
||||
} else if (pkt->getPayloadType() == PAYLOAD_TYPE_ACK) {
|
||||
if (!_tables->hasSeen(pkt)) { // don't retransmit!
|
||||
if (!_tables->wasSeen(pkt)) { // don't retransmit!
|
||||
_tables->markSeen(pkt);
|
||||
removePathPrefix(pkt, 1);
|
||||
routeDirectRecvAcks(pkt, 0);
|
||||
}
|
||||
return ACTION_RELEASE;
|
||||
}
|
||||
|
||||
if (!_tables->hasSeen(pkt)) {
|
||||
if (!_tables->wasSeen(pkt)) {
|
||||
_tables->markSeen(pkt);
|
||||
removePathPrefix(pkt, 1);
|
||||
|
||||
uint32_t d = getDirectRetransmitDelay(pkt);
|
||||
@@ -392,7 +395,8 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
|
||||
memcpy(&ack_crc, &pkt->payload[i], 4); i += 4;
|
||||
if (i > pkt->payload_len) {
|
||||
MESH_DEBUG_PRINTLN("%s Mesh::onRecvPacket(): incomplete ACK packet", getLogDateTime());
|
||||
} else if (!_tables->hasSeen(pkt)) {
|
||||
} else if (!_tables->wasSeen(pkt)) {
|
||||
_tables->markSeen(pkt);
|
||||
onAckRecv(pkt, ack_crc);
|
||||
action = routeRecvPacket(pkt);
|
||||
}
|
||||
@@ -409,7 +413,8 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
|
||||
uint8_t* macAndData = &pkt->payload[i]; // MAC + encrypted data
|
||||
if (i + CIPHER_MAC_SIZE >= pkt->payload_len) {
|
||||
MESH_DEBUG_PRINTLN("%s Mesh::onRecvPacket(): incomplete data packet", getLogDateTime());
|
||||
} else if (!_tables->hasSeen(pkt)) {
|
||||
} else if (!_tables->wasSeen(pkt)) {
|
||||
_tables->markSeen(pkt);
|
||||
// NOTE: this is a 'first packet wins' impl. When receiving from multiple paths, the first to arrive wins.
|
||||
// For flood mode, the path may not be the 'best' in terms of hops.
|
||||
// FUTURE: could send back multiple paths, using createPathReturn(), and let sender choose which to use(?)
|
||||
@@ -472,7 +477,8 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
|
||||
uint8_t* macAndData = &pkt->payload[i]; // MAC + encrypted data
|
||||
if (i + 2 >= pkt->payload_len) {
|
||||
MESH_DEBUG_PRINTLN("%s Mesh::onRecvPacket(): incomplete data packet", getLogDateTime());
|
||||
} else if (!_tables->hasSeen(pkt)) {
|
||||
} else if (!_tables->wasSeen(pkt)) {
|
||||
_tables->markSeen(pkt);
|
||||
if (self_id.isHashMatch(&dest_hash)) {
|
||||
Identity sender(sender_pub_key);
|
||||
|
||||
@@ -499,7 +505,8 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
|
||||
uint8_t* macAndData = &pkt->payload[i]; // MAC + encrypted data
|
||||
if (i + 2 >= pkt->payload_len) {
|
||||
MESH_DEBUG_PRINTLN("%s Mesh::onRecvPacket(): incomplete data packet", getLogDateTime());
|
||||
} else if (!_tables->hasSeen(pkt)) {
|
||||
} else if (!_tables->wasSeen(pkt)) {
|
||||
_tables->markSeen(pkt);
|
||||
// scan channels DB, for all matching hashes of 'channel_hash' (max 4 matches supported ATM)
|
||||
GroupChannel channels[4];
|
||||
int num = searchChannelsByHash(&channel_hash, channels, 4);
|
||||
@@ -530,7 +537,8 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
|
||||
MESH_DEBUG_PRINTLN("%s Mesh::onRecvPacket(): incomplete advertisement packet", getLogDateTime());
|
||||
} else if (self_id.matches(id.pub_key)) {
|
||||
MESH_DEBUG_PRINTLN("%s Mesh::onRecvPacket(): receiving SELF advert packet", getLogDateTime());
|
||||
} else if (!_tables->hasSeen(pkt)) {
|
||||
} else if (!_tables->wasSeen(pkt)) {
|
||||
_tables->markSeen(pkt);
|
||||
uint8_t* app_data = &pkt->payload[i];
|
||||
int app_data_len = pkt->payload_len - i;
|
||||
if (app_data_len > MAX_ADVERT_DATA_SIZE) { app_data_len = MAX_ADVERT_DATA_SIZE; }
|
||||
@@ -557,7 +565,8 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
|
||||
break;
|
||||
}
|
||||
case PAYLOAD_TYPE_RAW_CUSTOM: {
|
||||
if (pkt->isRouteDirect() && !_tables->hasSeen(pkt)) {
|
||||
if (pkt->isRouteDirect() && !_tables->wasSeen(pkt)) {
|
||||
_tables->markSeen(pkt);
|
||||
onRawDataRecv(pkt);
|
||||
//action = routeRecvPacket(pkt); don't flood route these (yet)
|
||||
}
|
||||
@@ -575,7 +584,8 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
|
||||
tmp.payload_len = pkt->payload_len - 1;
|
||||
memcpy(tmp.payload, &pkt->payload[1], tmp.payload_len);
|
||||
|
||||
if (!_tables->hasSeen(&tmp)) {
|
||||
if (!_tables->wasSeen(&tmp)) {
|
||||
_tables->markSeen(&tmp);
|
||||
uint32_t ack_crc;
|
||||
memcpy(&ack_crc, tmp.payload, 4);
|
||||
|
||||
@@ -637,7 +647,8 @@ DispatcherAction Mesh::forwardMultipartDirect(Packet* pkt) {
|
||||
tmp.payload_len = pkt->payload_len - 1;
|
||||
memcpy(tmp.payload, &pkt->payload[1], tmp.payload_len);
|
||||
|
||||
if (!_tables->hasSeen(&tmp)) { // don't retransmit!
|
||||
if (!_tables->wasSeen(&tmp)) { // don't retransmit!
|
||||
_tables->markSeen(&tmp);
|
||||
removePathPrefix(&tmp, 1);
|
||||
routeDirectRecvAcks(&tmp, ((uint32_t)remaining + 1) * 300); // expect multipart ACKs 300ms apart (x2)
|
||||
}
|
||||
|
||||
+4
-3
@@ -27,9 +27,10 @@ public:
|
||||
*/
|
||||
class MeshTables {
|
||||
public:
|
||||
virtual bool hasSeen(const Packet* packet) = 0;
|
||||
virtual bool wasSeen(const Packet* packet) = 0;
|
||||
virtual void markSeen(const Packet* packet) = 0;
|
||||
virtual void markSent(const Packet* packet) = 0;
|
||||
virtual void clear(const Packet* packet) = 0; // remove this packet hash from table
|
||||
virtual void clear(const Packet* packet) = 0; // remove this packet hash from table
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -256,7 +257,7 @@ protected:
|
||||
* \param auth_code a code to authenticate the packet
|
||||
* \param flags zero for now
|
||||
* \param path_snrs single byte SNR*4 for each hop in the path
|
||||
* \param path_hashes hashes if each repeater in the path
|
||||
* \param path_hashes hashes of each repeater in the path
|
||||
* \param path_len length of the path_snrs[] and path_hashes[] arrays
|
||||
*/
|
||||
virtual void onTraceRecv(Packet* packet, uint32_t tag, uint32_t auth_code, uint8_t flags, const uint8_t* path_snrs, const uint8_t* path_hashes, uint8_t path_len) { }
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ namespace mesh {
|
||||
#define PAYLOAD_TYPE_GRP_DATA 0x06 // an (unverified) group datagram (prefixed with channel hash, MAC) (enc data: data_type(uint16), data_len, blob)
|
||||
#define PAYLOAD_TYPE_ANON_REQ 0x07 // generic request (prefixed with dest_hash, ephemeral pub_key, MAC) (enc data: ...)
|
||||
#define PAYLOAD_TYPE_PATH 0x08 // returned path (prefixed with dest/src hashes, MAC) (enc data: path, extra)
|
||||
#define PAYLOAD_TYPE_TRACE 0x09 // trace a path, collecting SNI for each hop
|
||||
#define PAYLOAD_TYPE_TRACE 0x09 // trace a path, collecting SNR for each hop
|
||||
#define PAYLOAD_TYPE_MULTIPART 0x0A // packet is one of a set of packets
|
||||
#define PAYLOAD_TYPE_CONTROL 0x0B // a control/discovery packet
|
||||
//...
|
||||
|
||||
@@ -1170,13 +1170,15 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep
|
||||
_prefs->disable_fwd = memcmp(&config[7], "off", 3) == 0;
|
||||
savePrefs();
|
||||
strcpy(reply, _prefs->disable_fwd ? "OK - repeat is now OFF" : "OK - repeat is now ON");
|
||||
#if defined(USE_SX1262) || defined(USE_SX1268) || defined(USE_LR1110)
|
||||
} else if (memcmp(config, "radio.rxgain ", 13) == 0) {
|
||||
_prefs->rx_boosted_gain = memcmp(&config[13], "on", 2) == 0;
|
||||
strcpy(reply, "OK");
|
||||
bool enabled = memcmp(&config[13], "on", 2) == 0;
|
||||
_prefs->rx_boosted_gain = enabled;
|
||||
savePrefs();
|
||||
_callbacks->setRxBoostedGain(_prefs->rx_boosted_gain);
|
||||
#endif
|
||||
if (_callbacks->setRxBoostedGain(enabled)) {
|
||||
strcpy(reply, "OK");
|
||||
} else {
|
||||
strcpy(reply, "Error: unsupported");
|
||||
}
|
||||
} else if (memcmp(config, "radio.fem.rxgain ", 17) == 0) {
|
||||
if (!_board->canControlLoRaFemLna()) {
|
||||
strcpy(reply, "Error: unsupported");
|
||||
@@ -1679,10 +1681,8 @@ void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* rep
|
||||
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->node_lat));
|
||||
} else if (memcmp(config, "lon", 3) == 0) {
|
||||
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->node_lon));
|
||||
#if defined(USE_SX1262) || defined(USE_SX1268) || defined(USE_LR1110)
|
||||
} else if (memcmp(config, "radio.rxgain", 12) == 0) {
|
||||
sprintf(reply, "> %s", _prefs->rx_boosted_gain ? "on" : "off");
|
||||
#endif
|
||||
} else if (memcmp(config, "radio.fem.rxgain", 16) == 0) {
|
||||
if (!_board->canControlLoRaFemLna()) {
|
||||
strcpy(reply, "Error: unsupported");
|
||||
@@ -1854,13 +1854,9 @@ void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* rep
|
||||
strcpy(reply, "ERROR: Power management not supported");
|
||||
#endif
|
||||
} else if (memcmp(config, "pwrmgt.bootreason", 17) == 0) {
|
||||
#ifdef NRF52_POWER_MANAGEMENT
|
||||
sprintf(reply, "> Reset: %s; Shutdown: %s",
|
||||
_board->getResetReasonString(_board->getResetReason()),
|
||||
_board->getShutdownReasonString(_board->getShutdownReason()));
|
||||
#else
|
||||
strcpy(reply, "ERROR: Power management not supported");
|
||||
#endif
|
||||
} else if (memcmp(config, "pwrmgt.bootmv", 13) == 0) {
|
||||
#ifdef NRF52_POWER_MANAGEMENT
|
||||
sprintf(reply, "> %u mV", _board->getBootVoltage());
|
||||
|
||||
@@ -235,8 +235,8 @@ public:
|
||||
// no op by default
|
||||
};
|
||||
|
||||
virtual void setRxBoostedGain(bool enable) {
|
||||
// no op by default
|
||||
virtual bool setRxBoostedGain(bool enable) {
|
||||
return false; // CommonCLI reports unsupported if not overridden by wrapper
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
+27
-27
@@ -189,34 +189,34 @@ public:
|
||||
}
|
||||
|
||||
// https://docs.espressif.com/projects/esp-idf/en/v4.4.7/esp32/api-reference/system/system.html
|
||||
const char *getResetReasonString(uint32_t reason) {
|
||||
const char* getResetReasonString(uint32_t reason) {
|
||||
switch (reason) {
|
||||
case ESP_RST_UNKNOWN:
|
||||
return "Unknown or first boot";
|
||||
case ESP_RST_POWERON:
|
||||
return "Power-on reset";
|
||||
case ESP_RST_EXT:
|
||||
return "External reset";
|
||||
case ESP_RST_SW:
|
||||
return "Software reset";
|
||||
case ESP_RST_PANIC:
|
||||
return "Panic / exception reset";
|
||||
case ESP_RST_INT_WDT:
|
||||
return "Interrupt watchdog reset";
|
||||
case ESP_RST_TASK_WDT:
|
||||
return "Task watchdog reset";
|
||||
case ESP_RST_WDT:
|
||||
return "Other watchdog reset";
|
||||
case ESP_RST_DEEPSLEEP:
|
||||
return "Wake from deep sleep";
|
||||
case ESP_RST_BROWNOUT:
|
||||
return "Brownout (low voltage)";
|
||||
case ESP_RST_SDIO:
|
||||
return "SDIO reset";
|
||||
default:
|
||||
static char buf[40];
|
||||
snprintf(buf, sizeof(buf), "Unknown reset reason (%d)", reason);
|
||||
return buf;
|
||||
case ESP_RST_UNKNOWN:
|
||||
return "Unknown or first boot";
|
||||
case ESP_RST_POWERON:
|
||||
return "Power-on reset";
|
||||
case ESP_RST_EXT:
|
||||
return "External reset";
|
||||
case ESP_RST_SW:
|
||||
return "Software reset";
|
||||
case ESP_RST_PANIC:
|
||||
return "Panic / exception reset";
|
||||
case ESP_RST_INT_WDT:
|
||||
return "Interrupt watchdog reset";
|
||||
case ESP_RST_TASK_WDT:
|
||||
return "Task watchdog reset";
|
||||
case ESP_RST_WDT:
|
||||
return "Other watchdog reset";
|
||||
case ESP_RST_DEEPSLEEP:
|
||||
return "Wake from deep sleep";
|
||||
case ESP_RST_BROWNOUT:
|
||||
return "Brownout (low voltage)";
|
||||
case ESP_RST_SDIO:
|
||||
return "SDIO reset";
|
||||
default:
|
||||
static char buf[40];
|
||||
snprintf(buf, sizeof(buf), "Unknown reset reason (%d)", reason);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -139,7 +139,7 @@ bool RegionMap::save(FILESYSTEM* _fs, const char* path) {
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
return true;
|
||||
return success;
|
||||
}
|
||||
return false; // failed
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
bool hasSeen(const mesh::Packet* packet) override {
|
||||
bool wasSeen(const mesh::Packet* packet) override {
|
||||
uint8_t hash[MAX_HASH_SIZE];
|
||||
packet->calculatePacketHash(hash);
|
||||
|
||||
@@ -179,11 +179,18 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
storeHash(hash);
|
||||
recordRecentRepeater(packet);
|
||||
return false;
|
||||
}
|
||||
|
||||
void markSeen(const mesh::Packet* packet) override {
|
||||
uint8_t hash[MAX_HASH_SIZE];
|
||||
packet->calculatePacketHash(hash);
|
||||
if (!hasSeenHash(hash)) {
|
||||
storeHash(hash);
|
||||
recordRecentRepeater(packet);
|
||||
}
|
||||
}
|
||||
|
||||
void markSent(const mesh::Packet* packet) override {
|
||||
// Outbound packets must be marked as already-sent without teaching the recent-heard cache about ourselves.
|
||||
uint8_t hash[MAX_HASH_SIZE];
|
||||
@@ -199,7 +206,7 @@ public:
|
||||
|
||||
uint8_t* sp = _hashes;
|
||||
for (int i = 0; i < MAX_PACKET_HASHES; i++, sp += MAX_HASH_SIZE) {
|
||||
if (memcmp(hash, sp, MAX_HASH_SIZE) == 0) {
|
||||
if (memcmp(hash, sp, MAX_HASH_SIZE) == 0) {
|
||||
memset(sp, 0, MAX_HASH_SIZE);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,8 @@ void BridgeBase::handleReceivedPacket(mesh::Packet *packet) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_seen_packets.hasSeen(packet)) {
|
||||
if (!_seen_packets.wasSeen(packet)) {
|
||||
_seen_packets.markSeen(packet);
|
||||
// bridge_delay provides a buffer to prevent immediate processing conflicts in the mesh network.
|
||||
_mgr->queueInbound(packet, millis() + _prefs->bridge_delay);
|
||||
} else {
|
||||
|
||||
@@ -110,7 +110,7 @@ protected:
|
||||
* @brief Common packet handling for received packets
|
||||
*
|
||||
* Implements the standard pattern used by all bridges:
|
||||
* - Check if packet was seen before using _seen_packets.hasSeen()
|
||||
* - Check if packet was seen before using _seen_packets.wasSeen()
|
||||
* - Queue packet for mesh processing if not seen before
|
||||
* - Free packet if already seen to prevent duplicates
|
||||
*
|
||||
|
||||
@@ -41,7 +41,7 @@ void ESPNowBridge::begin() {
|
||||
// Initialize WiFi in station mode
|
||||
WiFi.mode(WIFI_STA);
|
||||
|
||||
// Set wifi channel
|
||||
// Set Wi-Fi channel
|
||||
if (esp_wifi_set_channel(_prefs->bridge_channel, WIFI_SECOND_CHAN_NONE) != ESP_OK) {
|
||||
BRIDGE_DEBUG_PRINTLN("Error setting WIFI channel to %d\n", _prefs->bridge_channel);
|
||||
return;
|
||||
@@ -176,7 +176,8 @@ void ESPNowBridge::sendPacket(mesh::Packet *packet) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_seen_packets.hasSeen(packet)) {
|
||||
if (!_seen_packets.wasSeen(packet)) {
|
||||
_seen_packets.markSeen(packet);
|
||||
// Create a temporary buffer just for size calculation and reuse for actual writing
|
||||
uint8_t sizingBuffer[MAX_PAYLOAD_SIZE];
|
||||
uint16_t meshPacketLen = packet->writeTo(sizingBuffer);
|
||||
|
||||
@@ -115,7 +115,8 @@ void RS232Bridge::sendPacket(mesh::Packet *packet) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_seen_packets.hasSeen(packet)) {
|
||||
if (!_seen_packets.wasSeen(packet)) {
|
||||
_seen_packets.markSeen(packet);
|
||||
|
||||
uint8_t buffer[MAX_SERIAL_PACKET_SIZE];
|
||||
uint16_t len = packet->writeTo(buffer + 4);
|
||||
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
* These two functions do nothing for ESP-NOW, but are needed for the
|
||||
* Radio interface.
|
||||
*/
|
||||
virtual void setRxBoostedGainMode(bool) { }
|
||||
virtual bool setRxBoostedGainMode(bool) { }
|
||||
virtual bool getRxBoostedGainMode() const { return false; }
|
||||
|
||||
uint32_t intID();
|
||||
|
||||
@@ -37,8 +37,8 @@ public:
|
||||
|
||||
void doResetAGC() override { sx126xResetAGC((SX126x *)_radio); }
|
||||
|
||||
void setRxBoostedGainMode(bool en) override {
|
||||
((CustomLLCC68 *)_radio)->setRxBoostedGainMode(en);
|
||||
bool setRxBoostedGainMode(bool en) override {
|
||||
return ((CustomLLCC68 *)_radio)->setRxBoostedGainMode(en) == RADIOLIB_ERR_NONE;
|
||||
}
|
||||
bool getRxBoostedGainMode() const override {
|
||||
return ((CustomLLCC68 *)_radio)->getRxBoostedGainMode();
|
||||
|
||||
@@ -34,6 +34,11 @@ public:
|
||||
return rssi;
|
||||
}
|
||||
|
||||
uint32_t getEstAirtimeFor(int len_bytes) override {
|
||||
auto airtime = RadioLibWrapper::getEstAirtimeFor(len_bytes);
|
||||
return airtime < 200 ? 200 : airtime; // at least 200 millis
|
||||
}
|
||||
|
||||
void onSendFinished() override {
|
||||
RadioLibWrapper::onSendFinished();
|
||||
_radio->setPreambleLength(preambleLengthForSF(getSpreadingFactor())); // overcomes weird issues with small and big pkts
|
||||
@@ -44,8 +49,8 @@ public:
|
||||
|
||||
uint8_t getSpreadingFactor() const override { return ((CustomLR1110 *)_radio)->getSpreadingFactor(); }
|
||||
|
||||
void setRxBoostedGainMode(bool en) override {
|
||||
((CustomLR1110 *)_radio)->setRxBoostedGainMode(en);
|
||||
bool setRxBoostedGainMode(bool en) override {
|
||||
return ((CustomLR1110 *)_radio)->setRxBoostedGainMode(en) == RADIOLIB_ERR_NONE;
|
||||
}
|
||||
bool getRxBoostedGainMode() const override {
|
||||
return ((CustomLR1110 *)_radio)->getRxBoostedGainMode();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <RadioLib.h>
|
||||
#include "MeshCore.h"
|
||||
|
||||
#define SX126X_IRQ_HEADER_VALID 0b0000010000 // 4 4 valid LoRa header received
|
||||
#define SX126X_IRQ_PREAMBLE_DETECTED 0x04
|
||||
@@ -27,6 +28,14 @@ class CustomSX1262 : public SX1262 {
|
||||
uint8_t cr = 5;
|
||||
#endif
|
||||
|
||||
#ifdef SX126X_USE_REGULATOR_LDO
|
||||
constexpr bool useRegulatorLDO = SX126X_USE_REGULATOR_LDO;
|
||||
#else
|
||||
constexpr bool useRegulatorLDO = false;
|
||||
#endif
|
||||
|
||||
MESH_DEBUG_PRINTLN("SX1262 regulator requested: %s", useRegulatorLDO ? "LDO" : "DC-DC");
|
||||
|
||||
#if defined(P_LORA_SCLK)
|
||||
#ifdef NRF52_PLATFORM
|
||||
if (spi) { spi->setPins(P_LORA_MISO, P_LORA_SCLK, P_LORA_MOSI); spi->begin(); }
|
||||
@@ -42,11 +51,12 @@ class CustomSX1262 : public SX1262 {
|
||||
if (spi) spi->begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI);
|
||||
#endif
|
||||
#endif
|
||||
int status = begin(LORA_FREQ, LORA_BW, LORA_SF, cr, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 16, tcxo);
|
||||
int status = begin(LORA_FREQ, LORA_BW, LORA_SF, cr, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 16, tcxo, useRegulatorLDO);
|
||||
// if radio init fails with -707/-706, try again with tcxo voltage set to 0.0f
|
||||
if (status == RADIOLIB_ERR_SPI_CMD_FAILED || status == RADIOLIB_ERR_SPI_CMD_INVALID) {
|
||||
MESH_DEBUG_PRINTLN("SX1262 init failed with error %d, retrying with TCXO at 0.0V", status);
|
||||
tcxo = 0.0f;
|
||||
status = begin(LORA_FREQ, LORA_BW, LORA_SF, cr, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 16, tcxo);
|
||||
status = begin(LORA_FREQ, LORA_BW, LORA_SF, cr, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 16, tcxo, useRegulatorLDO);
|
||||
}
|
||||
if (status != RADIOLIB_ERR_NONE) {
|
||||
Serial.print("ERROR: radio init failed: ");
|
||||
@@ -83,6 +93,8 @@ class CustomSX1262 : public SX1262 {
|
||||
writeRegister(0x8B5, &r_data, 1);
|
||||
#endif
|
||||
|
||||
MESH_DEBUG_PRINTLN("SX1262 status=0x%02X device_errors=0x%04X", getStatus(), getDeviceErrors());
|
||||
|
||||
return true; // success
|
||||
}
|
||||
|
||||
|
||||
@@ -44,8 +44,8 @@ public:
|
||||
|
||||
void doResetAGC() override { sx126xResetAGC((SX126x *)_radio); }
|
||||
|
||||
void setRxBoostedGainMode(bool en) override {
|
||||
((CustomSX1262 *)_radio)->setRxBoostedGainMode(en);
|
||||
bool setRxBoostedGainMode(bool en) override {
|
||||
return ((CustomSX1262 *)_radio)->setRxBoostedGainMode(en) == RADIOLIB_ERR_NONE;
|
||||
}
|
||||
bool getRxBoostedGainMode() const override {
|
||||
return ((CustomSX1262 *)_radio)->getRxBoostedGainMode();
|
||||
|
||||
@@ -41,8 +41,8 @@ public:
|
||||
|
||||
void doResetAGC() override { sx126xResetAGC((SX126x *)_radio); }
|
||||
|
||||
void setRxBoostedGainMode(bool en) override {
|
||||
((CustomSX1268 *)_radio)->setRxBoostedGainMode(en);
|
||||
bool setRxBoostedGainMode(bool en) override {
|
||||
return ((CustomSX1268 *)_radio)->setRxBoostedGainMode(en) == RADIOLIB_ERR_NONE;
|
||||
}
|
||||
bool getRxBoostedGainMode() const override {
|
||||
return ((CustomSX1268 *)_radio)->getRxBoostedGainMode();
|
||||
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
|
||||
float packetScore(float snr, int packet_len) override { return packetScoreInt(snr, 10, packet_len); } // assume sf=10
|
||||
|
||||
virtual void setRxBoostedGainMode(bool) { }
|
||||
virtual bool setRxBoostedGainMode(bool) { return false; }
|
||||
virtual bool getRxBoostedGainMode() const { return false; }
|
||||
};
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ public:
|
||||
case LPP_GPS:
|
||||
_pos += 9; break;
|
||||
case LPP_POLYLINE:
|
||||
_pos += 8; break; // TODO: this is MINIMIUM
|
||||
_pos += 8; break; // TODO: this is MINIMUM
|
||||
case LPP_GYROMETER:
|
||||
case LPP_ACCELEROMETER:
|
||||
_pos += 6; break;
|
||||
|
||||
@@ -37,7 +37,7 @@ static int _internal_flash_read(const struct lfs_config *c, lfs_block_t block, l
|
||||
}
|
||||
|
||||
// Program a region in a block. The block must have previously
|
||||
// been erased. Negative error codes are propogated to the user.
|
||||
// been erased. Negative error codes are propagated to the user.
|
||||
// May return LFS_ERR_CORRUPT if the block should be considered bad.
|
||||
static int _internal_flash_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size)
|
||||
{
|
||||
@@ -62,7 +62,7 @@ static int _internal_flash_prog(const struct lfs_config *c, lfs_block_t block, l
|
||||
|
||||
// Erase a block. A block must be erased before being programmed.
|
||||
// The state of an erased block is undefined. Negative error codes
|
||||
// are propogated to the user.
|
||||
// are propagated to the user.
|
||||
// May return LFS_ERR_CORRUPT if the block should be considered bad.
|
||||
static int _internal_flash_erase(const struct lfs_config *c, lfs_block_t block)
|
||||
{
|
||||
@@ -87,7 +87,7 @@ static int _internal_flash_erase(const struct lfs_config *c, lfs_block_t block)
|
||||
}
|
||||
|
||||
// Sync the state of the underlying block device. Negative error codes
|
||||
// are propogated to the user.
|
||||
// are propagated to the user.
|
||||
static int _internal_flash_sync(const struct lfs_config *c)
|
||||
{
|
||||
return LFS_ERR_OK; // don't need sync
|
||||
|
||||
@@ -1166,7 +1166,7 @@ char DefaultFontTableLookup(const uint8_t ch) {
|
||||
uint8_t last = LASTCHAR; // get last char
|
||||
LASTCHAR = ch;
|
||||
|
||||
switch (last) { // conversion depnding on first UTF8-character
|
||||
switch (last) { // conversion depending on first UTF8-character
|
||||
case 0xC2: return (uint8_t) ch;
|
||||
case 0xC3: return (uint8_t) (ch | 0xC0);
|
||||
case 0x82: if (ch == 0xAC) return (uint8_t) 0x80; // special case Euro-symbol
|
||||
|
||||
Reference in new issue
Block a user