mirror of
https://github.com/liberatedsystems/RNode_Firmware_CE.git
synced 2025-02-23 08:20:13 -05:00
Inital RadioLib support
This commit is contained in:
parent
2cdf2951e6
commit
f93c400eef
8
Boards.h
8
Boards.h
@ -699,7 +699,7 @@
|
||||
#define HAS_PMU true
|
||||
#define HAS_NP false
|
||||
#define HAS_SD false
|
||||
#define CONFIG_UART_BUFFER_SIZE 40000
|
||||
#define CONFIG_UART_BUFFER_SIZE 6144
|
||||
#define CONFIG_QUEUE_0_SIZE 6144
|
||||
#define CONFIG_QUEUE_MAX_LENGTH 200
|
||||
#define EEPROM_SIZE 296
|
||||
@ -711,7 +711,7 @@
|
||||
#define INTERFACE_COUNT 1
|
||||
|
||||
// first interface in list is the primary
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX126X};
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX1262};
|
||||
const bool interface_cfg[INTERFACE_COUNT][3] = {
|
||||
// SX1262
|
||||
{
|
||||
@ -738,10 +738,10 @@
|
||||
#elif BOARD_VARIANT == MODEL_13 || BOARD_VARIANT == MODEL_14 || BOARD_VARIANT == MODEL_21
|
||||
#define INTERFACE_COUNT 2
|
||||
|
||||
#define CONFIG_QUEUE_1_SIZE 40000
|
||||
#define CONFIG_QUEUE_1_SIZE 37500
|
||||
|
||||
// first interface in list is the primary
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {SX126X, SX128X};
|
||||
const uint8_t interfaces[INTERFACE_COUNT] = {INT_SX1262, INT_SX1280};
|
||||
const bool interface_cfg[INTERFACE_COUNT][3] = {
|
||||
// SX1262
|
||||
{
|
||||
|
61
Config.h
61
Config.h
@ -15,6 +15,7 @@
|
||||
|
||||
#include "ROM.h"
|
||||
#include "Boards.h"
|
||||
#include <RadioLib.h>
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
@ -95,10 +96,6 @@
|
||||
|
||||
bool serial_in_frame = false;
|
||||
|
||||
FIFOBuffer packet_rdy_interfaces;
|
||||
|
||||
uint8_t packet_rdy_interfaces_buf[MAX_INTERFACES];
|
||||
|
||||
// Incoming packet buffer
|
||||
uint8_t pbuf[MTU];
|
||||
|
||||
@ -141,7 +138,57 @@
|
||||
// Subinterfaces
|
||||
// select interface 0 by default
|
||||
uint8_t interface = 0;
|
||||
RadioInterface* selected_radio;
|
||||
RadioInterface* interface_obj[INTERFACE_COUNT];
|
||||
RadioInterface* interface_obj_sorted[INTERFACE_COUNT];
|
||||
PhysicalLayer* selected_radio;
|
||||
PhysicalLayer* interface_obj[INTERFACE_COUNT];
|
||||
PhysicalLayer* interface_obj_sorted[INTERFACE_COUNT];
|
||||
|
||||
// \todo move to another file
|
||||
struct radio_vars {
|
||||
bool radio_locked = false;
|
||||
bool radio_online = false;
|
||||
float st_airtime_limit = 0.0;
|
||||
float lt_airtime_limit = 0.0;
|
||||
bool airtime_lock = false;
|
||||
uint16_t airtime_bins[AIRTIME_BINS] = {0};
|
||||
uint16_t longterm_bins[AIRTIME_BINS] = {0};
|
||||
float airtime = 0.0;
|
||||
float longterm_airtime = 0.0;
|
||||
float local_channel_util = 0.0;
|
||||
float total_channel_util = 0.0;
|
||||
float longterm_channel_util = 0.0;
|
||||
uint32_t last_status_update = 0;
|
||||
bool stat_signal_detected = false;
|
||||
bool stat_signal_synced = false;
|
||||
bool stat_rx_ongoing = false;
|
||||
uint32_t last_dcd = 0;
|
||||
uint16_t dcd_count = 0;
|
||||
bool dcd = false;
|
||||
bool dcd_led = false;
|
||||
bool dcd_waiting = false;
|
||||
long dcd_wait_until = 0;
|
||||
bool util_samples[DCD_SAMPLES] = {false};
|
||||
int dcd_sample = 0;
|
||||
uint32_t post_tx_yield_timeout = 0;
|
||||
uint8_t csma_p = 0;
|
||||
int csma_slot_ms = 50;
|
||||
float csma_p_min = 0.1;
|
||||
float csma_p_max = 0.8;
|
||||
long preamble_length = 0;
|
||||
float lora_symbol_time_ms = 0.0;
|
||||
float lora_symbol_rate = 0.0;
|
||||
float lora_us_per_byte = 0.0;
|
||||
uint32_t bitrate = 0;
|
||||
int8_t txp = 0;
|
||||
uint8_t sf = 0;
|
||||
uint8_t cr = 0;
|
||||
float bw = 0.0;
|
||||
float freq = 0.0;
|
||||
};
|
||||
|
||||
struct radio_vars radio_details[INTERFACE_COUNT];
|
||||
|
||||
SX1280* sx1280_interfaces[INTERFACE_COUNT];
|
||||
SX1262* sx1262_interfaces[INTERFACE_COUNT];
|
||||
|
||||
volatile bool tx_flag = false;
|
||||
#endif
|
||||
|
58
Display.h
58
Display.h
@ -378,11 +378,11 @@ void draw_bt_icon(int px, int py) {
|
||||
}
|
||||
}
|
||||
|
||||
void draw_lora_icon(RadioInterface* radio, int px, int py) {
|
||||
void draw_lora_icon(uint8_t index, int px, int py) {
|
||||
// todo: make display show other interfaces
|
||||
if (radio_online) {
|
||||
#if DISPLAY == OLED
|
||||
if (online_interface_list[interface_page] != radio->getIndex()) {
|
||||
if (online_interface_list[interface_page] != index) {
|
||||
stat_area.drawBitmap(px - 1, py-1, bm_dot_sqr, 18, 19, SSD1306_WHITE, SSD1306_BLACK);
|
||||
|
||||
// redraw stat area on next refresh
|
||||
@ -394,13 +394,13 @@ void draw_lora_icon(RadioInterface* radio, int px, int py) {
|
||||
stat_area.drawBitmap(px, py, bm_rf+0*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
||||
}
|
||||
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||
if (online_interface_list[interface_page] != radio->getIndex()) {
|
||||
if (online_interface_list[interface_page] != index) {
|
||||
stat_area.drawBitmap(px - 2, py - 2, bm_dot_sqr, 34, 36, GxEPD_WHITE, GxEPD_BLACK);
|
||||
|
||||
// redraw stat area on next refresh
|
||||
stat_area_initialised = false;
|
||||
}
|
||||
if (radio->getRadioOnline()) {
|
||||
if (radio_details[index].radio_online) {
|
||||
stat_area.drawBitmap(px, py, bm_rf+1*128, 30, 32, GxEPD_WHITE, GxEPD_BLACK);
|
||||
} else {
|
||||
stat_area.drawBitmap(px, py, bm_rf+0*128, 30, 32, GxEPD_WHITE, GxEPD_BLACK);
|
||||
@ -417,7 +417,7 @@ void draw_lora_icon(RadioInterface* radio, int px, int py) {
|
||||
|
||||
void draw_mw_icon(int px, int py) {
|
||||
if (INTERFACE_COUNT >= 2) {
|
||||
if (interface_obj[1]->getRadioOnline()) {
|
||||
if (radio_details[1].radio_online) {
|
||||
#if DISPLAY == OLED
|
||||
stat_area.drawBitmap(px, py, bm_rf+3*32, 16, 16, SSD1306_WHITE, SSD1306_BLACK);
|
||||
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||
@ -527,7 +527,7 @@ void draw_battery_bars(int px, int py) {
|
||||
void draw_quality_bars(int px, int py) {
|
||||
signed char t_snr = (signed int)last_snr_raw;
|
||||
int snr_int = (int)t_snr;
|
||||
float snr_min = Q_SNR_MIN_BASE-(int)interface_obj[interface_page]->getSpreadingFactor()*Q_SNR_STEP;
|
||||
float snr_min = Q_SNR_MIN_BASE-(int)radio_details[interface_page].sf*Q_SNR_STEP;
|
||||
float snr_span = (Q_SNR_MAX-snr_min);
|
||||
float snr = ((int)snr_int) * 0.25;
|
||||
float quality = ((snr-snr_min)/(snr_span))*100;
|
||||
@ -641,7 +641,8 @@ void draw_signal_bars(int px, int py) {
|
||||
#define WF_PIXEL_WIDTH 22
|
||||
#endif
|
||||
void draw_waterfall(int px, int py) {
|
||||
int rssi_val = interface_obj[interface_page]->currentRssi();
|
||||
// \todo, this may not work, check
|
||||
int rssi_val = interface_obj[interface_page]->getRSSI();
|
||||
if (rssi_val < WF_RSSI_MIN) rssi_val = WF_RSSI_MIN;
|
||||
if (rssi_val > WF_RSSI_MAX) rssi_val = WF_RSSI_MAX;
|
||||
int rssi_normalised = ((rssi_val - WF_RSSI_MIN)*(1.0/WF_RSSI_SPAN))*WF_PIXEL_WIDTH;
|
||||
@ -681,9 +682,9 @@ void draw_stat_area() {
|
||||
if (millis()-last_interface_page_flip >= page_interval) {
|
||||
int online_interfaces_check = 0;
|
||||
|
||||
// todo, is there a more efficient way of doing this?
|
||||
// \todo, is there a more efficient way of doing this?
|
||||
for (int i = 0; i < INTERFACE_COUNT; i++) {
|
||||
if (interface_obj[i]->getRadioOnline()) {
|
||||
if (radio_details[i].radio_online) {
|
||||
online_interfaces_check++;
|
||||
}
|
||||
}
|
||||
@ -701,7 +702,7 @@ void draw_stat_area() {
|
||||
uint8_t index = 0;
|
||||
|
||||
for (int i = 0; i < INTERFACE_COUNT; i++) {
|
||||
if (interface_obj[i]->getRadioOnline()) {
|
||||
if (radio_details[i].radio_online) {
|
||||
online_interface_list[index] = i;
|
||||
index++;
|
||||
}
|
||||
@ -716,27 +717,27 @@ void draw_stat_area() {
|
||||
#if DISPLAY == OLED
|
||||
draw_cable_icon(3, 8);
|
||||
draw_bt_icon(3, 30);
|
||||
draw_lora_icon(interface_obj[0], 45, 8);
|
||||
draw_lora_icon(0, 45, 8);
|
||||
|
||||
// todo, expand support to show more than two interfaces on screen
|
||||
if (INTERFACE_COUNT > 1) {
|
||||
draw_lora_icon(interface_obj[1], 45, 30);
|
||||
draw_lora_icon(1, 45, 30);
|
||||
}
|
||||
draw_battery_bars(4, 58);
|
||||
#elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
|
||||
draw_cable_icon(6, 18);
|
||||
draw_bt_icon(6, 60);
|
||||
draw_lora_icon(interface_obj[0], 86, 18);
|
||||
draw_lora_icon(0, 86, 18);
|
||||
|
||||
// todo, expand support to show more than two interfaces on screen
|
||||
if (INTERFACE_COUNT > 1) {
|
||||
draw_lora_icon(interface_obj[1], 86, 60);
|
||||
draw_lora_icon(1, 86, 60);
|
||||
}
|
||||
draw_battery_bars(8, 113);
|
||||
#endif
|
||||
radio_online = false;
|
||||
for (int i = 0; i < INTERFACE_COUNT; i++) {
|
||||
if (interface_obj[i]->getRadioOnline()) {
|
||||
if (radio_details[i].radio_online) {
|
||||
radio_online = true;
|
||||
break;
|
||||
}
|
||||
@ -876,7 +877,6 @@ 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[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
|
||||
@ -886,25 +886,25 @@ void draw_disp_area() {
|
||||
disp_area.setCursor(14*2, 22);
|
||||
disp_area.print("@");
|
||||
disp_area.setCursor(21*2, 22);
|
||||
disp_area.printf("%.1fKbps", (float)(selected_radio->getBitrate())/1000.0);
|
||||
disp_area.printf("%.1fKbps", (float)(radio_details[online_interface_list[interface_page]].bitrate)/1000.0);
|
||||
|
||||
disp_area.setCursor(2, 36);
|
||||
disp_area.print("Airtime:");
|
||||
|
||||
disp_area.setCursor(7+12, 53);
|
||||
if (selected_radio->getTotalChannelUtil() < 0.099) {
|
||||
disp_area.printf("%.1f%%", selected_radio->getAirtime()*100.0);
|
||||
if (radio_details[online_interface_list[interface_page]].total_channel_util < 0.099) {
|
||||
disp_area.printf("%.1f%%", radio_details[online_interface_list[interface_page]].airtime*100.0);
|
||||
} else {
|
||||
disp_area.printf("%.0f%%", selected_radio->getAirtime()*100.0);
|
||||
disp_area.printf("%.0f%%", radio_details[online_interface_list[interface_page]].airtime*100.0);
|
||||
}
|
||||
|
||||
disp_area.drawBitmap(2, 41, bm_hg_low, 10, 18, GxEPD_WHITE, GxEPD_BLACK);
|
||||
|
||||
disp_area.setCursor(64+17, 53);
|
||||
if (selected_radio->getLongtermChannelUtil() < 0.099) {
|
||||
disp_area.printf("%.1f%%", selected_radio->getLongtermAirtime()*100.0);
|
||||
if (radio_details[online_interface_list[interface_page]].longterm_channel_util < 0.099) {
|
||||
disp_area.printf("%.1f%%", radio_details[online_interface_list[interface_page]].longterm_airtime*100.0);
|
||||
} else {
|
||||
disp_area.printf("%.0f%%", selected_radio->getLongtermAirtime()*100.0);
|
||||
disp_area.printf("%.0f%%", radio_details[online_interface_list[interface_page]].longterm_airtime*100.0);
|
||||
}
|
||||
disp_area.drawBitmap(64, 41, bm_hg_high, 10, 18, GxEPD_WHITE, GxEPD_BLACK);
|
||||
|
||||
@ -916,18 +916,18 @@ void draw_disp_area() {
|
||||
disp_area.print("Load:");
|
||||
|
||||
disp_area.setCursor(7+12, 110);
|
||||
if (selected_radio->getTotalChannelUtil() < 0.099) {
|
||||
disp_area.printf("%.1f%%", selected_radio->getTotalChannelUtil()*100.0);
|
||||
if (radio_details[online_interface_list[interface_page]].total_channel_util < 0.099) {
|
||||
disp_area.printf("%.1f%%", radio_details[online_interface_list[interface_page]].total_channel_util*100.0);
|
||||
} else {
|
||||
disp_area.printf("%.0f%%", selected_radio->getTotalChannelUtil()*100.0);
|
||||
disp_area.printf("%.0f%%", radio_details[online_interface_list[interface_page]].total_channel_util*100.0);
|
||||
}
|
||||
disp_area.drawBitmap(2, 98, bm_hg_low, 10, 18, GxEPD_BLACK, GxEPD_WHITE);
|
||||
|
||||
disp_area.setCursor(64+17, 110);
|
||||
if (selected_radio->getLongtermChannelUtil() < 0.099) {
|
||||
disp_area.printf("%.1f%%", selected_radio->getLongtermChannelUtil()*100.0);
|
||||
if (radio_details[online_interface_list[interface_page]].longterm_channel_util < 0.099) {
|
||||
disp_area.printf("%.1f%%", radio_details[online_interface_list[interface_page]].longterm_channel_util*100.0);
|
||||
} else {
|
||||
disp_area.printf("%.0f%%", selected_radio->getLongtermChannelUtil()*100.0);
|
||||
disp_area.printf("%.0f%%", radio_details[online_interface_list[interface_page]].longterm_channel_util*100.0);
|
||||
}
|
||||
disp_area.drawBitmap(64, 98, bm_hg_high, 10, 18, GxEPD_BLACK, GxEPD_WHITE);
|
||||
#endif
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
#ifndef FRAMING_H
|
||||
#define FRAMING_H
|
||||
|
||||
#define CMD_DEBUG 0xFD
|
||||
#define FEND 0xC0
|
||||
#define FESC 0xDB
|
||||
#define TFEND 0xDC
|
||||
@ -80,7 +80,7 @@
|
||||
#define CMD_INT1_DATA 0x10
|
||||
#define CMD_INT2_DATA 0x20
|
||||
#define CMD_INT3_DATA 0x70
|
||||
#define CMD_INT4_DATA 0x80
|
||||
#define CMD_INT4_DATA 0x75
|
||||
#define CMD_INT5_DATA 0x90
|
||||
#define CMD_INT6_DATA 0xA0
|
||||
#define CMD_INT7_DATA 0xB0
|
||||
@ -92,8 +92,8 @@
|
||||
#define CMD_SEL_INT0 0x1E
|
||||
#define CMD_SEL_INT1 0x1F
|
||||
#define CMD_SEL_INT2 0x2F
|
||||
#define CMD_SEL_INT3 0x7F
|
||||
#define CMD_SEL_INT4 0x8F
|
||||
#define CMD_SEL_INT3 0x74
|
||||
#define CMD_SEL_INT4 0x7F
|
||||
#define CMD_SEL_INT5 0x9F
|
||||
#define CMD_SEL_INT6 0xAF
|
||||
#define CMD_SEL_INT7 0xBF
|
||||
|
14
Interfaces.h
14
Interfaces.h
@ -1,7 +1,7 @@
|
||||
#define SX127X 0x00
|
||||
#define SX1276 0x01
|
||||
#define SX1278 0x02
|
||||
#define SX126X 0x10
|
||||
#define SX1262 0x11
|
||||
#define SX128X 0x20
|
||||
#define SX1280 0x21
|
||||
#define INT_SX127X 0x00
|
||||
#define INT_SX1276 0x01
|
||||
#define INT_SX1278 0x02
|
||||
#define INT_SX126X 0x10
|
||||
#define INT_SX1262 0x11
|
||||
#define INT_SX128X 0x20
|
||||
#define INT_SX1280 0x21
|
||||
|
File diff suppressed because it is too large
Load Diff
607
Radio.hpp
607
Radio.hpp
@ -9,6 +9,7 @@
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <SPI.h>
|
||||
#include <RadioLib.h>
|
||||
#include "Interfaces.h"
|
||||
#include "Boards.h"
|
||||
#include "src/misc/FIFOBuffer.h"
|
||||
@ -59,610 +60,4 @@ void led_indicate_airtime_lock();
|
||||
// get update_lock for ESP32
|
||||
extern portMUX_TYPE update_lock;
|
||||
#endif
|
||||
|
||||
class RadioInterface : public Stream {
|
||||
public:
|
||||
// todo: in the future define _spiModem and _spiSettings from here for inheritence by child classes
|
||||
RadioInterface(uint8_t index) : _index(index), _radio_locked(false),
|
||||
_radio_online(false), _st_airtime_limit(0.0), _lt_airtime_limit(0.0),
|
||||
_airtime_lock(false), _airtime(0.0), _longterm_airtime(0.0),
|
||||
_local_channel_util(0.0), _total_channel_util(0.0),
|
||||
_longterm_channel_util(0.0), _last_status_update(0),
|
||||
_stat_signal_detected(false), _stat_signal_synced(false),_stat_rx_ongoing(false), _last_dcd(0),
|
||||
_dcd_count(0), _dcd(false), _dcd_led(false),
|
||||
_dcd_waiting(false), _dcd_wait_until(0), _dcd_sample(0),
|
||||
_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),
|
||||
_packet{0}, _onReceive(NULL) {};
|
||||
virtual int begin() = 0;
|
||||
virtual void end() = 0;
|
||||
|
||||
virtual int beginPacket(int implicitHeader = false) = 0;
|
||||
virtual int endPacket() = 0;
|
||||
|
||||
virtual int packetRssi() = 0;
|
||||
virtual int currentRssi() = 0;
|
||||
virtual uint8_t packetRssiRaw() = 0;
|
||||
virtual uint8_t currentRssiRaw() = 0;
|
||||
virtual uint8_t packetSnrRaw() = 0;
|
||||
virtual float packetSnr() = 0;
|
||||
virtual long packetFrequencyError() = 0;
|
||||
|
||||
// from Print
|
||||
virtual size_t write(uint8_t byte) = 0;
|
||||
virtual size_t write(const uint8_t *buffer, size_t size) = 0;
|
||||
|
||||
// from Stream
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int peek() = 0;
|
||||
virtual void flush() = 0;
|
||||
|
||||
virtual void onReceive(void(*callback)(uint8_t, int)) = 0;
|
||||
|
||||
virtual void receive(int size = 0) = 0;
|
||||
virtual void standby() = 0;
|
||||
virtual void sleep() = 0;
|
||||
|
||||
virtual bool preInit() = 0;
|
||||
virtual uint8_t getTxPower() = 0;
|
||||
virtual void setTxPower(int level, int outputPin = PA_OUTPUT_PA_BOOST_PIN) = 0;
|
||||
virtual uint32_t getFrequency() = 0;
|
||||
virtual void setFrequency(uint32_t frequency) = 0;
|
||||
virtual void setSpreadingFactor(int sf) = 0;
|
||||
virtual uint8_t getSpreadingFactor() = 0;
|
||||
virtual uint32_t getSignalBandwidth() = 0;
|
||||
virtual void setSignalBandwidth(uint32_t sbw) = 0;
|
||||
virtual void setCodingRate4(int denominator) = 0;
|
||||
virtual uint8_t getCodingRate4() = 0;
|
||||
virtual void setPreambleLength(long length) = 0;
|
||||
virtual uint8_t modemStatus() = 0;
|
||||
virtual void enableCrc() = 0;
|
||||
virtual void disableCrc() = 0;
|
||||
virtual void enableTCXO() = 0;
|
||||
virtual void disableTCXO() = 0;
|
||||
|
||||
virtual byte random() = 0;
|
||||
|
||||
virtual void setSPIFrequency(uint32_t frequency) = 0;
|
||||
|
||||
virtual void updateBitrate() = 0;
|
||||
virtual void handleDio0Rise() = 0;
|
||||
virtual bool getPacketValidity() = 0;
|
||||
uint32_t getBitrate() { return _bitrate; };
|
||||
uint8_t getIndex() { return _index; };
|
||||
void setRadioLock(bool lock) { _radio_locked = lock; };
|
||||
bool getRadioLock() { return _radio_locked; };
|
||||
void setRadioOnline(bool online) { _radio_online = online; };
|
||||
bool getRadioOnline() { return _radio_online; };
|
||||
void setSTALock(float at) { _st_airtime_limit = at; };
|
||||
float getSTALock() { return _st_airtime_limit; };
|
||||
void setLTALock(float at) { _lt_airtime_limit = at; };
|
||||
float getLTALock() { return _lt_airtime_limit; };
|
||||
bool calculateALock() {
|
||||
_airtime_lock = false;
|
||||
if (_st_airtime_limit != 0.0 && _airtime >= _st_airtime_limit) {
|
||||
_airtime_lock = true;
|
||||
}
|
||||
if (_lt_airtime_limit != 0.0 && _longterm_airtime >= _lt_airtime_limit) {
|
||||
_airtime_lock = true;
|
||||
}
|
||||
return _airtime_lock;
|
||||
};
|
||||
void updateAirtime() {
|
||||
uint16_t cb = current_airtime_bin();
|
||||
uint16_t pb = cb-1; if (cb-1 < 0) { pb = AIRTIME_BINS-1; }
|
||||
uint16_t nb = cb+1; if (nb == AIRTIME_BINS) { nb = 0; }
|
||||
_airtime_bins[nb] = 0;
|
||||
_airtime = (float)(_airtime_bins[cb]+_airtime_bins[pb])/(2.0*AIRTIME_BINLEN_MS);
|
||||
|
||||
uint32_t longterm_airtime_sum = 0;
|
||||
for (uint16_t bin = 0; bin < AIRTIME_BINS; bin++) {
|
||||
longterm_airtime_sum += _airtime_bins[bin];
|
||||
}
|
||||
_longterm_airtime = (float)longterm_airtime_sum/(float)AIRTIME_LONGTERM_MS;
|
||||
|
||||
float longterm_channel_util_sum = 0.0;
|
||||
for (uint16_t bin = 0; bin < AIRTIME_BINS; bin++) {
|
||||
longterm_channel_util_sum += _longterm_bins[bin];
|
||||
}
|
||||
_longterm_channel_util = (float)longterm_channel_util_sum/(float)AIRTIME_BINS;
|
||||
|
||||
updateCSMAp();
|
||||
|
||||
//kiss_indicate_channel_stats(); // todo: enable me!
|
||||
};
|
||||
void addAirtime(uint16_t written) {
|
||||
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 += (_preambleLength+4.25)*_lora_symbol_time_ms;
|
||||
packet_cost_ms += PHY_HEADER_LORA_SYMBOLS * _lora_symbol_time_ms;
|
||||
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;
|
||||
};
|
||||
void checkModemStatus() {
|
||||
if (millis()-_last_status_update >= STATUS_INTERVAL_MS) {
|
||||
updateModemStatus();
|
||||
|
||||
_util_samples[_dcd_sample] = _dcd;
|
||||
_dcd_sample = (_dcd_sample+1)%DCD_SAMPLES;
|
||||
if (_dcd_sample % UTIL_UPDATE_INTERVAL == 0) {
|
||||
int util_count = 0;
|
||||
for (int ui = 0; ui < DCD_SAMPLES; ui++) {
|
||||
if (_util_samples[ui]) util_count++;
|
||||
}
|
||||
_local_channel_util = (float)util_count / (float)DCD_SAMPLES;
|
||||
_total_channel_util = _local_channel_util + _airtime;
|
||||
if (_total_channel_util > 1.0) _total_channel_util = 1.0;
|
||||
|
||||
int16_t cb = current_airtime_bin();
|
||||
uint16_t nb = cb+1; if (nb == AIRTIME_BINS) { nb = 0; }
|
||||
if (_total_channel_util > _longterm_bins[cb]) _longterm_bins[cb] = _total_channel_util;
|
||||
_longterm_bins[nb] = 0.0;
|
||||
|
||||
updateAirtime();
|
||||
}
|
||||
}
|
||||
};
|
||||
void updateModemStatus() {
|
||||
#if PLATFORM == PLATFORM_ESP32
|
||||
portENTER_CRITICAL(&update_lock);
|
||||
#elif PLATFORM == PLATFORM_NRF52
|
||||
portENTER_CRITICAL();
|
||||
#endif
|
||||
|
||||
uint8_t status = modemStatus();
|
||||
|
||||
_last_status_update = millis();
|
||||
|
||||
#if PLATFORM == PLATFORM_ESP32
|
||||
portEXIT_CRITICAL(&update_lock);
|
||||
#elif PLATFORM == PLATFORM_NRF52
|
||||
portEXIT_CRITICAL();
|
||||
#endif
|
||||
|
||||
if ((status & SIG_DETECT) == SIG_DETECT) { _stat_signal_detected = true; } else { _stat_signal_detected = false; }
|
||||
if ((status & SIG_SYNCED) == SIG_SYNCED) { _stat_signal_synced = true; } else { _stat_signal_synced = false; }
|
||||
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) {
|
||||
if (_stat_signal_detected || _stat_signal_synced) {
|
||||
if (_stat_rx_ongoing) {
|
||||
if (_dcd_count < DCD_THRESHOLD) {
|
||||
_dcd_count++;
|
||||
} else {
|
||||
_last_dcd = _last_status_update;
|
||||
_dcd_led = true;
|
||||
_dcd = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
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 setPostTxYieldTimeout(uint32_t timeout) { _post_tx_yield_timeout = timeout; };
|
||||
uint32_t getPostTxYieldTimeout() { return _post_tx_yield_timeout; };
|
||||
void setDCD(bool dcd) { _dcd = dcd; };
|
||||
bool getDCD() { return _dcd; };
|
||||
void setDCDWaiting(bool dcd_waiting) { _dcd_waiting = dcd_waiting; };
|
||||
bool getDCDWaiting() { return _dcd_waiting; };
|
||||
void setDCDWaitUntil(uint32_t dcd_wait_until) { _dcd_wait_until = dcd_wait_until; };
|
||||
bool getDCDWaitUntil() { return _dcd_wait_until; };
|
||||
float getAirtime() { return _airtime; };
|
||||
float getLongtermAirtime() { return _longterm_airtime; };
|
||||
float getTotalChannelUtil() { return _total_channel_util; };
|
||||
float getLongtermChannelUtil() { return _longterm_channel_util; };
|
||||
float CSMASlope(float u) { return (pow(_e,_S*u-_S/2.0))/(pow(_e,_S*u-_S/2.0)+1.0); };
|
||||
void updateCSMAp() {
|
||||
_csma_p = (uint8_t)((1.0-(_csma_p_min+(_csma_p_max-_csma_p_min)*CSMASlope(_airtime)))*255.0);
|
||||
};
|
||||
uint8_t getCSMAp() { return _csma_p; };
|
||||
void setCSMASlotMS(int slot_size) { _csma_slot_ms = slot_size; };
|
||||
int getCSMASlotMS() { return _csma_slot_ms; };
|
||||
float getSymbolTime() { return _lora_symbol_time_ms; };
|
||||
float getSymbolRate() { return _lora_symbol_rate; };
|
||||
long getPreambleLength() { return _preambleLength; };
|
||||
protected:
|
||||
virtual void explicitHeaderMode() = 0;
|
||||
virtual void implicitHeaderMode() = 0;
|
||||
|
||||
uint8_t _index;
|
||||
bool _radio_locked;
|
||||
bool _radio_online;
|
||||
float _st_airtime_limit;
|
||||
float _lt_airtime_limit;
|
||||
bool _airtime_lock;
|
||||
uint16_t _airtime_bins[AIRTIME_BINS] = {0};
|
||||
uint16_t _longterm_bins[AIRTIME_BINS] = {0};
|
||||
float _airtime;
|
||||
float _longterm_airtime;
|
||||
float _local_channel_util;
|
||||
float _total_channel_util;
|
||||
float _longterm_channel_util;
|
||||
uint32_t _last_status_update;
|
||||
bool _stat_signal_detected;
|
||||
bool _stat_signal_synced;
|
||||
bool _stat_rx_ongoing;
|
||||
uint32_t _last_dcd;
|
||||
uint16_t _dcd_count;
|
||||
bool _dcd;
|
||||
bool _dcd_led;
|
||||
bool _dcd_waiting;
|
||||
long _dcd_wait_until;
|
||||
bool _util_samples[DCD_SAMPLES] = {false};
|
||||
int _dcd_sample;
|
||||
uint32_t _post_tx_yield_timeout;
|
||||
uint8_t _csma_p;
|
||||
int _csma_slot_ms;
|
||||
float _csma_p_min;
|
||||
float _csma_p_max;
|
||||
long _preambleLength;
|
||||
float _lora_symbol_time_ms;
|
||||
float _lora_symbol_rate;
|
||||
float _lora_us_per_byte;
|
||||
uint32_t _bitrate;
|
||||
uint8_t _packet[255];
|
||||
void (*_onReceive)(uint8_t, int);
|
||||
};
|
||||
|
||||
class sx126x : public RadioInterface {
|
||||
public:
|
||||
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);
|
||||
|
||||
int begin();
|
||||
void end();
|
||||
|
||||
int beginPacket(int implicitHeader = false);
|
||||
int endPacket();
|
||||
|
||||
int packetRssi();
|
||||
int currentRssi();
|
||||
uint8_t packetRssiRaw();
|
||||
uint8_t currentRssiRaw();
|
||||
uint8_t packetSnrRaw();
|
||||
float packetSnr();
|
||||
long packetFrequencyError();
|
||||
|
||||
// from Print
|
||||
size_t write(uint8_t byte);
|
||||
size_t write(const uint8_t *buffer, size_t size);
|
||||
|
||||
// from Stream
|
||||
int available();
|
||||
int read();
|
||||
int peek();
|
||||
void flush();
|
||||
|
||||
void onReceive(void(*callback)(uint8_t, int));
|
||||
|
||||
void receive(int size = 0);
|
||||
void standby();
|
||||
void sleep();
|
||||
|
||||
bool preInit();
|
||||
uint8_t getTxPower();
|
||||
void setTxPower(int level, int outputPin = PA_OUTPUT_PA_BOOST_PIN);
|
||||
uint32_t getFrequency();
|
||||
void setFrequency(uint32_t frequency);
|
||||
void setSpreadingFactor(int sf);
|
||||
uint8_t getSpreadingFactor();
|
||||
uint32_t getSignalBandwidth();
|
||||
void setSignalBandwidth(uint32_t sbw);
|
||||
void setCodingRate4(int denominator);
|
||||
uint8_t getCodingRate4();
|
||||
void setPreambleLength(long length);
|
||||
uint8_t modemStatus();
|
||||
void enableCrc();
|
||||
void disableCrc();
|
||||
void enableTCXO();
|
||||
void disableTCXO();
|
||||
|
||||
|
||||
byte random();
|
||||
|
||||
void setSPIFrequency(uint32_t frequency);
|
||||
|
||||
void dumpRegisters(Stream& out);
|
||||
|
||||
void updateBitrate();
|
||||
|
||||
void handleDio0Rise();
|
||||
private:
|
||||
void writeBuffer(const uint8_t* buffer, size_t size);
|
||||
void readBuffer(uint8_t* buffer, size_t size);
|
||||
void loraMode();
|
||||
void rxAntEnable();
|
||||
void setPacketParams(uint32_t preamble, uint8_t headermode, uint8_t length, uint8_t crc);
|
||||
void setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr, int ldro);
|
||||
void setSyncWord(uint16_t sw);
|
||||
void waitOnBusy();
|
||||
void executeOpcode(uint8_t opcode, uint8_t *buffer, uint8_t size);
|
||||
void executeOpcodeRead(uint8_t opcode, uint8_t *buffer, uint8_t size);
|
||||
void explicitHeaderMode();
|
||||
void implicitHeaderMode();
|
||||
|
||||
|
||||
uint8_t readRegister(uint16_t address);
|
||||
void writeRegister(uint16_t address, uint8_t value);
|
||||
uint8_t singleTransfer(uint8_t opcode, uint16_t address, uint8_t value);
|
||||
|
||||
static void onDio0Rise();
|
||||
|
||||
void handleLowDataRate();
|
||||
void optimizeModemSensitivity();
|
||||
|
||||
void reset(void);
|
||||
void calibrate(void);
|
||||
void calibrate_image(uint32_t frequency);
|
||||
bool getPacketValidity();
|
||||
|
||||
private:
|
||||
SPISettings _spiSettings;
|
||||
SPIClass* _spiModem;
|
||||
int _ss;
|
||||
int _sclk;
|
||||
int _mosi;
|
||||
int _miso;
|
||||
int _reset;
|
||||
int _dio0;
|
||||
int _rxen;
|
||||
int _busy;
|
||||
uint32_t _frequency;
|
||||
int _txp;
|
||||
uint8_t _sf;
|
||||
uint8_t _bw;
|
||||
uint8_t _cr;
|
||||
uint8_t _ldro;
|
||||
int _packetIndex;
|
||||
int _implicitHeaderMode;
|
||||
int _payloadLength;
|
||||
int _crcMode;
|
||||
int _fifo_tx_addr_ptr;
|
||||
int _fifo_rx_addr_ptr;
|
||||
bool _preinit_done;
|
||||
uint8_t _index;
|
||||
bool _tcxo;
|
||||
bool _dio2_as_rf_switch;
|
||||
};
|
||||
|
||||
class sx127x : public RadioInterface {
|
||||
public:
|
||||
sx127x(uint8_t index, SPIClass* spi, int ss, int sclk, int mosi, int miso, int reset, int dio0, int busy);
|
||||
|
||||
int begin();
|
||||
void end();
|
||||
|
||||
int beginPacket(int implicitHeader = false);
|
||||
int endPacket();
|
||||
|
||||
int packetRssi();
|
||||
int currentRssi();
|
||||
uint8_t packetRssiRaw();
|
||||
uint8_t currentRssiRaw();
|
||||
uint8_t packetSnrRaw();
|
||||
float packetSnr();
|
||||
long packetFrequencyError();
|
||||
|
||||
// from Print
|
||||
size_t write(uint8_t byte);
|
||||
size_t write(const uint8_t *buffer, size_t size);
|
||||
|
||||
// from Stream
|
||||
int available();
|
||||
int read();
|
||||
int peek();
|
||||
void flush();
|
||||
|
||||
void onReceive(void(*callback)(uint8_t, int));
|
||||
|
||||
void receive(int size = 0);
|
||||
void standby();
|
||||
void sleep();
|
||||
|
||||
bool preInit();
|
||||
uint8_t getTxPower();
|
||||
void setTxPower(int level, int outputPin = PA_OUTPUT_PA_BOOST_PIN);
|
||||
uint32_t getFrequency();
|
||||
void setFrequency(uint32_t frequency);
|
||||
void setSpreadingFactor(int sf);
|
||||
uint8_t getSpreadingFactor();
|
||||
uint32_t getSignalBandwidth();
|
||||
void setSignalBandwidth(uint32_t sbw);
|
||||
void setCodingRate4(int denominator);
|
||||
uint8_t getCodingRate4();
|
||||
void setPreambleLength(long length);
|
||||
uint8_t modemStatus();
|
||||
void enableCrc();
|
||||
void disableCrc();
|
||||
void enableTCXO();
|
||||
void disableTCXO();
|
||||
|
||||
byte random();
|
||||
|
||||
void setSPIFrequency(uint32_t frequency);
|
||||
|
||||
void updateBitrate();
|
||||
|
||||
void handleDio0Rise();
|
||||
bool getPacketValidity();
|
||||
private:
|
||||
void setSyncWord(uint8_t sw);
|
||||
void explicitHeaderMode();
|
||||
void implicitHeaderMode();
|
||||
|
||||
|
||||
uint8_t readRegister(uint8_t address);
|
||||
void writeRegister(uint8_t address, uint8_t value);
|
||||
uint8_t singleTransfer(uint8_t address, uint8_t value);
|
||||
|
||||
static void onDio0Rise();
|
||||
|
||||
void handleLowDataRate();
|
||||
void optimizeModemSensitivity();
|
||||
|
||||
private:
|
||||
SPISettings _spiSettings;
|
||||
SPIClass* _spiModem;
|
||||
int _ss;
|
||||
int _sclk;
|
||||
int _mosi;
|
||||
int _miso;
|
||||
int _reset;
|
||||
int _dio0;
|
||||
int _busy;
|
||||
uint32_t _frequency;
|
||||
int _packetIndex;
|
||||
int _implicitHeaderMode;
|
||||
bool _preinit_done;
|
||||
uint8_t _index;
|
||||
uint8_t _sf;
|
||||
uint8_t _cr;
|
||||
};
|
||||
|
||||
class sx128x : public RadioInterface {
|
||||
public:
|
||||
sx128x(uint8_t index, SPIClass* spi, bool tcxo, int ss, int sclk, int mosi, int miso, int reset, int dio0, int busy, int rxen, int txen);
|
||||
|
||||
int begin();
|
||||
void end();
|
||||
|
||||
int beginPacket(int implicitHeader = false);
|
||||
int endPacket();
|
||||
|
||||
int packetRssi();
|
||||
int currentRssi();
|
||||
uint8_t packetRssiRaw();
|
||||
uint8_t currentRssiRaw();
|
||||
uint8_t packetSnrRaw();
|
||||
float packetSnr();
|
||||
long packetFrequencyError();
|
||||
|
||||
// from Print
|
||||
size_t write(uint8_t byte);
|
||||
size_t write(const uint8_t *buffer, size_t size);
|
||||
|
||||
// from Stream
|
||||
int available();
|
||||
int read();
|
||||
int peek();
|
||||
void flush();
|
||||
|
||||
void onReceive(void(*callback)(uint8_t, int));
|
||||
|
||||
void receive(int size = 0);
|
||||
void standby();
|
||||
void sleep();
|
||||
|
||||
bool preInit();
|
||||
uint8_t getTxPower();
|
||||
void setTxPower(int level, int outputPin = PA_OUTPUT_PA_BOOST_PIN);
|
||||
uint32_t getFrequency();
|
||||
void setFrequency(uint32_t frequency);
|
||||
void setSpreadingFactor(int sf);
|
||||
uint8_t getSpreadingFactor();
|
||||
uint32_t getSignalBandwidth();
|
||||
void setSignalBandwidth(uint32_t sbw);
|
||||
void setCodingRate4(int denominator);
|
||||
uint8_t getCodingRate4();
|
||||
void setPreambleLength(long length);
|
||||
uint8_t modemStatus();
|
||||
void enableCrc();
|
||||
void disableCrc();
|
||||
void enableTCXO();
|
||||
void disableTCXO();
|
||||
|
||||
byte random();
|
||||
|
||||
void setSPIFrequency(uint32_t frequency);
|
||||
|
||||
void dumpRegisters(Stream& out);
|
||||
|
||||
void updateBitrate();
|
||||
|
||||
void handleDio0Rise();
|
||||
|
||||
bool getPacketValidity();
|
||||
|
||||
private:
|
||||
void writeBuffer(const uint8_t* buffer, size_t size);
|
||||
void readBuffer(uint8_t* buffer, size_t size);
|
||||
void txAntEnable();
|
||||
void rxAntEnable();
|
||||
void loraMode();
|
||||
void waitOnBusy();
|
||||
void executeOpcode(uint8_t opcode, uint8_t *buffer, uint8_t size);
|
||||
void executeOpcodeRead(uint8_t opcode, uint8_t *buffer, uint8_t size);
|
||||
void setPacketParams(uint32_t preamble, uint8_t headermode, uint8_t length, uint8_t crc);
|
||||
void setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr);
|
||||
void setSyncWord(int sw);
|
||||
void explicitHeaderMode();
|
||||
void implicitHeaderMode();
|
||||
|
||||
|
||||
uint8_t readRegister(uint16_t address);
|
||||
void writeRegister(uint16_t address, uint8_t value);
|
||||
uint8_t singleTransfer(uint8_t opcode, uint16_t address, uint8_t value);
|
||||
|
||||
static void onDio0Rise();
|
||||
|
||||
void handleLowDataRate();
|
||||
void optimizeModemSensitivity();
|
||||
|
||||
private:
|
||||
SPISettings _spiSettings;
|
||||
SPIClass* _spiModem;
|
||||
int _ss;
|
||||
int _sclk;
|
||||
int _mosi;
|
||||
int _miso;
|
||||
int _reset;
|
||||
int _dio0;
|
||||
int _rxen;
|
||||
int _txen;
|
||||
int _busy;
|
||||
int _modem;
|
||||
uint32_t _frequency;
|
||||
int _txp;
|
||||
uint8_t _sf;
|
||||
uint8_t _bw;
|
||||
uint8_t _cr;
|
||||
int _packetIndex;
|
||||
int _implicitHeaderMode;
|
||||
int _payloadLength;
|
||||
int _crcMode;
|
||||
int _fifo_tx_addr_ptr;
|
||||
int _fifo_rx_addr_ptr;
|
||||
bool _preinit_done;
|
||||
int _rxPacketLength;
|
||||
uint8_t _index;
|
||||
bool _tcxo;
|
||||
};
|
||||
#endif
|
||||
|
458
Utilities.h
458
Utilities.h
@ -20,6 +20,10 @@
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
// For CSMA
|
||||
#define _e 2.71828183
|
||||
#define _S 10.0
|
||||
|
||||
#if HAS_EEPROM
|
||||
#include <EEPROM.h>
|
||||
#elif PLATFORM == PLATFORM_NRF52
|
||||
@ -565,16 +569,9 @@ int8_t led_standby_direction = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
bool interface_bitrate_cmp(RadioInterface* p, RadioInterface* q) {
|
||||
long p_bitrate = p->getBitrate();
|
||||
long q_bitrate = q->getBitrate();
|
||||
return p_bitrate > q_bitrate;
|
||||
}
|
||||
|
||||
// Sort interfaces in descending order according to bitrate.
|
||||
void sort_interfaces() {
|
||||
std::sort(std::begin(interface_obj_sorted), std::end(interface_obj_sorted), interface_bitrate_cmp);
|
||||
//std::sort(std::begin(interface_obj_sorted), std::end(interface_obj_sorted), interface_bitrate_cmp);
|
||||
}
|
||||
|
||||
void serial_write(uint8_t byte) {
|
||||
@ -621,10 +618,10 @@ void kiss_indicate_error(uint8_t error_code) {
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
void kiss_indicate_radiostate(RadioInterface* radio) {
|
||||
void kiss_indicate_radiostate(uint8_t index) {
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_RADIO_STATE);
|
||||
serial_write(radio->getRadioOnline());
|
||||
serial_write(radio_details[index].radio_online);
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
@ -665,24 +662,25 @@ void kiss_indicate_stat_snr() {
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
void kiss_indicate_radio_lock(RadioInterface* radio) {
|
||||
void kiss_indicate_radio_lock(uint8_t index) {
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_RADIO_LOCK);
|
||||
serial_write(radio->getRadioLock());
|
||||
serial_write(radio_details[index].radio_locked);
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
void kiss_indicate_spreadingfactor(RadioInterface* radio) {
|
||||
void kiss_indicate_spreadingfactor(uint8_t index) {
|
||||
// \todo, add ability to choose FSK when multiple modem mode support added
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_SF);
|
||||
serial_write(radio->getSpreadingFactor());
|
||||
serial_write(radio_details[index].sf);
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
void kiss_indicate_codingrate(RadioInterface* radio) {
|
||||
void kiss_indicate_codingrate(uint8_t index) {
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_CR);
|
||||
serial_write(radio->getCodingRate4());
|
||||
serial_write(radio_details[index].cr);
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
@ -693,16 +691,16 @@ void kiss_indicate_implicit_length() {
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
void kiss_indicate_txpower(RadioInterface* radio) {
|
||||
int8_t txp = radio->getTxPower();
|
||||
void kiss_indicate_txpower(uint8_t index) {
|
||||
int8_t txp = radio_details[index].txp;
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_TXPOWER);
|
||||
serial_write(txp);
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
void kiss_indicate_bandwidth(RadioInterface* radio) {
|
||||
uint32_t bw = radio->getSignalBandwidth();
|
||||
void kiss_indicate_bandwidth(uint8_t index) {
|
||||
uint32_t bw = radio_details[index].bw * 1000;
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_BANDWIDTH);
|
||||
escaped_serial_write(bw>>24);
|
||||
@ -712,8 +710,8 @@ void kiss_indicate_bandwidth(RadioInterface* radio) {
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
void kiss_indicate_frequency(RadioInterface* radio) {
|
||||
uint32_t freq = radio->getFrequency();
|
||||
void kiss_indicate_frequency(uint8_t index) {
|
||||
uint32_t freq = uint32_t(radio_details[index].freq * 1000000);
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_FREQUENCY);
|
||||
escaped_serial_write(freq>>24);
|
||||
@ -732,8 +730,8 @@ void kiss_indicate_interface(int index) {
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
void kiss_indicate_st_alock(RadioInterface* radio) {
|
||||
uint16_t at = (uint16_t)(radio->getSTALock()*100*100);
|
||||
void kiss_indicate_st_alock(uint8_t index) {
|
||||
uint16_t at = (uint16_t)(radio_details[index].st_airtime_limit*100*100);
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_ST_ALOCK);
|
||||
escaped_serial_write(at>>8);
|
||||
@ -741,8 +739,8 @@ void kiss_indicate_st_alock(RadioInterface* radio) {
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
void kiss_indicate_lt_alock(RadioInterface* radio) {
|
||||
uint16_t at = (uint16_t)(radio->getLTALock()*100*100);
|
||||
void kiss_indicate_lt_alock(uint8_t index) {
|
||||
uint16_t at = (uint16_t)(radio_details[index].lt_airtime_limit*100*100);
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_LT_ALOCK);
|
||||
escaped_serial_write(at>>8);
|
||||
@ -750,11 +748,11 @@ void kiss_indicate_lt_alock(RadioInterface* radio) {
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
void kiss_indicate_channel_stats(RadioInterface* radio) {
|
||||
uint16_t ats = (uint16_t)(radio->getAirtime()*100*100);
|
||||
uint16_t atl = (uint16_t)(radio->getLongtermAirtime()*100*100);
|
||||
uint16_t cls = (uint16_t)(radio->getTotalChannelUtil()*100*100);
|
||||
uint16_t cll = (uint16_t)(radio->getLongtermChannelUtil()*100*100);
|
||||
void kiss_indicate_channel_stats(uint8_t index) {
|
||||
uint16_t ats = (uint16_t)(radio_details[index].airtime*100*100);
|
||||
uint16_t atl = (uint16_t)(radio_details[index].longterm_airtime*100*100);
|
||||
uint16_t cls = (uint16_t)(radio_details[index].total_channel_util*100*100);
|
||||
uint16_t cll = (uint16_t)(radio_details[index].longterm_channel_util*100*100);
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_STAT_CHTM);
|
||||
escaped_serial_write(ats>>8);
|
||||
@ -768,12 +766,12 @@ void kiss_indicate_channel_stats(RadioInterface* radio) {
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
void kiss_indicate_phy_stats(RadioInterface* radio) {
|
||||
uint16_t lst = (uint16_t)(radio->getSymbolTime()*1000);
|
||||
uint16_t lsr = (uint16_t)(radio->getSymbolRate());
|
||||
uint16_t prs = (uint16_t)(radio->getPreambleLength()+4);
|
||||
uint16_t prt = (uint16_t)((radio->getPreambleLength()+4)*radio->getSymbolTime());
|
||||
uint16_t cst = (uint16_t)(radio->getCSMASlotMS());
|
||||
void kiss_indicate_phy_stats(uint8_t index) {
|
||||
uint16_t lst = (uint16_t)(radio_details[index].lora_symbol_time_ms*1000);
|
||||
uint16_t lsr = (uint16_t)(radio_details[index].lora_symbol_rate);
|
||||
uint16_t prs = (uint16_t)(radio_details[index].preamble_length+4);
|
||||
uint16_t prt = (uint16_t)((radio_details[index].preamble_length+4)*radio_details[index].lora_symbol_time_ms);
|
||||
uint16_t cst = (uint16_t)(radio_details[index].csma_slot_ms);
|
||||
serial_write(FEND);
|
||||
serial_write(CMD_STAT_PHYPRM);
|
||||
escaped_serial_write(lst>>8);
|
||||
@ -964,6 +962,203 @@ void kiss_indicate_mcu() {
|
||||
serial_write(FEND);
|
||||
}
|
||||
|
||||
void update_radio_params(PhysicalLayer* radio, struct radio_vars* config) {
|
||||
DataRate_t params;
|
||||
params.lora.spreadingFactor = config->sf;
|
||||
params.lora.codingRate = config->cr;
|
||||
params.lora.bandwidth = config->bw;
|
||||
int16_t status = radio->setDataRate(params);
|
||||
if (status != RADIOLIB_ERR_NONE) {
|
||||
kiss_indicate_error(ERROR_INITRADIO);
|
||||
led_indicate_error(0);
|
||||
}
|
||||
}
|
||||
|
||||
int16_t set_spreading_factor(PhysicalLayer* radio, uint8_t index, uint8_t sf) {
|
||||
struct radio_vars* config = &radio_details[index];
|
||||
config->sf = sf;
|
||||
update_radio_params(radio, config);
|
||||
}
|
||||
|
||||
int16_t set_coding_rate(PhysicalLayer* radio, uint8_t index, uint8_t cr) {
|
||||
struct radio_vars* config = &radio_details[index];
|
||||
config->cr = cr;
|
||||
update_radio_params(radio, config);
|
||||
}
|
||||
|
||||
int16_t set_bandwidth(PhysicalLayer* radio, uint8_t index, float bw) {
|
||||
struct radio_vars* config = &radio_details[index];
|
||||
config->bw = bw;
|
||||
update_radio_params(radio, config);
|
||||
}
|
||||
|
||||
void update_modem_status(PhysicalLayer* radio, uint8_t index) {
|
||||
struct radio_vars* config = &radio_details[index];
|
||||
#if PLATFORM == PLATFORM_ESP32
|
||||
portENTER_CRITICAL(&update_lock);
|
||||
#elif PLATFORM == PLATFORM_NRF52
|
||||
portENTER_CRITICAL();
|
||||
#endif
|
||||
|
||||
// \todo implement again
|
||||
uint8_t status = 0;//modemStatus();
|
||||
|
||||
config->last_status_update = millis();
|
||||
|
||||
#if PLATFORM == PLATFORM_ESP32
|
||||
portEXIT_CRITICAL(&update_lock);
|
||||
#elif PLATFORM == PLATFORM_NRF52
|
||||
portEXIT_CRITICAL();
|
||||
#endif
|
||||
|
||||
if ((status & SIG_DETECT) == SIG_DETECT) { config->stat_signal_detected = true; } else { config->stat_signal_detected = false; }
|
||||
if ((status & SIG_SYNCED) == SIG_SYNCED) { config->stat_signal_synced = true; } else { config->stat_signal_synced = false; }
|
||||
if ((status & RX_ONGOING) == RX_ONGOING) { config->stat_rx_ongoing = true; } else { config->stat_rx_ongoing = false; }
|
||||
|
||||
if (config->stat_signal_detected || config->stat_signal_synced) {
|
||||
if (config->stat_rx_ongoing) {
|
||||
if (config->dcd_count < DCD_THRESHOLD) {
|
||||
config->dcd_count++;
|
||||
} else {
|
||||
config->last_dcd = config->last_status_update;
|
||||
config->dcd_led = true;
|
||||
config->dcd = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (config->dcd_count == 0) {
|
||||
config->dcd_led = false;
|
||||
} else if (config->dcd_count > DCD_LED_STEP_D) {
|
||||
config->dcd_count -= DCD_LED_STEP_D;
|
||||
} else {
|
||||
config->dcd_count = 0;
|
||||
}
|
||||
|
||||
if (config->last_status_update > config->last_dcd+config->csma_slot_ms) {
|
||||
config->dcd = false;
|
||||
config->dcd_led = false;
|
||||
config->dcd_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (config->dcd_led) {
|
||||
led_rx_on();
|
||||
} else {
|
||||
if (config->airtime_lock) {
|
||||
led_indicate_airtime_lock();
|
||||
} else {
|
||||
led_rx_off();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
float csma_slope(float u) { return (pow(_e,_S*u-_S/2.0))/(pow(_e,_S*u-_S/2.0)+1.0); };
|
||||
void update_csma_p(struct radio_vars* config) {
|
||||
config->csma_p = (uint8_t)((1.0-(config->csma_p_min+(config->csma_p_max-config->csma_p_min)*csma_slope(config->airtime)))*255.0);
|
||||
};
|
||||
|
||||
bool calculate_alock(struct radio_vars* config) {
|
||||
bool airtime_lock = false;
|
||||
if (config->st_airtime_limit != 0.0 && config->airtime >= config->st_airtime_limit) {
|
||||
airtime_lock = true;
|
||||
config->airtime_lock = true;
|
||||
}
|
||||
if (config->lt_airtime_limit != 0.0 && config->longterm_airtime >= config->lt_airtime_limit) {
|
||||
airtime_lock = true;
|
||||
config->airtime_lock = true;
|
||||
}
|
||||
return airtime_lock;
|
||||
};
|
||||
|
||||
void add_airtime(uint8_t index, uint16_t written) {
|
||||
// \todo is referencing it this was actually necessary? Could I not just do it without the pointer?
|
||||
struct radio_vars* config = &radio_details[index];
|
||||
float packet_cost_ms = 0.0;
|
||||
float payload_cost_ms = ((float)written * config->lora_us_per_byte)/1000.0;
|
||||
packet_cost_ms += payload_cost_ms;
|
||||
packet_cost_ms += (config->preamble_length+4.25)*config->lora_symbol_time_ms;
|
||||
packet_cost_ms += PHY_HEADER_LORA_SYMBOLS * config->lora_symbol_time_ms;
|
||||
uint16_t cb = current_airtime_bin();
|
||||
uint16_t nb = cb+1; if (nb == AIRTIME_BINS) { nb = 0; }
|
||||
config->airtime_bins[cb] += packet_cost_ms;
|
||||
config->airtime_bins[nb] = 0;
|
||||
};
|
||||
|
||||
void update_airtime(uint8_t index) {
|
||||
struct radio_vars* config = &radio_details[index];
|
||||
uint16_t cb = current_airtime_bin();
|
||||
uint16_t pb = cb-1; if (cb-1 < 0) { pb = AIRTIME_BINS-1; }
|
||||
uint16_t nb = cb+1; if (nb == AIRTIME_BINS) { nb = 0; }
|
||||
config->airtime_bins[nb] = 0;
|
||||
config->airtime = (float)(config->airtime_bins[cb]+config->airtime_bins[pb])/(2.0*AIRTIME_BINLEN_MS);
|
||||
|
||||
uint32_t longterm_airtime_sum = 0;
|
||||
for (uint16_t bin = 0; bin < AIRTIME_BINS; bin++) {
|
||||
longterm_airtime_sum += config->airtime_bins[bin];
|
||||
}
|
||||
config->longterm_airtime = (float)longterm_airtime_sum/(float)AIRTIME_LONGTERM_MS;
|
||||
|
||||
float longterm_channel_util_sum = 0.0;
|
||||
for (uint16_t bin = 0; bin < AIRTIME_BINS; bin++) {
|
||||
longterm_channel_util_sum += config->longterm_bins[bin];
|
||||
}
|
||||
config->longterm_channel_util = (float)longterm_channel_util_sum/(float)AIRTIME_BINS;
|
||||
|
||||
update_csma_p(config);
|
||||
|
||||
//kiss_indicate_channel_stats(); // todo: enable me!
|
||||
};
|
||||
|
||||
void check_modem_status(PhysicalLayer* radio, uint8_t index) {
|
||||
struct radio_vars* config = &radio_details[index];
|
||||
if (millis()-(config->last_status_update) >= STATUS_INTERVAL_MS) {
|
||||
update_modem_status(radio, index);
|
||||
|
||||
config->util_samples[config->dcd_sample] = config->dcd;
|
||||
config->dcd_sample = (config->dcd_sample+1)%DCD_SAMPLES;
|
||||
if (config->dcd_sample % UTIL_UPDATE_INTERVAL == 0) {
|
||||
int util_count = 0;
|
||||
for (int ui = 0; ui < DCD_SAMPLES; ui++) {
|
||||
if (config->util_samples[ui]) util_count++;
|
||||
}
|
||||
config->local_channel_util = (float)util_count / (float)DCD_SAMPLES;
|
||||
config->total_channel_util = config->local_channel_util + config->airtime;
|
||||
if (config->total_channel_util > 1.0) config->total_channel_util = 1.0;
|
||||
|
||||
int16_t cb = current_airtime_bin();
|
||||
uint16_t nb = cb+1; if (nb == AIRTIME_BINS) { nb = 0; }
|
||||
if (config->total_channel_util > config->longterm_bins[cb]) config->longterm_bins[cb] = config->total_channel_util;
|
||||
config->longterm_bins[nb] = 0.0;
|
||||
|
||||
update_airtime(index);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void update_bitrate(PhysicalLayer* radio, uint8_t index) {
|
||||
struct radio_vars* config = &radio_details[index];
|
||||
if (config->radio_online) {
|
||||
config->lora_symbol_rate = (config->bw*1000)/(float)(pow(2, config->sf));
|
||||
config->lora_symbol_time_ms = (1.0/config->lora_symbol_rate)*1000.0;
|
||||
config->bitrate = (uint32_t)(config->sf * ( (4.0/(float)(config->cr+4)) / ((float)(pow(2, config->sf))/config->bw) ) * 1000.0);
|
||||
config->lora_us_per_byte = 1000000.0/((float)config->bitrate/8.0);
|
||||
//_csma_slot_ms = _lora_symbol_time_ms*10;
|
||||
float target_preamble_symbols = (LORA_PREAMBLE_TARGET_MS/config->lora_symbol_time_ms)-LORA_PREAMBLE_SYMBOLS_HW;
|
||||
if (target_preamble_symbols < LORA_PREAMBLE_SYMBOLS_MIN) {
|
||||
target_preamble_symbols = LORA_PREAMBLE_SYMBOLS_MIN;
|
||||
} else {
|
||||
target_preamble_symbols = ceil(target_preamble_symbols);
|
||||
}
|
||||
// \todo actually update this on the radio
|
||||
config->preamble_length = target_preamble_symbols;
|
||||
radio->setPreambleLength(target_preamble_symbols);
|
||||
} else {
|
||||
config->bitrate = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline bool isSplitPacket(uint8_t header) {
|
||||
return (header & FLAG_SPLIT);
|
||||
}
|
||||
@ -981,66 +1176,69 @@ void set_implicit_length(uint8_t len) {
|
||||
}
|
||||
}
|
||||
|
||||
void setTXPower(RadioInterface* radio, int txp) {
|
||||
void setTXPower(PhysicalLayer* radio, uint8_t index, int txp) {
|
||||
// Todo, revamp this function. The current parameters for setTxPower are
|
||||
// suboptimal, as some chips have power amplifiers which means that the max
|
||||
// dBm is not always the same.
|
||||
if (model == MODEL_11) {
|
||||
if (interfaces[radio->getIndex()] == SX128X) {
|
||||
radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
} else {
|
||||
radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
|
||||
}
|
||||
}
|
||||
if (model == MODEL_12) {
|
||||
if (interfaces[radio->getIndex()] == SX128X) {
|
||||
radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
} else {
|
||||
radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
|
||||
}
|
||||
}
|
||||
int8_t set_pwr;
|
||||
radio->checkOutputPower(txp, &set_pwr);
|
||||
radio_details[index].txp = set_pwr;
|
||||
//if (model == MODEL_11) {
|
||||
// if (interfaces[radio->getIndex()] == SX128X) {
|
||||
// radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
// } else {
|
||||
// radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
|
||||
// }
|
||||
//}
|
||||
//if (model == MODEL_12) {
|
||||
// if (interfaces[radio->getIndex()] == SX128X) {
|
||||
// radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
// } else {
|
||||
// radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
|
||||
// }
|
||||
//}
|
||||
|
||||
if (model == MODEL_21) {
|
||||
if (interfaces[radio->getIndex()] == SX128X) {
|
||||
radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
} else {
|
||||
radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
|
||||
}
|
||||
}
|
||||
//if (model == MODEL_21) {
|
||||
// if (interfaces[radio->getIndex()] == SX128X) {
|
||||
// radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
// } else {
|
||||
// radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
|
||||
// }
|
||||
//}
|
||||
|
||||
if (model == MODEL_A1) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_A2) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_A3) radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
|
||||
if (model == MODEL_A4) radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
|
||||
if (model == MODEL_A5) radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
|
||||
if (model == MODEL_A6) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_A7) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_A8) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_A9) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
//if (model == MODEL_A1) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
//if (model == MODEL_A2) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
//if (model == MODEL_A3) radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
|
||||
//if (model == MODEL_A4) radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
|
||||
//if (model == MODEL_A5) radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
|
||||
//if (model == MODEL_A6) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
//if (model == MODEL_A7) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
//if (model == MODEL_A8) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
//if (model == MODEL_A9) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
|
||||
if (model == MODEL_B3) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_B4) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_B8) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_B9) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
//if (model == MODEL_B3) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
//if (model == MODEL_B4) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
//if (model == MODEL_B8) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
//if (model == MODEL_B9) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
|
||||
if (model == MODEL_C4) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_C9) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
//if (model == MODEL_C4) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
//if (model == MODEL_C9) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
|
||||
if (model == MODEL_E4) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_E9) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_E3) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_E8) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
//if (model == MODEL_E4) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
//if (model == MODEL_E9) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
//if (model == MODEL_E3) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
//if (model == MODEL_E8) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
|
||||
if (model == MODEL_FE) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
if (model == MODEL_FF) radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
|
||||
//if (model == MODEL_FE) radio->setTxPower(txp, PA_OUTPUT_PA_BOOST_PIN);
|
||||
//if (model == MODEL_FF) radio->setTxPower(txp, PA_OUTPUT_RFO_PIN);
|
||||
}
|
||||
|
||||
uint8_t getRandom(RadioInterface* radio) {
|
||||
if (radio->getRadioOnline()) {
|
||||
return radio->random();
|
||||
} else {
|
||||
uint8_t getRandom(PhysicalLayer* radio) {
|
||||
//if (radio->getRadioOnline()) {
|
||||
// return radio->random();
|
||||
//} else {
|
||||
return 0x00;
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
uint8_t getInterfaceIndex(uint8_t byte) {
|
||||
@ -1475,57 +1673,59 @@ bool eeprom_have_conf() {
|
||||
}
|
||||
}
|
||||
|
||||
void eeprom_conf_load(RadioInterface* radio) {
|
||||
if (eeprom_have_conf()) {
|
||||
if (!(radio->getRadioOnline())) {
|
||||
#if HAS_EEPROM
|
||||
uint8_t sf = EEPROM.read(eeprom_addr(ADDR_CONF_SF));
|
||||
uint8_t cr = EEPROM.read(eeprom_addr(ADDR_CONF_CR));
|
||||
uint8_t txp = EEPROM.read(eeprom_addr(ADDR_CONF_TXP));
|
||||
uint32_t freq = (uint32_t)EEPROM.read(eeprom_addr(ADDR_CONF_FREQ)+0x00) << 24 | (uint32_t)EEPROM.read(eeprom_addr(ADDR_CONF_FREQ)+0x01) << 16 | (uint32_t)EEPROM.read(eeprom_addr(ADDR_CONF_FREQ)+0x02) << 8 | (uint32_t)EEPROM.read(eeprom_addr(ADDR_CONF_FREQ)+0x03);
|
||||
uint32_t bw = (uint32_t)EEPROM.read(eeprom_addr(ADDR_CONF_BW)+0x00) << 24 | (uint32_t)EEPROM.read(eeprom_addr(ADDR_CONF_BW)+0x01) << 16 | (uint32_t)EEPROM.read(eeprom_addr(ADDR_CONF_BW)+0x02) << 8 | (uint32_t)EEPROM.read(eeprom_addr(ADDR_CONF_BW)+0x03);
|
||||
#elif MCU_VARIANT == MCU_NRF52
|
||||
uint8_t sf = eeprom_read(eeprom_addr(ADDR_CONF_SF));
|
||||
uint8_t cr = eeprom_read(eeprom_addr(ADDR_CONF_CR));
|
||||
uint8_t txp = eeprom_read(eeprom_addr(ADDR_CONF_TXP));
|
||||
uint32_t freq = (uint32_t)eeprom_read(eeprom_addr(ADDR_CONF_FREQ)+0x00) << 24 | (uint32_t)eeprom_read(eeprom_addr(ADDR_CONF_FREQ)+0x01) << 16 | (uint32_t)eeprom_read(eeprom_addr(ADDR_CONF_FREQ)+0x02) << 8 | (uint32_t)eeprom_read(eeprom_addr(ADDR_CONF_FREQ)+0x03);
|
||||
uint32_t bw = (uint32_t)eeprom_read(eeprom_addr(ADDR_CONF_BW)+0x00) << 24 | (uint32_t)eeprom_read(eeprom_addr(ADDR_CONF_BW)+0x01) << 16 | (uint32_t)eeprom_read(eeprom_addr(ADDR_CONF_BW)+0x02) << 8 | (uint32_t)eeprom_read(eeprom_addr(ADDR_CONF_BW)+0x03);
|
||||
#endif
|
||||
radio->setSpreadingFactor(sf);
|
||||
radio->setCodingRate4(cr);
|
||||
setTXPower(radio, txp);
|
||||
radio->setFrequency(freq);
|
||||
radio->setSignalBandwidth(bw);
|
||||
radio->updateBitrate();
|
||||
}
|
||||
}
|
||||
void eeprom_conf_load(PhysicalLayer* radio) {
|
||||
// \todo remove, or will attermann need it?
|
||||
//if (eeprom_have_conf()) {
|
||||
// if (!(radio->getRadioOnline())) {
|
||||
// #if HAS_EEPROM
|
||||
// uint8_t sf = EEPROM.read(eeprom_addr(ADDR_CONF_SF));
|
||||
// uint8_t cr = EEPROM.read(eeprom_addr(ADDR_CONF_CR));
|
||||
// uint8_t txp = EEPROM.read(eeprom_addr(ADDR_CONF_TXP));
|
||||
// uint32_t freq = (uint32_t)EEPROM.read(eeprom_addr(ADDR_CONF_FREQ)+0x00) << 24 | (uint32_t)EEPROM.read(eeprom_addr(ADDR_CONF_FREQ)+0x01) << 16 | (uint32_t)EEPROM.read(eeprom_addr(ADDR_CONF_FREQ)+0x02) << 8 | (uint32_t)EEPROM.read(eeprom_addr(ADDR_CONF_FREQ)+0x03);
|
||||
// uint32_t bw = (uint32_t)EEPROM.read(eeprom_addr(ADDR_CONF_BW)+0x00) << 24 | (uint32_t)EEPROM.read(eeprom_addr(ADDR_CONF_BW)+0x01) << 16 | (uint32_t)EEPROM.read(eeprom_addr(ADDR_CONF_BW)+0x02) << 8 | (uint32_t)EEPROM.read(eeprom_addr(ADDR_CONF_BW)+0x03);
|
||||
// #elif MCU_VARIANT == MCU_NRF52
|
||||
// uint8_t sf = eeprom_read(eeprom_addr(ADDR_CONF_SF));
|
||||
// uint8_t cr = eeprom_read(eeprom_addr(ADDR_CONF_CR));
|
||||
// uint8_t txp = eeprom_read(eeprom_addr(ADDR_CONF_TXP));
|
||||
// uint32_t freq = (uint32_t)eeprom_read(eeprom_addr(ADDR_CONF_FREQ)+0x00) << 24 | (uint32_t)eeprom_read(eeprom_addr(ADDR_CONF_FREQ)+0x01) << 16 | (uint32_t)eeprom_read(eeprom_addr(ADDR_CONF_FREQ)+0x02) << 8 | (uint32_t)eeprom_read(eeprom_addr(ADDR_CONF_FREQ)+0x03);
|
||||
// uint32_t bw = (uint32_t)eeprom_read(eeprom_addr(ADDR_CONF_BW)+0x00) << 24 | (uint32_t)eeprom_read(eeprom_addr(ADDR_CONF_BW)+0x01) << 16 | (uint32_t)eeprom_read(eeprom_addr(ADDR_CONF_BW)+0x02) << 8 | (uint32_t)eeprom_read(eeprom_addr(ADDR_CONF_BW)+0x03);
|
||||
// #endif
|
||||
// radio->setSpreadingFactor(sf);
|
||||
// radio->setCodingRate(cr);
|
||||
// setTXPower(radio, txp);
|
||||
// radio->setFrequency(freq);
|
||||
// radio->setBandwidth(bw);
|
||||
// radio->updateBitrate();
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
void eeprom_conf_save(RadioInterface* radio) {
|
||||
if (hw_ready && radio->getRadioOnline()) {
|
||||
eeprom_update(eeprom_addr(ADDR_CONF_SF), radio->getSpreadingFactor());
|
||||
eeprom_update(eeprom_addr(ADDR_CONF_CR), radio->getCodingRate4());
|
||||
eeprom_update(eeprom_addr(ADDR_CONF_TXP), radio->getTxPower());
|
||||
void eeprom_conf_save(PhysicalLayer* radio) {
|
||||
// \todo fixme
|
||||
//if (hw_ready && radio->getRadioOnline()) {
|
||||
// eeprom_update(eeprom_addr(ADDR_CONF_SF), radio->getSpreadingFactorVal());
|
||||
// eeprom_update(eeprom_addr(ADDR_CONF_CR), radio->getCodingRateVal());
|
||||
// eeprom_update(eeprom_addr(ADDR_CONF_TXP), radio->getTXPowerVal());
|
||||
|
||||
uint32_t bw = radio->getSignalBandwidth();
|
||||
// uint32_t bw = radio->getBandwidthVal() * 1000;
|
||||
|
||||
eeprom_update(eeprom_addr(ADDR_CONF_BW)+0x00, bw>>24);
|
||||
eeprom_update(eeprom_addr(ADDR_CONF_BW)+0x01, bw>>16);
|
||||
eeprom_update(eeprom_addr(ADDR_CONF_BW)+0x02, bw>>8);
|
||||
eeprom_update(eeprom_addr(ADDR_CONF_BW)+0x03, bw);
|
||||
// eeprom_update(eeprom_addr(ADDR_CONF_BW)+0x00, bw>>24);
|
||||
// eeprom_update(eeprom_addr(ADDR_CONF_BW)+0x01, bw>>16);
|
||||
// eeprom_update(eeprom_addr(ADDR_CONF_BW)+0x02, bw>>8);
|
||||
// eeprom_update(eeprom_addr(ADDR_CONF_BW)+0x03, bw);
|
||||
|
||||
uint32_t freq = radio->getFrequency();
|
||||
// uint32_t freq = radio->getFrequencyVal() * 1000;
|
||||
|
||||
eeprom_update(eeprom_addr(ADDR_CONF_FREQ)+0x00, freq>>24);
|
||||
eeprom_update(eeprom_addr(ADDR_CONF_FREQ)+0x01, freq>>16);
|
||||
eeprom_update(eeprom_addr(ADDR_CONF_FREQ)+0x02, freq>>8);
|
||||
eeprom_update(eeprom_addr(ADDR_CONF_FREQ)+0x03, freq);
|
||||
// eeprom_update(eeprom_addr(ADDR_CONF_FREQ)+0x00, freq>>24);
|
||||
// eeprom_update(eeprom_addr(ADDR_CONF_FREQ)+0x01, freq>>16);
|
||||
// eeprom_update(eeprom_addr(ADDR_CONF_FREQ)+0x02, freq>>8);
|
||||
// eeprom_update(eeprom_addr(ADDR_CONF_FREQ)+0x03, freq);
|
||||
|
||||
eeprom_update(eeprom_addr(ADDR_CONF_OK), CONF_OK_BYTE);
|
||||
led_indicate_info(10);
|
||||
} else {
|
||||
led_indicate_warning(10);
|
||||
}
|
||||
// eeprom_update(eeprom_addr(ADDR_CONF_OK), CONF_OK_BYTE);
|
||||
// led_indicate_info(10);
|
||||
//} else {
|
||||
// led_indicate_warning(10);
|
||||
//}
|
||||
}
|
||||
|
||||
void eeprom_conf_delete() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user