kopia lustrzana https://github.com/meshtastic/firmware
new RF95 driver is written
rodzic
b1a55b4576
commit
e9ca7792eb
|
@ -0,0 +1,132 @@
|
||||||
|
#include "RF95Interface.h"
|
||||||
|
#include "MeshRadio.h" // kinda yucky, but we need to know which region we are in
|
||||||
|
|
||||||
|
#include <configuration.h>
|
||||||
|
|
||||||
|
RF95Interface::RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, SPIClass &spi)
|
||||||
|
: RadioLibInterface(cs, irq, rst, 0, spi)
|
||||||
|
{
|
||||||
|
// FIXME - we assume devices never get destroyed
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Initialise the Driver transport hardware and software.
|
||||||
|
/// Make sure the Driver is properly configured before calling init().
|
||||||
|
/// \return true if initialisation succeeded.
|
||||||
|
bool RF95Interface::init()
|
||||||
|
{
|
||||||
|
// FIXME, move this to main
|
||||||
|
SPI.begin();
|
||||||
|
|
||||||
|
applyModemConfig();
|
||||||
|
if (power > 20) // This chip has lower power limits than some
|
||||||
|
power = 20;
|
||||||
|
|
||||||
|
int res;
|
||||||
|
/**
|
||||||
|
* We do a nasty check on freq range to figure our RFM96 vs RFM95
|
||||||
|
*/
|
||||||
|
if (CH0 < 500.0) {
|
||||||
|
auto dev = new RFM96(&module);
|
||||||
|
lora = dev;
|
||||||
|
res = dev->begin(freq, bw, sf, cr, syncWord, power, currentLimit, preambleLength);
|
||||||
|
} else {
|
||||||
|
auto dev = new RFM95(&module);
|
||||||
|
lora = dev;
|
||||||
|
res = dev->begin(freq, bw, sf, cr, syncWord, power, currentLimit, preambleLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_MSG("LORA init result %d\n", res);
|
||||||
|
|
||||||
|
if (res == ERR_NONE)
|
||||||
|
res = lora->setCRC(SX126X_LORA_CRC_ON);
|
||||||
|
|
||||||
|
if (res == ERR_NONE)
|
||||||
|
startReceive(); // start receiving
|
||||||
|
|
||||||
|
return res == ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RF95Interface::reconfigure()
|
||||||
|
{
|
||||||
|
applyModemConfig();
|
||||||
|
|
||||||
|
// set mode to standby
|
||||||
|
setStandby();
|
||||||
|
|
||||||
|
// configure publicly accessible settings
|
||||||
|
int err = lora->setSpreadingFactor(sf);
|
||||||
|
assert(err == ERR_NONE);
|
||||||
|
|
||||||
|
err = lora->setBandwidth(bw);
|
||||||
|
assert(err == ERR_NONE);
|
||||||
|
|
||||||
|
err = lora->setCodingRate(cr);
|
||||||
|
assert(err == ERR_NONE);
|
||||||
|
|
||||||
|
err = lora->setSyncWord(syncWord);
|
||||||
|
assert(err == ERR_NONE);
|
||||||
|
|
||||||
|
err = lora->setCurrentLimit(currentLimit);
|
||||||
|
assert(err == ERR_NONE);
|
||||||
|
|
||||||
|
err = lora->setPreambleLength(preambleLength);
|
||||||
|
assert(err == ERR_NONE);
|
||||||
|
|
||||||
|
err = lora->setFrequency(freq);
|
||||||
|
assert(err == ERR_NONE);
|
||||||
|
|
||||||
|
if (power > 20) // This chip has lower power limits than some
|
||||||
|
power = 20;
|
||||||
|
err = lora->setOutputPower(power);
|
||||||
|
assert(err == ERR_NONE);
|
||||||
|
|
||||||
|
startReceive(); // restart receiving
|
||||||
|
|
||||||
|
return ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RF95Interface::setStandby()
|
||||||
|
{
|
||||||
|
int err = lora->standby();
|
||||||
|
assert(err == ERR_NONE);
|
||||||
|
|
||||||
|
isReceiving = false; // If we were receiving, not any more
|
||||||
|
completeSending(); // If we were sending, not anymore
|
||||||
|
disableInterrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RF95Interface::startReceive()
|
||||||
|
{
|
||||||
|
setStandby();
|
||||||
|
int err = lora->startReceive();
|
||||||
|
assert(err == ERR_NONE);
|
||||||
|
|
||||||
|
isReceiving = true;
|
||||||
|
|
||||||
|
// Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register bits
|
||||||
|
enableInterrupt(isrRxLevel0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Could we send right now (i.e. either not actively receving or transmitting)? */
|
||||||
|
bool RF95Interface::canSendImmediately()
|
||||||
|
{
|
||||||
|
// We wait _if_ we are partially though receiving a packet (rather than just merely waiting for one).
|
||||||
|
// To do otherwise would be doubly bad because not only would we drop the packet that was on the way in,
|
||||||
|
// we almost certainly guarantee no one outside will like the packet we are sending.
|
||||||
|
bool busyTx = sendingPacket != NULL;
|
||||||
|
bool busyRx = isReceiving && lora->getPacketLength() > 0;
|
||||||
|
|
||||||
|
if (busyTx || busyRx)
|
||||||
|
DEBUG_MSG("Can not set now, busyTx=%d, busyRx=%d\n", busyTx, busyRx);
|
||||||
|
|
||||||
|
return !busyTx && !busyRx;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RF95Interface::sleep()
|
||||||
|
{
|
||||||
|
// put chipset into sleep mode
|
||||||
|
disableInterrupt();
|
||||||
|
lora->sleep();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "MeshRadio.h" // kinda yucky, but we need to know which region we are in
|
||||||
|
#include "RadioLibInterface.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Our new not radiohead adapter for RF95 style radios
|
||||||
|
*/
|
||||||
|
class RF95Interface : public RadioLibInterface
|
||||||
|
{
|
||||||
|
SX1278 *lora; // Either a RFM95 or RFM96 depending on what was stuffed on this board
|
||||||
|
|
||||||
|
public:
|
||||||
|
RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, SPIClass &spi);
|
||||||
|
|
||||||
|
/// Initialise the Driver transport hardware and software.
|
||||||
|
/// Make sure the Driver is properly configured before calling init().
|
||||||
|
/// \return true if initialisation succeeded.
|
||||||
|
virtual bool init();
|
||||||
|
|
||||||
|
/// Apply any radio provisioning changes
|
||||||
|
/// Make sure the Driver is properly configured before calling init().
|
||||||
|
/// \return true if initialisation succeeded.
|
||||||
|
virtual bool reconfigure();
|
||||||
|
|
||||||
|
/// Prepare hardware for sleep. Call this _only_ for deep sleep, not needed for light sleep.
|
||||||
|
virtual bool sleep();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Glue functions called from ISR land
|
||||||
|
*/
|
||||||
|
virtual void INTERRUPT_ATTR disableInterrupt() { lora->clearDio0Action(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable a particular ISR callback glue function
|
||||||
|
*/
|
||||||
|
virtual void enableInterrupt(void (*callback)()) { lora->setDio0Action(callback); }
|
||||||
|
|
||||||
|
/** Could we send right now (i.e. either not actively receiving or transmitting)? */
|
||||||
|
virtual bool canSendImmediately();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start waiting to receive a message
|
||||||
|
*/
|
||||||
|
virtual void startReceive();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setStandby();
|
||||||
|
};
|
|
@ -11,7 +11,7 @@ static SPISettings spiSettings(4000000, MSBFIRST, SPI_MODE0);
|
||||||
|
|
||||||
RadioLibInterface::RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
|
RadioLibInterface::RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
|
||||||
SPIClass &spi, PhysicalLayer *_iface)
|
SPIClass &spi, PhysicalLayer *_iface)
|
||||||
: module(cs, irq, rst, busy, spi, spiSettings), iface(*_iface)
|
: module(cs, irq, rst, busy, spi, spiSettings), iface(_iface)
|
||||||
{
|
{
|
||||||
assert(!instance); // We assume only one for now
|
assert(!instance); // We assume only one for now
|
||||||
instance = this;
|
instance = this;
|
||||||
|
@ -156,9 +156,9 @@ void RadioLibInterface::handleReceiveInterrupt()
|
||||||
DEBUG_MSG("handling lora RX interrupt\n");
|
DEBUG_MSG("handling lora RX interrupt\n");
|
||||||
|
|
||||||
// read the number of actually received bytes
|
// read the number of actually received bytes
|
||||||
size_t length = iface.getPacketLength();
|
size_t length = iface->getPacketLength();
|
||||||
|
|
||||||
int state = iface.readData(radiobuf, length);
|
int state = iface->readData(radiobuf, length);
|
||||||
if (state != ERR_NONE) {
|
if (state != ERR_NONE) {
|
||||||
DEBUG_MSG("ignoring received packet due to error=%d\n", state);
|
DEBUG_MSG("ignoring received packet due to error=%d\n", state);
|
||||||
rxBad++;
|
rxBad++;
|
||||||
|
@ -207,7 +207,7 @@ void RadioLibInterface::startSend(MeshPacket *txp)
|
||||||
{
|
{
|
||||||
size_t numbytes = beginSending(txp);
|
size_t numbytes = beginSending(txp);
|
||||||
|
|
||||||
int res = iface.startTransmit(radiobuf, numbytes);
|
int res = iface->startTransmit(radiobuf, numbytes);
|
||||||
assert(res == ERR_NONE);
|
assert(res == ERR_NONE);
|
||||||
|
|
||||||
// Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register bits
|
// Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register bits
|
||||||
|
|
|
@ -52,7 +52,7 @@ class RadioLibInterface : public RadioInterface
|
||||||
/**
|
/**
|
||||||
* provides lowest common denominator RadioLib API
|
* provides lowest common denominator RadioLib API
|
||||||
*/
|
*/
|
||||||
PhysicalLayer &iface;
|
PhysicalLayer *iface;
|
||||||
|
|
||||||
/// are _trying_ to receive a packet currently (note - we might just be waiting for one)
|
/// are _trying_ to receive a packet currently (note - we might just be waiting for one)
|
||||||
bool isReceiving;
|
bool isReceiving;
|
||||||
|
@ -69,7 +69,7 @@ class RadioLibInterface : public RadioInterface
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi,
|
RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi,
|
||||||
PhysicalLayer *iface);
|
PhysicalLayer *iface = NULL);
|
||||||
|
|
||||||
virtual ErrorCode send(MeshPacket *p);
|
virtual ErrorCode send(MeshPacket *p);
|
||||||
|
|
||||||
|
|
|
@ -109,13 +109,11 @@ bool SX1262Interface::canSendImmediately()
|
||||||
return !busyTx && !busyRx;
|
return !busyTx && !busyRx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool SX1262Interface::sleep()
|
bool SX1262Interface::sleep()
|
||||||
{
|
{
|
||||||
// we no longer care about interrupts from this device
|
// put chipset into sleep mode
|
||||||
// prepareDeepSleep();
|
disableInterrupt();
|
||||||
|
lora.sleep();
|
||||||
|
|
||||||
// FIXME - put chipset into sleep mode
|
return true;
|
||||||
return false;
|
|
||||||
}
|
}
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
#include "RadioLibInterface.h"
|
#include "RadioLibInterface.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Our adapter for SX1262 radios
|
||||||
|
*/
|
||||||
class SX1262Interface : public RadioLibInterface
|
class SX1262Interface : public RadioLibInterface
|
||||||
{
|
{
|
||||||
SX1262 lora;
|
SX1262 lora;
|
||||||
|
|
Ładowanie…
Reference in New Issue