Initial support for additional Radio Module SX1262

This commit is contained in:
Sassa NF
2025-01-26 11:50:29 +00:00
parent 2b1da5ae4a
commit 1963734e48
10 changed files with 298 additions and 21 deletions

View File

@@ -35,8 +35,8 @@ bool initSPIs(Config &config)
// if all the pins are -1, then will use the default for SPI bus_num
hspi.begin(config.spi1.clk, config.spi1.miso, config.spi1.mosi);
Serial.printf("Initialized SPI%d: SC:%d MISO:%d MOSI:%d clock:%d\n",
(int)config.spi1.bus_num, (int)config.spi1.clk,
Serial.printf("Initialized SPI%d @ %x: SC:%d MISO:%d MOSI:%d clock:%d\n",
(int)config.spi1.bus_num, (void *)&hspi, (int)config.spi1.clk,
(int)config.spi1.miso, (int)config.spi1.mosi,
(int)config.spi1.clock_freq);
}

View File

@@ -418,7 +418,7 @@ String _scan_result_str(ScanTaskResult &r)
for (int i = 0; i < r.sz; i++)
{
p += (i == 0 ? "(" : ", (") + String(r.freqs_khz[i]) + ", " + String(r.rssis[i]) +
")";
(r.rssis2 ? ", " + String(r.rssis2[i]) : "") + ")";
}
return p + " ]\n";

View File

@@ -51,6 +51,7 @@ struct ScanTaskResult
size_t sz;
uint32_t *freqs_khz;
int16_t *rssis;
int16_t *rssis2;
int16_t prssi;
};

View File

@@ -88,18 +88,6 @@ Config Config::init()
continue;
}
if (r.key.equalsIgnoreCase("rx_lora"))
{
c.rx_lora = configureLora(r.value);
continue;
}
if (r.key.equalsIgnoreCase("tx_lora"))
{
c.tx_lora = configureLora(r.value);
continue;
}
Serial.printf("Unknown key '%s' will be ignored\n", r.key);
}
@@ -194,6 +182,12 @@ bool Config::updateConfig(String key, String value)
return true;
}
if (key.equalsIgnoreCase("radio2"))
{
radio2 = RadioModuleSPIConfig::configure(value);
return true;
}
UPDATE_BOOL(is_host, key, value);
UPDATE_BOOL(lora_enabled, key, value);
@@ -523,6 +517,102 @@ void Config::configureDetectionStrategy(String cfg)
}
}
RadioModuleSPIConfig RadioModuleSPIConfig::configure(String cfg)
{
RadioModuleSPIConfig c;
c.bus_num = 1;
c.cs = RADIO_MODULE_CS_PIN;
c.rst = RADIO_MODULE_RST_PIN;
c.dio1 = RADIO_MODULE_DIO1_PIN;
c.busy = RADIO_MODULE_BUSY_PIN;
c.clock_freq = RADIO_MODULE_CLOCK_FREQ;
c.msb_first = RADIO_MODULE_MSB_FIRST;
c.spi_mode = RADIO_MODULE_SPI_MODE;
int begin = 0;
int end, i;
while ((i = findSepa(cfg, ",", begin, end)) >= 0)
{
String param = cfg.substring(begin, end);
begin = i;
int j = param.indexOf(":");
if (j < 0)
{
c.module = param;
c.enabled = !param.equalsIgnoreCase("none");
continue;
}
String k = param.substring(0, j);
param = param.substring(j + 1);
k.toLowerCase();
if (k.equals("bus"))
{
c.bus_num = param.toInt();
continue;
}
if (k.equals("rst"))
{
c.rst = param.toInt();
continue;
}
if (k.equals("dio1"))
{
c.dio1 = param.toInt();
continue;
}
if (k.equals("busy"))
{
c.busy = param.toInt();
continue;
}
if (k.equals("freq"))
{
c.clock_freq = param.toInt();
continue;
}
if (k.equals("msb"))
{
c.msb_first = !!param.toInt();
continue;
}
if (k.equals("spi_mode"))
{
c.spi_mode = param.toInt();
continue;
}
c.module = k;
c.cs = param.toInt();
c.enabled = true;
}
return c;
}
String RadioModuleSPIConfig::toStr()
{
if (!enabled)
{
return "none";
}
return module + ":" + String(cs) + ",bus:" + String(bus_num) + ",rst:" + String(rst) +
",dio1:" + String(dio1) + ",busy:" + String(busy) +
",freq:" + String(clock_freq) + ",msb:" + String(msb_first ? 1 : 0) +
",spi_mode:" + String(spi_mode);
}
bool Config::write_config(const char *path)
{
File f = SD.open(path, FILE_WRITE, /*create = */ true);
@@ -549,6 +639,7 @@ bool Config::write_config(const char *path)
f.println("uart1 = " + getConfig("uart1"));
f.println("spi1 = " + getConfig("spi1"));
f.println("wire1 = " + getConfig("wire1"));
f.println("radio2 = " + getConfig("radio2"));
f.close();
return true;
@@ -621,6 +712,11 @@ String Config::getConfig(String key)
return wire1.toStr();
}
if (key.equalsIgnoreCase("radio2"))
{
return radio2.toStr();
}
return "";
}

