mirror of
https://github.com/Genaker/LoraSA.git
synced 2026-03-28 17:42:59 +01:00
Initial support for additional Radio Module SX1262
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -51,6 +51,7 @@ struct ScanTaskResult
|
||||
size_t sz;
|
||||
uint32_t *freqs_khz;
|
||||
int16_t *rssis;
|
||||
int16_t *rssis2;
|
||||
int16_t prssi;
|
||||
};
|
||||
|
||||
|
||||
@@ -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 "";
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ struct Event
|
||||
struct
|
||||
{
|
||||
float rssi;
|
||||
float rssi2;
|
||||
float freq;
|
||||
bool trigger;
|
||||
bool detected;
|
||||
|
||||
@@ -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
49
lib/radio/SX1262.cpp
Normal 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
29
lib/radio/radio.h
Normal 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
|
||||
50
src/main.cpp
50
src/main.cpp
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user