mirror of
https://github.com/liberatedsystems/RNode_Firmware_CE.git
synced 2025-03-15 19:06:05 -04:00
Accurate preamble and airtime calculations on SX1280. Fix airtime calculation on SX1262 when LDRO is enabled.
This commit is contained in:
parent
b667e825f8
commit
c39164e272
@ -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
|
||||
}
|
||||
|
||||
|
20
Utilities.h
20
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();
|
||||
|
24
sx126x.cpp
24
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) {
|
||||
|
4
sx126x.h
4
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);
|
||||
|
||||
|
@ -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<<sf) / (getSignalBandwidth()/1000)) > 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
2
sx127x.h
2
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();
|
||||
|
60
sx128x.cpp
60
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
|
||||
|
4
sx128x.h
4
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(); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user