mirror of
https://github.com/markqvist/RNode_Firmware.git
synced 2025-05-04 23:55:18 -04:00
Reworked SX1262 LoRa carrier detection
This commit is contained in:
parent
e40532ed35
commit
08651f92f7
7 changed files with 70 additions and 65 deletions
6
Boards.h
6
Boards.h
|
@ -13,6 +13,12 @@
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// TODO: Remove debug setup
|
||||||
|
#define PIN_PREAMBLE 7
|
||||||
|
#define PIN_HEADER 6
|
||||||
|
#define PIN_DCD 5
|
||||||
|
#define PIN_TXSIG 4
|
||||||
|
|
||||||
#include "Modem.h"
|
#include "Modem.h"
|
||||||
|
|
||||||
#ifndef BOARDS_H
|
#ifndef BOARDS_H
|
||||||
|
|
4
Config.h
4
Config.h
|
@ -70,6 +70,8 @@
|
||||||
const int lora_rx_turnaround_ms = 66;
|
const int lora_rx_turnaround_ms = 66;
|
||||||
const int lora_post_tx_yield_slots = 6;
|
const int lora_post_tx_yield_slots = 6;
|
||||||
uint32_t post_tx_yield_timeout = 0;
|
uint32_t post_tx_yield_timeout = 0;
|
||||||
|
#define PHY_HEADER_LORA_SYMBOLS 20
|
||||||
|
#define PHY_CRC_LORA_BITS 16
|
||||||
#define LORA_PREAMBLE_SYMBOLS_MIN 18
|
#define LORA_PREAMBLE_SYMBOLS_MIN 18
|
||||||
#define LORA_PREAMBLE_TARGET_MS 15
|
#define LORA_PREAMBLE_TARGET_MS 15
|
||||||
#define LORA_CAD_SYMBOLS 3
|
#define LORA_CAD_SYMBOLS 3
|
||||||
|
@ -78,6 +80,8 @@
|
||||||
#define CSMA_SLOT_MIN_MS 24
|
#define CSMA_SLOT_MIN_MS 24
|
||||||
|
|
||||||
long lora_preamble_symbols = 12;
|
long lora_preamble_symbols = 12;
|
||||||
|
long lora_preamble_time_ms = 0;
|
||||||
|
long lora_header_time_ms = 0;
|
||||||
float lora_symbol_time_ms = 0.0;
|
float lora_symbol_time_ms = 0.0;
|
||||||
float lora_symbol_rate = 0.0;
|
float lora_symbol_rate = 0.0;
|
||||||
float lora_us_per_byte = 0.0;
|
float lora_us_per_byte = 0.0;
|
||||||
|
|
8
Makefile
8
Makefile
|
@ -156,8 +156,8 @@ upload-tbeam_sx1262:
|
||||||
arduino-cli upload -p /dev/ttyACM0 --fqbn esp32:esp32:t-beam
|
arduino-cli upload -p /dev/ttyACM0 --fqbn esp32:esp32:t-beam
|
||||||
@sleep 1
|
@sleep 1
|
||||||
rnodeconf /dev/ttyACM0 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.t-beam/RNode_Firmware.ino.bin)
|
rnodeconf /dev/ttyACM0 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.t-beam/RNode_Firmware.ino.bin)
|
||||||
@sleep 3
|
#@sleep 3
|
||||||
python ./Release/esptool/esptool.py --chip esp32 --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
|
#python ./Release/esptool/esptool.py --chip esp32 --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-lora32_v10:
|
upload-lora32_v10:
|
||||||
arduino-cli upload -p /dev/ttyUSB0 --fqbn esp32:esp32:ttgo-lora32
|
arduino-cli upload -p /dev/ttyUSB0 --fqbn esp32:esp32:ttgo-lora32
|
||||||
|
@ -188,9 +188,9 @@ upload-heltec32_v2:
|
||||||
python ./Release/esptool/esptool.py --chip esp32 --port /dev/ttyUSB1 --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
|
python ./Release/esptool/esptool.py --chip esp32 --port /dev/ttyUSB1 --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-heltec32_v3:
|
upload-heltec32_v3:
|
||||||
arduino-cli upload -p /dev/ttyUSB1 --fqbn esp32:esp32:heltec_wifi_lora_32_V3
|
arduino-cli upload -p /dev/ttyUSB2 --fqbn esp32:esp32:heltec_wifi_lora_32_V3
|
||||||
@sleep 1
|
@sleep 1
|
||||||
rnodeconf /dev/ttyUSB1 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.heltec_wifi_lora_32_V3/RNode_Firmware.ino.bin)
|
rnodeconf /dev/ttyUSB2 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.heltec_wifi_lora_32_V3/RNode_Firmware.ino.bin)
|
||||||
#@sleep 3
|
#@sleep 3
|
||||||
#python ./Release/esptool/esptool.py --chip esp32-s3 --port /dev/ttyUSB0 --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
|
#python ./Release/esptool/esptool.py --chip esp32-s3 --port /dev/ttyUSB0 --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
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,13 @@ char sbuf[128];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
|
// TODO: Remove debug setup
|
||||||
|
pinMode(PIN_PREAMBLE, OUTPUT);
|
||||||
|
pinMode(PIN_HEADER, OUTPUT);
|
||||||
|
pinMode(PIN_DCD, OUTPUT);
|
||||||
|
pinMode(PIN_TXSIG, OUTPUT);
|
||||||
|
///////////////////////////
|
||||||
|
|
||||||
#if MCU_VARIANT == MCU_ESP32
|
#if MCU_VARIANT == MCU_ESP32
|
||||||
boot_seq();
|
boot_seq();
|
||||||
EEPROM.begin(EEPROM_SIZE);
|
EEPROM.begin(EEPROM_SIZE);
|
||||||
|
@ -516,6 +523,10 @@ bool queueFull() {
|
||||||
volatile bool queue_flushing = false;
|
volatile bool queue_flushing = false;
|
||||||
void flushQueue(void) {
|
void flushQueue(void) {
|
||||||
if (!queue_flushing) {
|
if (!queue_flushing) {
|
||||||
|
|
||||||
|
// TODO: Remove debug
|
||||||
|
digitalWrite(PIN_TXSIG, HIGH);
|
||||||
|
|
||||||
queue_flushing = true;
|
queue_flushing = true;
|
||||||
|
|
||||||
led_tx_on();
|
led_tx_on();
|
||||||
|
@ -557,8 +568,6 @@ void flushQueue(void) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PHY_HEADER_LORA_SYMBOLS 20
|
|
||||||
#define PHY_CRC_LORA_BITS 16
|
|
||||||
void add_airtime(uint16_t written) {
|
void add_airtime(uint16_t written) {
|
||||||
#if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52
|
#if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52
|
||||||
float lora_symbols = 0;
|
float lora_symbols = 0;
|
||||||
|
@ -1197,7 +1206,7 @@ void updateModemStatus() {
|
||||||
portENTER_CRITICAL();
|
portENTER_CRITICAL();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint8_t status = LoRa->modemStatus();
|
bool carrier_detected = LoRa->dcd();
|
||||||
current_rssi = LoRa->currentRssi();
|
current_rssi = LoRa->currentRssi();
|
||||||
last_status_update = millis();
|
last_status_update = millis();
|
||||||
|
|
||||||
|
@ -1207,47 +1216,13 @@ void updateModemStatus() {
|
||||||
portEXIT_CRITICAL();
|
portEXIT_CRITICAL();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((status & SIG_DETECT) == SIG_DETECT) { stat_signal_detected = true; } else { stat_signal_detected = false; }
|
if (carrier_detected) { dcd = true; digitalWrite(PIN_DCD, HIGH); /* TODO: Remove debug */ }
|
||||||
if ((status & SIG_SYNCED) == SIG_SYNCED) { stat_signal_synced = true; } else { stat_signal_synced = false; }
|
else { dcd = false; digitalWrite(PIN_DCD, LOW); /* TODO: Remove debug */ }
|
||||||
if ((status & RX_ONGOING) == RX_ONGOING) { stat_rx_ongoing = true; } else { stat_rx_ongoing = false; }
|
|
||||||
|
|
||||||
// if (stat_signal_detected || stat_signal_synced || stat_rx_ongoing) {
|
dcd_led = dcd;
|
||||||
if (stat_signal_detected || stat_signal_synced) {
|
if (dcd_led) { led_rx_on(); }
|
||||||
if (stat_rx_ongoing) {
|
else { if (airtime_lock) { led_indicate_airtime_lock(); }
|
||||||
if (dcd_count < dcd_threshold) {
|
else { led_rx_off(); } }
|
||||||
dcd_count++;
|
|
||||||
} else {
|
|
||||||
last_dcd = last_status_update;
|
|
||||||
dcd_led = true;
|
|
||||||
dcd = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
#define DCD_LED_STEP_D 3
|
|
||||||
if (dcd_count == 0) {
|
|
||||||
dcd_led = false;
|
|
||||||
} else if (dcd_count > DCD_LED_STEP_D) {
|
|
||||||
dcd_count -= DCD_LED_STEP_D;
|
|
||||||
} else {
|
|
||||||
dcd_count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (last_status_update > last_dcd+csma_slot_ms) {
|
|
||||||
dcd = false;
|
|
||||||
dcd_led = false;
|
|
||||||
dcd_count = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dcd_led) {
|
|
||||||
led_rx_on();
|
|
||||||
} else {
|
|
||||||
if (airtime_lock) {
|
|
||||||
led_indicate_airtime_lock();
|
|
||||||
} else {
|
|
||||||
led_rx_off();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkModemStatus() {
|
void checkModemStatus() {
|
||||||
|
@ -1463,6 +1438,7 @@ void loop() {
|
||||||
if (!airtime_lock) {
|
if (!airtime_lock) {
|
||||||
if (queue_height > 0) {
|
if (queue_height > 0) {
|
||||||
#if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52
|
#if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52
|
||||||
|
|
||||||
long check_time = millis();
|
long check_time = millis();
|
||||||
if (check_time > post_tx_yield_timeout) {
|
if (check_time > post_tx_yield_timeout) {
|
||||||
if (dcd_waiting && (check_time >= dcd_wait_until)) { dcd_waiting = false; }
|
if (dcd_waiting && (check_time >= dcd_wait_until)) { dcd_waiting = false; }
|
||||||
|
@ -1486,7 +1462,7 @@ void loop() {
|
||||||
#else
|
#else
|
||||||
if (!dcd_waiting) updateModemStatus();
|
if (!dcd_waiting) updateModemStatus();
|
||||||
|
|
||||||
if (!dcd && !dcd_led) {
|
if (!dcd) {
|
||||||
if (dcd_waiting) delay(lora_rx_turnaround_ms);
|
if (dcd_waiting) delay(lora_rx_turnaround_ms);
|
||||||
|
|
||||||
updateModemStatus();
|
updateModemStatus();
|
||||||
|
|
|
@ -864,7 +864,7 @@ void kiss_indicate_phy_stats() {
|
||||||
uint16_t lst = (uint16_t)(lora_symbol_time_ms*1000);
|
uint16_t lst = (uint16_t)(lora_symbol_time_ms*1000);
|
||||||
uint16_t lsr = (uint16_t)(lora_symbol_rate);
|
uint16_t lsr = (uint16_t)(lora_symbol_rate);
|
||||||
uint16_t prs = (uint16_t)(lora_preamble_symbols);
|
uint16_t prs = (uint16_t)(lora_preamble_symbols);
|
||||||
uint16_t prt = (uint16_t)((lora_preamble_symbols)*lora_symbol_time_ms);
|
uint16_t prt = (uint16_t)(lora_preamble_time_ms);
|
||||||
uint16_t cst = (uint16_t)(csma_slot_ms);
|
uint16_t cst = (uint16_t)(csma_slot_ms);
|
||||||
serial_write(FEND);
|
serial_write(FEND);
|
||||||
serial_write(CMD_STAT_PHYPRM);
|
serial_write(CMD_STAT_PHYPRM);
|
||||||
|
@ -1102,6 +1102,8 @@ void updateBitrate() {
|
||||||
|
|
||||||
lora_preamble_symbols = (long)target_preamble_symbols;
|
lora_preamble_symbols = (long)target_preamble_symbols;
|
||||||
setPreamble();
|
setPreamble();
|
||||||
|
lora_preamble_time_ms = (ceil)(lora_preamble_symbols * lora_symbol_time_ms);
|
||||||
|
lora_header_time_ms = (ceil)(PHY_HEADER_LORA_SYMBOLS * lora_symbol_time_ms);
|
||||||
} else {
|
} else {
|
||||||
lora_bitrate = 0;
|
lora_bitrate = 0;
|
||||||
}
|
}
|
||||||
|
|
47
sx126x.cpp
47
sx126x.cpp
|
@ -97,7 +97,7 @@ extern SPIClass SPI;
|
||||||
#define MAX_PKT_LENGTH 255
|
#define MAX_PKT_LENGTH 255
|
||||||
|
|
||||||
sx126x::sx126x() :
|
sx126x::sx126x() :
|
||||||
_spiSettings(8E6, MSBFIRST, SPI_MODE0),
|
_spiSettings(16E6, MSBFIRST, SPI_MODE0),
|
||||||
_ss(LORA_DEFAULT_SS_PIN), _reset(LORA_DEFAULT_RESET_PIN), _dio0(LORA_DEFAULT_DIO0_PIN), _busy(LORA_DEFAULT_BUSY_PIN), _rxen(LORA_DEFAULT_RXEN_PIN),
|
_ss(LORA_DEFAULT_SS_PIN), _reset(LORA_DEFAULT_RESET_PIN), _dio0(LORA_DEFAULT_DIO0_PIN), _busy(LORA_DEFAULT_BUSY_PIN), _rxen(LORA_DEFAULT_RXEN_PIN),
|
||||||
_frequency(0),
|
_frequency(0),
|
||||||
_txp(0),
|
_txp(0),
|
||||||
|
@ -293,11 +293,11 @@ void sx126x::calibrate(void) {
|
||||||
|
|
||||||
void sx126x::calibrate_image(long frequency) {
|
void sx126x::calibrate_image(long frequency) {
|
||||||
uint8_t image_freq[2] = {0};
|
uint8_t image_freq[2] = {0};
|
||||||
if (frequency >= 430E6 && frequency <= 440E6) { image_freq[0] = 0x6B; image_freq[1] = 0x6F; }
|
if (frequency >= 430E6 && frequency <= 440E6) { image_freq[0] = 0x6B; image_freq[1] = 0x6F; }
|
||||||
else if (frequency >= 470E6 && frequency <= 510E6) { image_freq[0] = 0x75; image_freq[1] = 0x81; }
|
else if (frequency >= 470E6 && frequency <= 510E6) { image_freq[0] = 0x75; image_freq[1] = 0x81; }
|
||||||
else if (frequency >= 779E6 && frequency <= 787E6) { image_freq[0] = 0xC1; image_freq[1] = 0xC5; }
|
else if (frequency >= 779E6 && frequency <= 787E6) { image_freq[0] = 0xC1; image_freq[1] = 0xC5; }
|
||||||
else if (frequency >= 863E6 && frequency <= 870E6) { image_freq[0] = 0xD7; image_freq[1] = 0xDB; }
|
else if (frequency >= 863E6 && frequency <= 870E6) { image_freq[0] = 0xD7; image_freq[1] = 0xDB; }
|
||||||
else if (frequency >= 902E6 && frequency <= 928E6) { image_freq[0] = 0xE1; image_freq[1] = 0xE9; }
|
else if (frequency >= 902E6 && frequency <= 928E6) { image_freq[0] = 0xE1; image_freq[1] = 0xE9; } // TODO: Allow higher freq calibration
|
||||||
executeOpcode(OP_CALIBRATE_IMAGE_6X, image_freq, 2);
|
executeOpcode(OP_CALIBRATE_IMAGE_6X, image_freq, 2);
|
||||||
waitOnBusy();
|
waitOnBusy();
|
||||||
}
|
}
|
||||||
|
@ -372,6 +372,9 @@ int sx126x::endPacket() {
|
||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Remove debug
|
||||||
|
digitalWrite(PIN_TXSIG, LOW);
|
||||||
|
|
||||||
if (!(millis() < w_timeout)) { timed_out = true; }
|
if (!(millis() < w_timeout)) { timed_out = true; }
|
||||||
|
|
||||||
// Clear IRQs
|
// Clear IRQs
|
||||||
|
@ -382,27 +385,41 @@ int sx126x::endPacket() {
|
||||||
if (timed_out) { return 0; } else { return 1; }
|
if (timed_out) { return 0; } else { return 1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t sx126x::modemStatus() {
|
unsigned long preamble_detected_at = 0;
|
||||||
// Imitate the register status from the sx1276 / 78
|
unsigned long header_detected_at = 0;
|
||||||
uint8_t buf[2] = {0};
|
extern long lora_preamble_time_ms;
|
||||||
executeOpcodeRead(OP_GET_IRQ_STATUS_6X, buf, 2);
|
extern long lora_header_time_ms;
|
||||||
uint8_t clearbuf[2] = {0};
|
bool sx126x::dcd() {
|
||||||
uint8_t byte = 0x00;
|
bool carrier_detected = false;
|
||||||
|
uint8_t buf[2] = {0}; executeOpcodeRead(OP_GET_IRQ_STATUS_6X, buf, 2);
|
||||||
|
|
||||||
if ((buf[1] & IRQ_PREAMBLE_DET_MASK_6X) != 0) {
|
if ((buf[1] & IRQ_PREAMBLE_DET_MASK_6X) != 0) {
|
||||||
byte = byte | 0x01 | 0x04;
|
carrier_detected = true;
|
||||||
clearbuf[1] = IRQ_PREAMBLE_DET_MASK_6X; // Clear register after reading
|
if (preamble_detected_at == 0) preamble_detected_at = millis();
|
||||||
|
if (millis() - preamble_detected_at > lora_preamble_time_ms + lora_header_time_ms) {
|
||||||
|
preamble_detected_at = 0;
|
||||||
|
uint8_t clearbuf[2] = {0};
|
||||||
|
clearbuf[1] = IRQ_PREAMBLE_DET_MASK_6X;
|
||||||
|
executeOpcode(OP_CLEAR_IRQ_STATUS_6X, clearbuf, 2);
|
||||||
|
}
|
||||||
|
// TODO: Remove
|
||||||
|
digitalWrite(PIN_PREAMBLE, HIGH);
|
||||||
|
} else {
|
||||||
|
digitalWrite(PIN_PREAMBLE, LOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((buf[1] & IRQ_HEADER_DET_MASK_6X) != 0) {
|
if ((buf[1] & IRQ_HEADER_DET_MASK_6X) != 0) {
|
||||||
byte = byte | 0x02 | 0x04;
|
carrier_detected = true;
|
||||||
|
header_detected_at = millis();
|
||||||
|
// TODO: Remove
|
||||||
|
digitalWrite(PIN_HEADER, HIGH);
|
||||||
|
} else {
|
||||||
|
digitalWrite(PIN_HEADER, LOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
executeOpcode(OP_CLEAR_IRQ_STATUS_6X, clearbuf, 2);
|
return carrier_detected;
|
||||||
return byte;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t sx126x::currentRssiRaw() {
|
uint8_t sx126x::currentRssiRaw() {
|
||||||
uint8_t byte = 0;
|
uint8_t byte = 0;
|
||||||
executeOpcodeRead(OP_CURRENT_RSSI_6X, &byte, 1);
|
executeOpcodeRead(OP_CURRENT_RSSI_6X, &byte, 1);
|
||||||
|
|
2
sx126x.h
2
sx126x.h
|
@ -68,7 +68,7 @@ public:
|
||||||
void setCodingRate4(int denominator);
|
void setCodingRate4(int denominator);
|
||||||
void setPreambleLength(long preamble_symbols);
|
void setPreambleLength(long preamble_symbols);
|
||||||
void setSyncWord(uint16_t sw);
|
void setSyncWord(uint16_t sw);
|
||||||
uint8_t modemStatus();
|
bool dcd();
|
||||||
void enableCrc();
|
void enableCrc();
|
||||||
void disableCrc();
|
void disableCrc();
|
||||||
void enableTCXO();
|
void enableTCXO();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue