firmware/src/mesh/SX1262Interface.cpp

221 lines
6.4 KiB
C++
Raw Normal View History

#include "SX1262Interface.h"
#include <configuration.h>
// Particular boards might define a different max power based on what their hardware can do
#ifndef SX1262_MAX_POWER
#define SX1262_MAX_POWER 22
#endif
SX1262Interface::SX1262Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
SPIClass &spi)
: RadioLibInterface(cs, irq, rst, busy, spi, &lora), lora(&module)
{
}
/// Initialise the Driver transport hardware and software.
/// Make sure the Driver is properly configured before calling init().
/// \return true if initialisation succeeded.
bool SX1262Interface::init()
{
#ifdef SX1262_POWER_EN
digitalWrite(SX1262_POWER_EN, HIGH);
pinMode(SX1262_POWER_EN, OUTPUT);
#endif
RadioLibInterface::init();
#ifdef SX1262_RXEN // set not rx or tx mode
digitalWrite(SX1262_RXEN, LOW); // Set low before becoming an output
pinMode(SX1262_RXEN, OUTPUT);
2020-06-16 13:26:21 +00:00
#endif
#ifdef SX1262_TXEN
digitalWrite(SX1262_TXEN, LOW);
pinMode(SX1262_TXEN, OUTPUT);
#endif
#ifndef SX1262_E22
float tcxoVoltage = 0; // None - we use an XTAL
#else
float tcxoVoltage =
2020-06-16 19:02:13 +00:00
1.8; // E22 uses DIO3 to power tcxo per https://github.com/jgromes/RadioLib/issues/12#issuecomment-520695575
#endif
bool useRegulatorLDO = false; // Seems to depend on the connection to pin 9/DCC_SW - if an inductor DCDC?
applyModemConfig();
if (power == 0)
power = SX1262_MAX_POWER;
if (power > SX1262_MAX_POWER) // This chip has lower power limits than some
power = SX1262_MAX_POWER;
2020-09-16 01:54:50 +00:00
limitPower();
int res = lora.begin(freq, bw, sf, cr, syncWord, power, currentLimit, preambleLength, tcxoVoltage, useRegulatorLDO);
2020-07-10 21:37:01 +00:00
DEBUG_MSG("SX1262 init result %d\n", res);
2020-06-16 13:38:08 +00:00
#ifdef SX1262_TXEN
2020-06-16 13:26:21 +00:00
// lora.begin sets Dio2 as RF switch control, which is not true if we are manually controlling RX and TX
if (res == ERR_NONE)
res = lora.setDio2AsRfSwitch(false);
#endif
2020-04-30 17:00:40 +00:00
if (res == ERR_NONE)
res = lora.setCRC(SX126X_LORA_CRC_ON);
2020-04-30 19:37:58 +00:00
if (res == ERR_NONE)
startReceive(); // start receiving
2020-04-30 20:50:40 +00:00
return res == ERR_NONE;
}
bool SX1262Interface::reconfigure()
{
applyModemConfig();
// set mode to standby
2020-04-30 20:50:40 +00:00
setStandby();
// configure publicly accessible settings
2020-04-30 20:50:40 +00:00
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);
2020-08-25 19:06:36 +00:00
// Hmm - seems to lower SNR when the signal levels are high. Leaving off for now...
err = lora.setRxGain(true);
assert(err == ERR_NONE);
2020-08-25 19:06:36 +00:00
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 > 22) // This chip has lower power limits than some
power = 22;
err = lora.setOutputPower(power);
assert(err == ERR_NONE);
2020-04-30 19:37:58 +00:00
startReceive(); // restart receiving
return ERR_NONE;
}
void INTERRUPT_ATTR SX1262Interface::disableInterrupt()
{
lora.clearDio1Action();
}
2020-04-30 20:50:40 +00:00
void SX1262Interface::setStandby()
{
int err = lora.standby();
assert(err == ERR_NONE);
#ifdef SX1262_RXEN // we have RXEN/TXEN control - turn off RX and TX power
digitalWrite(SX1262_RXEN, LOW);
2020-06-16 19:02:13 +00:00
#endif
2020-06-16 13:26:21 +00:00
#ifdef SX1262_TXEN
digitalWrite(SX1262_TXEN, LOW);
#endif
2020-04-30 20:50:40 +00:00
isReceiving = false; // If we were receiving, not any more
disableInterrupt();
2020-05-01 05:53:21 +00:00
completeSending(); // If we were sending, not anymore
2020-04-30 20:50:40 +00:00
}
2020-05-01 02:58:10 +00:00
/**
* Add SNR data to received messages
*/
2020-05-01 05:53:21 +00:00
void SX1262Interface::addReceiveMetadata(MeshPacket *mp)
{
2020-08-25 19:06:36 +00:00
// DEBUG_MSG("PacketStatus %x\n", lora.getPacketStatus());
2020-05-01 02:58:10 +00:00
mp->rx_snr = lora.getSNR();
}
/** We override to turn on transmitter power as needed.
*/
2020-06-16 13:26:21 +00:00
void SX1262Interface::configHardwareForSend()
{
2020-06-16 13:26:21 +00:00
#ifdef SX1262_TXEN // we have RXEN/TXEN control - turn on TX power / off RX power
digitalWrite(SX1262_TXEN, HIGH);
#endif
2020-06-16 13:26:21 +00:00
RadioLibInterface::configHardwareForSend();
}
// For power draw measurements, helpful to force radio to stay sleeping
// #define SLEEP_ONLY
2020-04-30 19:37:58 +00:00
void SX1262Interface::startReceive()
{
#ifdef SLEEP_ONLY
sleep();
#else
2020-06-16 13:26:21 +00:00
setStandby();
#ifdef SX1262_RXEN // we have RXEN/TXEN control - turn on RX power / off TX power
digitalWrite(SX1262_RXEN, HIGH);
#endif
// int err = lora.startReceive();
int err = lora.startReceiveDutyCycleAuto(); // We use a 32 bit preamble so this should save some power by letting radio sit in
// standby mostly.
2020-04-30 19:37:58 +00:00
assert(err == ERR_NONE);
2020-04-30 20:50:40 +00:00
isReceiving = true;
2020-04-30 19:37:58 +00:00
// Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register bits
enableInterrupt(isrRxLevel0);
#endif
}
/** Could we send right now (i.e. either not actively receving or transmitting)? */
bool SX1262Interface::isActivelyReceiving()
{
// The IRQ status will be cleared when we start our read operation. Check if we've started a header, but haven't yet
// received and handled the interrupt for reading the packet/handling errors.
// FIXME: it would be better to check for preamble, but we currently have our ISR not set to fire for packets that
// never even get a valid header, so we don't want preamble to get set and stay set due to noise on the network.
uint16_t irq = lora.getIrqStatus();
bool hasPreamble = (irq & SX126X_IRQ_HEADER_VALID);
// this is not correct - often always true - need to add an extra conditional
// size_t bytesPending = lora.getPacketLength();
// if (hasPreamble) DEBUG_MSG("rx hasPreamble\n");
return hasPreamble;
}
bool SX1262Interface::sleep()
{
// Not keeping config is busted - next time nrf52 board boots lora sending fails tcxo related? - see datasheet
DEBUG_MSG("sx1262 entering sleep mode (FIXME, don't keep config)\n");
2020-10-30 09:05:32 +00:00
setStandby(); // Stop any pending operations
// turn off TCXO if it was powered
// FIXME - this isn't correct
// lora.setTCXO(0);
// put chipset into sleep mode (we've already disabled interrupts by now)
bool keepConfig = true;
lora.sleep(keepConfig); // Note: we do not keep the config, full reinit will be needed
2020-10-30 09:05:32 +00:00
#ifdef SX1262_POWER_EN
digitalWrite(SX1262_POWER_EN, LOW);
#endif
2020-05-01 00:43:29 +00:00
return true;
}