|
|
|
@ -70,115 +70,98 @@ |
|
|
|
|
|
|
|
|
|
// IRQ masks
|
|
|
|
|
#define IRQ_TX_DONE_MASK_7X 0x08 |
|
|
|
|
#define IRQ_PAYLOAD_CRC_ERROR_MASK_7X 0x20 |
|
|
|
|
#define IRQ_RX_DONE_MASK_7X 0x40 |
|
|
|
|
|
|
|
|
|
extern SPIClass SPI; |
|
|
|
|
#define IRQ_PAYLOAD_CRC_ERROR_MASK_7X 0x20 |
|
|
|
|
|
|
|
|
|
#define MAX_PKT_LENGTH 255 |
|
|
|
|
#define SYNC_WORD_7X 0x12 |
|
|
|
|
|
|
|
|
|
extern SPIClass SPI; |
|
|
|
|
|
|
|
|
|
sx127x::sx127x() : |
|
|
|
|
_spiSettings(8E6, MSBFIRST, SPI_MODE0), |
|
|
|
|
_ss(LORA_DEFAULT_SS_PIN), _reset(LORA_DEFAULT_RESET_PIN), _dio0(LORA_DEFAULT_DIO0_PIN), |
|
|
|
|
_frequency(0), |
|
|
|
|
_packetIndex(0), |
|
|
|
|
_preinit_done(false), |
|
|
|
|
_onReceive(NULL) |
|
|
|
|
{ |
|
|
|
|
// overide Stream timeout value
|
|
|
|
|
setTimeout(0); |
|
|
|
|
} |
|
|
|
|
_onReceive(NULL) { setTimeout(0); } |
|
|
|
|
|
|
|
|
|
void sx127x::setSPIFrequency(uint32_t frequency) { _spiSettings = SPISettings(frequency, MSBFIRST, SPI_MODE0); } |
|
|
|
|
void sx127x::setPins(int ss, int reset, int dio0, int busy) { _ss = ss; _reset = reset; _dio0 = dio0; _busy = busy; } |
|
|
|
|
uint8_t ISR_VECT sx127x::readRegister(uint8_t address) { return singleTransfer(address & 0x7f, 0x00); } |
|
|
|
|
void sx127x::writeRegister(uint8_t address, uint8_t value) { singleTransfer(address | 0x80, value); } |
|
|
|
|
void sx127x::idle() { writeRegister(REG_OP_MODE_7X, MODE_LONG_RANGE_MODE_7X | MODE_STDBY_7X); } |
|
|
|
|
void sx127x::sleep() { writeRegister(REG_OP_MODE_7X, MODE_LONG_RANGE_MODE_7X | MODE_SLEEP_7X); } |
|
|
|
|
uint8_t sx127x::modemStatus() { return readRegister(REG_MODEM_STAT_7X); } |
|
|
|
|
void sx127x::setSyncWord(uint8_t sw) { writeRegister(REG_SYNC_WORD_7X, sw); } |
|
|
|
|
void sx127x::enableCrc() { writeRegister(REG_MODEM_CONFIG_2_7X, readRegister(REG_MODEM_CONFIG_2_7X) | 0x04); } |
|
|
|
|
void sx127x::disableCrc() { writeRegister(REG_MODEM_CONFIG_2_7X, readRegister(REG_MODEM_CONFIG_2_7X) & 0xfb); } |
|
|
|
|
void sx127x::enableTCXO() { uint8_t tcxo_reg = readRegister(REG_TCXO_7X); writeRegister(REG_TCXO_7X, tcxo_reg | 0x10); } |
|
|
|
|
void sx127x::disableTCXO() { uint8_t tcxo_reg = readRegister(REG_TCXO_7X); writeRegister(REG_TCXO_7X, tcxo_reg & 0xEF); } |
|
|
|
|
void sx127x::explicitHeaderMode() { _implicitHeaderMode = 0; writeRegister(REG_MODEM_CONFIG_1_7X, readRegister(REG_MODEM_CONFIG_1_7X) & 0xfe); } |
|
|
|
|
void sx127x::implicitHeaderMode() { _implicitHeaderMode = 1; writeRegister(REG_MODEM_CONFIG_1_7X, readRegister(REG_MODEM_CONFIG_1_7X) | 0x01); } |
|
|
|
|
byte sx127x::random() { return readRegister(REG_RSSI_WIDEBAND_7X); } |
|
|
|
|
void sx127x::flush() { } |
|
|
|
|
|
|
|
|
|
bool sx127x::preInit() { |
|
|
|
|
// setup pins
|
|
|
|
|
pinMode(_ss, OUTPUT); |
|
|
|
|
// set SS high
|
|
|
|
|
digitalWrite(_ss, HIGH); |
|
|
|
|
|
|
|
|
|
SPI.begin(); |
|
|
|
|
|
|
|
|
|
// check version (retry for up to 2 seconds)
|
|
|
|
|
// Check modem version
|
|
|
|
|
uint8_t version; |
|
|
|
|
long start = millis(); |
|
|
|
|
while (((millis() - start) < 2000) && (millis() >= start)) { |
|
|
|
|
while (((millis() - start) < 500) && (millis() >= start)) { |
|
|
|
|
version = readRegister(REG_VERSION_7X); |
|
|
|
|
if (version == 0x12) { |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
if (version == 0x12) { break; } |
|
|
|
|
delay(100); |
|
|
|
|
} |
|
|
|
|
if (version != 0x12) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (version != 0x12) { return false; } |
|
|
|
|
|
|
|
|
|
_preinit_done = true; |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint8_t ISR_VECT sx127x::readRegister(uint8_t address) |
|
|
|
|
{ |
|
|
|
|
return singleTransfer(address & 0x7f, 0x00); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::writeRegister(uint8_t address, uint8_t value) |
|
|
|
|
{ |
|
|
|
|
singleTransfer(address | 0x80, value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint8_t ISR_VECT sx127x::singleTransfer(uint8_t address, uint8_t value) |
|
|
|
|
{ |
|
|
|
|
uint8_t ISR_VECT sx127x::singleTransfer(uint8_t address, uint8_t value) { |
|
|
|
|
uint8_t response; |
|
|
|
|
|
|
|
|
|
digitalWrite(_ss, LOW); |
|
|
|
|
|
|
|
|
|
SPI.beginTransaction(_spiSettings); |
|
|
|
|
SPI.transfer(address); |
|
|
|
|
response = SPI.transfer(value); |
|
|
|
|
SPI.endTransaction(); |
|
|
|
|
|
|
|
|
|
digitalWrite(_ss, HIGH); |
|
|
|
|
|
|
|
|
|
return response; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int sx127x::begin(long frequency) |
|
|
|
|
{ |
|
|
|
|
int sx127x::begin(long frequency) { |
|
|
|
|
if (_reset != -1) { |
|
|
|
|
pinMode(_reset, OUTPUT); |
|
|
|
|
|
|
|
|
|
// perform reset
|
|
|
|
|
// Perform reset
|
|
|
|
|
digitalWrite(_reset, LOW); |
|
|
|
|
delay(10); |
|
|
|
|
digitalWrite(_reset, HIGH); |
|
|
|
|
delay(10); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (_busy != -1) { |
|
|
|
|
pinMode(_busy, INPUT); |
|
|
|
|
} |
|
|
|
|
if (_busy != -1) { pinMode(_busy, INPUT); } |
|
|
|
|
|
|
|
|
|
if (!_preinit_done) { |
|
|
|
|
if (!preInit()) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
if (!preInit()) { return false; } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// put in sleep mode
|
|
|
|
|
sleep(); |
|
|
|
|
|
|
|
|
|
// set frequency
|
|
|
|
|
setFrequency(frequency); |
|
|
|
|
|
|
|
|
|
// set base addresses
|
|
|
|
|
writeRegister(REG_FIFO_TX_BASE_ADDR_7X, 0); |
|
|
|
|
writeRegister(REG_FIFO_RX_BASE_ADDR_7X, 0); |
|
|
|
|
|
|
|
|
|
// set LNA boost
|
|
|
|
|
// set LNA boost and auto AGC
|
|
|
|
|
writeRegister(REG_LNA_7X, readRegister(REG_LNA_7X) | 0x03); |
|
|
|
|
|
|
|
|
|
// set auto AGC
|
|
|
|
|
writeRegister(REG_MODEM_CONFIG_3_7X, 0x04); |
|
|
|
|
|
|
|
|
|
setSyncWord(SYNC_WORD_7X); |
|
|
|
@ -190,20 +173,13 @@ int sx127x::begin(long frequency) |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::end() |
|
|
|
|
{ |
|
|
|
|
// put in sleep mode
|
|
|
|
|
void sx127x::end() { |
|
|
|
|
sleep(); |
|
|
|
|
|
|
|
|
|
// stop SPI
|
|
|
|
|
SPI.end(); |
|
|
|
|
|
|
|
|
|
_preinit_done = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int sx127x::beginPacket(int implicitHeader) |
|
|
|
|
{ |
|
|
|
|
// put in standby mode
|
|
|
|
|
int sx127x::beginPacket(int implicitHeader) { |
|
|
|
|
idle(); |
|
|
|
|
|
|
|
|
|
if (implicitHeader) { |
|
|
|
@ -212,33 +188,27 @@ int sx127x::beginPacket(int implicitHeader) |
|
|
|
|
explicitHeaderMode(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// reset FIFO address and payload length
|
|
|
|
|
// Reset FIFO address and payload length
|
|
|
|
|
writeRegister(REG_FIFO_ADDR_PTR_7X, 0); |
|
|
|
|
writeRegister(REG_PAYLOAD_LENGTH_7X, 0); |
|
|
|
|
|
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int sx127x::endPacket() |
|
|
|
|
{ |
|
|
|
|
// put in TX mode
|
|
|
|
|
int sx127x::endPacket() { |
|
|
|
|
// Enter TX mode
|
|
|
|
|
writeRegister(REG_OP_MODE_7X, MODE_LONG_RANGE_MODE_7X | MODE_TX_7X); |
|
|
|
|
|
|
|
|
|
// wait for TX done
|
|
|
|
|
// Wait for TX completion
|
|
|
|
|
while ((readRegister(REG_IRQ_FLAGS_7X) & IRQ_TX_DONE_MASK_7X) == 0) { |
|
|
|
|
yield(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// clear IRQ's
|
|
|
|
|
// Clear TX complete IRQ
|
|
|
|
|
writeRegister(REG_IRQ_FLAGS_7X, IRQ_TX_DONE_MASK_7X); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint8_t sx127x::modemStatus() { |
|
|
|
|
return readRegister(REG_MODEM_STAT_7X); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t sx127x::currentRssiRaw() { |
|
|
|
|
uint8_t rssi = readRegister(REG_RSSI_VALUE_7X); |
|
|
|
|
return rssi; |
|
|
|
@ -280,8 +250,7 @@ float ISR_VECT sx127x::packetSnr() { |
|
|
|
|
return ((int8_t)readRegister(REG_PKT_SNR_VALUE_7X)) * 0.25; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
long sx127x::packetFrequencyError() |
|
|
|
|
{ |
|
|
|
|
long sx127x::packetFrequencyError() { |
|
|
|
|
int32_t freqError = 0; |
|
|
|
|
freqError = static_cast<int32_t>(readRegister(REG_FREQ_ERROR_MSB_7X) & B111); |
|
|
|
|
freqError <<= 8L; |
|
|
|
@ -294,158 +263,99 @@ long sx127x::packetFrequencyError() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const float fXtal = 32E6; // FXOSC: crystal oscillator (XTAL) frequency (2.5. Chip Specification, p. 14)
|
|
|
|
|
const float fError = ((static_cast<float>(freqError) * (1L << 24)) / fXtal) * (getSignalBandwidth() / 500000.0f); // p. 37
|
|
|
|
|
const float fError = ((static_cast<float>(freqError) * (1L << 24)) / fXtal) * (getSignalBandwidth() / 500000.0f); |
|
|
|
|
|
|
|
|
|
return static_cast<long>(fError); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
size_t sx127x::write(uint8_t byte) |
|
|
|
|
{ |
|
|
|
|
return write(&byte, sizeof(byte)); |
|
|
|
|
} |
|
|
|
|
size_t sx127x::write(uint8_t byte) { return write(&byte, sizeof(byte)); } |
|
|
|
|
|
|
|
|
|
size_t sx127x::write(const uint8_t *buffer, size_t size) |
|
|
|
|
{ |
|
|
|
|
size_t sx127x::write(const uint8_t *buffer, size_t size) { |
|
|
|
|
int currentLength = readRegister(REG_PAYLOAD_LENGTH_7X); |
|
|
|
|
|
|
|
|
|
// check size
|
|
|
|
|
if ((currentLength + size) > MAX_PKT_LENGTH) { |
|
|
|
|
size = MAX_PKT_LENGTH - currentLength; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// write data
|
|
|
|
|
for (size_t i = 0; i < size; i++) { |
|
|
|
|
writeRegister(REG_FIFO_7X, buffer[i]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// update length
|
|
|
|
|
writeRegister(REG_PAYLOAD_LENGTH_7X, currentLength + size); |
|
|
|
|
return size; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int ISR_VECT sx127x::available() |
|
|
|
|
{ |
|
|
|
|
return (readRegister(REG_RX_NB_BYTES_7X) - _packetIndex); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int ISR_VECT sx127x::read() |
|
|
|
|
{ |
|
|
|
|
if (!available()) { |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
int ISR_VECT sx127x::available() { return (readRegister(REG_RX_NB_BYTES_7X) - _packetIndex); } |
|
|
|
|
|
|
|
|
|
int ISR_VECT sx127x::read() { |
|
|
|
|
if (!available()) { return -1; } |
|
|
|
|
_packetIndex++; |
|
|
|
|
return readRegister(REG_FIFO_7X); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int sx127x::peek() |
|
|
|
|
{ |
|
|
|
|
if (!available()) { |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
int sx127x::peek() { |
|
|
|
|
if (!available()) { return -1; } |
|
|
|
|
|
|
|
|
|
// store current FIFO address
|
|
|
|
|
// Remember current FIFO address, read, and then reset address
|
|
|
|
|
int currentAddress = readRegister(REG_FIFO_ADDR_PTR_7X); |
|
|
|
|
|
|
|
|
|
// read
|
|
|
|
|
uint8_t b = readRegister(REG_FIFO_7X); |
|
|
|
|
|
|
|
|
|
// restore FIFO address
|
|
|
|
|
writeRegister(REG_FIFO_ADDR_PTR_7X, currentAddress); |
|
|
|
|
|
|
|
|
|
return b; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::flush() |
|
|
|
|
{ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::onReceive(void(*callback)(int)) |
|
|
|
|
{ |
|
|
|
|
void sx127x::onReceive(void(*callback)(int)) { |
|
|
|
|
_onReceive = callback; |
|
|
|
|
|
|
|
|
|
if (callback) { |
|
|
|
|
pinMode(_dio0, INPUT); |
|
|
|
|
|
|
|
|
|
writeRegister(REG_DIO_MAPPING_1_7X, 0x00); |
|
|
|
|
|
|
|
|
|
#ifdef SPI_HAS_NOTUSINGINTERRUPT |
|
|
|
|
SPI.usingInterrupt(digitalPinToInterrupt(_dio0)); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
attachInterrupt(digitalPinToInterrupt(_dio0), sx127x::onDio0Rise, RISING); |
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
detachInterrupt(digitalPinToInterrupt(_dio0)); |
|
|
|
|
|
|
|
|
|
#ifdef SPI_HAS_NOTUSINGINTERRUPT |
|
|
|
|
SPI.notUsingInterrupt(digitalPinToInterrupt(_dio0)); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::receive(int size) |
|
|
|
|
{ |
|
|
|
|
void sx127x::receive(int size) { |
|
|
|
|
if (size > 0) { |
|
|
|
|
implicitHeaderMode(); |
|
|
|
|
|
|
|
|
|
writeRegister(REG_PAYLOAD_LENGTH_7X, size & 0xff); |
|
|
|
|
} else { |
|
|
|
|
explicitHeaderMode(); |
|
|
|
|
} |
|
|
|
|
} else { explicitHeaderMode(); } |
|
|
|
|
|
|
|
|
|
writeRegister(REG_OP_MODE_7X, MODE_LONG_RANGE_MODE_7X | MODE_RX_CONTINUOUS_7X); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::idle() |
|
|
|
|
{ |
|
|
|
|
writeRegister(REG_OP_MODE_7X, MODE_LONG_RANGE_MODE_7X | MODE_STDBY_7X); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::sleep() |
|
|
|
|
{ |
|
|
|
|
writeRegister(REG_OP_MODE_7X, MODE_LONG_RANGE_MODE_7X | MODE_SLEEP_7X); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::enableTCXO() { |
|
|
|
|
uint8_t tcxo_reg = readRegister(REG_TCXO_7X); |
|
|
|
|
writeRegister(REG_TCXO_7X, tcxo_reg | 0x10); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::disableTCXO() { |
|
|
|
|
uint8_t tcxo_reg = readRegister(REG_TCXO_7X); |
|
|
|
|
writeRegister(REG_TCXO_7X, tcxo_reg & 0xEF); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::setTxPower(int level, int outputPin) { |
|
|
|
|
// Setup according to RFO or PA_BOOST output pin
|
|
|
|
|
if (PA_OUTPUT_RFO_PIN == outputPin) { |
|
|
|
|
// RFO
|
|
|
|
|
if (level < 0) { |
|
|
|
|
level = 0; |
|
|
|
|
} else if (level > 14) { |
|
|
|
|
level = 14; |
|
|
|
|
} |
|
|
|
|
if (level < 0) { level = 0; } |
|
|
|
|
else if (level > 14) { level = 14; } |
|
|
|
|
|
|
|
|
|
writeRegister(REG_PA_DAC_7X, 0x84); |
|
|
|
|
writeRegister(REG_PA_CONFIG_7X, 0x70 | level); |
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
// PA BOOST
|
|
|
|
|
if (level < 2) { |
|
|
|
|
level = 2; |
|
|
|
|
} else if (level > 17) { |
|
|
|
|
level = 17; |
|
|
|
|
} |
|
|
|
|
if (level < 2) { level = 2; } |
|
|
|
|
else if (level > 17) { level = 17; } |
|
|
|
|
|
|
|
|
|
writeRegister(REG_PA_DAC_7X, 0x84); |
|
|
|
|
writeRegister(REG_PA_CONFIG_7X, PA_BOOST_7X | (level - 2)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint8_t sx127x::getTxPower() { |
|
|
|
|
byte txp = readRegister(REG_PA_CONFIG_7X); |
|
|
|
|
return txp; |
|
|
|
|
} |
|
|
|
|
uint8_t sx127x::getTxPower() { byte txp = readRegister(REG_PA_CONFIG_7X); return txp; } |
|
|
|
|
|
|
|
|
|
void sx127x::setFrequency(unsigned long frequency) { |
|
|
|
|
_frequency = frequency; |
|
|
|
|
|
|
|
|
|
uint32_t frf = ((uint64_t)frequency << 19) / 32000000; |
|
|
|
|
|
|
|
|
|
writeRegister(REG_FRF_MSB_7X, (uint8_t)(frf >> 16)); |
|
|
|
@ -467,13 +377,9 @@ uint32_t sx127x::getFrequency() { |
|
|
|
|
return frequency; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::setSpreadingFactor(int sf) |
|
|
|
|
{ |
|
|
|
|
if (sf < 6) { |
|
|
|
|
sf = 6; |
|
|
|
|
} else if (sf > 12) { |
|
|
|
|
sf = 12; |
|
|
|
|
} |
|
|
|
|
void sx127x::setSpreadingFactor(int sf) { |
|
|
|
|
if (sf < 6) { sf = 6; } |
|
|
|
|
else if (sf > 12) { sf = 12; } |
|
|
|
|
|
|
|
|
|
if (sf == 6) { |
|
|
|
|
writeRegister(REG_DETECTION_OPTIMIZE_7X, 0xc5); |
|
|
|
@ -487,8 +393,7 @@ void sx127x::setSpreadingFactor(int sf) |
|
|
|
|
handleLowDataRate(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
long sx127x::getSignalBandwidth() |
|
|
|
|
{ |
|
|
|
|
long sx127x::getSignalBandwidth() { |
|
|
|
|
byte bw = (readRegister(REG_MODEM_CONFIG_1_7X) >> 4); |
|
|
|
|
switch (bw) { |
|
|
|
|
case 0: return 7.8E3; |
|
|
|
@ -500,41 +405,13 @@ long sx127x::getSignalBandwidth() |
|
|
|
|
case 6: return 62.5E3; |
|
|
|
|
case 7: return 125E3; |
|
|
|
|
case 8: return 250E3; |
|
|
|
|
case 9: return 500E3; |
|
|
|
|
} |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::handleLowDataRate(){ |
|
|
|
|
int sf = (readRegister(REG_MODEM_CONFIG_2_7X) >> 4); |
|
|
|
|
if ( long( (1<<sf) / (getSignalBandwidth()/1000)) > 16) { |
|
|
|
|
// set auto AGC and LowDataRateOptimize
|
|
|
|
|
writeRegister(REG_MODEM_CONFIG_3_7X, (1<<3)|(1<<2)); |
|
|
|
|
} else { |
|
|
|
|
// set auto AGC
|
|
|
|
|
writeRegister(REG_MODEM_CONFIG_3_7X, (1<<2)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
case 9: return 500E3; } |
|
|
|
|
|
|
|
|
|
void sx127x::optimizeModemSensitivity(){ |
|
|
|
|
byte bw = (readRegister(REG_MODEM_CONFIG_1_7X) >> 4); |
|
|
|
|
uint32_t freq = getFrequency(); |
|
|
|
|
|
|
|
|
|
if (bw == 9 && (410E6 <= freq) && (freq <= 525E6)) { |
|
|
|
|
writeRegister(REG_HIGH_BW_OPTIMIZE_1_7X, 0x02); |
|
|
|
|
writeRegister(REG_HIGH_BW_OPTIMIZE_2_7X, 0x7f); |
|
|
|
|
} else if (bw == 9 && (820E6 <= freq) && (freq <= 1020E6)) { |
|
|
|
|
writeRegister(REG_HIGH_BW_OPTIMIZE_1_7X, 0x02); |
|
|
|
|
writeRegister(REG_HIGH_BW_OPTIMIZE_2_7X, 0x64); |
|
|
|
|
} else { |
|
|
|
|
writeRegister(REG_HIGH_BW_OPTIMIZE_1_7X, 0x03); |
|
|
|
|
} |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::setSignalBandwidth(long sbw) |
|
|
|
|
{ |
|
|
|
|
void sx127x::setSignalBandwidth(long sbw) { |
|
|
|
|
int bw; |
|
|
|
|
|
|
|
|
|
if (sbw <= 7.8E3) { |
|
|
|
|
bw = 0; |
|
|
|
|
} else if (sbw <= 10.4E3) { |
|
|
|
@ -558,119 +435,63 @@ void sx127x::setSignalBandwidth(long sbw) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
writeRegister(REG_MODEM_CONFIG_1_7X, (readRegister(REG_MODEM_CONFIG_1_7X) & 0x0f) | (bw << 4)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handleLowDataRate(); |
|
|
|
|
optimizeModemSensitivity(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::setCodingRate4(int denominator) |
|
|
|
|
{ |
|
|
|
|
if (denominator < 5) { |
|
|
|
|
denominator = 5; |
|
|
|
|
} else if (denominator > 8) { |
|
|
|
|
denominator = 8; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::setCodingRate4(int denominator) { |
|
|
|
|
if (denominator < 5) { denominator = 5; } |
|
|
|
|
else if (denominator > 8) { denominator = 8; } |
|
|
|
|
int cr = denominator - 4; |
|
|
|
|
|
|
|
|
|
writeRegister(REG_MODEM_CONFIG_1_7X, (readRegister(REG_MODEM_CONFIG_1_7X) & 0xf1) | (cr << 1)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::setPreambleLength(long length) |
|
|
|
|
{ |
|
|
|
|
void sx127x::setPreambleLength(long length) {
|
|
|
|
|
writeRegister(REG_PREAMBLE_MSB_7X, (uint8_t)(length >> 8)); |
|
|
|
|
writeRegister(REG_PREAMBLE_LSB_7X, (uint8_t)(length >> 0)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::setSyncWord(uint8_t sw) |
|
|
|
|
{ |
|
|
|
|
writeRegister(REG_SYNC_WORD_7X, sw); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::enableCrc() |
|
|
|
|
{ |
|
|
|
|
writeRegister(REG_MODEM_CONFIG_2_7X, readRegister(REG_MODEM_CONFIG_2_7X) | 0x04); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::disableCrc() |
|
|
|
|
{ |
|
|
|
|
writeRegister(REG_MODEM_CONFIG_2_7X, readRegister(REG_MODEM_CONFIG_2_7X) & 0xfb); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
byte sx127x::random() |
|
|
|
|
{ |
|
|
|
|
return readRegister(REG_RSSI_WIDEBAND_7X); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::setPins(int ss, int reset, int dio0, int busy) |
|
|
|
|
{ |
|
|
|
|
_ss = ss; |
|
|
|
|
_reset = reset; |
|
|
|
|
_dio0 = dio0; |
|
|
|
|
_busy = busy; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::setSPIFrequency(uint32_t frequency) |
|
|
|
|
{ |
|
|
|
|
_spiSettings = SPISettings(frequency, MSBFIRST, SPI_MODE0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::dumpRegisters(Stream& out) |
|
|
|
|
{ |
|
|
|
|
for (int i = 0; i < 128; i++) { |
|
|
|
|
out.print("0x"); |
|
|
|
|
out.print(i, HEX); |
|
|
|
|
out.print(": 0x"); |
|
|
|
|
out.println(readRegister(i), HEX); |
|
|
|
|
void sx127x::handleLowDataRate() { |
|
|
|
|
int sf = (readRegister(REG_MODEM_CONFIG_2_7X) >> 4); |
|
|
|
|
if ( long( (1<<sf) / (getSignalBandwidth()/1000)) > 16) { |
|
|
|
|
// Set auto AGC and LowDataRateOptimize
|
|
|
|
|
writeRegister(REG_MODEM_CONFIG_3_7X, (1<<3)|(1<<2)); |
|
|
|
|
} else { |
|
|
|
|
// Only set auto AGC
|
|
|
|
|
writeRegister(REG_MODEM_CONFIG_3_7X, (1<<2)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::explicitHeaderMode() |
|
|
|
|
{ |
|
|
|
|
_implicitHeaderMode = 0; |
|
|
|
|
void sx127x::optimizeModemSensitivity() { |
|
|
|
|
byte bw = (readRegister(REG_MODEM_CONFIG_1_7X) >> 4); |
|
|
|
|
uint32_t freq = getFrequency(); |
|
|
|
|
|
|
|
|
|
writeRegister(REG_MODEM_CONFIG_1_7X, readRegister(REG_MODEM_CONFIG_1_7X) & 0xfe); |
|
|
|
|
if (bw == 9 && (410E6 <= freq) && (freq <= 525E6)) { |
|
|
|
|
writeRegister(REG_HIGH_BW_OPTIMIZE_1_7X, 0x02); |
|
|
|
|
writeRegister(REG_HIGH_BW_OPTIMIZE_2_7X, 0x7f); |
|
|
|
|
} else if (bw == 9 && (820E6 <= freq) && (freq <= 1020E6)) { |
|
|
|
|
writeRegister(REG_HIGH_BW_OPTIMIZE_1_7X, 0x02); |
|
|
|
|
writeRegister(REG_HIGH_BW_OPTIMIZE_2_7X, 0x64); |
|
|
|
|
} else { |
|
|
|
|
writeRegister(REG_HIGH_BW_OPTIMIZE_1_7X, 0x03); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx127x::implicitHeaderMode() |
|
|
|
|
{ |
|
|
|
|
_implicitHeaderMode = 1; |
|
|
|
|
|
|
|
|
|
writeRegister(REG_MODEM_CONFIG_1_7X, readRegister(REG_MODEM_CONFIG_1_7X) | 0x01); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ISR_VECT sx127x::handleDio0Rise() |
|
|
|
|
{ |
|
|
|
|
void ISR_VECT sx127x::handleDio0Rise() { |
|
|
|
|
int irqFlags = readRegister(REG_IRQ_FLAGS_7X); |
|
|
|
|
|
|
|
|
|
// clear IRQ's
|
|
|
|
|
// Clear IRQs
|
|
|
|
|
writeRegister(REG_IRQ_FLAGS_7X, irqFlags); |
|
|
|
|
if ((irqFlags & IRQ_PAYLOAD_CRC_ERROR_MASK_7X) == 0) { |
|
|
|
|
|
|
|
|
|
// received a packet
|
|
|
|
|
_packetIndex = 0; |
|
|
|
|
|
|
|
|
|
// read packet length
|
|
|
|
|
int packetLength = _implicitHeaderMode ? readRegister(REG_PAYLOAD_LENGTH_7X) : readRegister(REG_RX_NB_BYTES_7X); |
|
|
|
|
|
|
|
|
|
// set FIFO address to current RX address
|
|
|
|
|
writeRegister(REG_FIFO_ADDR_PTR_7X, readRegister(REG_FIFO_RX_CURRENT_ADDR_7X)); |
|
|
|
|
|
|
|
|
|
if (_onReceive) { |
|
|
|
|
_onReceive(packetLength); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// reset FIFO address
|
|
|
|
|
if (_onReceive) { _onReceive(packetLength); } |
|
|
|
|
writeRegister(REG_FIFO_ADDR_PTR_7X, 0); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ISR_VECT sx127x::onDio0Rise() |
|
|
|
|
{ |
|
|
|
|
sx127x_modem.handleDio0Rise(); |
|
|
|
|
} |
|
|
|
|
void ISR_VECT sx127x::onDio0Rise() { sx127x_modem.handleDio0Rise(); } |
|
|
|
|
|
|
|
|
|
sx127x sx127x_modem; |
|
|
|
|
|
|
|
|
|