Radiolib support (#23)

- Radiolib support
pull/25/head
sh123 2021-10-20 13:20:19 +03:00 zatwierdzone przez GitHub
rodzic b5b61e6318
commit e1520628c5
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
5 zmienionych plików z 179 dodań i 35 usunięć

Wyświetl plik

@ -19,6 +19,7 @@
#define CFG_LORA_PIN_SS SS
#define CFG_LORA_PIN_RST LORA_RST
#define CFG_LORA_PIN_DIO0 LORA_IRQ
#define CFG_LORA_PIN_DIO1 LORA_IRQ
#define CFG_LORA_USE_ISR false // set to true for incoming packet ISR usage (stream mode, e.g. speech)
#define CFG_LORA_FREQ 433.775E6

Wyświetl plik

@ -1,12 +1,16 @@
#include <arduino-timer.h>
#include "WiFi.h"
// when defined RadioLib will be used, otherwise arduino-LoRa
//#define USE_RADIOLIB
#include "loraprs_service.h"
#if __has_include("/tmp/esp32_loraprs_config.h")
#pragma message("Using external config")
#include "/tmp/esp32_loraprs_config.h"
#else
#pragma message("Using default config")
#pragma message("Using default built-in config")
#include "config.h"
#endif
@ -34,6 +38,7 @@ void initializeConfig(LoraPrs::Config &cfg) {
cfg.LoraPinSs = CFG_LORA_PIN_SS;
cfg.LoraPinRst = CFG_LORA_PIN_RST;
cfg.LoraPinDio0 = CFG_LORA_PIN_DIO0;
cfg.LoraPinDio1 = CFG_LORA_PIN_DIO1;
cfg.LoraUseIsr = CFG_LORA_USE_ISR; // set to true for incoming packet ISR usage (stream mode, e.g. speech)
// aprs configuration

Wyświetl plik

@ -22,6 +22,7 @@ struct Config
byte LoraPinSs; // lora ss pin
byte LoraPinRst; // lora rst pin
byte LoraPinDio0; // lora dio0 pin
byte LoraPinDio1; // lora dio1 pin
bool LoraUseIsr; // true to use interrupts, false for fallback polling, e.g. if Dio0 is not connected
// bluetooth

Wyświetl plik

@ -1,7 +1,14 @@
#include "loraprs_service.h"
namespace LoraPrs {
byte Service::rxBuf_[256];
#ifdef USE_RADIOLIB
bool Service::interruptEnabled_ = true;
std::shared_ptr<SX1278> Service::radio_;
#endif
Service::Service()
: Kiss::Processor()
, csmaP_(CfgCsmaPersistence)
@ -10,6 +17,9 @@ Service::Service()
, serialBt_()
, serialBLE_()
{
#ifdef USE_RADIOLIB
interruptEnabled_ = true;
#endif
}
void Service::setup(const Config &conf)
@ -118,7 +128,27 @@ void Service::setupLora(long loraFreq, long bw, int sf, int cr, int pwr, int syn
Serial.print(enableCrc); Serial.print("...");
isImplicitHeaderMode_ = sf == 6;
#ifdef USE_RADIOLIB
radio_ = std::make_shared<SX1278>(new Module(config_.LoraPinSs, config_.LoraPinDio0, config_.LoraPinRst, RADIOLIB_NC));
int state = radio_->begin((float)loraFreq / 1e6, (float)bw / 1e3, sf, cr, sync, pwr);
if (state != ERR_NONE) {
Serial.print("Radio start error: "); Serial.println(state);
}
radio_->setCRC(enableCrc);
//radio_->forceLDRO(false);
//radio_->setRfSwitchPins(4, 5);
radio_->clearDio0Action();
radio_->setDio0Action(onLoraDataAvailableIsr);
state = radio_->startReceive();
if (state != ERR_NONE) {
Serial.print("Receive start error: "); Serial.println(state);
}
#else // USE_RADIOLIB
LoRa.setPins(config_.LoraPinSs, config_.LoraPinRst, config_.LoraPinDio0);
int retryCnt = 0;
@ -135,6 +165,7 @@ void Service::setupLora(long loraFreq, long bw, int sf, int cr, int pwr, int syn
LoRa.setSignalBandwidth(bw);
LoRa.setCodingRate4(cr);
LoRa.setTxPower(pwr);
if (enableCrc) {
LoRa.enableCrc();
}
@ -143,30 +174,25 @@ void Service::setupLora(long loraFreq, long bw, int sf, int cr, int pwr, int syn
LoRa.onReceive(onLoraDataAvailableIsr);
LoRa.receive();
}
#endif // USE_RADIOLIB
Serial.println("ok");
}
void Service::setupBt(const String &btName)
{
if (config_.BtEnableBle) {
Serial.print("BLE init " + btName + "...");
if (serialBLE_.begin(btName.c_str())) {
Serial.println("ok");
}
else {
Serial.println("failed");
}
}
else {
Serial.print("BT init " + btName + "...");
String btType = config_.BtEnableBle ? "BLE" : "BT";
Serial.print(btType + " init " + btName + "...");
if (serialBt_.begin(btName)) {
Serial.println("ok");
}
else {
Serial.println("failed");
}
bool btOk = config_.BtEnableBle
? serialBLE_.begin(btName.c_str())
: serialBt_.begin(btName);
if (btOk) {
Serial.println("ok");
}
else {
Serial.println("failed");
}
}
@ -182,6 +208,9 @@ void Service::loop()
// RX path, Rig -> Serial
bool isRigToSerialProcessed = false;
#ifdef USE_RADIOLIB
isRigToSerialProcessed = processRigToSerial();
#else
if (config_.LoraUseIsr) {
isRigToSerialProcessed = processRigToSerial();
} else {
@ -190,6 +219,7 @@ void Service::loop()
isRigToSerialProcessed = true;
}
}
#endif
// TX path, Serial -> Rig
if (!isRigToSerialProcessed) {
@ -202,8 +232,18 @@ void Service::loop()
if (needsBeacon()) {
sendPeriodicBeacon();
}
if (processSerialToRig() && config_.LoraUseIsr) {
LoRa.receive();
bool allTxProcessed = processSerialToRig();
if (allTxProcessed) {
#ifdef USE_RADIOLIB
int state = radio_->startReceive();
if (state != ERR_NONE) {
Serial.print("Start receive error: "); Serial.println(state);
}
#else
if (config_.LoraUseIsr) {
LoRa.receive();
}
#endif
}
csmaSlotTimePrev_ = currentTime;
}
@ -211,18 +251,43 @@ void Service::loop()
delay(CfgPollDelayMs);
}
#ifdef USE_RADIOLIB
ICACHE_RAM_ATTR void Service::onLoraDataAvailableIsr() {
if (interruptEnabled_) {
int packetSize = radio_->getPacketLength();
if (packetSize > 0) {
int state = radio_->readData(rxBuf_, packetSize);
if (state == ERR_NONE) {
queueRigToSerialIsr(Cmd::Data, rxBuf_, packetSize);
} else {
Serial.print("Read data error: "); Serial.println(state);
}
state = radio_->startReceive();
if (state != ERR_NONE) {
Serial.print("Start receive error: "); Serial.println(state);
}
}
}
}
#else // USE_RADIOLIB
ICACHE_RAM_ATTR void Service::onLoraDataAvailableIsr(int packetSize)
{
// TODO, move to separate ESP32 task
int rxBufIndex = 0;
byte rxBuf[packetSize];
for (int i = 0; i < packetSize; i++) {
rxBuf[rxBufIndex++] = LoRa.read();
rxBuf_[rxBufIndex++] = LoRa.read();
}
queueRigToSerialIsr(Cmd::Data, rxBuf, rxBufIndex);
queueRigToSerialIsr(Cmd::Data, rxBuf_, rxBufIndex);
}
#endif // USE_RADIOLIB
void Service::sendPeriodicBeacon()
{
long currentMs = millis();
@ -309,20 +374,35 @@ bool Service::sendAX25ToLora(const AX25::Payload &payload)
void Service::onRigPacket(void *packet, int packetLength)
{
long frequencyError = LoRa.packetFrequencyError();
if (config_.EnableAutoFreqCorrection && abs(frequencyError) > config_.AutoFreqCorrectionDeltaHz) {
config_.LoraFreq -= frequencyError;
Serial.print("Correcting frequency: "); Serial.println(frequencyError);
#ifdef USE_RADIOLIB
long frequencyErrorHz = radio_->getFrequencyError();
#else
long frequencyErrorHz = LoRa.packetFrequencyError();
#endif
if (config_.EnableAutoFreqCorrection && abs(frequencyErrorHz) > config_.AutoFreqCorrectionDeltaHz) {
config_.LoraFreq -= frequencyErrorHz;
Serial.print("Correcting frequency: "); Serial.println(frequencyErrorHz);
#ifdef USE_RADIOLIB
radio_->setFrequency((float)config_.LoraFreq / 1e6);
int state = radio_->startReceive();
if (state != ERR_NONE) {
Serial.print("Start receive error: "); Serial.println(state);
}
#else
LoRa.setFrequency(config_.LoraFreq);
if (config_.LoraUseIsr) {
LoRa.idle();
LoRa.receive();
}
#endif
}
if (config_.EnableKissExtensions) {
#ifdef USE_RADIOLIB
sendSignalReportEvent(radio_->getRSSI(), radio_->getSNR());
#else
sendSignalReportEvent(LoRa.packetRssi(), LoRa.packetSnr());
#endif
}
if (!config_.IsClientMode) {
@ -330,17 +410,19 @@ void Service::onRigPacket(void *packet, int packetLength)
}
}
#ifndef USE_RADIOLIB
void Service::loraReceive(int packetSize)
{
int rxBufIndex = 0;
byte rxBuf[packetSize];
while (LoRa.available()) {
rxBuf[rxBufIndex++] = LoRa.read();
}
sendRigToSerial(Cmd::Data, rxBuf, rxBufIndex);
onRigPacket(rxBuf, rxBufIndex);
}
#endif
void Service::processIncomingRawPacketAsServer(const byte *packet, int packetLength) {
@ -348,10 +430,15 @@ void Service::processIncomingRawPacketAsServer(const byte *packet, int packetLen
if (payload.IsValid()) {
#ifdef USE_RADIOLIB
float snr = radio_->getSNR();
int rssi = radio_->getRSSI();
long frequencyError = radio_->getFrequencyError();
#else
float snr = LoRa.packetSnr();
int rssi = LoRa.packetRssi();
long frequencyError = LoRa.packetFrequencyError();
#endif
String signalReport = String(" ") +
String("rssi: ") +
String(snr < 0 ? rssi + snr : rssi) +
@ -387,22 +474,50 @@ bool Service::onRigTxBegin()
} else {
delay(CfgPollDelayMs);
}
#ifdef USE_RADIOLIB
return true;
#else
return (LoRa.beginPacket(isImplicitHeaderMode_) == 1);
#endif
}
void Service::onRigTx(byte b)
{
#ifdef USE_RADIOLIB
txQueue_.push(b);
#else
LoRa.write(b);
#endif
}
void Service::onRigTxEnd()
{
#ifdef USE_RADIOLIB
int txPacketSize = txQueue_.size();
byte txBuf[txPacketSize];
for (int i = 0; i < txPacketSize; i++) {
txBuf[i] = txQueue_.shift();
}
interruptEnabled_ = false;
int state = radio_->transmit(txBuf, txPacketSize);
if (state != ERR_NONE) {
Serial.print("TX error: "); Serial.println(state);
}
interruptEnabled_ = true;
#endif
if (config_.PttEnable) {
#ifndef USE_RADIOLIB
LoRa.endPacket(false);
#endif
delay(config_.PttTxTailMs);
digitalWrite(config_.PttPin, LOW);
} else {
#ifndef USE_RADIOLIB
LoRa.endPacket(true);
#endif
}
}
@ -428,7 +543,10 @@ bool Service::onSerialRxHasData()
bool Service::onSerialRx(byte *b)
{
int rxResult = config_.BtEnableBle ? serialBLE_.read() : serialBt_.read();
int rxResult = config_.BtEnableBle
? serialBLE_.read()
: serialBt_.read();
if (rxResult == -1) {
return false;
}
@ -482,6 +600,7 @@ void Service::onRadioControlCommand(const std::vector<byte> &rawCommand) {
void Service::onRebootCommand()
{
Serial.println("Reboot requested");
ESP.restart();
}

Wyświetl plik

@ -3,7 +3,15 @@
#include <Arduino.h>
#include <SPI.h>
#ifdef USE_RADIOLIB
#include <RadioLib.h>
#pragma message("Using RadioLib")
#else
#include <LoRa.h>
#pragma message("Using arduino-LoRa")
#endif
#include <WiFi.h>
#include <endian.h>
@ -31,9 +39,13 @@ private:
void reconnectWifi() const;
bool reconnectAprsis();
#ifdef USE_RADIOLIB
void onLoraDataAvailable();
static ICACHE_RAM_ATTR void onLoraDataAvailableIsr();
#else
static ICACHE_RAM_ATTR void onLoraDataAvailableIsr(int packetSize);
void loraReceive(int packetSize);
#endif
void onAprsisDataAvailable();
void sendSignalReportEvent(int rssi, float snr);
@ -109,6 +121,12 @@ private:
long previousBeaconMs_;
// peripherals
static byte rxBuf_[256];
#ifdef USE_RADIOLIB
static bool interruptEnabled_;
CircularBuffer<uint8_t, 256> txQueue_;
static std::shared_ptr<SX1278> radio_;
#endif
BluetoothSerial serialBt_;
BLESerial serialBLE_;
WiFiClient aprsisConn_;