View File

@@ -96,6 +96,52 @@ struct BusConfig
String toStr();
};
#ifndef RADIO_MODULE_CS_PIN
#define RADIO_MODULE_CS_PIN 38
#endif
#ifndef RADIO_MODULE_DIO1_PIN
#define RADIO_MODULE_DIO1_PIN 40
#endif
#ifndef RADIO_MODULE_RST_PIN
#define RADIO_MODULE_RST_PIN 41
#endif
#ifndef RADIO_MODULE_BUSY_PIN
#define RADIO_MODULE_BUSY_PIN 39
#endif
#ifndef RADIO_MODULE_CLOCK_FREQ
#define RADIO_MODULE_CLOCK_FREQ 16000000
#endif
#ifndef RADIO_MODULE_MSB_FIRST
#define RADIO_MODULE_MSB_FIRST 1
#endif
#ifndef RADIO_MODULE_SPI_MODE
#define RADIO_MODULE_SPI_MODE 0
#endif
struct RadioModuleSPIConfig
{
bool enabled;
String module;
int8_t bus_num;
int8_t cs;
int8_t rst;
int8_t dio1;
int8_t busy;
uint32_t clock_freq;
bool msb_first;
int8_t spi_mode;
static RadioModuleSPIConfig configure(String cfg);
String toStr();
};
#ifndef FREQ_RX
#define FREQ_RX 866
#endif
@@ -136,13 +182,17 @@ struct BusConfig
#endif
#ifndef DEFAULT_SPI1
#define DEFAULT_SPI1 "none"
#define DEFAULT_SPI1 "s1:16000000,clk:42,mosi:46,miso:45"
#endif
#ifndef DEFAULT_WIRE1
#define DEFAULT_WIRE1 "none"
#endif
#ifndef DEFAULT_RADIO2
#define DEFAULT_RADIO2 "none"
#endif
#define CREATE_MISSING_CONFIG true
struct Config
{
@@ -163,6 +213,7 @@ struct Config
BusConfig uart1;
BusConfig spi1;
BusConfig wire1;
RadioModuleSPIConfig radio2;
bool is_host;
bool lora_enabled;
@@ -177,8 +228,8 @@ struct Config
uart0(BusConfig::configure(DEFAULT_UART0)),
uart1(BusConfig::configure(DEFAULT_UART1)),
spi1(BusConfig::configure(DEFAULT_SPI1)),
wire1(BusConfig::configure(DEFAULT_WIRE1)),
lora_enabled(DEFAULT_LORA_ENABLED) {};
wire1(BusConfig::configure(DEFAULT_WIRE1)), lora_enabled(DEFAULT_LORA_ENABLED),
radio2(RadioModuleSPIConfig::configure(DEFAULT_RADIO2)) {};
bool write_config(const char *path);

View File

@@ -18,6 +18,7 @@ struct Event
struct
{
float rssi;
float rssi2;
float freq;
bool trigger;
bool detected;

View File

@@ -533,7 +533,7 @@ bool beginDisplay()
Wire.beginTransmission(DISPLAY_ADDR);
if (Wire.endTransmission() == 0)
{
Serial.printf("Find Display model at 0x%X address\n", DISPLAY_ADDR);
Serial.printf("Found Display model at 0x%X address\n", DISPLAY_ADDR);
u8g2 = new DISPLAY_MODEL(U8G2_R0, U8X8_PIN_NONE);
u8g2->begin();
u8g2->clearBuffer();
@@ -569,6 +569,7 @@ bool beginSDCard()
else
{
Serial.println("Warning: Failed to init Sd Card");
SDCardSPI.end();
}
#endif
return false;
@@ -792,10 +793,9 @@ void setupBoards(bool disable_u8g2)
bool sdReady;
#ifndef DISABLE_SDCARD
for (int i = 0; i < 5 && !(sdReady = beginSDCard()); i++)
if (!(sdReady = beginSDCard()))
{
Serial.println("SD card failed or not found");
delay(1000);
}
#endif

49
lib/radio/SX1262.cpp Normal file
View File

@@ -0,0 +1,49 @@
#include "radio.h"
#include <LoRaBoards.h>
#include <bus.h>
SX1262Module::SX1262Module(RadioModuleSPIConfig radio2) : RadioModule()
{
_radio = new SX1262(new Module(
radio2.cs, radio2.dio1, radio2.rst, radio2.busy, radio2.bus_num == 1 ? hspi : SPI,
SPISettings(radio2.clock_freq, radio2.msb_first ? MSBFIRST : LSBFIRST,
radio2.spi_mode)));
Serial.printf("Initialized Radio2: %s\n", radio2.toStr().c_str());
}
int16_t SX1262Module::beginScan(float init_freq, float bw, uint8_t shaping)
{
int16_t status = _radio->beginFSK(init_freq);
if (status != RADIOLIB_ERR_NONE)
{
Serial.printf("Radio2: Failed beginFSK: %d\n", status);
return status;
}
status = _radio->startReceive(RADIOLIB_SX126X_RX_TIMEOUT_NONE);
if (status != RADIOLIB_ERR_NONE)
{
Serial.printf("Radio2: Failed startReceive: %d\n", status);
return status;
}
status = setFrequency(init_freq);
if (status != RADIOLIB_ERR_NONE)
{
Serial.printf("Radio2: Failed setFrequency: %d\n", status);
return status;
}
return status;
}
int16_t SX1262Module::setFrequency(float freq)
{
return _radio->setFrequency(freq,
true); // false = calibration is needed here
}
int16_t SX1262Module::setRxBandwidth(float bw) { return _radio->setRxBandwidth(bw); }
float SX1262Module::getRSSI() { return _radio->getRSSI(false); }

29
lib/radio/radio.h Normal file
View File

@@ -0,0 +1,29 @@
#pragma once
#include <RadioLib.h>
#include <config.h>
struct RadioModule
{
RadioModule() {};
virtual int16_t beginScan(float init_freq, float bw, uint8_t shaping) = 0;
virtual int16_t setFrequency(float freq) = 0;
virtual int16_t setRxBandwidth(float bw) = 0;
virtual float getRSSI() = 0;
};
#ifdef USING_SX1262
struct SX1262Module : RadioModule
{
SX1262 *_radio;
SX1262Module(RadioModuleSPIConfig cfg);
int16_t beginScan(float init_freq, float bw, uint8_t shaping) override;
int16_t setFrequency(float freq) override;
int16_t setRxBandwidth(float bw) override;
float getRSSI() override;
};
#endif

View File

@@ -141,10 +141,13 @@ void sendBTData(float heading, float rssi)
#include <bus.h>
#include <heading.h>
#include <radio.h>
DroneHeading droneHeading;
Compass *compass = NULL;
RadioModule *radio2;
#define BT_SCAN_DELAY 60 * 1 * 1000
#define WF_SCAN_DELAY 60 * 2 * 1000
long noDevicesMillis = 0, cycleCnt = 0;
@@ -942,6 +945,25 @@ void init_radio()
setFrequency(CONF_FREQ_BEGIN);
delay(100);
if (config.radio2.enabled && config.radio2.module.equalsIgnoreCase("SX1262"))
{
radio2 = new SX1262Module(config.radio2);
state = radio2->beginScan(CONF_FREQ_BEGIN, BANDWIDTH, RADIOLIB_SHAPING_NONE);
if (state == RADIOLIB_ERR_NONE)
{
both.println("Initialized additional module OK");
radio2->setRxBandwidth(BANDWIDTH);
}
else
{
Serial.printf("Error initializing additional module: %d\n", state);
if (state == RADIOLIB_ERR_CHIP_NOT_FOUND)
{
Serial.println("Radio2: CHIP NOT FOUND");
}
}
}
}
struct frequency_scan_result
@@ -973,12 +995,19 @@ void eventListenerForReport(void *arg, Event &e)
frequency_scan_result.readings_sz = frequency_scan_result.dump.sz + 1;
uint32_t *f = new uint32_t[frequency_scan_result.readings_sz];
int16_t *r = new int16_t[frequency_scan_result.readings_sz];
int16_t *r2 = radio2 ? new int16_t[frequency_scan_result.readings_sz] : NULL;
if (old_sz > 0)
{
memcpy(f, frequency_scan_result.dump.freqs_khz,
old_sz * sizeof(uint32_t));
memcpy(r, frequency_scan_result.dump.rssis, old_sz * sizeof(int16_t));
if (radio2)
{
memcpy(r2, frequency_scan_result.dump.rssis2,
old_sz * sizeof(int16_t));
delete[] frequency_scan_result.dump.rssis2;
}
delete[] frequency_scan_result.dump.freqs_khz;
delete[] frequency_scan_result.dump.rssis;
@@ -986,12 +1015,16 @@ void eventListenerForReport(void *arg, Event &e)
frequency_scan_result.dump.freqs_khz = f;
frequency_scan_result.dump.rssis = r;
frequency_scan_result.dump.rssis2 = r2;
}
frequency_scan_result.dump.freqs_khz[frequency_scan_result.dump.sz] =
e.detected.freq * 1000; // convert to kHz
frequency_scan_result.dump.rssis[frequency_scan_result.dump.sz] =
max(e.detected.rssi, -999.0f);
if (radio2)
frequency_scan_result.dump.rssis2[frequency_scan_result.dump.sz] =
max(e.detected.rssi2, -999.0f);
frequency_scan_result.dump.sz++;
if (e.epoch != frequency_scan_result.last_epoch ||
@@ -2705,6 +2738,14 @@ void doScan()
int display_x = x / SCAN_RBW_FACTOR;
freqX[(int)r.current_frequency] = display_x;
setFrequency(curr_freq / 1000.0);
if (radio2 != NULL)
{
state = radio2->setFrequency(curr_freq / 1000.0);
if (state != RADIOLIB_ERR_NONE)
{
Serial.printf("Radio2: Failed to set freq: %d\n", state);
}
}
LOG("Step:%d Freq: %f\n", x, r.current_frequency);
// SpectralScan Method
@@ -2736,6 +2777,8 @@ void doScan()
#endif
#ifdef METHOD_RSSI
// Spectrum analyzer using getRSSI
float rssi2 = -999;
{
LOG("METHOD RSSI");
@@ -2755,6 +2798,7 @@ void doScan()
else
g = &getRSSI;
uint16_t max_rssi = 120;
// Scan if not in the ignore list
if (ignoredFreq.find((int)r.current_frequency) == ignoredFreq.end())
{
@@ -2766,6 +2810,11 @@ void doScan()
{
xRSSI[display_x] = (int)max_rssi;
}
for (int i = 0; radio2 != NULL && i < samples; i++)
{
rssi2 = max(rssi2, radio2->getRSSI());
}
}
else
{
@@ -2801,6 +2850,7 @@ void doScan()
Event event = r.detect(result, filtered_result,
RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE, samples);
event.time_ms = millis();
event.detected.rssi2 = rssi2;
size_t detected_at = event.detected.detected_at;
if (max_rssi_x > detected_at)