From 379dce99b351fe70240ea197dc3b8331389a8943 Mon Sep 17 00:00:00 2001 From: "jacob.eva" Date: Wed, 3 Jul 2024 11:06:52 +0100 Subject: [PATCH] Fix various SX1280 issues, revamp RX ISR flow --- Boards.h | 5 +- Config.h | 3 + Display.h | 38 +++++++++--- RNode_Firmware_CE.ino | 131 +++++++++++++++++++++++++++--------------- Radio.cpp | 76 ++++++++++++++++-------- Radio.h | 16 +++++- Utilities.h | 51 ++++++++++++++++ 7 files changed, 236 insertions(+), 84 deletions(-) diff --git a/Boards.h b/Boards.h index 7321269..8af9fab 100644 --- a/Boards.h +++ b/Boards.h @@ -626,9 +626,8 @@ #define HAS_PMU true #define HAS_NP false #define HAS_SD false - #define HAS_RF_SWITCH_RX_TX true #define CONFIG_UART_BUFFER_SIZE 6144 - #define CONFIG_QUEUE_SIZE 6144 + #define CONFIG_QUEUE_0_SIZE 6144 #define CONFIG_QUEUE_MAX_LENGTH 200 #define EEPROM_SIZE 296 #define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED @@ -647,7 +646,7 @@ true // DIO2_AS_RF_SWITCH } }; - const uint8_t interface_pins[INTERFACE_COUNT][10] = { + const int8_t interface_pins[INTERFACE_COUNT][10] = { // SX1262 { 42, // pin_ss diff --git a/Config.h b/Config.h index f0bb09c..53e985f 100644 --- a/Config.h +++ b/Config.h @@ -100,6 +100,9 @@ uint32_t stat_rx = 0; uint32_t stat_tx = 0; + unsigned long last_tx = 0; + unsigned long last_rx = 0; + // Power management #define BATTERY_STATE_DISCHARGING 0x01 #define BATTERY_STATE_CHARGING 0x02 diff --git a/Display.h b/Display.h index 54f53b2..9bc0098 100644 --- a/Display.h +++ b/Display.h @@ -143,6 +143,10 @@ const uint8_t pages = 3; uint8_t disp_page = START_PAGE; uint8_t interface_page = START_PAGE; +uint8_t* online_interface_list; + +uint8_t online_interfaces = 0; + #if DISPLAY == OLED #define WATERFALL_SIZE 46 #elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C) @@ -369,7 +373,7 @@ void draw_lora_icon(RadioInterface* radio, int px, int py) { // todo: make display show other interfaces if (radio_online) { #if DISPLAY == OLED - if (interface_page == radio->getIndex()) { + if (online_interface_list[interface_page] == radio->getIndex()) { stat_area.drawBitmap(px - 2, py - 2, bm_dot_sqr, 18, 18, GxEPD_WHITE, GxEPD_BLACK); // redraw stat area on next refresh @@ -381,7 +385,7 @@ void draw_lora_icon(RadioInterface* radio, int px, int py) { stat_area.drawBitmap(px, py, bm_rf+0*32, 16, 16, GxEPD_WHITE, GxEPD_BLACK); } #elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C) - if (interface_page == radio->getIndex()) { + if (online_interface_list[interface_page] == radio->getIndex()) { stat_area.drawBitmap(px - 2, py - 2, bm_dot_sqr, 34, 36, GxEPD_WHITE, GxEPD_BLACK); // redraw stat area on next refresh @@ -666,19 +670,38 @@ void draw_stat_area() { } if (millis()-last_interface_page_flip >= page_interval) { - int online_interfaces = 0; + int online_interfaces_check = 0; + + // todo, is there a more efficient way of doing this? for (int i = 0; i < INTERFACE_COUNT; i++) { if (interface_obj[i]->getRadioOnline()) { - online_interfaces++; + online_interfaces_check++; } } + if (online_interfaces != online_interfaces_check) { + online_interfaces = online_interfaces_check; + } + // cap at two for now, as only two boxes to symbolise interfaces // available on display if (online_interfaces > 2) { online_interfaces = 2; } - interface_page = (++interface_page%online_interfaces); + + online_interface_list = (uint8_t*)malloc(online_interfaces); + uint8_t index = 0; + + for (int i = 0; i < INTERFACE_COUNT; i++) { + if (interface_obj[i]->getRadioOnline()) { + online_interface_list[index] = i; + index++; + } + } + + if (online_interfaces > 0) { + interface_page = (++interface_page%online_interfaces); + } last_interface_page_flip = millis(); } @@ -789,7 +812,7 @@ void draw_disp_area() { if (!disp_ext_fb or bt_ssp_pin != 0) { if (radio_online && display_diagnostics) { #if DISPLAY == OLED - selected_radio = interface_obj[interface_page]; + selected_radio = interface_obj[online_interface_list[interface_page]]; disp_area.fillRect(0,8,disp_area.width(),37, SSD1306_BLACK); disp_area.fillRect(0,37,disp_area.width(),27, SSD1306_WHITE); disp_area.setFont(SMALL_FONT); disp_area.setTextWrap(false); disp_area.setTextColor(SSD1306_WHITE); @@ -845,7 +868,7 @@ void draw_disp_area() { disp_area.drawBitmap(32+2, 50, bm_hg_high, 5, 9, SSD1306_BLACK, SSD1306_WHITE); #elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C) - selected_radio = interface_obj[interface_page]; + selected_radio = interface_obj[online_interface_list[interface_page]]; disp_area.fillRect(0,12,disp_area.width(),57, GxEPD_BLACK); disp_area.fillRect(0,69,disp_area.width(),56, GxEPD_WHITE); disp_area.setFont(SMALL_FONT); disp_area.setTextWrap(false); disp_area.setTextColor(GxEPD_WHITE); disp_area.setTextSize(2); // scale text 2x @@ -1096,6 +1119,7 @@ void update_display(bool blank = false) { update_disp_area(); display.display(true); #endif + free(online_interface_list); last_disp_update = millis(); } } diff --git a/RNode_Firmware_CE.ino b/RNode_Firmware_CE.ino index cc4630b..ef9fe1d 100644 --- a/RNode_Firmware_CE.ino +++ b/RNode_Firmware_CE.ino @@ -20,17 +20,13 @@ FIFOBuffer serialFIFO; uint8_t serialBuffer[CONFIG_UART_BUFFER_SIZE+1]; -uint16_t packet_starts_buf[(CONFIG_QUEUE_MAX_LENGTH/INTERFACE_COUNT)+1]; +uint16_t packet_starts_buf[(CONFIG_QUEUE_MAX_LENGTH)+1]; -uint16_t packet_lengths_buf[(CONFIG_QUEUE_MAX_LENGTH/INTERFACE_COUNT)+1]; +uint16_t packet_lengths_buf[(CONFIG_QUEUE_MAX_LENGTH)+1]; FIFOBuffer16 packet_starts[INTERFACE_COUNT]; FIFOBuffer16 packet_lengths[INTERFACE_COUNT]; -// The total queue size is split evenly between all the interfaces. -// todo, bias in size may be needed here for interfaces with higher data rates. -uint8_t packet_queue[INTERFACE_COUNT][CONFIG_QUEUE_SIZE/INTERFACE_COUNT]; - volatile uint8_t queue_height[INTERFACE_COUNT] = {0}; volatile uint16_t queued_bytes[INTERFACE_COUNT] = {0}; @@ -48,7 +44,11 @@ volatile bool serial_buffering = false; char sbuf[128]; bool packet_ready = false; -uint8_t packet_interface; + +volatile bool process_packet = false; +volatile uint8_t packet_interface = 0; + +uint8_t *packet_queue[INTERFACE_COUNT]; void setup() { #if MCU_VARIANT == MCU_ESP32 @@ -112,11 +112,11 @@ void setup() { memset(packet_starts_buf, 0, sizeof(packet_starts_buf)); memset(packet_lengths_buf, 0, sizeof(packet_starts_buf)); - memset(packet_queue, 0, sizeof(packet_queue)); for (int i = 0; i < INTERFACE_COUNT; i++) { - fifo16_init(&packet_starts[i], packet_starts_buf, CONFIG_QUEUE_MAX_LENGTH/INTERFACE_COUNT); - fifo16_init(&packet_lengths[i], packet_lengths_buf, CONFIG_QUEUE_MAX_LENGTH/INTERFACE_COUNT); + fifo16_init(&packet_starts[i], packet_starts_buf, CONFIG_QUEUE_MAX_LENGTH); + fifo16_init(&packet_lengths[i], packet_lengths_buf, CONFIG_QUEUE_MAX_LENGTH); + packet_queue[i] = (uint8_t*)malloc(getQueueSize(i)); } // Create and configure interface objects @@ -378,6 +378,7 @@ void ISR_VECT receive_callback(uint8_t index, int packet_size) { getPacketData(selected_radio, packet_size); packet_ready = true; } + last_rx = millis(); } bool startRadio(RadioInterface* radio) { @@ -442,7 +443,7 @@ void update_radio_lock(RadioInterface* radio) { // Check if the queue is full for the selected radio. // Returns true if full, false if not bool queueFull(RadioInterface* radio) { - return (queue_height[radio->getIndex()] >= (CONFIG_QUEUE_MAX_LENGTH/INTERFACE_COUNT) || queued_bytes[radio->getIndex()] >= (CONFIG_QUEUE_SIZE/INTERFACE_COUNT)); + return (queue_height[radio->getIndex()] >= (CONFIG_QUEUE_MAX_LENGTH) || queued_bytes[radio->getIndex()] >= (getQueueSize(radio->getIndex()))); } volatile bool queue_flushing = false; @@ -463,7 +464,7 @@ void flushQueue(RadioInterface* radio) { if (length >= MIN_L && length <= MTU) { for (uint16_t i = 0; i < length; i++) { - uint16_t pos = (start+i)%(CONFIG_QUEUE_SIZE/INTERFACE_COUNT); + uint16_t pos = (start+i)%(getQueueSize(index)); tbuf[i] = packet_queue[index][pos]; } transmit(radio, length); @@ -538,6 +539,7 @@ void transmit(RadioInterface* radio, uint16_t size) { } radio->endPacket(); radio->addAirtime(written); } + last_tx = millis(); } else { kiss_indicate_error(ERROR_TXFAILED); led_indicate_error(5); @@ -562,13 +564,13 @@ void serialCallback(uint8_t sbyte) { if (getInterfaceIndex(command) < INTERFACE_COUNT) { uint8_t index = getInterfaceIndex(command); - if (!fifo16_isfull(&packet_starts[index]) && queued_bytes[index] < (CONFIG_QUEUE_SIZE/INTERFACE_COUNT)) { + if (!fifo16_isfull(&packet_starts[index]) && queued_bytes[index] < (getQueueSize(index))) { uint16_t s = current_packet_start[index]; - int16_t e = queue_cursor[index]-1; if (e == -1) e = (CONFIG_QUEUE_SIZE/INTERFACE_COUNT)-1; + int16_t e = queue_cursor[index]-1; if (e == -1) e = (getQueueSize(index))-1; uint16_t l; if (s != e) { - l = (s < e) ? e - s + 1: (CONFIG_QUEUE_SIZE/INTERFACE_COUNT) - s + e + 1; + l = (s < e) ? e - s + 1: (getQueueSize(index)) - s + e + 1; } else { l = 1; } @@ -631,10 +633,10 @@ void serialCallback(uint8_t sbyte) { if (getInterfaceIndex(command) < INTERFACE_COUNT) { uint8_t index = getInterfaceIndex(command); - if (queue_height[index] < (CONFIG_QUEUE_MAX_LENGTH/INTERFACE_COUNT) && queued_bytes[index] < (CONFIG_QUEUE_SIZE/INTERFACE_COUNT)) { + if (queue_height[index] < CONFIG_QUEUE_MAX_LENGTH && queued_bytes[index] < (getQueueSize(index))) { queued_bytes[index]++; packet_queue[index][queue_cursor[index]++] = sbyte; - if (queue_cursor[index] == (CONFIG_QUEUE_SIZE/INTERFACE_COUNT)) queue_cursor[index] = 0; + if (queue_cursor[index] == (getQueueSize(index))) queue_cursor[index] = 0; } } } @@ -1133,44 +1135,40 @@ void validate_status() { } } - void loop() { + packet_poll(); + bool ready = false; - for (int i = 0; i < INTERFACE_COUNT; i++) { - selected_radio = interface_obj[i]; - if (selected_radio->getRadioOnline()) { - selected_radio->checkModemStatus(); - ready = true; - } - } + for (int i = 0; i < INTERFACE_COUNT; i++) { + selected_radio = interface_obj[i]; + if (selected_radio->getRadioOnline()) { + selected_radio->checkModemStatus(); + ready = true; + } + } - // if at least one radio is online then we can continue + + // If at least one radio is online then we can continue if (ready) { - #if MCU_VARIANT == MCU_ESP32 if (packet_ready) { selected_radio = interface_obj[packet_interface]; + #if MCU_VARIANT == MCU_ESP32 portENTER_CRITICAL(&update_lock); - last_rssi = selected_radio->packetRssi(); - last_snr_raw = selected_radio->packetSnrRaw(); - portEXIT_CRITICAL(&update_lock); - kiss_indicate_stat_rssi(); - kiss_indicate_stat_snr(); - kiss_write_packet(packet_interface); - } - - #elif MCU_VARIANT == MCU_NRF52 - if (packet_ready) { - selected_radio = interface_obj[packet_interface]; + #elif MCU_VARIANT == MCU_NRF52 portENTER_CRITICAL(); + #endif last_rssi = selected_radio->packetRssi(); last_snr_raw = selected_radio->packetSnrRaw(); + #if MCU_VARIANT == MCU_ESP32 + portEXIT_CRITICAL(&update_lock); + #elif MCU_VARIANT == MCU_NRF52 portEXIT_CRITICAL(); + #endif kiss_indicate_stat_rssi(); kiss_indicate_stat_snr(); kiss_write_packet(packet_interface); } - #endif - + for (int i = 0; i < INTERFACE_COUNT; i++) { selected_radio = interface_obj_sorted[i]; @@ -1182,13 +1180,11 @@ void loop() { // If a higher data rate interface has received a packet after its // loop, it still needs to be the first to transmit, so check if this // is the case. - if (i != 0) { - for (int j = 0; j < INTERFACE_COUNT; j++) { - if (!interface_obj_sorted[j]->calculateALock() || interface_obj_sorted[j]->getRadioOnline()) { - if (interface_obj_sorted[j]->getBitrate() > selected_radio->getBitrate()) { - if (queue_height[interface_obj_sorted[j]->getIndex()] > 0) { - selected_radio = interface_obj_sorted[j]; - } + for (int j = 0; j < INTERFACE_COUNT; j++) { + if (!interface_obj_sorted[j]->calculateALock() || interface_obj_sorted[j]->getRadioOnline()) { + if (interface_obj_sorted[j]->getBitrate() > selected_radio->getBitrate()) { + if (queue_height[interface_obj_sorted[j]->getIndex()] > 0) { + selected_radio = interface_obj_sorted[j]; } } } @@ -1241,7 +1237,24 @@ void loop() { if (!fifo_isempty(&serialFIFO)) serial_poll(); #if HAS_DISPLAY + #if DISPLAY == OLED if (disp_ready) update_display(); + #elif DISPLAY == EINK_BW || DISPLAY == EINK_3C + // Display refreshes take so long on e-paper displays that they can disrupt + // the regular operation of the device. To combat this the time it is + // chosen to do so must be strategically chosen. Particularly on the + // RAK4631, the display and the potentially installed SX1280 modem share + // the same SPI bus. Thus it is not possible to solve this by utilising the + // callback functionality to poll the modem in this case. todo, this may be + // able to be improved in the future. + if (disp_ready) { + if (millis() - last_tx >= 4000) { + if (millis() - last_rx >= 1000) { + update_display(); + } + } + } + #endif #endif #if HAS_PMU @@ -1283,6 +1296,30 @@ void button_event(uint8_t event, unsigned long duration) { } } +void poll_buffers() { + process_serial(); +} + +void packet_poll() { + #if MCU_VARIANT == MCU_ESP32 + portENTER_CRITICAL(&update_lock); + #elif MCU_VARIANT == MCU_NRF52 + portENTER_CRITICAL(); + #endif + // If we have received a packet on an interface which needs to be processed + if (process_packet) { + selected_radio = interface_obj[packet_interface]; + selected_radio->clearIRQStatus(); + selected_radio->handleDio0Rise(); + process_packet = false; + } + #if MCU_VARIANT == MCU_ESP32 + portEXIT_CRITICAL(&update_lock); + #elif MCU_VARIANT == MCU_NRF52 + portEXIT_CRITICAL(); + #endif +} + volatile bool serial_polling = false; void serial_poll() { serial_polling = true; diff --git a/Radio.cpp b/Radio.cpp index d1ee1c4..f7bd4fc 100644 --- a/Radio.cpp +++ b/Radio.cpp @@ -15,8 +15,6 @@ #define ISR_VECT #endif -#define MAX_PKT_LENGTH 255 - // SX126x registers #define OP_RF_FREQ_6X 0x86 #define OP_SLEEP_6X 0x84 @@ -90,19 +88,19 @@ #define FREQ_DIV_6X (double)pow(2.0, 25.0) #define FREQ_STEP_6X (double)(XTAL_FREQ_6X / FREQ_DIV_6X) -extern int packet_interface; +extern bool process_packet; +extern uint8_t packet_interface; extern RadioInterface* interface_obj[]; // ISRs cannot provide parameters to the functions they call. Since we have -// multiple radio objects, we have to read each dio0 pin for each one and see +// multiple interfaces, we have to read each dio0 pin for each one and see // which one is high. We can then use the index of this pin in the 2D array to -// call the correct object. -void onDio0Rise() { +// signal the correct interface to the main loop +void ISR_VECT onDio0Rise() { for (int i = 0; i < INTERFACE_COUNT; i++) { if (digitalRead(interface_pins[i][5]) == HIGH) { + process_packet = true; packet_interface = i; - RadioInterface* obj = interface_obj[i]; - obj->handleDio0Rise(); break; } } @@ -110,14 +108,13 @@ void onDio0Rise() { sx126x::sx126x(uint8_t index, SPIClass spi, bool tcxo, bool dio2_as_rf_switch, int ss, int sclk, int mosi, int miso, int reset, int dio0, int busy, int rxen) : RadioInterface(index), - _spiSettings(8E6, MSBFIRST, SPI_MODE0), - _spiModem(spi), - _ss(ss), _sclk(sclk), _mosi(mosi), _miso(miso), _reset(reset), _dio0(dio0), - _busy(busy), _rxen(rxen), _frequency(0), _txp(0), _sf(0x07), _bw(0x04), - _cr(0x01), _ldro(0x00), _packetIndex(0), _implicitHeaderMode(0), - _payloadLength(255), _crcMode(1), _fifo_tx_addr_ptr(0), _fifo_rx_addr_ptr(0), - _packet({0}), _preinit_done(false), _tcxo(tcxo), - _dio2_as_rf_switch(dio2_as_rf_switch) + _spiSettings(8E6, MSBFIRST, SPI_MODE0), _spiModem(spi), _ss(ss), + _sclk(sclk), _mosi(mosi), _miso(miso), _reset(reset), _dio0(dio0), + _busy(busy), _rxen(rxen), _frequency(0), _txp(0), _sf(0x07), _bw(0x04), + _cr(0x01), _ldro(0x00), _packetIndex(0), _implicitHeaderMode(0), + _payloadLength(255), _crcMode(1), _fifo_tx_addr_ptr(0), + _fifo_rx_addr_ptr(0), _preinit_done(false), _tcxo(tcxo), + _dio2_as_rf_switch(dio2_as_rf_switch) { // overide Stream timeout value setTimeout(0); @@ -966,7 +963,7 @@ void sx126x::implicitHeaderMode() } -void ISR_VECT sx126x::handleDio0Rise() +void sx126x::handleDio0Rise() { uint8_t buf[2]; @@ -1017,6 +1014,16 @@ void sx126x::updateBitrate() { } } +void sx126x::clearIRQStatus() { + uint8_t buf[2]; + + buf[0] = 0x00; + buf[1] = 0x00; + + executeOpcodeRead(OP_GET_IRQ_STATUS_6X, buf, 2); + + executeOpcode(OP_CLEAR_IRQ_STATUS_6X, buf, 2); +} // SX127x registers #define REG_FIFO_7X 0x00 #define REG_OP_MODE_7X 0x01 @@ -1507,7 +1514,7 @@ void sx127x::optimizeModemSensitivity() { } } -void ISR_VECT sx127x::handleDio0Rise() { +void sx127x::handleDio0Rise() { int irqFlags = readRegister(REG_IRQ_FLAGS_7X); // Clear IRQs @@ -1542,6 +1549,10 @@ void sx127x::updateBitrate() { } } +void sx127x::clearIRQStatus() { + // todo, implement +} + // SX128x registers #define OP_RF_FREQ_8X 0x86 #define OP_SLEEP_8X 0x84 @@ -1590,10 +1601,10 @@ sx128x::sx128x(uint8_t index, SPIClass spi, bool tcxo, int ss, int sclk, int mos _spiSettings(8E6, MSBFIRST, SPI_MODE0), _spiModem(spi), _ss(ss), _sclk(sclk), _mosi(mosi), _miso(miso), _reset(reset), _dio0(dio0), - _busy(busy), _rxen(rxen), _txen(txen), _frequency(0), _txp(0), _sf(0x50), + _busy(busy), _rxen(rxen), _txen(txen), _frequency(0), _txp(0), _sf(0x05), _bw(0x34), _cr(0x01), _packetIndex(0), _implicitHeaderMode(0), _payloadLength(255), _crcMode(0), _fifo_tx_addr_ptr(0), _fifo_rx_addr_ptr(0), - _packet({0}), _rxPacketLength(0), _preinit_done(false), + _rxPacketLength(0), _preinit_done(false), _tcxo(tcxo) { // overide Stream timeout value @@ -2137,7 +2148,7 @@ void sx128x::receive(int size) implicitHeaderMode(); // tell radio payload length - _rxPacketLength = size; + //_rxPacketLength = size; //_payloadLength = size; //setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); } else { @@ -2358,7 +2369,7 @@ void sx128x::implicitHeaderMode() } -void ISR_VECT sx128x::handleDio0Rise() +void sx128x::handleDio0Rise() { uint8_t buf[2]; @@ -2392,8 +2403,14 @@ void sx128x::updateBitrate() { _lora_symbol_time_ms = (1.0/_lora_symbol_rate)*1000.0; _bitrate = (uint32_t)(_sf * ( (4.0/(float)(_cr+4)) / ((float)(pow(2, _sf))/((float)getSignalBandwidth()/1000.0)) ) * 1000.0); _lora_us_per_byte = 1000000.0/((float)_bitrate/8.0); - //_csma_slot_ms = _lora_symbol_time_ms*10; - float target_preamble_symbols = (LORA_PREAMBLE_TARGET_MS/_lora_symbol_time_ms)-LORA_PREAMBLE_SYMBOLS_HW; + _csma_slot_ms = 10; + + float target_preamble_symbols; + if (_bitrate <= LORA_FAST_BITRATE_THRESHOLD) { + target_preamble_symbols = (LORA_PREAMBLE_TARGET_MS/_lora_symbol_time_ms)-LORA_PREAMBLE_SYMBOLS_HW; + } else { + target_preamble_symbols = (LORA_PREAMBLE_FAST_TARGET_MS/_lora_symbol_time_ms)-LORA_PREAMBLE_SYMBOLS_HW; + } if (target_preamble_symbols < LORA_PREAMBLE_SYMBOLS_MIN) { target_preamble_symbols = LORA_PREAMBLE_SYMBOLS_MIN; } else { @@ -2405,3 +2422,14 @@ void sx128x::updateBitrate() { _bitrate = 0; } } + +void sx128x::clearIRQStatus() { + uint8_t buf[2]; + + buf[0] = 0x00; + buf[1] = 0x00; + + executeOpcodeRead(OP_GET_IRQ_STATUS_8X, buf, 2); + + executeOpcode(OP_CLEAR_IRQ_STATUS_8X, buf, 2); +} diff --git a/Radio.h b/Radio.h index 94e47bc..9b88114 100644 --- a/Radio.h +++ b/Radio.h @@ -12,6 +12,8 @@ #include "Interfaces.h" #include "Boards.h" +#define MAX_PKT_LENGTH 255 + // TX #define PA_OUTPUT_RFO_PIN 0 #define PA_OUTPUT_PA_BOOST_PIN 1 @@ -31,6 +33,8 @@ #define LORA_PREAMBLE_SYMBOLS_HW 4 #define LORA_PREAMBLE_SYMBOLS_MIN 18 #define LORA_PREAMBLE_TARGET_MS 15 +#define LORA_PREAMBLE_FAST_TARGET_MS 1 +#define LORA_FAST_BITRATE_THRESHOLD 40000 #define RSSI_OFFSET 157 @@ -46,6 +50,7 @@ const uint8_t RX_ONGOING = 0x04; // forward declare Utilities.h LED functions void led_rx_on(); + void led_rx_off(); void led_indicate_airtime_lock(); @@ -68,7 +73,7 @@ public: _post_tx_yield_timeout(0), _csma_slot_ms(50), _csma_p_min(0.1), _csma_p_max(0.8), _preambleLength(6), _lora_symbol_time_ms(0.0), _lora_symbol_rate(0.0), _lora_us_per_byte(0.0), _bitrate(0), - _onReceive(NULL) {}; + _onReceive(NULL), _packet{0} {}; virtual int begin(); virtual void end(); @@ -123,6 +128,7 @@ public: virtual void updateBitrate(); virtual void handleDio0Rise(); + virtual void clearIRQStatus(); uint32_t getBitrate() { return _bitrate; }; uint8_t getIndex() { return _index; }; void setRadioLock(bool lock) { _radio_locked = lock; }; @@ -248,6 +254,7 @@ public: _dcd_count = 0; } } + if (_dcd_led) { led_rx_on(); @@ -320,6 +327,7 @@ protected: float _lora_symbol_rate; float _lora_us_per_byte; uint32_t _bitrate; + uint8_t _packet[255]; void (*_onReceive)(uint8_t, int); }; @@ -413,6 +421,7 @@ private: void reset(void); void calibrate(void); void calibrate_image(uint32_t frequency); + void clearIRQStatus(); private: SPISettings _spiSettings; @@ -437,7 +446,6 @@ private: int _crcMode; int _fifo_tx_addr_ptr; int _fifo_rx_addr_ptr; - uint8_t _packet[255]; bool _preinit_done; uint8_t _index; bool _tcxo; @@ -503,6 +511,7 @@ public: void updateBitrate(); void handleDio0Rise(); + void clearIRQStatus(); private: void setSyncWord(uint8_t sw); void explicitHeaderMode(); @@ -598,6 +607,8 @@ public: void updateBitrate(); void handleDio0Rise(); + + void clearIRQStatus(); private: void writeBuffer(const uint8_t* buffer, size_t size); void readBuffer(uint8_t* buffer, size_t size); @@ -647,7 +658,6 @@ private: int _crcMode; int _fifo_tx_addr_ptr; int _fifo_rx_addr_ptr; - uint8_t _packet[255]; bool _preinit_done; int _rxPacketLength; uint8_t _index; diff --git a/Utilities.h b/Utilities.h index ef18e7f..8156ea4 100644 --- a/Utilities.h +++ b/Utilities.h @@ -1076,6 +1076,57 @@ uint8_t getInterfaceCommandByte(uint8_t index) { } } +uint32_t getQueueSize(uint8_t index) { + switch (index) { + case 0: + return CONFIG_QUEUE_0_SIZE; + #if INTERFACE_COUNT > 1 + case 1: + return CONFIG_QUEUE_1_SIZE; + #endif + #if INTERFACE_COUNT > 2 + case 2: + return CONFIG_QUEUE_2_SIZE; + #endif + #if INTERFACE_COUNT > 3 + case 3: + return CONFIG_QUEUE_3_SIZE; + #endif + #if INTERFACE_COUNT > 4 + case 4: + return CONFIG_QUEUE_4_SIZE; + #endif + #if INTERFACE_COUNT > 5 + case 5: + return CONFIG_QUEUE_5_SIZE; + #endif + #if INTERFACE_COUNT > 6 + case 6: + return CONFIG_QUEUE_6_SIZE; + #endif + #if INTERFACE_COUNT > 7 + case 7: + return CONFIG_QUEUE_7_SIZE; + #endif + #if INTERFACE_COUNT > 8 + case 8: + return CONFIG_QUEUE_8_SIZE; + #endif + #if INTERFACE_COUNT > 9 + case 9: + return CONFIG_QUEUE_9_SIZE; + #endif + #if INTERFACE_COUNT > 10 + case 10: + return CONFIG_QUEUE_10_SIZE; + #endif + #if INTERFACE_COUNT > 11 + case 11: + return CONFIG_QUEUE_11_SIZE; + #endif + } +} + void promisc_enable() { promisc = true; }