This commit is contained in:
Mark Qvist 2024-02-12 13:37:10 +01:00
parent bbc267ac80
commit f229b78372
2 changed files with 212 additions and 393 deletions

View File

@ -19,166 +19,149 @@
#endif #endif
// Registers // Registers
#define REG_FIFO_7X 0x00 #define REG_FIFO_7X 0x00
#define REG_OP_MODE_7X 0x01 #define REG_OP_MODE_7X 0x01
#define REG_FRF_MSB_7X 0x06 #define REG_FRF_MSB_7X 0x06
#define REG_FRF_MID_7X 0x07 #define REG_FRF_MID_7X 0x07
#define REG_FRF_LSB_7X 0x08 #define REG_FRF_LSB_7X 0x08
#define REG_PA_CONFIG_7X 0x09 #define REG_PA_CONFIG_7X 0x09
#define REG_OCP_7X 0x0b #define REG_OCP_7X 0x0b
#define REG_LNA_7X 0x0c #define REG_LNA_7X 0x0c
#define REG_FIFO_ADDR_PTR_7X 0x0d #define REG_FIFO_ADDR_PTR_7X 0x0d
#define REG_FIFO_TX_BASE_ADDR_7X 0x0e #define REG_FIFO_TX_BASE_ADDR_7X 0x0e
#define REG_FIFO_RX_BASE_ADDR_7X 0x0f #define REG_FIFO_RX_BASE_ADDR_7X 0x0f
#define REG_FIFO_RX_CURRENT_ADDR_7X 0x10 #define REG_FIFO_RX_CURRENT_ADDR_7X 0x10
#define REG_IRQ_FLAGS_7X 0x12 #define REG_IRQ_FLAGS_7X 0x12
#define REG_RX_NB_BYTES_7X 0x13 #define REG_RX_NB_BYTES_7X 0x13
#define REG_MODEM_STAT_7X 0x18 #define REG_MODEM_STAT_7X 0x18
#define REG_PKT_SNR_VALUE_7X 0x19 #define REG_PKT_SNR_VALUE_7X 0x19
#define REG_PKT_RSSI_VALUE_7X 0x1a #define REG_PKT_RSSI_VALUE_7X 0x1a
#define REG_RSSI_VALUE_7X 0x1b #define REG_RSSI_VALUE_7X 0x1b
#define REG_MODEM_CONFIG_1_7X 0x1d #define REG_MODEM_CONFIG_1_7X 0x1d
#define REG_MODEM_CONFIG_2_7X 0x1e #define REG_MODEM_CONFIG_2_7X 0x1e
#define REG_PREAMBLE_MSB_7X 0x20 #define REG_PREAMBLE_MSB_7X 0x20
#define REG_PREAMBLE_LSB_7X 0x21 #define REG_PREAMBLE_LSB_7X 0x21
#define REG_PAYLOAD_LENGTH_7X 0x22 #define REG_PAYLOAD_LENGTH_7X 0x22
#define REG_MODEM_CONFIG_3_7X 0x26 #define REG_MODEM_CONFIG_3_7X 0x26
#define REG_FREQ_ERROR_MSB_7X 0x28 #define REG_FREQ_ERROR_MSB_7X 0x28
#define REG_FREQ_ERROR_MID_7X 0x29 #define REG_FREQ_ERROR_MID_7X 0x29
#define REG_FREQ_ERROR_LSB_7X 0x2a #define REG_FREQ_ERROR_LSB_7X 0x2a
#define REG_RSSI_WIDEBAND_7X 0x2c #define REG_RSSI_WIDEBAND_7X 0x2c
#define REG_DETECTION_OPTIMIZE_7X 0x31 #define REG_DETECTION_OPTIMIZE_7X 0x31
#define REG_HIGH_BW_OPTIMIZE_1_7X 0x36 #define REG_HIGH_BW_OPTIMIZE_1_7X 0x36
#define REG_DETECTION_THRESHOLD_7X 0x37 #define REG_DETECTION_THRESHOLD_7X 0x37
#define REG_SYNC_WORD_7X 0x39 #define REG_SYNC_WORD_7X 0x39
#define REG_HIGH_BW_OPTIMIZE_2_7X 0x3a #define REG_HIGH_BW_OPTIMIZE_2_7X 0x3a
#define REG_DIO_MAPPING_1_7X 0x40 #define REG_DIO_MAPPING_1_7X 0x40
#define REG_VERSION_7X 0x42 #define REG_VERSION_7X 0x42
#define REG_TCXO_7X 0x4b #define REG_TCXO_7X 0x4b
#define REG_PA_DAC_7X 0x4d #define REG_PA_DAC_7X 0x4d
// Modes // Modes
#define MODE_LONG_RANGE_MODE_7X 0x80 #define MODE_LONG_RANGE_MODE_7X 0x80
#define MODE_SLEEP_7X 0x00 #define MODE_SLEEP_7X 0x00
#define MODE_STDBY_7X 0x01 #define MODE_STDBY_7X 0x01
#define MODE_TX_7X 0x03 #define MODE_TX_7X 0x03
#define MODE_RX_CONTINUOUS_7X 0x05 #define MODE_RX_CONTINUOUS_7X 0x05
#define MODE_RX_SINGLE_7X 0x06 #define MODE_RX_SINGLE_7X 0x06
// PA config // PA config
#define PA_BOOST_7X 0x80 #define PA_BOOST_7X 0x80
// IRQ masks // IRQ masks
#define IRQ_TX_DONE_MASK_7X 0x08 #define IRQ_TX_DONE_MASK_7X 0x08
#define IRQ_RX_DONE_MASK_7X 0x40
#define IRQ_PAYLOAD_CRC_ERROR_MASK_7X 0x20 #define IRQ_PAYLOAD_CRC_ERROR_MASK_7X 0x20
#define IRQ_RX_DONE_MASK_7X 0x40
extern SPIClass SPI;
#define MAX_PKT_LENGTH 255 #define MAX_PKT_LENGTH 255
#define SYNC_WORD_7X 0x12 #define SYNC_WORD_7X 0x12
extern SPIClass SPI;
sx127x::sx127x() : sx127x::sx127x() :
_spiSettings(8E6, MSBFIRST, SPI_MODE0), _spiSettings(8E6, MSBFIRST, SPI_MODE0),
_ss(LORA_DEFAULT_SS_PIN), _reset(LORA_DEFAULT_RESET_PIN), _dio0(LORA_DEFAULT_DIO0_PIN), _ss(LORA_DEFAULT_SS_PIN), _reset(LORA_DEFAULT_RESET_PIN), _dio0(LORA_DEFAULT_DIO0_PIN),
_frequency(0), _frequency(0),
_packetIndex(0), _packetIndex(0),
_preinit_done(false), _preinit_done(false),
_onReceive(NULL) _onReceive(NULL) { setTimeout(0); }
{
// overide Stream timeout value void sx127x::setSPIFrequency(uint32_t frequency) { _spiSettings = SPISettings(frequency, MSBFIRST, SPI_MODE0); }
setTimeout(0); 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() { bool sx127x::preInit() {
// setup pins
pinMode(_ss, OUTPUT); pinMode(_ss, OUTPUT);
// set SS high
digitalWrite(_ss, HIGH); digitalWrite(_ss, HIGH);
SPI.begin(); SPI.begin();
// check version (retry for up to 2 seconds) // Check modem version
uint8_t version; uint8_t version;
long start = millis(); long start = millis();
while (((millis() - start) < 2000) && (millis() >= start)) { while (((millis() - start) < 500) && (millis() >= start)) {
version = readRegister(REG_VERSION_7X); version = readRegister(REG_VERSION_7X);
if (version == 0x12) { if (version == 0x12) { break; }
break;
}
delay(100); delay(100);
} }
if (version != 0x12) {
return false; if (version != 0x12) { return false; }
}
_preinit_done = true; _preinit_done = true;
return true; return true;
} }
uint8_t ISR_VECT sx127x::readRegister(uint8_t address) uint8_t ISR_VECT sx127x::singleTransfer(uint8_t address, uint8_t value) {
{
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 response; uint8_t response;
digitalWrite(_ss, LOW); digitalWrite(_ss, LOW);
SPI.beginTransaction(_spiSettings); SPI.beginTransaction(_spiSettings);
SPI.transfer(address); SPI.transfer(address);
response = SPI.transfer(value); response = SPI.transfer(value);
SPI.endTransaction(); SPI.endTransaction();
digitalWrite(_ss, HIGH); digitalWrite(_ss, HIGH);
return response; return response;
} }
int sx127x::begin(long frequency) {
int sx127x::begin(long frequency)
{
if (_reset != -1) { if (_reset != -1) {
pinMode(_reset, OUTPUT); pinMode(_reset, OUTPUT);
// perform reset // Perform reset
digitalWrite(_reset, LOW); digitalWrite(_reset, LOW);
delay(10); delay(10);
digitalWrite(_reset, HIGH); digitalWrite(_reset, HIGH);
delay(10); delay(10);
} }
if (_busy != -1) { if (_busy != -1) { pinMode(_busy, INPUT); }
pinMode(_busy, INPUT);
}
if (!_preinit_done) { if (!_preinit_done) {
if (!preInit()) { if (!preInit()) { return false; }
return false;
}
} }
// put in sleep mode
sleep(); sleep();
// set frequency
setFrequency(frequency); setFrequency(frequency);
// set base addresses // set base addresses
writeRegister(REG_FIFO_TX_BASE_ADDR_7X, 0); writeRegister(REG_FIFO_TX_BASE_ADDR_7X, 0);
writeRegister(REG_FIFO_RX_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); writeRegister(REG_LNA_7X, readRegister(REG_LNA_7X) | 0x03);
// set auto AGC
writeRegister(REG_MODEM_CONFIG_3_7X, 0x04); writeRegister(REG_MODEM_CONFIG_3_7X, 0x04);
setSyncWord(SYNC_WORD_7X); setSyncWord(SYNC_WORD_7X);
@ -190,20 +173,13 @@ int sx127x::begin(long frequency)
return 1; return 1;
} }
void sx127x::end() void sx127x::end() {
{
// put in sleep mode
sleep(); sleep();
// stop SPI
SPI.end(); SPI.end();
_preinit_done = false; _preinit_done = false;
} }
int sx127x::beginPacket(int implicitHeader) int sx127x::beginPacket(int implicitHeader) {
{
// put in standby mode
idle(); idle();
if (implicitHeader) { if (implicitHeader) {
@ -212,33 +188,27 @@ int sx127x::beginPacket(int implicitHeader)
explicitHeaderMode(); explicitHeaderMode();
} }
// reset FIFO address and payload length // Reset FIFO address and payload length
writeRegister(REG_FIFO_ADDR_PTR_7X, 0); writeRegister(REG_FIFO_ADDR_PTR_7X, 0);
writeRegister(REG_PAYLOAD_LENGTH_7X, 0); writeRegister(REG_PAYLOAD_LENGTH_7X, 0);
return 1; return 1;
} }
int sx127x::endPacket() int sx127x::endPacket() {
{ // Enter TX mode
// put in TX mode
writeRegister(REG_OP_MODE_7X, MODE_LONG_RANGE_MODE_7X | MODE_TX_7X); 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) { while ((readRegister(REG_IRQ_FLAGS_7X) & IRQ_TX_DONE_MASK_7X) == 0) {
yield(); yield();
} }
// clear IRQ's // Clear TX complete IRQ
writeRegister(REG_IRQ_FLAGS_7X, IRQ_TX_DONE_MASK_7X); writeRegister(REG_IRQ_FLAGS_7X, IRQ_TX_DONE_MASK_7X);
return 1; return 1;
} }
uint8_t sx127x::modemStatus() {
return readRegister(REG_MODEM_STAT_7X);
}
uint8_t sx127x::currentRssiRaw() { uint8_t sx127x::currentRssiRaw() {
uint8_t rssi = readRegister(REG_RSSI_VALUE_7X); uint8_t rssi = readRegister(REG_RSSI_VALUE_7X);
return rssi; return rssi;
@ -280,8 +250,7 @@ float ISR_VECT sx127x::packetSnr() {
return ((int8_t)readRegister(REG_PKT_SNR_VALUE_7X)) * 0.25; return ((int8_t)readRegister(REG_PKT_SNR_VALUE_7X)) * 0.25;
} }
long sx127x::packetFrequencyError() long sx127x::packetFrequencyError() {
{
int32_t freqError = 0; int32_t freqError = 0;
freqError = static_cast<int32_t>(readRegister(REG_FREQ_ERROR_MSB_7X) & B111); freqError = static_cast<int32_t>(readRegister(REG_FREQ_ERROR_MSB_7X) & B111);
freqError <<= 8L; 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 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); return static_cast<long>(fError);
} }
size_t sx127x::write(uint8_t byte) size_t sx127x::write(uint8_t byte) { return write(&byte, sizeof(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); int currentLength = readRegister(REG_PAYLOAD_LENGTH_7X);
// check size
if ((currentLength + size) > MAX_PKT_LENGTH) { if ((currentLength + size) > MAX_PKT_LENGTH) {
size = MAX_PKT_LENGTH - currentLength; size = MAX_PKT_LENGTH - currentLength;
} }
// write data
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
writeRegister(REG_FIFO_7X, buffer[i]); writeRegister(REG_FIFO_7X, buffer[i]);
} }
// update length
writeRegister(REG_PAYLOAD_LENGTH_7X, currentLength + size); writeRegister(REG_PAYLOAD_LENGTH_7X, currentLength + size);
return size; return size;
} }
int ISR_VECT sx127x::available() int ISR_VECT sx127x::available() { return (readRegister(REG_RX_NB_BYTES_7X) - _packetIndex); }
{
return (readRegister(REG_RX_NB_BYTES_7X) - _packetIndex);
}
int ISR_VECT sx127x::read()
{
if (!available()) {
return -1;
}
int ISR_VECT sx127x::read() {
if (!available()) { return -1; }
_packetIndex++; _packetIndex++;
return readRegister(REG_FIFO_7X); return readRegister(REG_FIFO_7X);
} }
int sx127x::peek() int sx127x::peek() {
{ if (!available()) { return -1; }
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); int currentAddress = readRegister(REG_FIFO_ADDR_PTR_7X);
// read
uint8_t b = readRegister(REG_FIFO_7X); uint8_t b = readRegister(REG_FIFO_7X);
// restore FIFO address
writeRegister(REG_FIFO_ADDR_PTR_7X, currentAddress); writeRegister(REG_FIFO_ADDR_PTR_7X, currentAddress);
return b; return b;
} }
void sx127x::flush() void sx127x::onReceive(void(*callback)(int)) {
{
}
void sx127x::onReceive(void(*callback)(int))
{
_onReceive = callback; _onReceive = callback;
if (callback) { if (callback) {
pinMode(_dio0, INPUT); pinMode(_dio0, INPUT);
writeRegister(REG_DIO_MAPPING_1_7X, 0x00); writeRegister(REG_DIO_MAPPING_1_7X, 0x00);
#ifdef SPI_HAS_NOTUSINGINTERRUPT
SPI.usingInterrupt(digitalPinToInterrupt(_dio0)); #ifdef SPI_HAS_NOTUSINGINTERRUPT
#endif SPI.usingInterrupt(digitalPinToInterrupt(_dio0));
#endif
attachInterrupt(digitalPinToInterrupt(_dio0), sx127x::onDio0Rise, RISING); attachInterrupt(digitalPinToInterrupt(_dio0), sx127x::onDio0Rise, RISING);
} else { } else {
detachInterrupt(digitalPinToInterrupt(_dio0)); detachInterrupt(digitalPinToInterrupt(_dio0));
#ifdef SPI_HAS_NOTUSINGINTERRUPT
SPI.notUsingInterrupt(digitalPinToInterrupt(_dio0)); #ifdef SPI_HAS_NOTUSINGINTERRUPT
#endif SPI.notUsingInterrupt(digitalPinToInterrupt(_dio0));
#endif
} }
} }
void sx127x::receive(int size) void sx127x::receive(int size) {
{ if (size > 0) {
if (size > 0) { implicitHeaderMode();
implicitHeaderMode(); writeRegister(REG_PAYLOAD_LENGTH_7X, size & 0xff);
} else { explicitHeaderMode(); }
writeRegister(REG_PAYLOAD_LENGTH_7X, size & 0xff); writeRegister(REG_OP_MODE_7X, MODE_LONG_RANGE_MODE_7X | MODE_RX_CONTINUOUS_7X);
} 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) { void sx127x::setTxPower(int level, int outputPin) {
if (PA_OUTPUT_RFO_PIN == outputPin) { // Setup according to RFO or PA_BOOST output pin
// RFO if (PA_OUTPUT_RFO_PIN == outputPin) {
if (level < 0) { if (level < 0) { level = 0; }
level = 0; else if (level > 14) { level = 14; }
} else if (level > 14) {
level = 14;
}
writeRegister(REG_PA_DAC_7X, 0x84); writeRegister(REG_PA_DAC_7X, 0x84);
writeRegister(REG_PA_CONFIG_7X, 0x70 | level); writeRegister(REG_PA_CONFIG_7X, 0x70 | level);
} else { } else {
// PA BOOST if (level < 2) { level = 2; }
if (level < 2) { else if (level > 17) { level = 17; }
level = 2;
} else if (level > 17) {
level = 17;
}
writeRegister(REG_PA_DAC_7X, 0x84); writeRegister(REG_PA_DAC_7X, 0x84);
writeRegister(REG_PA_CONFIG_7X, PA_BOOST_7X | (level - 2)); writeRegister(REG_PA_CONFIG_7X, PA_BOOST_7X | (level - 2));
} }
} }
uint8_t sx127x::getTxPower() { uint8_t sx127x::getTxPower() { byte txp = readRegister(REG_PA_CONFIG_7X); return txp; }
byte txp = readRegister(REG_PA_CONFIG_7X);
return txp;
}
void sx127x::setFrequency(unsigned long frequency) { void sx127x::setFrequency(unsigned long frequency) {
_frequency = frequency; _frequency = frequency;
uint32_t frf = ((uint64_t)frequency << 19) / 32000000; uint32_t frf = ((uint64_t)frequency << 19) / 32000000;
writeRegister(REG_FRF_MSB_7X, (uint8_t)(frf >> 16)); writeRegister(REG_FRF_MSB_7X, (uint8_t)(frf >> 16));
@ -456,221 +366,132 @@ void sx127x::setFrequency(unsigned long frequency) {
} }
uint32_t sx127x::getFrequency() { uint32_t sx127x::getFrequency() {
uint8_t msb = readRegister(REG_FRF_MSB_7X); uint8_t msb = readRegister(REG_FRF_MSB_7X);
uint8_t mid = readRegister(REG_FRF_MID_7X); uint8_t mid = readRegister(REG_FRF_MID_7X);
uint8_t lsb = readRegister(REG_FRF_LSB_7X); uint8_t lsb = readRegister(REG_FRF_LSB_7X);
uint32_t frf = ((uint32_t)msb << 16) | ((uint32_t)mid << 8) | (uint32_t)lsb; uint32_t frf = ((uint32_t)msb << 16) | ((uint32_t)mid << 8) | (uint32_t)lsb;
uint64_t frm = (uint64_t)frf*32000000; uint64_t frm = (uint64_t)frf*32000000;
uint32_t frequency = (frm >> 19); uint32_t frequency = (frm >> 19);
return frequency; return frequency;
} }
void sx127x::setSpreadingFactor(int sf) void sx127x::setSpreadingFactor(int sf) {
{ if (sf < 6) { sf = 6; }
if (sf < 6) { else if (sf > 12) { sf = 12; }
sf = 6;
} else if (sf > 12) {
sf = 12;
}
if (sf == 6) { if (sf == 6) {
writeRegister(REG_DETECTION_OPTIMIZE_7X, 0xc5); writeRegister(REG_DETECTION_OPTIMIZE_7X, 0xc5);
writeRegister(REG_DETECTION_THRESHOLD_7X, 0x0c); writeRegister(REG_DETECTION_THRESHOLD_7X, 0x0c);
} else { } else {
writeRegister(REG_DETECTION_OPTIMIZE_7X, 0xc3); writeRegister(REG_DETECTION_OPTIMIZE_7X, 0xc3);
writeRegister(REG_DETECTION_THRESHOLD_7X, 0x0a); writeRegister(REG_DETECTION_THRESHOLD_7X, 0x0a);
} }
writeRegister(REG_MODEM_CONFIG_2_7X, (readRegister(REG_MODEM_CONFIG_2_7X) & 0x0f) | ((sf << 4) & 0xf0)); writeRegister(REG_MODEM_CONFIG_2_7X, (readRegister(REG_MODEM_CONFIG_2_7X) & 0x0f) | ((sf << 4) & 0xf0));
handleLowDataRate(); handleLowDataRate();
} }
long sx127x::getSignalBandwidth() long sx127x::getSignalBandwidth() {
{ byte bw = (readRegister(REG_MODEM_CONFIG_1_7X) >> 4);
byte bw = (readRegister(REG_MODEM_CONFIG_1_7X) >> 4); switch (bw) {
switch (bw) { case 0: return 7.8E3;
case 0: return 7.8E3; case 1: return 10.4E3;
case 1: return 10.4E3; case 2: return 15.6E3;
case 2: return 15.6E3; case 3: return 20.8E3;
case 3: return 20.8E3; case 4: return 31.25E3;
case 4: return 31.25E3; case 5: return 41.7E3;
case 5: return 41.7E3; case 6: return 62.5E3;
case 6: return 62.5E3; case 7: return 125E3;
case 7: return 125E3; case 8: return 250E3;
case 8: return 250E3; case 9: return 500E3; }
case 9: return 500E3;
}
return 0; return 0;
} }
void sx127x::handleLowDataRate(){ void sx127x::setSignalBandwidth(long sbw) {
int sf = (readRegister(REG_MODEM_CONFIG_2_7X) >> 4); int bw;
if ( long( (1<<sf) / (getSignalBandwidth()/1000)) > 16) { if (sbw <= 7.8E3) {
// set auto AGC and LowDataRateOptimize bw = 0;
writeRegister(REG_MODEM_CONFIG_3_7X, (1<<3)|(1<<2)); } else if (sbw <= 10.4E3) {
} else { bw = 1;
// set auto AGC } else if (sbw <= 15.6E3) {
writeRegister(REG_MODEM_CONFIG_3_7X, (1<<2)); bw = 2;
} } else if (sbw <= 20.8E3) {
} bw = 3;
} else if (sbw <= 31.25E3) {
void sx127x::optimizeModemSensitivity(){ bw = 4;
byte bw = (readRegister(REG_MODEM_CONFIG_1_7X) >> 4); } else if (sbw <= 41.7E3) {
uint32_t freq = getFrequency(); bw = 5;
} else if (sbw <= 62.5E3) {
if (bw == 9 && (410E6 <= freq) && (freq <= 525E6)) { bw = 6;
writeRegister(REG_HIGH_BW_OPTIMIZE_1_7X, 0x02); } else if (sbw <= 125E3) {
writeRegister(REG_HIGH_BW_OPTIMIZE_2_7X, 0x7f); bw = 7;
} else if (bw == 9 && (820E6 <= freq) && (freq <= 1020E6)) { } else if (sbw <= 250E3) {
writeRegister(REG_HIGH_BW_OPTIMIZE_1_7X, 0x02); bw = 8;
writeRegister(REG_HIGH_BW_OPTIMIZE_2_7X, 0x64); } else /*if (sbw <= 250E3)*/ {
} else { bw = 9;
writeRegister(REG_HIGH_BW_OPTIMIZE_1_7X, 0x03); }
}
}
void sx127x::setSignalBandwidth(long sbw)
{
int bw;
if (sbw <= 7.8E3) {
bw = 0;
} else if (sbw <= 10.4E3) {
bw = 1;
} else if (sbw <= 15.6E3) {
bw = 2;
} else if (sbw <= 20.8E3) {
bw = 3;
} else if (sbw <= 31.25E3) {
bw = 4;
} else if (sbw <= 41.7E3) {
bw = 5;
} else if (sbw <= 62.5E3) {
bw = 6;
} else if (sbw <= 125E3) {
bw = 7;
} else if (sbw <= 250E3) {
bw = 8;
} else /*if (sbw <= 250E3)*/ {
bw = 9;
}
writeRegister(REG_MODEM_CONFIG_1_7X, (readRegister(REG_MODEM_CONFIG_1_7X) & 0x0f) | (bw << 4));
writeRegister(REG_MODEM_CONFIG_1_7X, (readRegister(REG_MODEM_CONFIG_1_7X) & 0x0f) | (bw << 4));
handleLowDataRate(); handleLowDataRate();
optimizeModemSensitivity(); optimizeModemSensitivity();
} }
void sx127x::setCodingRate4(int denominator) void sx127x::setCodingRate4(int denominator) {
{ if (denominator < 5) { denominator = 5; }
if (denominator < 5) { else if (denominator > 8) { denominator = 8; }
denominator = 5;
} else if (denominator > 8) {
denominator = 8;
}
int cr = denominator - 4; int cr = denominator - 4;
writeRegister(REG_MODEM_CONFIG_1_7X, (readRegister(REG_MODEM_CONFIG_1_7X) & 0xf1) | (cr << 1)); 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_MSB_7X, (uint8_t)(length >> 8));
writeRegister(REG_PREAMBLE_LSB_7X, (uint8_t)(length >> 0)); writeRegister(REG_PREAMBLE_LSB_7X, (uint8_t)(length >> 0));
} }
void sx127x::setSyncWord(uint8_t sw) void sx127x::handleLowDataRate() {
{ int sf = (readRegister(REG_MODEM_CONFIG_2_7X) >> 4);
writeRegister(REG_SYNC_WORD_7X, sw); if ( long( (1<<sf) / (getSignalBandwidth()/1000)) > 16) {
} // Set auto AGC and LowDataRateOptimize
writeRegister(REG_MODEM_CONFIG_3_7X, (1<<3)|(1<<2));
void sx127x::enableCrc() } else {
{ // Only set auto AGC
writeRegister(REG_MODEM_CONFIG_2_7X, readRegister(REG_MODEM_CONFIG_2_7X) | 0x04); writeRegister(REG_MODEM_CONFIG_3_7X, (1<<2));
}
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::explicitHeaderMode() void sx127x::optimizeModemSensitivity() {
{ byte bw = (readRegister(REG_MODEM_CONFIG_1_7X) >> 4);
_implicitHeaderMode = 0; 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() void ISR_VECT sx127x::handleDio0Rise() {
{ int irqFlags = readRegister(REG_IRQ_FLAGS_7X);
_implicitHeaderMode = 1;
writeRegister(REG_MODEM_CONFIG_1_7X, readRegister(REG_MODEM_CONFIG_1_7X) | 0x01); // Clear IRQs
writeRegister(REG_IRQ_FLAGS_7X, irqFlags);
if ((irqFlags & IRQ_PAYLOAD_CRC_ERROR_MASK_7X) == 0) {
_packetIndex = 0;
int packetLength = _implicitHeaderMode ? readRegister(REG_PAYLOAD_LENGTH_7X) : readRegister(REG_RX_NB_BYTES_7X);
writeRegister(REG_FIFO_ADDR_PTR_7X, readRegister(REG_FIFO_RX_CURRENT_ADDR_7X));
if (_onReceive) { _onReceive(packetLength); }
writeRegister(REG_FIFO_ADDR_PTR_7X, 0);
}
} }
void ISR_VECT sx127x::onDio0Rise() { sx127x_modem.handleDio0Rise(); }
void ISR_VECT sx127x::handleDio0Rise()
{
int irqFlags = readRegister(REG_IRQ_FLAGS_7X);
// clear IRQ's
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
writeRegister(REG_FIFO_ADDR_PTR_7X, 0);
}
}
void ISR_VECT sx127x::onDio0Rise()
{
sx127x_modem.handleDio0Rise();
}
sx127x sx127x_modem; sx127x sx127x_modem;

View File

@ -78,8 +78,6 @@ public:
void setPins(int ss = LORA_DEFAULT_SS_PIN, int reset = LORA_DEFAULT_RESET_PIN, int dio0 = LORA_DEFAULT_DIO0_PIN, int busy = LORA_DEFAULT_BUSY_PIN); void setPins(int ss = LORA_DEFAULT_SS_PIN, int reset = LORA_DEFAULT_RESET_PIN, int dio0 = LORA_DEFAULT_DIO0_PIN, int busy = LORA_DEFAULT_BUSY_PIN);
void setSPIFrequency(uint32_t frequency); void setSPIFrequency(uint32_t frequency);
void dumpRegisters(Stream& out);
private: private:
void explicitHeaderMode(); void explicitHeaderMode();
void implicitHeaderMode(); void implicitHeaderMode();