diff --git a/RNode_Firmware.ino b/RNode_Firmware.ino index e476392..f8d5b35 100644 --- a/RNode_Firmware.ino +++ b/RNode_Firmware.ino @@ -557,18 +557,44 @@ void flushQueue(void) { #endif } -#define PHY_HEADER_LORA_SYMBOLS 8 +#define PHY_HEADER_LORA_SYMBOLS 20 +#define PHY_CRC_LORA_BITS 16 void add_airtime(uint16_t written) { #if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52 + float lora_symbols = 0; float packet_cost_ms = 0.0; - float payload_cost_ms = ((float)written * lora_us_per_byte)/1000.0; - packet_cost_ms += payload_cost_ms; - packet_cost_ms += (lora_preamble_symbols+4.25)*lora_symbol_time_ms; - packet_cost_ms += PHY_HEADER_LORA_SYMBOLS * lora_symbol_time_ms; + int ldr_opt = 0; if (lora_low_datarate) ldr_opt = 1; + + #if MODEM == SX1276 || MODEM == SX1278 + lora_symbols += (8*written + PHY_CRC_LORA_BITS - 4*lora_sf + 8 + PHY_HEADER_LORA_SYMBOLS); + lora_symbols /= 4*(lora_sf-2*ldr_opt); + lora_symbols *= lora_cr; + lora_symbols += lora_preamble_symbols + 0.25 + 8; + packet_cost_ms += lora_symbols * lora_symbol_time_ms; + + #elif MODEM == SX1262 || MODEM == SX1280 + if (lora_sf < 7) { + lora_symbols += (8*written + PHY_CRC_LORA_BITS - 4*lora_sf + PHY_HEADER_LORA_SYMBOLS); + lora_symbols /= 4*lora_sf; + lora_symbols *= lora_cr; + lora_symbols += lora_preamble_symbols + 2.25 + 8; + packet_cost_ms += lora_symbols * lora_symbol_time_ms; + + } else { + lora_symbols += (8*written + PHY_CRC_LORA_BITS - 4*lora_sf + 8 + PHY_HEADER_LORA_SYMBOLS); + lora_symbols /= 4*(lora_sf-2*ldr_opt); + lora_symbols *= lora_cr; + lora_symbols += lora_preamble_symbols + 0.25 + 8; + packet_cost_ms += lora_symbols * lora_symbol_time_ms; + } + + #endif + uint16_t cb = current_airtime_bin(); uint16_t nb = cb+1; if (nb == AIRTIME_BINS) { nb = 0; } airtime_bins[cb] += packet_cost_ms; airtime_bins[nb] = 0; + #endif } diff --git a/Utilities.h b/Utilities.h index aae8738..5a981bd 100644 --- a/Utilities.h +++ b/Utilities.h @@ -863,8 +863,8 @@ void kiss_indicate_phy_stats() { #if MCU_VARIANT == MCU_ESP32 uint16_t lst = (uint16_t)(lora_symbol_time_ms*1000); uint16_t lsr = (uint16_t)(lora_symbol_rate); - uint16_t prs = (uint16_t)(lora_preamble_symbols+4); - uint16_t prt = (uint16_t)((lora_preamble_symbols+4)*lora_symbol_time_ms); + uint16_t prs = (uint16_t)(lora_preamble_symbols); + uint16_t prt = (uint16_t)((lora_preamble_symbols)*lora_symbol_time_ms); uint16_t cst = (uint16_t)(csma_slot_ms); serial_write(FEND); serial_write(CMD_STAT_PHYPRM); @@ -1091,20 +1091,14 @@ void updateBitrate() { lora_symbol_time_ms = (1.0/lora_symbol_rate)*1000.0; lora_bitrate = (uint32_t)(lora_sf * ( (4.0/(float)lora_cr) / ((float)(pow(2, lora_sf))/((float)lora_bw/1000.0)) ) * 1000.0); lora_us_per_byte = 1000000.0/((float)lora_bitrate/8.0); - csma_slot_ms = lora_symbol_time_ms*12; + + csma_slot_ms = lora_symbol_time_ms*CSMA_SLOT_SYMBOLS; if (csma_slot_ms > CSMA_SLOT_MAX_MS) { csma_slot_ms = CSMA_SLOT_MAX_MS; } if (csma_slot_ms < CSMA_SLOT_MIN_MS) { csma_slot_ms = CSMA_SLOT_MIN_MS; } - float target_preamble_symbols = (LORA_PREAMBLE_TARGET_MS/lora_symbol_time_ms)-LORA_PREAMBLE_SYMBOLS_HW; - #if MODEM == SX1280 - target_preamble_symbols = 12; - #else - if (target_preamble_symbols < LORA_PREAMBLE_SYMBOLS_MIN) { - target_preamble_symbols = LORA_PREAMBLE_SYMBOLS_MIN; - } else { - target_preamble_symbols = ceil(target_preamble_symbols); - } - #endif + float target_preamble_symbols = LORA_PREAMBLE_TARGET_MS/lora_symbol_time_ms; + if (target_preamble_symbols < LORA_PREAMBLE_SYMBOLS_MIN) { target_preamble_symbols = LORA_PREAMBLE_SYMBOLS_MIN; } + else { target_preamble_symbols = (ceil)(target_preamble_symbols); } lora_preamble_symbols = (long)target_preamble_symbols; setPreamble(); diff --git a/sx126x.cpp b/sx126x.cpp index cd74343..697d97d 100644 --- a/sx126x.cpp +++ b/sx126x.cpp @@ -252,14 +252,14 @@ void sx126x::setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr, int ldro) { executeOpcode(OP_MODULATION_PARAMS_6X, buf, 8); } -void sx126x::setPacketParams(long preamble, uint8_t headermode, uint8_t length, uint8_t crc) { +void sx126x::setPacketParams(long preamble_symbols, uint8_t headermode, uint8_t payload_length, uint8_t crc) { // Because there is no access to these registers on the sx1262, we have // to set all these parameters at once or not at all. uint8_t buf[9]; - buf[0] = uint8_t((preamble & 0xFF00) >> 8); - buf[1] = uint8_t((preamble & 0x00FF)); + buf[0] = uint8_t((preamble_symbols & 0xFF00) >> 8); + buf[1] = uint8_t((preamble_symbols & 0x00FF)); buf[2] = headermode; - buf[3] = length; + buf[3] = payload_length; buf[4] = crc; buf[5] = 0x00; // standard IQ setting (no inversion) buf[6] = 0x00; // unused params @@ -642,12 +642,14 @@ long sx126x::getSignalBandwidth() { return 0; } -void sx126x::handleLowDataRate(){ - if ( long( (1<<_sf) / (getSignalBandwidth()/1000)) > 16) { _ldro = 0x01; } - else { _ldro = 0x00; } +extern bool lora_low_datarate; +void sx126x::handleLowDataRate() { + if ( long( (1<<_sf) / (getSignalBandwidth()/1000)) > 16) + { _ldro = 0x01; lora_low_datarate = true; } + else { _ldro = 0x00; lora_low_datarate = false; } } -// TODO: check if there's anything the sx1262 can do here +// TODO: Check if there's anything the sx1262 can do here void sx126x::optimizeModemSensitivity(){ } void sx126x::setSignalBandwidth(long sbw) { @@ -675,9 +677,9 @@ void sx126x::setCodingRate4(int denominator) { setModulationParams(_sf, _bw, cr, _ldro); } -void sx126x::setPreambleLength(long length) { - _preambleLength = length; - setPacketParams(length, _implicitHeaderMode, _payloadLength, _crcMode); +void sx126x::setPreambleLength(long preamble_symbols) { + _preambleLength = preamble_symbols; + setPacketParams(preamble_symbols, _implicitHeaderMode, _payloadLength, _crcMode); } void sx126x::setSyncWord(uint16_t sw) { diff --git a/sx126x.h b/sx126x.h index bec13f8..1edf750 100644 --- a/sx126x.h +++ b/sx126x.h @@ -66,7 +66,7 @@ public: long getSignalBandwidth(); void setSignalBandwidth(long sbw); void setCodingRate4(int denominator); - void setPreambleLength(long length); + void setPreambleLength(long preamble_symbols); void setSyncWord(uint16_t sw); uint8_t modemStatus(); void enableCrc(); @@ -81,7 +81,7 @@ public: void executeOpcodeRead(uint8_t opcode, uint8_t *buffer, uint8_t size); void writeBuffer(const uint8_t* buffer, size_t size); void readBuffer(uint8_t* buffer, size_t size); - void setPacketParams(long preamble, uint8_t headermode, uint8_t length, uint8_t crc); + void setPacketParams(long preamble_symbols, uint8_t headermode, uint8_t payload_length, uint8_t crc); void setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr, int ldro); diff --git a/sx127x.cpp b/sx127x.cpp index 2d562c2..8871593 100644 --- a/sx127x.cpp +++ b/sx127x.cpp @@ -440,19 +440,23 @@ void sx127x::setCodingRate4(int denominator) { writeRegister(REG_MODEM_CONFIG_1_7X, (readRegister(REG_MODEM_CONFIG_1_7X) & 0xf1) | (cr << 1)); } -void sx127x::setPreambleLength(long length) { +void sx127x::setPreambleLength(long preamble_symbols) { + long length = preamble_symbols - 4; writeRegister(REG_PREAMBLE_MSB_7X, (uint8_t)(length >> 8)); writeRegister(REG_PREAMBLE_LSB_7X, (uint8_t)(length >> 0)); } +extern bool lora_low_datarate; void sx127x::handleLowDataRate() { int sf = (readRegister(REG_MODEM_CONFIG_2_7X) >> 4); if ( long( (1< 16) { // Set auto AGC and LowDataRateOptimize writeRegister(REG_MODEM_CONFIG_3_7X, (1<<3)|(1<<2)); + lora_low_datarate = true; } else { // Only set auto AGC writeRegister(REG_MODEM_CONFIG_3_7X, (1<<2)); + lora_low_datarate = false; } } diff --git a/sx127x.h b/sx127x.h index 56ff889..c87b636 100644 --- a/sx127x.h +++ b/sx127x.h @@ -63,7 +63,7 @@ public: long getSignalBandwidth(); void setSignalBandwidth(long sbw); void setCodingRate4(int denominator); - void setPreambleLength(long length); + void setPreambleLength(long preamble_symbols); void setSyncWord(uint8_t sw); uint8_t modemStatus(); void enableCrc(); diff --git a/sx128x.cpp b/sx128x.cpp index ed7415e..9aa6d7d 100644 --- a/sx128x.cpp +++ b/sx128x.cpp @@ -269,32 +269,43 @@ void sx128x::setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr) { writeRegister(0x093C, 0x1); } -void sx128x::setPacketParams(uint32_t preamble, uint8_t headermode, uint8_t length, uint8_t crc) { - // Because there is no access to these registers on the sx1280, we have - // to set all these parameters at once or not at all. - uint8_t buf[7]; - // calculate exponent and mantissa values for modem - uint8_t e = 1; - uint8_t m = 1; - uint32_t preamblelen; - - while (e <= 15) { +uint8_t preamble_e = 0; +uint8_t preamble_m = 0; +uint32_t last_me_result_target = 0; +extern long lora_preamble_symbols; +void sx128x::setPacketParams(uint32_t target_preamble_symbols, uint8_t headermode, uint8_t payload_length, uint8_t crc) { + if (last_me_result_target != target_preamble_symbols) { + // Calculate exponent and mantissa values for modem + if (target_preamble_symbols >= 0xF000) target_preamble_symbols = 0xF000; + uint32_t calculated_preamble_symbols; + uint8_t e = 1; + uint8_t m = 1; + while (e <= 15) { while (m <= 15) { - preamblelen = m * (pow(2,e)); - if (preamblelen >= preamble) break; - m++; + calculated_preamble_symbols = m * (pow(2,e)); + if (calculated_preamble_symbols >= target_preamble_symbols-4) break; + m++; } - if (preamblelen >= preamble) break; - m = 0; - e++; + + if (calculated_preamble_symbols >= target_preamble_symbols-4) break; + m = 1; e++; + } + + last_me_result_target = target_preamble_symbols; + lora_preamble_symbols = calculated_preamble_symbols+4; + _preambleLength = lora_preamble_symbols; + + preamble_e = e; + preamble_m = m; } - buf[0] = (e << 4) | m; + uint8_t buf[7]; + buf[0] = (preamble_e << 4) | preamble_m; buf[1] = headermode; - buf[2] = length; + buf[2] = payload_length; buf[3] = crc; - buf[4] = 0x40; // standard IQ setting (no inversion) - buf[5] = 0x00; // unused params + buf[4] = 0x40; // Standard IQ setting (no inversion) + buf[5] = 0x00; // Unused params buf[6] = 0x00; executeOpcode(OP_PACKET_PARAMS_8X, buf, 7); @@ -847,10 +858,15 @@ void sx128x::setCodingRate4(int denominator) { setModulationParams(_sf, _bw, _cr); } -void sx128x::handleLowDataRate() { } // TODO: Is this needed for SX1280? +extern bool lora_low_datarate; +void sx128x::handleLowDataRate() { + if (_sf > 10) { lora_low_datarate = true; } + else { lora_low_datarate = false; } +} + void sx128x::optimizeModemSensitivity() { } // TODO: Check if there's anything the sx1280 can do here uint8_t sx128x::getCodingRate4() { return _cr + 4; } -void sx128x::setPreambleLength(long length) { _preambleLength = length; setPacketParams(length, _implicitHeaderMode, _payloadLength, _crcMode); } +void sx128x::setPreambleLength(long preamble_symbols) { setPacketParams(preamble_symbols, _implicitHeaderMode, _payloadLength, _crcMode); } void sx128x::setSyncWord(int sw) { } // TODO: Implement void sx128x::enableTCXO() { } // TODO: Need to check how to implement on sx1280 void sx128x::disableTCXO() { } // TODO: Need to check how to implement on sx1280 diff --git a/sx128x.h b/sx128x.h index 8a3e7d1..5977f7d 100644 --- a/sx128x.h +++ b/sx128x.h @@ -67,7 +67,7 @@ public: void setSignalBandwidth(uint32_t sbw); void setCodingRate4(int denominator); uint8_t getCodingRate4(); - void setPreambleLength(long length); + void setPreambleLength(long preamble_symbols); void setSyncWord(int sw); uint8_t modemStatus(); void clearIRQStatus(); @@ -84,7 +84,7 @@ public: void executeOpcodeRead(uint8_t opcode, uint8_t *buffer, uint8_t size); void writeBuffer(const uint8_t* buffer, size_t size); void readBuffer(uint8_t* buffer, size_t size); - void setPacketParams(uint32_t preamble, uint8_t headermode, uint8_t length, uint8_t crc); + void setPacketParams(uint32_t target_preamble_symbols, uint8_t headermode, uint8_t payload_length, uint8_t crc); void setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr); void crc() { enableCrc(); }