Added support for handling noise floor calculations on devices with LNA gain variance during LNA recalibration. Fixed potential incoming packet buffer corruption on split packet reception at high bitrates.

This commit is contained in:
Mark Qvist 2025-11-19 14:40:34 +01:00
parent 1e054097dd
commit 121f9e79e8
5 changed files with 25 additions and 12 deletions

View file

@ -419,6 +419,7 @@
#define DIO2_AS_RF_SWITCH true
#define LORA_LNA_GAIN 17
#define LORA_LNA_GVT 12
#define LORA_PA_GC1109 true
#define LORA_PA_PWR_EN 7
#define LORA_PA_CSD 2

View file

@ -86,6 +86,8 @@
#define LORA_PREAMBLE_FAST_DELTA 18
#define LORA_FAST_THRESHOLD_BPS 30E3
#define LORA_LIMIT_THRESHOLD_BPS 60E3
#define LORA_GUARD_THRESHOLD_BPS 14E3
#define LORA_FAST_GUARD_MS 48
long lora_preamble_symbols = LORA_PREAMBLE_SYMBOLS_MIN;
long lora_preamble_time_ms = 0;
long lora_header_time_ms = 0;
@ -94,6 +96,7 @@
float lora_us_per_byte = 0.0;
bool lora_low_datarate = false;
bool lora_limit_rate = false;
bool lora_guard_rate = false;
// CSMA Parameters
#define CSMA_SIFS_MS 0
@ -154,6 +157,7 @@
uint8_t last_snr_raw = 0x80;
uint8_t seq = 0xFF;
uint16_t read_len = 0;
uint16_t host_write_len = 0;
// Incoming packet buffer
uint8_t pbuf[MTU];

View file

@ -211,8 +211,8 @@ upload-heltec32_v4:
arduino-cli upload -p /dev/ttyACM0 --fqbn esp32:esp32:esp32s3
@sleep 1
rnodeconf /dev/ttyACM0 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.esp32s3/RNode_Firmware.ino.bin)
@sleep 3
python ./Release/esptool/esptool.py --chip esp32-s3 --port /dev/ttyACM0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/console_image.bin
#@sleep 3
#python ./Release/esptool/esptool.py --chip esp32-s3 --port /dev/ttyACM0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/console_image.bin
upload-tdeck:
arduino-cli upload -p /dev/ttyACM0 --fqbn esp32:esp32:esp32s3

View file

@ -42,7 +42,7 @@ volatile bool serial_buffering = false;
#endif
#if PLATFORM == PLATFORM_ESP32 || PLATFORM == PLATFORM_NRF52
#define MODEM_QUEUE_SIZE 4
#define MODEM_QUEUE_SIZE 8
typedef struct {
size_t len;
int rssi;
@ -314,7 +314,7 @@ inline void kiss_write_packet() {
serial_write(FEND);
serial_write(CMD_DATA);
for (uint16_t i = 0; i < read_len; i++) {
for (uint16_t i = 0; i < host_write_len; i++) {
#if MCU_VARIANT == MCU_NRF52
portENTER_CRITICAL();
uint8_t byte = pbuf[i];
@ -329,7 +329,7 @@ inline void kiss_write_packet() {
}
serial_write(FEND);
read_len = 0;
host_write_len = 0;
#if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52
packet_ready = false;
@ -455,7 +455,8 @@ void ISR_VECT receive_callback(int packet_size) {
kiss_indicate_stat_snr();
// And then write the entire packet
kiss_write_packet();
host_write_len = read_len;
kiss_write_packet(); read_len = 0;
#else
// Allocate packet struct, but abort if there
@ -473,7 +474,7 @@ void ISR_VECT receive_callback(int packet_size) {
// allocated memory again if the queue is
// unable to receive the packet.
modem_packet->len = read_len;
memcpy(modem_packet->data, pbuf, read_len);
memcpy(modem_packet->data, pbuf, read_len); read_len = 0;
if (!modem_packet_queue || xQueueSendFromISR(modem_packet_queue, &modem_packet, NULL) != pdPASS) {
free(modem_packet);
}
@ -1359,6 +1360,11 @@ void update_noise_floor() {
#if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52
if (!dcd) {
if (!noise_floor_sampled || current_rssi < noise_floor + CSMA_INFR_THRESHOLD_DB) {
#if HAS_LORA_LNA
// Discard invalid samples due to gain variance
// during LoRa LNA re-calibration
if (current_rssi < noise_floor-LORA_LNA_GVT) { return; }
#endif
noise_floor_buffer[noise_floor_sample] = current_rssi;
noise_floor_sample = noise_floor_sample+1;
if (noise_floor_sample >= NOISE_FLOOR_SAMPLES) {
@ -1612,7 +1618,8 @@ void tx_queue_handler() {
cw_wait_passed += millis()-cw_wait_start; cw_wait_start = millis();
if (cw_wait_passed < cw_wait_target) { return; } // Contention window wait time has not yet passed, continue waiting
else { // Wait time has passed, flush the queue
if (!lora_limit_rate) { flush_queue(); } else { pop_queue(); }
bool should_flush = !lora_limit_rate && !lora_guard_rate;
if (should_flush) { flush_queue(); } else { pop_queue(); }
cw_wait_passed = 0; csma_cw = -1; difs_wait_start = -1; }
}
}
@ -1628,7 +1635,7 @@ void loop() {
#if MCU_VARIANT == MCU_ESP32
modem_packet_t *modem_packet = NULL;
if(modem_packet_queue && xQueueReceive(modem_packet_queue, &modem_packet, 0) == pdTRUE && modem_packet) {
read_len = modem_packet->len;
host_write_len = modem_packet->len;
last_rssi = modem_packet->rssi;
last_snr_raw = modem_packet->snr_raw;
memcpy(&pbuf, modem_packet->data, modem_packet->len);
@ -1648,7 +1655,7 @@ void loop() {
modem_packet_t *modem_packet = NULL;
if(modem_packet_queue && xQueueReceive(modem_packet_queue, &modem_packet, 0) == pdTRUE && modem_packet) {
memcpy(&pbuf, modem_packet->data, modem_packet->len);
read_len = modem_packet->len;
host_write_len = modem_packet->len;
free(modem_packet);
modem_packet = NULL;

View file

@ -1239,6 +1239,7 @@ void updateBitrate() {
bool fast_rate = lora_bitrate > LORA_FAST_THRESHOLD_BPS;
lora_limit_rate = lora_bitrate > LORA_LIMIT_THRESHOLD_BPS;
lora_guard_rate = (!lora_limit_rate && lora_bitrate > LORA_GUARD_THRESHOLD_BPS);
int csma_slot_min_ms = CSMA_SLOT_MIN_MS;
float lora_preamble_target_ms = LORA_PREAMBLE_TARGET_MS;