Fix various SX1280 issues, revamp RX ISR flow
This commit is contained in:
parent
11c9522d53
commit
379dce99b3
5
Boards.h
5
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
|
||||
|
3
Config.h
3
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
|
||||
|
38
Display.h
38
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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
76
Radio.cpp
76
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);
|
||||
}
|
||||
|
16
Radio.h
16
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;
|
||||
|
51
Utilities.h
51
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user