|
|
@ -1,9 +1,6 @@ |
|
|
|
// Copyright (c) Sandeep Mistry. All rights reserved.
|
|
|
|
// Copyright Sandeep Mistry, Mark Qvist and Jacob Eva.
|
|
|
|
// Licensed under the MIT license.
|
|
|
|
// Licensed under the MIT license.
|
|
|
|
|
|
|
|
|
|
|
|
// Modifications and additions copyright 2024 by Mark Qvist
|
|
|
|
|
|
|
|
// Obviously still under the MIT license.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "Boards.h" |
|
|
|
#include "Boards.h" |
|
|
|
|
|
|
|
|
|
|
|
#if MODEM == SX1262 |
|
|
|
#if MODEM == SX1262 |
|
|
@ -24,19 +21,19 @@ |
|
|
|
#define OP_TX_6X 0x83 |
|
|
|
#define OP_TX_6X 0x83 |
|
|
|
#define OP_RX_6X 0x82 |
|
|
|
#define OP_RX_6X 0x82 |
|
|
|
#define OP_PA_CONFIG_6X 0x95 |
|
|
|
#define OP_PA_CONFIG_6X 0x95 |
|
|
|
#define OP_SET_IRQ_FLAGS_6X 0x08 // also provides info such as
|
|
|
|
#define OP_SET_IRQ_FLAGS_6X 0x08 // Also provides info such as
|
|
|
|
// preamble detection, etc for
|
|
|
|
// preamble detection, etc for
|
|
|
|
// knowing when it's safe to switch
|
|
|
|
// knowing when it's safe to switch
|
|
|
|
// antenna modes
|
|
|
|
// antenna modes
|
|
|
|
#define OP_CLEAR_IRQ_STATUS_6X 0x02 |
|
|
|
#define OP_CLEAR_IRQ_STATUS_6X 0x02 |
|
|
|
#define OP_GET_IRQ_STATUS_6X 0x12 |
|
|
|
#define OP_GET_IRQ_STATUS_6X 0x12 |
|
|
|
#define OP_RX_BUFFER_STATUS_6X 0x13 |
|
|
|
#define OP_RX_BUFFER_STATUS_6X 0x13 |
|
|
|
#define OP_PACKET_STATUS_6X 0x14 // get snr & rssi of last packet
|
|
|
|
#define OP_PACKET_STATUS_6X 0x14 // Get snr & rssi of last packet
|
|
|
|
#define OP_CURRENT_RSSI_6X 0x15 |
|
|
|
#define OP_CURRENT_RSSI_6X 0x15 |
|
|
|
#define OP_MODULATION_PARAMS_6X 0x8B // bw, sf, cr, etc.
|
|
|
|
#define OP_MODULATION_PARAMS_6X 0x8B // BW, SF, CR, etc.
|
|
|
|
#define OP_PACKET_PARAMS_6X 0x8C // crc, preamble, payload length, etc.
|
|
|
|
#define OP_PACKET_PARAMS_6X 0x8C // CRC, preamble, payload length, etc.
|
|
|
|
#define OP_STATUS_6X 0xC0 |
|
|
|
#define OP_STATUS_6X 0xC0 |
|
|
|
#define OP_TX_PARAMS_6X 0x8E // set dbm, etc
|
|
|
|
#define OP_TX_PARAMS_6X 0x8E // Set dbm, etc
|
|
|
|
#define OP_PACKET_TYPE_6X 0x8A |
|
|
|
#define OP_PACKET_TYPE_6X 0x8A |
|
|
|
#define OP_BUFFER_BASE_ADDR_6X 0x8F |
|
|
|
#define OP_BUFFER_BASE_ADDR_6X 0x8F |
|
|
|
#define OP_READ_REGISTER_6X 0x1D |
|
|
|
#define OP_READ_REGISTER_6X 0x1D |
|
|
@ -63,7 +60,7 @@ |
|
|
|
#define OP_FIFO_WRITE_6X 0x0E |
|
|
|
#define OP_FIFO_WRITE_6X 0x0E |
|
|
|
#define OP_FIFO_READ_6X 0x1E |
|
|
|
#define OP_FIFO_READ_6X 0x1E |
|
|
|
#define REG_OCP_6X 0x08E7 |
|
|
|
#define REG_OCP_6X 0x08E7 |
|
|
|
#define REG_LNA_6X 0x08AC // no agc in sx1262
|
|
|
|
#define REG_LNA_6X 0x08AC // No agc in sx1262
|
|
|
|
#define REG_SYNC_WORD_MSB_6X 0x0740 |
|
|
|
#define REG_SYNC_WORD_MSB_6X 0x0740 |
|
|
|
#define REG_SYNC_WORD_LSB_6X 0x0741 |
|
|
|
#define REG_SYNC_WORD_LSB_6X 0x0741 |
|
|
|
#define REG_PAYLOAD_LENGTH_6X 0x0702 // https://github.com/beegee-tokyo/SX126x-Arduino/blob/master/src/radio/sx126x/sx126x.h#L98
|
|
|
|
#define REG_PAYLOAD_LENGTH_6X 0x0702 // https://github.com/beegee-tokyo/SX126x-Arduino/blob/master/src/radio/sx126x/sx126x.h#L98
|
|
|
@ -118,10 +115,7 @@ sx126x::sx126x() : |
|
|
|
_packet({0}), |
|
|
|
_packet({0}), |
|
|
|
_preinit_done(false), |
|
|
|
_preinit_done(false), |
|
|
|
_onReceive(NULL) |
|
|
|
_onReceive(NULL) |
|
|
|
{ |
|
|
|
{ setTimeout(0); } |
|
|
|
// overide Stream timeout value
|
|
|
|
|
|
|
|
setTimeout(0); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool sx126x::preInit() { |
|
|
|
bool sx126x::preInit() { |
|
|
|
pinMode(_ss, OUTPUT); |
|
|
|
pinMode(_ss, OUTPUT); |
|
|
@ -133,7 +127,7 @@ bool sx126x::preInit() { |
|
|
|
SPI.begin(); |
|
|
|
SPI.begin(); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
// check version (retry for up to 2 seconds)
|
|
|
|
// Check version (retry for up to 2 seconds)
|
|
|
|
// TODO: Actually read version registers, not syncwords
|
|
|
|
// TODO: Actually read version registers, not syncwords
|
|
|
|
long start = millis(); |
|
|
|
long start = millis(); |
|
|
|
uint8_t syncmsb; |
|
|
|
uint8_t syncmsb; |
|
|
@ -154,31 +148,24 @@ bool sx126x::preInit() { |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
uint8_t ISR_VECT sx126x::readRegister(uint16_t address) |
|
|
|
uint8_t ISR_VECT sx126x::readRegister(uint16_t address) { |
|
|
|
{ |
|
|
|
|
|
|
|
return singleTransfer(OP_READ_REGISTER_6X, address, 0x00); |
|
|
|
return singleTransfer(OP_READ_REGISTER_6X, address, 0x00); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::writeRegister(uint16_t address, uint8_t value) |
|
|
|
void sx126x::writeRegister(uint16_t address, uint8_t value) { |
|
|
|
{ |
|
|
|
|
|
|
|
singleTransfer(OP_WRITE_REGISTER_6X, address, value); |
|
|
|
singleTransfer(OP_WRITE_REGISTER_6X, address, value); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
uint8_t ISR_VECT sx126x::singleTransfer(uint8_t opcode, uint16_t address, uint8_t value) |
|
|
|
uint8_t ISR_VECT sx126x::singleTransfer(uint8_t opcode, uint16_t address, uint8_t value) { |
|
|
|
{ |
|
|
|
|
|
|
|
waitOnBusy(); |
|
|
|
waitOnBusy(); |
|
|
|
|
|
|
|
|
|
|
|
uint8_t response; |
|
|
|
uint8_t response; |
|
|
|
|
|
|
|
|
|
|
|
digitalWrite(_ss, LOW); |
|
|
|
digitalWrite(_ss, LOW); |
|
|
|
|
|
|
|
|
|
|
|
SPI.beginTransaction(_spiSettings); |
|
|
|
SPI.beginTransaction(_spiSettings); |
|
|
|
SPI.transfer(opcode); |
|
|
|
SPI.transfer(opcode); |
|
|
|
SPI.transfer((address & 0xFF00) >> 8); |
|
|
|
SPI.transfer((address & 0xFF00) >> 8); |
|
|
|
SPI.transfer(address & 0x00FF); |
|
|
|
SPI.transfer(address & 0x00FF); |
|
|
|
if (opcode == OP_READ_REGISTER_6X) { |
|
|
|
if (opcode == OP_READ_REGISTER_6X) { SPI.transfer(0x00); } |
|
|
|
SPI.transfer(0x00); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
response = SPI.transfer(value); |
|
|
|
response = SPI.transfer(value); |
|
|
|
SPI.endTransaction(); |
|
|
|
SPI.endTransaction(); |
|
|
|
|
|
|
|
|
|
|
@ -187,15 +174,12 @@ uint8_t ISR_VECT sx126x::singleTransfer(uint8_t opcode, uint16_t address, uint8_ |
|
|
|
return response; |
|
|
|
return response; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::rxAntEnable() |
|
|
|
void sx126x::rxAntEnable() { |
|
|
|
{ |
|
|
|
if (_rxen != -1) { digitalWrite(_rxen, HIGH); } |
|
|
|
if (_rxen != -1) { |
|
|
|
|
|
|
|
digitalWrite(_rxen, HIGH); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::loraMode() { |
|
|
|
void sx126x::loraMode() { |
|
|
|
// enable lora mode on the SX1262 chip
|
|
|
|
// Enable lora mode on the SX1262 chip
|
|
|
|
uint8_t mode = MODE_LONG_RANGE_MODE_6X; |
|
|
|
uint8_t mode = MODE_LONG_RANGE_MODE_6X; |
|
|
|
executeOpcode(OP_PACKET_TYPE_6X, &mode, 1); |
|
|
|
executeOpcode(OP_PACKET_TYPE_6X, &mode, 1); |
|
|
|
} |
|
|
|
} |
|
|
@ -203,141 +187,90 @@ void sx126x::loraMode() { |
|
|
|
void sx126x::waitOnBusy() { |
|
|
|
void sx126x::waitOnBusy() { |
|
|
|
unsigned long time = millis(); |
|
|
|
unsigned long time = millis(); |
|
|
|
if (_busy != -1) { |
|
|
|
if (_busy != -1) { |
|
|
|
while (digitalRead(_busy) == HIGH) |
|
|
|
while (digitalRead(_busy) == HIGH) { |
|
|
|
{ |
|
|
|
if (millis() >= (time + 100)) { break; } |
|
|
|
if (millis() >= (time + 100)) { |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// do nothing
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::executeOpcode(uint8_t opcode, uint8_t *buffer, uint8_t size) |
|
|
|
void sx126x::executeOpcode(uint8_t opcode, uint8_t *buffer, uint8_t size) { |
|
|
|
{ |
|
|
|
|
|
|
|
waitOnBusy(); |
|
|
|
waitOnBusy(); |
|
|
|
|
|
|
|
|
|
|
|
digitalWrite(_ss, LOW); |
|
|
|
digitalWrite(_ss, LOW); |
|
|
|
|
|
|
|
|
|
|
|
SPI.beginTransaction(_spiSettings); |
|
|
|
SPI.beginTransaction(_spiSettings); |
|
|
|
SPI.transfer(opcode); |
|
|
|
SPI.transfer(opcode); |
|
|
|
|
|
|
|
for (int i = 0; i < size; i++) { SPI.transfer(buffer[i]); } |
|
|
|
for (int i = 0; i < size; i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
SPI.transfer(buffer[i]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SPI.endTransaction(); |
|
|
|
SPI.endTransaction(); |
|
|
|
|
|
|
|
|
|
|
|
digitalWrite(_ss, HIGH); |
|
|
|
digitalWrite(_ss, HIGH); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::executeOpcodeRead(uint8_t opcode, uint8_t *buffer, uint8_t size) |
|
|
|
void sx126x::executeOpcodeRead(uint8_t opcode, uint8_t *buffer, uint8_t size) { |
|
|
|
{ |
|
|
|
|
|
|
|
waitOnBusy(); |
|
|
|
waitOnBusy(); |
|
|
|
|
|
|
|
|
|
|
|
digitalWrite(_ss, LOW); |
|
|
|
digitalWrite(_ss, LOW); |
|
|
|
|
|
|
|
|
|
|
|
SPI.beginTransaction(_spiSettings); |
|
|
|
SPI.beginTransaction(_spiSettings); |
|
|
|
SPI.transfer(opcode); |
|
|
|
SPI.transfer(opcode); |
|
|
|
SPI.transfer(0x00); |
|
|
|
SPI.transfer(0x00); |
|
|
|
|
|
|
|
for (int i = 0; i < size; i++) { buffer[i] = SPI.transfer(0x00); } |
|
|
|
for (int i = 0; i < size; i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
buffer[i] = SPI.transfer(0x00); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SPI.endTransaction(); |
|
|
|
SPI.endTransaction(); |
|
|
|
|
|
|
|
|
|
|
|
digitalWrite(_ss, HIGH); |
|
|
|
digitalWrite(_ss, HIGH); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::writeBuffer(const uint8_t* buffer, size_t size) |
|
|
|
void sx126x::writeBuffer(const uint8_t* buffer, size_t size) { |
|
|
|
{ |
|
|
|
|
|
|
|
waitOnBusy(); |
|
|
|
waitOnBusy(); |
|
|
|
|
|
|
|
|
|
|
|
digitalWrite(_ss, LOW); |
|
|
|
digitalWrite(_ss, LOW); |
|
|
|
|
|
|
|
|
|
|
|
SPI.beginTransaction(_spiSettings); |
|
|
|
SPI.beginTransaction(_spiSettings); |
|
|
|
SPI.transfer(OP_FIFO_WRITE_6X); |
|
|
|
SPI.transfer(OP_FIFO_WRITE_6X); |
|
|
|
SPI.transfer(_fifo_tx_addr_ptr); |
|
|
|
SPI.transfer(_fifo_tx_addr_ptr); |
|
|
|
|
|
|
|
for (int i = 0; i < size; i++) { SPI.transfer(buffer[i]); _fifo_tx_addr_ptr++; } |
|
|
|
for (int i = 0; i < size; i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
SPI.transfer(buffer[i]); |
|
|
|
|
|
|
|
_fifo_tx_addr_ptr++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SPI.endTransaction(); |
|
|
|
SPI.endTransaction(); |
|
|
|
|
|
|
|
|
|
|
|
digitalWrite(_ss, HIGH); |
|
|
|
digitalWrite(_ss, HIGH); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::readBuffer(uint8_t* buffer, size_t size) |
|
|
|
void sx126x::readBuffer(uint8_t* buffer, size_t size) { |
|
|
|
{ |
|
|
|
|
|
|
|
waitOnBusy(); |
|
|
|
waitOnBusy(); |
|
|
|
|
|
|
|
|
|
|
|
digitalWrite(_ss, LOW); |
|
|
|
digitalWrite(_ss, LOW); |
|
|
|
|
|
|
|
|
|
|
|
SPI.beginTransaction(_spiSettings); |
|
|
|
SPI.beginTransaction(_spiSettings); |
|
|
|
SPI.transfer(OP_FIFO_READ_6X); |
|
|
|
SPI.transfer(OP_FIFO_READ_6X); |
|
|
|
SPI.transfer(_fifo_rx_addr_ptr); |
|
|
|
SPI.transfer(_fifo_rx_addr_ptr); |
|
|
|
SPI.transfer(0x00); |
|
|
|
SPI.transfer(0x00); |
|
|
|
|
|
|
|
for (int i = 0; i < size; i++) { buffer[i] = SPI.transfer(0x00); } |
|
|
|
for (int i = 0; i < size; i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
buffer[i] = SPI.transfer(0x00); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SPI.endTransaction(); |
|
|
|
SPI.endTransaction(); |
|
|
|
|
|
|
|
|
|
|
|
digitalWrite(_ss, HIGH); |
|
|
|
digitalWrite(_ss, HIGH); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr, int ldro) { |
|
|
|
void sx126x::setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr, int ldro) { |
|
|
|
// because there is no access to these registers on the sx1262, we have
|
|
|
|
// Because there is no access to these registers on the sx1262, we have
|
|
|
|
// to set all these parameters at once or not at all.
|
|
|
|
// to set all these parameters at once or not at all.
|
|
|
|
uint8_t buf[8]; |
|
|
|
uint8_t buf[8]; |
|
|
|
|
|
|
|
|
|
|
|
buf[0] = sf; |
|
|
|
buf[0] = sf; |
|
|
|
buf[1] = bw; |
|
|
|
buf[1] = bw; |
|
|
|
buf[2] = cr;
|
|
|
|
buf[2] = cr;
|
|
|
|
// low data rate toggle
|
|
|
|
buf[3] = ldro; // Low data rate toggle
|
|
|
|
buf[3] = ldro; |
|
|
|
buf[4] = 0x00; // Unused params in LoRa mode
|
|
|
|
// unused params in LoRa mode
|
|
|
|
|
|
|
|
buf[4] = 0x00;
|
|
|
|
|
|
|
|
buf[5] = 0x00; |
|
|
|
buf[5] = 0x00; |
|
|
|
buf[6] = 0x00; |
|
|
|
buf[6] = 0x00; |
|
|
|
buf[7] = 0x00; |
|
|
|
buf[7] = 0x00; |
|
|
|
|
|
|
|
|
|
|
|
executeOpcode(OP_MODULATION_PARAMS_6X, buf, 8); |
|
|
|
executeOpcode(OP_MODULATION_PARAMS_6X, buf, 8); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::setPacketParams(long preamble, uint8_t headermode, uint8_t length, uint8_t crc) { |
|
|
|
void sx126x::setPacketParams(long preamble, uint8_t headermode, uint8_t length, uint8_t crc) { |
|
|
|
// because there is no access to these registers on the sx1262, we have
|
|
|
|
// Because there is no access to these registers on the sx1262, we have
|
|
|
|
// to set all these parameters at once or not at all.
|
|
|
|
// to set all these parameters at once or not at all.
|
|
|
|
uint8_t buf[9]; |
|
|
|
uint8_t buf[9]; |
|
|
|
|
|
|
|
|
|
|
|
buf[0] = uint8_t((preamble & 0xFF00) >> 8); |
|
|
|
buf[0] = uint8_t((preamble & 0xFF00) >> 8); |
|
|
|
buf[1] = uint8_t((preamble & 0x00FF)); |
|
|
|
buf[1] = uint8_t((preamble & 0x00FF)); |
|
|
|
buf[2] = headermode; |
|
|
|
buf[2] = headermode; |
|
|
|
buf[3] = length; |
|
|
|
buf[3] = length; |
|
|
|
buf[4] = crc; |
|
|
|
buf[4] = crc; |
|
|
|
// standard IQ setting (no inversion)
|
|
|
|
buf[5] = 0x00; // standard IQ setting (no inversion)
|
|
|
|
buf[5] = 0x00; |
|
|
|
buf[6] = 0x00; // unused params
|
|
|
|
// unused params
|
|
|
|
|
|
|
|
buf[6] = 0x00;
|
|
|
|
|
|
|
|
buf[7] = 0x00;
|
|
|
|
buf[7] = 0x00;
|
|
|
|
buf[8] = 0x00;
|
|
|
|
buf[8] = 0x00;
|
|
|
|
|
|
|
|
|
|
|
|
executeOpcode(OP_PACKET_PARAMS_6X, buf, 9); |
|
|
|
executeOpcode(OP_PACKET_PARAMS_6X, buf, 9); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::reset(void) { |
|
|
|
void sx126x::reset(void) { |
|
|
|
if (_reset != -1) { |
|
|
|
if (_reset != -1) { |
|
|
|
pinMode(_reset, OUTPUT); |
|
|
|
pinMode(_reset, OUTPUT); |
|
|
|
|
|
|
|
|
|
|
|
// perform reset
|
|
|
|
|
|
|
|
digitalWrite(_reset, LOW); |
|
|
|
digitalWrite(_reset, LOW); |
|
|
|
delay(10); |
|
|
|
delay(10); |
|
|
|
digitalWrite(_reset, HIGH); |
|
|
|
digitalWrite(_reset, HIGH); |
|
|
@ -350,7 +283,7 @@ void sx126x::calibrate(void) { |
|
|
|
uint8_t mode_byte = MODE_STDBY_RC_6X; |
|
|
|
uint8_t mode_byte = MODE_STDBY_RC_6X; |
|
|
|
executeOpcode(OP_STANDBY_6X, &mode_byte, 1); |
|
|
|
executeOpcode(OP_STANDBY_6X, &mode_byte, 1); |
|
|
|
|
|
|
|
|
|
|
|
// calibrate RC64k, RC13M, PLL, ADC and image
|
|
|
|
// Calibrate RC64k, RC13M, PLL, ADC and image
|
|
|
|
uint8_t calibrate = MASK_CALIBRATE_ALL; |
|
|
|
uint8_t calibrate = MASK_CALIBRATE_ALL; |
|
|
|
executeOpcode(OP_CALIBRATE_6X, &calibrate, 1); |
|
|
|
executeOpcode(OP_CALIBRATE_6X, &calibrate, 1); |
|
|
|
|
|
|
|
|
|
|
@ -360,55 +293,25 @@ void sx126x::calibrate(void) { |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::calibrate_image(long frequency) { |
|
|
|
void sx126x::calibrate_image(long frequency) { |
|
|
|
uint8_t image_freq[2] = {0}; |
|
|
|
uint8_t image_freq[2] = {0}; |
|
|
|
|
|
|
|
if (frequency >= 430E6 && frequency <= 440E6) { image_freq[0] = 0x6B; image_freq[1] = 0x6F; } |
|
|
|
if (frequency >= 430E6 && frequency <= 440E6) { |
|
|
|
else if (frequency >= 470E6 && frequency <= 510E6) { image_freq[0] = 0x75; image_freq[1] = 0x81; } |
|
|
|
image_freq[0] = 0x6B; |
|
|
|
else if (frequency >= 779E6 && frequency <= 787E6) { image_freq[0] = 0xC1; image_freq[1] = 0xC5; } |
|
|
|
image_freq[1] = 0x6F; |
|
|
|
else if (frequency >= 863E6 && frequency <= 870E6) { image_freq[0] = 0xD7; image_freq[1] = 0xDB; } |
|
|
|
} |
|
|
|
else if (frequency >= 902E6 && frequency <= 928E6) { image_freq[0] = 0xE1; image_freq[1] = 0xE9; } |
|
|
|
else if (frequency >= 470E6 && frequency <= 510E6) { |
|
|
|
|
|
|
|
image_freq[0] = 0x75; |
|
|
|
|
|
|
|
image_freq[1] = 0x81; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (frequency >= 779E6 && frequency <= 787E6) { |
|
|
|
|
|
|
|
image_freq[0] = 0xC1; |
|
|
|
|
|
|
|
image_freq[1] = 0xC5; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (frequency >= 863E6 && frequency <= 870E6) { |
|
|
|
|
|
|
|
image_freq[0] = 0xD7; |
|
|
|
|
|
|
|
image_freq[1] = 0xDB; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (frequency >= 902E6 && frequency <= 928E6) { |
|
|
|
|
|
|
|
image_freq[0] = 0xE1; |
|
|
|
|
|
|
|
image_freq[1] = 0xE9; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
executeOpcode(OP_CALIBRATE_IMAGE_6X, image_freq, 2); |
|
|
|
executeOpcode(OP_CALIBRATE_IMAGE_6X, image_freq, 2); |
|
|
|
waitOnBusy(); |
|
|
|
waitOnBusy(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int sx126x::begin(long frequency) |
|
|
|
int sx126x::begin(long frequency) { |
|
|
|
{ |
|
|
|
|
|
|
|
reset(); |
|
|
|
reset(); |
|
|
|
|
|
|
|
|
|
|
|
if (_busy != -1) { |
|
|
|
if (_busy != -1) { pinMode(_busy, INPUT); } |
|
|
|
pinMode(_busy, INPUT); |
|
|
|
if (!_preinit_done) { if (!preInit()) { return false; } } |
|
|
|
} |
|
|
|
if (_rxen != -1) { pinMode(_rxen, OUTPUT); } |
|
|
|
|
|
|
|
|
|
|
|
if (!_preinit_done) { |
|
|
|
|
|
|
|
if (!preInit()) { |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (_rxen != -1) { |
|
|
|
|
|
|
|
pinMode(_rxen, OUTPUT); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
calibrate(); |
|
|
|
calibrate(); |
|
|
|
calibrate_image(frequency); |
|
|
|
calibrate_image(frequency); |
|
|
|
|
|
|
|
|
|
|
|
enableTCXO(); |
|
|
|
enableTCXO(); |
|
|
|
|
|
|
|
|
|
|
|
loraMode(); |
|
|
|
loraMode(); |
|
|
|
standby(); |
|
|
|
standby(); |
|
|
|
|
|
|
|
|
|
|
@ -422,18 +325,11 @@ int sx126x::begin(long frequency) |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
rxAntEnable(); |
|
|
|
rxAntEnable(); |
|
|
|
|
|
|
|
|
|
|
|
setFrequency(frequency); |
|
|
|
setFrequency(frequency); |
|
|
|
|
|
|
|
|
|
|
|
// set output power to 2 dBm
|
|
|
|
|
|
|
|
setTxPower(2); |
|
|
|
setTxPower(2); |
|
|
|
enableCrc(); |
|
|
|
enableCrc(); |
|
|
|
|
|
|
|
writeRegister(REG_LNA_6X, 0x96); // Set LNA boost
|
|
|
|
// set LNA boost
|
|
|
|
uint8_t basebuf[2] = {0}; // Set base addresses
|
|
|
|
writeRegister(REG_LNA_6X, 0x96); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// set base addresses
|
|
|
|
|
|
|
|
uint8_t basebuf[2] = {0}; |
|
|
|
|
|
|
|
executeOpcode(OP_BUFFER_BASE_ADDR_6X, basebuf, 2); |
|
|
|
executeOpcode(OP_BUFFER_BASE_ADDR_6X, basebuf, 2); |
|
|
|
|
|
|
|
|
|
|
|
setModulationParams(_sf, _bw, _cr, _ldro); |
|
|
|
setModulationParams(_sf, _bw, _cr, _ldro); |
|
|
@ -442,26 +338,12 @@ int sx126x::begin(long frequency) |
|
|
|
return 1; |
|
|
|
return 1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::end() |
|
|
|
void sx126x::end() { sleep(); SPI.end(); _preinit_done = false; } |
|
|
|
{ |
|
|
|
|
|
|
|
// put in sleep mode
|
|
|
|
|
|
|
|
sleep(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// stop SPI
|
|
|
|
|
|
|
|
SPI.end(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_preinit_done = false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int sx126x::beginPacket(int implicitHeader) |
|
|
|
int sx126x::beginPacket(int implicitHeader) { |
|
|
|
{ |
|
|
|
|
|
|
|
standby(); |
|
|
|
standby(); |
|
|
|
|
|
|
|
if (implicitHeader) { implicitHeaderMode(); } |
|
|
|
if (implicitHeader) { |
|
|
|
else { explicitHeaderMode(); } |
|
|
|
implicitHeaderMode(); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
explicitHeaderMode(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_payloadLength = 0; |
|
|
|
_payloadLength = 0; |
|
|
|
_fifo_tx_addr_ptr = 0; |
|
|
|
_fifo_tx_addr_ptr = 0; |
|
|
@ -470,24 +352,19 @@ int sx126x::beginPacket(int implicitHeader) |
|
|
|
return 1; |
|
|
|
return 1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int sx126x::endPacket() |
|
|
|
int sx126x::endPacket() { |
|
|
|
{ |
|
|
|
|
|
|
|
setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); |
|
|
|
setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); |
|
|
|
|
|
|
|
uint8_t timeout[3] = {0}; // Put in single TX mode
|
|
|
|
// put in single TX mode
|
|
|
|
|
|
|
|
uint8_t timeout[3] = {0}; |
|
|
|
|
|
|
|
executeOpcode(OP_TX_6X, timeout, 3); |
|
|
|
executeOpcode(OP_TX_6X, timeout, 3); |
|
|
|
|
|
|
|
|
|
|
|
uint8_t buf[2]; |
|
|
|
uint8_t buf[2]; |
|
|
|
|
|
|
|
|
|
|
|
buf[0] = 0x00; |
|
|
|
buf[0] = 0x00; |
|
|
|
buf[1] = 0x00; |
|
|
|
buf[1] = 0x00; |
|
|
|
|
|
|
|
|
|
|
|
executeOpcodeRead(OP_GET_IRQ_STATUS_6X, buf, 2); |
|
|
|
executeOpcodeRead(OP_GET_IRQ_STATUS_6X, buf, 2); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Wait for TX done
|
|
|
|
bool timed_out = false; |
|
|
|
bool timed_out = false; |
|
|
|
uint32_t w_timeout = millis()+LORA_MODEM_TIMEOUT_MS; |
|
|
|
uint32_t w_timeout = millis()+LORA_MODEM_TIMEOUT_MS; |
|
|
|
// wait for TX done
|
|
|
|
|
|
|
|
while ((millis() < w_timeout) && ((buf[1] & IRQ_TX_DONE_MASK_6X) == 0)) { |
|
|
|
while ((millis() < w_timeout) && ((buf[1] & IRQ_TX_DONE_MASK_6X) == 0)) { |
|
|
|
buf[0] = 0x00; |
|
|
|
buf[0] = 0x00; |
|
|
|
buf[1] = 0x00; |
|
|
|
buf[1] = 0x00; |
|
|
@ -497,32 +374,24 @@ int sx126x::endPacket() |
|
|
|
|
|
|
|
|
|
|
|
if (!(millis() < w_timeout)) { timed_out = true; } |
|
|
|
if (!(millis() < w_timeout)) { timed_out = true; } |
|
|
|
|
|
|
|
|
|
|
|
// clear IRQ's
|
|
|
|
// Clear IRQs
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t mask[2]; |
|
|
|
uint8_t mask[2]; |
|
|
|
mask[0] = 0x00; |
|
|
|
mask[0] = 0x00; |
|
|
|
mask[1] = IRQ_TX_DONE_MASK_6X; |
|
|
|
mask[1] = IRQ_TX_DONE_MASK_6X; |
|
|
|
executeOpcode(OP_CLEAR_IRQ_STATUS_6X, mask, 2); |
|
|
|
executeOpcode(OP_CLEAR_IRQ_STATUS_6X, mask, 2); |
|
|
|
|
|
|
|
if (timed_out) { return 0; } else { return 1; } |
|
|
|
if (timed_out) { |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
return 1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
uint8_t sx126x::modemStatus() { |
|
|
|
uint8_t sx126x::modemStatus() { |
|
|
|
// imitate the register status from the sx1276 / 78
|
|
|
|
// Imitate the register status from the sx1276 / 78
|
|
|
|
uint8_t buf[2] = {0}; |
|
|
|
uint8_t buf[2] = {0}; |
|
|
|
|
|
|
|
|
|
|
|
executeOpcodeRead(OP_GET_IRQ_STATUS_6X, buf, 2); |
|
|
|
executeOpcodeRead(OP_GET_IRQ_STATUS_6X, buf, 2); |
|
|
|
uint8_t clearbuf[2] = {0}; |
|
|
|
uint8_t clearbuf[2] = {0}; |
|
|
|
uint8_t byte = 0x00; |
|
|
|
uint8_t byte = 0x00; |
|
|
|
|
|
|
|
|
|
|
|
if ((buf[1] & IRQ_PREAMBLE_DET_MASK_6X) != 0) { |
|
|
|
if ((buf[1] & IRQ_PREAMBLE_DET_MASK_6X) != 0) { |
|
|
|
byte = byte | 0x01 | 0x04; |
|
|
|
byte = byte | 0x01 | 0x04; |
|
|
|
// clear register after reading
|
|
|
|
clearbuf[1] = IRQ_PREAMBLE_DET_MASK_6X; // Clear register after reading
|
|
|
|
clearbuf[1] = IRQ_PREAMBLE_DET_MASK_6X; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if ((buf[1] & IRQ_HEADER_DET_MASK_6X) != 0) { |
|
|
|
if ((buf[1] & IRQ_HEADER_DET_MASK_6X) != 0) { |
|
|
@ -530,7 +399,6 @@ uint8_t sx126x::modemStatus() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
executeOpcode(OP_CLEAR_IRQ_STATUS_6X, clearbuf, 2); |
|
|
|
executeOpcode(OP_CLEAR_IRQ_STATUS_6X, clearbuf, 2); |
|
|
|
|
|
|
|
|
|
|
|
return byte;
|
|
|
|
return byte;
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -555,7 +423,7 @@ uint8_t sx126x::packetRssiRaw() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int ISR_VECT sx126x::packetRssi() { |
|
|
|
int ISR_VECT sx126x::packetRssi() { |
|
|
|
// may need more calculations here
|
|
|
|
// TODO: May need more calculations here
|
|
|
|
uint8_t buf[3] = {0}; |
|
|
|
uint8_t buf[3] = {0}; |
|
|
|
executeOpcodeRead(OP_PACKET_STATUS_6X, buf, 3); |
|
|
|
executeOpcodeRead(OP_PACKET_STATUS_6X, buf, 3); |
|
|
|
int pkt_rssi = -buf[0] / 2; |
|
|
|
int pkt_rssi = -buf[0] / 2; |
|
|
@ -563,7 +431,7 @@ int ISR_VECT sx126x::packetRssi() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int ISR_VECT sx126x::packetRssi(uint8_t pkt_snr_raw) { |
|
|
|
int ISR_VECT sx126x::packetRssi(uint8_t pkt_snr_raw) { |
|
|
|
// may need more calculations here
|
|
|
|
// TODO: May need more calculations here
|
|
|
|
uint8_t buf[3] = {0}; |
|
|
|
uint8_t buf[3] = {0}; |
|
|
|
executeOpcodeRead(OP_PACKET_STATUS_6X, buf, 3); |
|
|
|
executeOpcodeRead(OP_PACKET_STATUS_6X, buf, 3); |
|
|
|
int pkt_rssi = -buf[0] / 2; |
|
|
|
int pkt_rssi = -buf[0] / 2; |
|
|
@ -582,50 +450,33 @@ float ISR_VECT sx126x::packetSnr() { |
|
|
|
return float(buf[1]) * 0.25; |
|
|
|
return float(buf[1]) * 0.25; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
long sx126x::packetFrequencyError() |
|
|
|
long sx126x::packetFrequencyError() { |
|
|
|
{ |
|
|
|
// TODO: Implement this, no idea how to check it on the sx1262
|
|
|
|
// todo: implement this, no idea how to check it on the sx1262
|
|
|
|
|
|
|
|
const float fError = 0.0; |
|
|
|
const float fError = 0.0; |
|
|
|
return static_cast<long>(fError); |
|
|
|
return static_cast<long>(fError); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
size_t sx126x::write(uint8_t byte) |
|
|
|
size_t sx126x::write(uint8_t byte) { return write(&byte, sizeof(byte)); } |
|
|
|
{ |
|
|
|
size_t sx126x::write(const uint8_t *buffer, size_t size) { |
|
|
|
return write(&byte, sizeof(byte)); |
|
|
|
if ((_payloadLength + size) > MAX_PKT_LENGTH) { size = MAX_PKT_LENGTH - _payloadLength; } |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
size_t sx126x::write(const uint8_t *buffer, size_t size) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if ((_payloadLength + size) > MAX_PKT_LENGTH) { |
|
|
|
|
|
|
|
size = MAX_PKT_LENGTH - _payloadLength; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// write data
|
|
|
|
|
|
|
|
writeBuffer(buffer, size); |
|
|
|
writeBuffer(buffer, size); |
|
|
|
_payloadLength = _payloadLength + size; |
|
|
|
_payloadLength = _payloadLength + size; |
|
|
|
return size; |
|
|
|
return size; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int ISR_VECT sx126x::available() |
|
|
|
int ISR_VECT sx126x::available() { |
|
|
|
{ |
|
|
|
|
|
|
|
uint8_t buf[2] = {0}; |
|
|
|
uint8_t buf[2] = {0}; |
|
|
|
executeOpcodeRead(OP_RX_BUFFER_STATUS_6X, buf, 2); |
|
|
|
executeOpcodeRead(OP_RX_BUFFER_STATUS_6X, buf, 2); |
|
|
|
return buf[0] - _packetIndex; |
|
|
|
return buf[0] - _packetIndex; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int ISR_VECT sx126x::read() |
|
|
|
int ISR_VECT sx126x::read(){ |
|
|
|
{ |
|
|
|
if (!available()) { return -1; } |
|
|
|
if (!available()) { |
|
|
|
|
|
|
|
return -1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if received new packet
|
|
|
|
|
|
|
|
if (_packetIndex == 0) { |
|
|
|
if (_packetIndex == 0) { |
|
|
|
uint8_t rxbuf[2] = {0}; |
|
|
|
uint8_t rxbuf[2] = {0}; |
|
|
|
executeOpcodeRead(OP_RX_BUFFER_STATUS_6X, rxbuf, 2); |
|
|
|
executeOpcodeRead(OP_RX_BUFFER_STATUS_6X, rxbuf, 2); |
|
|
|
int size = rxbuf[0]; |
|
|
|
int size = rxbuf[0]; |
|
|
|
_fifo_rx_addr_ptr = rxbuf[1]; |
|
|
|
_fifo_rx_addr_ptr = rxbuf[1]; |
|
|
|
|
|
|
|
|
|
|
|
readBuffer(_packet, size); |
|
|
|
readBuffer(_packet, size); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -634,19 +485,13 @@ int ISR_VECT sx126x::read() |
|
|
|
return byte; |
|
|
|
return byte; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int sx126x::peek() |
|
|
|
int sx126x::peek() { |
|
|
|
{ |
|
|
|
if (!available()) { return -1; } |
|
|
|
if (!available()) { |
|
|
|
|
|
|
|
return -1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if received new packet
|
|
|
|
|
|
|
|
if (_packetIndex == 0) { |
|
|
|
if (_packetIndex == 0) { |
|
|
|
uint8_t rxbuf[2] = {0}; |
|
|
|
uint8_t rxbuf[2] = {0}; |
|
|
|
executeOpcodeRead(OP_RX_BUFFER_STATUS_6X, rxbuf, 2); |
|
|
|
executeOpcodeRead(OP_RX_BUFFER_STATUS_6X, rxbuf, 2); |
|
|
|
int size = rxbuf[0]; |
|
|
|
int size = rxbuf[0]; |
|
|
|
_fifo_rx_addr_ptr = rxbuf[1]; |
|
|
|
_fifo_rx_addr_ptr = rxbuf[1]; |
|
|
|
|
|
|
|
|
|
|
|
readBuffer(_packet, size); |
|
|
|
readBuffer(_packet, size); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -654,41 +499,29 @@ int sx126x::peek() |
|
|
|
return b; |
|
|
|
return b; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::flush() |
|
|
|
void sx126x::flush() { } |
|
|
|
{ |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void sx126x::onReceive(void(*callback)(int)) |
|
|
|
void sx126x::onReceive(void(*callback)(int)){ |
|
|
|
{ |
|
|
|
|
|
|
|
_onReceive = callback; |
|
|
|
_onReceive = callback; |
|
|
|
|
|
|
|
|
|
|
|
if (callback) { |
|
|
|
if (callback) { |
|
|
|
pinMode(_dio0, INPUT); |
|
|
|
pinMode(_dio0, INPUT); |
|
|
|
|
|
|
|
uint8_t buf[8]; // Set preamble and header detection irqs, plus dio0 mask
|
|
|
|
// set preamble and header detection irqs, plus dio0 mask
|
|
|
|
buf[0] = 0xFF; // Set irq masks, enable all
|
|
|
|
uint8_t buf[8]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// set irq masks, enable all
|
|
|
|
|
|
|
|
buf[0] = 0xFF;
|
|
|
|
|
|
|
|
buf[1] = 0xFF; |
|
|
|
buf[1] = 0xFF; |
|
|
|
|
|
|
|
buf[2] = 0x00; // Set dio0 masks
|
|
|
|
// set dio0 masks
|
|
|
|
|
|
|
|
buf[2] = 0x00; |
|
|
|
|
|
|
|
buf[3] = IRQ_RX_DONE_MASK_6X;
|
|
|
|
buf[3] = IRQ_RX_DONE_MASK_6X;
|
|
|
|
|
|
|
|
buf[4] = 0x00; // Set dio1 masks
|
|
|
|
// set dio1 masks
|
|
|
|
|
|
|
|
buf[4] = 0x00;
|
|
|
|
|
|
|
|
buf[5] = 0x00; |
|
|
|
buf[5] = 0x00; |
|
|
|
|
|
|
|
buf[6] = 0x00; // Set dio2 masks
|
|
|
|
// set dio2 masks
|
|
|
|
|
|
|
|
buf[6] = 0x00;
|
|
|
|
|
|
|
|
buf[7] = 0x00; |
|
|
|
buf[7] = 0x00; |
|
|
|
|
|
|
|
|
|
|
|
executeOpcode(OP_SET_IRQ_FLAGS_6X, buf, 8); |
|
|
|
executeOpcode(OP_SET_IRQ_FLAGS_6X, buf, 8); |
|
|
|
|
|
|
|
|
|
|
|
#ifdef SPI_HAS_NOTUSINGINTERRUPT |
|
|
|
#ifdef SPI_HAS_NOTUSINGINTERRUPT |
|
|
|
SPI.usingInterrupt(digitalPinToInterrupt(_dio0)); |
|
|
|
SPI.usingInterrupt(digitalPinToInterrupt(_dio0)); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
attachInterrupt(digitalPinToInterrupt(_dio0), sx126x::onDio0Rise, RISING); |
|
|
|
attachInterrupt(digitalPinToInterrupt(_dio0), sx126x::onDio0Rise, RISING); |
|
|
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
detachInterrupt(digitalPinToInterrupt(_dio0)); |
|
|
|
detachInterrupt(digitalPinToInterrupt(_dio0)); |
|
|
|
#ifdef SPI_HAS_NOTUSINGINTERRUPT |
|
|
|
#ifdef SPI_HAS_NOTUSINGINTERRUPT |
|
|
@ -697,40 +530,24 @@ void sx126x::onReceive(void(*callback)(int)) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::receive(int size) |
|
|
|
void sx126x::receive(int size) { |
|
|
|
{ |
|
|
|
|
|
|
|
if (size > 0) { |
|
|
|
if (size > 0) { |
|
|
|
implicitHeaderMode(); |
|
|
|
implicitHeaderMode(); |
|
|
|
|
|
|
|
|
|
|
|
// tell radio payload length
|
|
|
|
|
|
|
|
_payloadLength = size; |
|
|
|
_payloadLength = size; |
|
|
|
setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); |
|
|
|
setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); |
|
|
|
} else { |
|
|
|
} else { explicitHeaderMode(); } |
|
|
|
explicitHeaderMode(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (_rxen != -1) { |
|
|
|
if (_rxen != -1) { rxAntEnable(); } |
|
|
|
rxAntEnable(); |
|
|
|
uint8_t mode[3] = {0xFF, 0xFF, 0xFF}; // Continuous mode
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t mode[3] = {0xFF, 0xFF, 0xFF}; // continuous mode
|
|
|
|
|
|
|
|
executeOpcode(OP_RX_6X, mode, 3); |
|
|
|
executeOpcode(OP_RX_6X, mode, 3); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::standby() |
|
|
|
void sx126x::standby() { |
|
|
|
{ |
|
|
|
uint8_t byte = MODE_STDBY_XOSC_6X; // STDBY_XOSC
|
|
|
|
// STDBY_XOSC
|
|
|
|
|
|
|
|
uint8_t byte = MODE_STDBY_XOSC_6X; |
|
|
|
|
|
|
|
// STDBY_RC
|
|
|
|
|
|
|
|
// uint8_t byte = MODE_STDBY_RC_6X;
|
|
|
|
|
|
|
|
executeOpcode(OP_STANDBY_6X, &byte, 1);
|
|
|
|
executeOpcode(OP_STANDBY_6X, &byte, 1);
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::sleep() |
|
|
|
void sx126x::sleep() { uint8_t byte = 0x00; executeOpcode(OP_SLEEP_6X, &byte, 1); } |
|
|
|
{ |
|
|
|
|
|
|
|
uint8_t byte = 0x00; |
|
|
|
|
|
|
|
executeOpcode(OP_SLEEP_6X, &byte, 1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void sx126x::enableTCXO() { |
|
|
|
void sx126x::enableTCXO() { |
|
|
|
#if HAS_TCXO |
|
|
|
#if HAS_TCXO |
|
|
@ -755,78 +572,60 @@ void sx126x::enableTCXO() { |
|
|
|
void sx126x::disableTCXO() { } |
|
|
|
void sx126x::disableTCXO() { } |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::setTxPower(int level, int outputPin) { |
|
|
|
void sx126x::setTxPower(int level, int outputPin) { |
|
|
|
// currently no low power mode for SX1262 implemented, assuming PA boost
|
|
|
|
// Currently no low power mode for SX1262 implemented, assuming PA boost
|
|
|
|
|
|
|
|
|
|
|
|
// WORKAROUND - Better Resistance of the SX1262 Tx to Antenna Mismatch, see DS_SX1261-2_V1.2 datasheet chapter 15.2
|
|
|
|
// WORKAROUND - Better Resistance of the SX1262 Tx to Antenna Mismatch, see DS_SX1261-2_V1.2 datasheet chapter 15.2
|
|
|
|
// RegTxClampConfig = @address 0x08D8
|
|
|
|
// RegTxClampConfig = @address 0x08D8
|
|
|
|
writeRegister(0x08D8, readRegister(0x08D8) | (0x0F << 1)); |
|
|
|
writeRegister(0x08D8, readRegister(0x08D8) | (0x0F << 1)); |
|
|
|
|
|
|
|
|
|
|
|
uint8_t pa_buf[4]; |
|
|
|
uint8_t pa_buf[4]; |
|
|
|
|
|
|
|
|
|
|
|
pa_buf[0] = 0x04; // PADutyCycle needs to be 0x04 to achieve 22dBm output, but can be lowered for better efficiency at lower outputs
|
|
|
|
pa_buf[0] = 0x04; // PADutyCycle needs to be 0x04 to achieve 22dBm output, but can be lowered for better efficiency at lower outputs
|
|
|
|
pa_buf[1] = 0x07; // HPMax at 0x07 is maximum supported for SX1262
|
|
|
|
pa_buf[1] = 0x07; // HPMax at 0x07 is maximum supported for SX1262
|
|
|
|
pa_buf[2] = 0x00; // DeviceSel 0x00 for SX1262 (0x01 for SX1261)
|
|
|
|
pa_buf[2] = 0x00; // DeviceSel 0x00 for SX1262 (0x01 for SX1261)
|
|
|
|
pa_buf[3] = 0x01; // PALut always 0x01 (reserved according to datasheet)
|
|
|
|
pa_buf[3] = 0x01; // PALut always 0x01 (reserved according to datasheet)
|
|
|
|
|
|
|
|
|
|
|
|
executeOpcode(OP_PA_CONFIG_6X, pa_buf, 4); // set pa_config for high power
|
|
|
|
executeOpcode(OP_PA_CONFIG_6X, pa_buf, 4); // set pa_config for high power
|
|
|
|
|
|
|
|
|
|
|
|
if (level > 22) { level = 22; } |
|
|
|
if (level > 22) { level = 22; } |
|
|
|
else if (level < -9) { level = -9; } |
|
|
|
else if (level < -9) { level = -9; } |
|
|
|
|
|
|
|
|
|
|
|
writeRegister(REG_OCP_6X, OCP_TUNED); // Use board-specific tuned OCP
|
|
|
|
writeRegister(REG_OCP_6X, OCP_TUNED); // Use board-specific tuned OCP
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t tx_buf[2]; |
|
|
|
uint8_t tx_buf[2]; |
|
|
|
|
|
|
|
|
|
|
|
tx_buf[0] = level; |
|
|
|
tx_buf[0] = level; |
|
|
|
tx_buf[1] = 0x02; // PA ramping time - 40 microseconds
|
|
|
|
tx_buf[1] = 0x02; // PA ramping time - 40 microseconds
|
|
|
|
|
|
|
|
|
|
|
|
executeOpcode(OP_TX_PARAMS_6X, tx_buf, 2); |
|
|
|
executeOpcode(OP_TX_PARAMS_6X, tx_buf, 2); |
|
|
|
|
|
|
|
|
|
|
|
_txp = level; |
|
|
|
_txp = level; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
uint8_t sx126x::getTxPower() { |
|
|
|
uint8_t sx126x::getTxPower() { return _txp; } |
|
|
|
return _txp; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void sx126x::setFrequency(long frequency) { |
|
|
|
void sx126x::setFrequency(long frequency) { |
|
|
|
_frequency = frequency; |
|
|
|
_frequency = frequency; |
|
|
|
|
|
|
|
|
|
|
|
uint8_t buf[4]; |
|
|
|
uint8_t buf[4]; |
|
|
|
|
|
|
|
|
|
|
|
uint32_t freq = (uint32_t)((double)frequency / (double)FREQ_STEP_6X); |
|
|
|
uint32_t freq = (uint32_t)((double)frequency / (double)FREQ_STEP_6X); |
|
|
|
|
|
|
|
|
|
|
|
buf[0] = ((freq >> 24) & 0xFF); |
|
|
|
buf[0] = ((freq >> 24) & 0xFF); |
|
|
|
buf[1] = ((freq >> 16) & 0xFF); |
|
|
|
buf[1] = ((freq >> 16) & 0xFF); |
|
|
|
buf[2] = ((freq >> 8) & 0xFF); |
|
|
|
buf[2] = ((freq >> 8) & 0xFF); |
|
|
|
buf[3] = (freq & 0xFF); |
|
|
|
buf[3] = (freq & 0xFF); |
|
|
|
|
|
|
|
|
|
|
|
executeOpcode(OP_RF_FREQ_6X, buf, 4); |
|
|
|
executeOpcode(OP_RF_FREQ_6X, buf, 4); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
uint32_t sx126x::getFrequency() { |
|
|
|
uint32_t sx126x::getFrequency() { |
|
|
|
// we can't read the frequency on the sx1262 / 80
|
|
|
|
// We can't read the frequency on the sx1262 / 80
|
|
|
|
uint32_t frequency = _frequency; |
|
|
|
uint32_t frequency = _frequency; |
|
|
|
|
|
|
|
|
|
|
|
return frequency; |
|
|
|
return frequency; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::setSpreadingFactor(int sf) |
|
|
|
void sx126x::setSpreadingFactor(int sf) { |
|
|
|
{ |
|
|
|
if (sf < 5) { sf = 5; } |
|
|
|
if (sf < 5) { |
|
|
|
else if (sf > 12) { sf = 12; } |
|
|
|
sf = 5; |
|
|
|
|
|
|
|
} else if (sf > 12) { |
|
|
|
|
|
|
|
sf = 12; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_sf = sf; |
|
|
|
_sf = sf; |
|
|
|
|
|
|
|
|
|
|
|
handleLowDataRate(); |
|
|
|
handleLowDataRate(); |
|
|
|
setModulationParams(sf, _bw, _cr, _ldro); |
|
|
|
setModulationParams(sf, _bw, _cr, _ldro); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
long sx126x::getSignalBandwidth() |
|
|
|
long sx126x::getSignalBandwidth() { |
|
|
|
{ |
|
|
|
|
|
|
|
int bw = _bw; |
|
|
|
int bw = _bw; |
|
|
|
switch (bw) { |
|
|
|
switch (bw) { |
|
|
|
case 0x00: return 7.8E3; |
|
|
|
case 0x00: return 7.8E3; |
|
|
@ -844,96 +643,52 @@ long sx126x::getSignalBandwidth() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::handleLowDataRate(){ |
|
|
|
void sx126x::handleLowDataRate(){ |
|
|
|
if ( long( (1<<_sf) / (getSignalBandwidth()/1000)) > 16) { |
|
|
|
if ( long( (1<<_sf) / (getSignalBandwidth()/1000)) > 16) { _ldro = 0x01; } |
|
|
|
_ldro = 0x01; |
|
|
|
else { _ldro = 0x00; } |
|
|
|
} else { |
|
|
|
|
|
|
|
_ldro = 0x00; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void sx126x::optimizeModemSensitivity(){ |
|
|
|
|
|
|
|
// todo: check if there's anything the sx1262 can do here
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void sx126x::setSignalBandwidth(long sbw) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (sbw <= 7.8E3) { |
|
|
|
|
|
|
|
_bw = 0x00; |
|
|
|
|
|
|
|
} else if (sbw <= 10.4E3) { |
|
|
|
|
|
|
|
_bw = 0x08; |
|
|
|
|
|
|
|
} else if (sbw <= 15.6E3) { |
|
|
|
|
|
|
|
_bw = 0x01; |
|
|
|
|
|
|
|
} else if (sbw <= 20.8E3) { |
|
|
|
|
|
|
|
_bw = 0x09; |
|
|
|
|
|
|
|
} else if (sbw <= 31.25E3) { |
|
|
|
|
|
|
|
_bw = 0x02; |
|
|
|
|
|
|
|
} else if (sbw <= 41.7E3) { |
|
|
|
|
|
|
|
_bw = 0x0A; |
|
|
|
|
|
|
|
} else if (sbw <= 62.5E3) { |
|
|
|
|
|
|
|
_bw = 0x03; |
|
|
|
|
|
|
|
} else if (sbw <= 125E3) { |
|
|
|
|
|
|
|
_bw = 0x04; |
|
|
|
|
|
|
|
} else if (sbw <= 250E3) { |
|
|
|
|
|
|
|
_bw = 0x05; |
|
|
|
|
|
|
|
} else /*if (sbw <= 250E3)*/ { |
|
|
|
|
|
|
|
_bw = 0x06; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: check if there's anything the sx1262 can do here
|
|
|
|
|
|
|
|
void sx126x::optimizeModemSensitivity(){ } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void sx126x::setSignalBandwidth(long sbw) { |
|
|
|
|
|
|
|
if (sbw <= 7.8E3) { _bw = 0x00; } |
|
|
|
|
|
|
|
else if (sbw <= 10.4E3) { _bw = 0x08; } |
|
|
|
|
|
|
|
else if (sbw <= 15.6E3) { _bw = 0x01; } |
|
|
|
|
|
|
|
else if (sbw <= 20.8E3) { _bw = 0x09; } |
|
|
|
|
|
|
|
else if (sbw <= 31.25E3) { _bw = 0x02; } |
|
|
|
|
|
|
|
else if (sbw <= 41.7E3) { _bw = 0x0A; } |
|
|
|
|
|
|
|
else if (sbw <= 62.5E3) { _bw = 0x03; } |
|
|
|
|
|
|
|
else if (sbw <= 125E3) { _bw = 0x04; } |
|
|
|
|
|
|
|
else if (sbw <= 250E3) { _bw = 0x05; }
|
|
|
|
|
|
|
|
else { _bw = 0x06; } |
|
|
|
|
|
|
|
|
|
|
|
handleLowDataRate(); |
|
|
|
handleLowDataRate(); |
|
|
|
setModulationParams(_sf, _bw, _cr, _ldro); |
|
|
|
setModulationParams(_sf, _bw, _cr, _ldro); |
|
|
|
|
|
|
|
|
|
|
|
optimizeModemSensitivity(); |
|
|
|
optimizeModemSensitivity(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::setCodingRate4(int denominator) |
|
|
|
void sx126x::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; |
|
|
|
|
|
|
|
|
|
|
|
_cr = cr; |
|
|
|
_cr = cr; |
|
|
|
|
|
|
|
|
|
|
|
setModulationParams(_sf, _bw, cr, _ldro); |
|
|
|
setModulationParams(_sf, _bw, cr, _ldro); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::setPreambleLength(long length) |
|
|
|
void sx126x::setPreambleLength(long length) { |
|
|
|
{ |
|
|
|
|
|
|
|
_preambleLength = length; |
|
|
|
_preambleLength = length; |
|
|
|
setPacketParams(length, _implicitHeaderMode, _payloadLength, _crcMode); |
|
|
|
setPacketParams(length, _implicitHeaderMode, _payloadLength, _crcMode); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::setSyncWord(uint16_t sw) |
|
|
|
void sx126x::setSyncWord(uint16_t sw) { |
|
|
|
{ |
|
|
|
// TODO: Why was this hardcoded instead of using the config value?
|
|
|
|
// TODO: Fix
|
|
|
|
|
|
|
|
// writeRegister(REG_SYNC_WORD_MSB_6X, (sw & 0xFF00) >> 8);
|
|
|
|
// writeRegister(REG_SYNC_WORD_MSB_6X, (sw & 0xFF00) >> 8);
|
|
|
|
// writeRegister(REG_SYNC_WORD_LSB_6X, sw & 0x00FF);
|
|
|
|
// writeRegister(REG_SYNC_WORD_LSB_6X, sw & 0x00FF);
|
|
|
|
writeRegister(REG_SYNC_WORD_MSB_6X, 0x14); |
|
|
|
writeRegister(REG_SYNC_WORD_MSB_6X, 0x14); |
|
|
|
writeRegister(REG_SYNC_WORD_LSB_6X, 0x24); |
|
|
|
writeRegister(REG_SYNC_WORD_LSB_6X, 0x24); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::enableCrc() |
|
|
|
void sx126x::setPins(int ss, int reset, int dio0, int busy, int rxen) { |
|
|
|
{ |
|
|
|
|
|
|
|
_crcMode = 1; |
|
|
|
|
|
|
|
setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void sx126x::disableCrc() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
_crcMode = 0; |
|
|
|
|
|
|
|
setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
byte sx126x::random() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return readRegister(REG_RANDOM_GEN_6X); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void sx126x::setPins(int ss, int reset, int dio0, int busy, int rxen) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
_ss = ss; |
|
|
|
_ss = ss; |
|
|
|
_reset = reset; |
|
|
|
_reset = reset; |
|
|
|
_dio0 = dio0; |
|
|
|
_dio0 = dio0; |
|
|
@ -941,13 +696,7 @@ void sx126x::setPins(int ss, int reset, int dio0, int busy, int rxen) |
|
|
|
_rxen = rxen; |
|
|
|
_rxen = rxen; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::setSPIFrequency(uint32_t frequency) |
|
|
|
void sx126x::dumpRegisters(Stream& out) { |
|
|
|
{ |
|
|
|
|
|
|
|
_spiSettings = SPISettings(frequency, MSBFIRST, SPI_MODE0); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void sx126x::dumpRegisters(Stream& out) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
for (int i = 0; i < 128; i++) { |
|
|
|
for (int i = 0; i < 128; i++) { |
|
|
|
out.print("0x"); |
|
|
|
out.print("0x"); |
|
|
|
out.print(i, HEX); |
|
|
|
out.print(i, HEX); |
|
|
@ -956,49 +705,29 @@ void sx126x::dumpRegisters(Stream& out) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void sx126x::explicitHeaderMode() |
|
|
|
void ISR_VECT sx126x::handleDio0Rise() { |
|
|
|
{ |
|
|
|
|
|
|
|
_implicitHeaderMode = 0; |
|
|
|
|
|
|
|
setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void sx126x::implicitHeaderMode() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
_implicitHeaderMode = 1; |
|
|
|
|
|
|
|
setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ISR_VECT sx126x::handleDio0Rise() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
uint8_t buf[2]; |
|
|
|
uint8_t buf[2]; |
|
|
|
|
|
|
|
|
|
|
|
buf[0] = 0x00; |
|
|
|
buf[0] = 0x00; |
|
|
|
buf[1] = 0x00; |
|
|
|
buf[1] = 0x00; |
|
|
|
|
|
|
|
|
|
|
|
executeOpcodeRead(OP_GET_IRQ_STATUS_6X, buf, 2); |
|
|
|
executeOpcodeRead(OP_GET_IRQ_STATUS_6X, buf, 2); |
|
|
|
|
|
|
|
|
|
|
|
executeOpcode(OP_CLEAR_IRQ_STATUS_6X, buf, 2); |
|
|
|
executeOpcode(OP_CLEAR_IRQ_STATUS_6X, buf, 2); |
|
|
|
|
|
|
|
|
|
|
|
if ((buf[1] & IRQ_PAYLOAD_CRC_ERROR_MASK_6X) == 0) { |
|
|
|
if ((buf[1] & IRQ_PAYLOAD_CRC_ERROR_MASK_6X) == 0) { |
|
|
|
// received a packet
|
|
|
|
|
|
|
|
_packetIndex = 0; |
|
|
|
_packetIndex = 0; |
|
|
|
|
|
|
|
uint8_t rxbuf[2] = {0}; // Read packet length
|
|
|
|
// read packet length
|
|
|
|
|
|
|
|
uint8_t rxbuf[2] = {0}; |
|
|
|
|
|
|
|
executeOpcodeRead(OP_RX_BUFFER_STATUS_6X, rxbuf, 2); |
|
|
|
executeOpcodeRead(OP_RX_BUFFER_STATUS_6X, rxbuf, 2); |
|
|
|
int packetLength = rxbuf[0]; |
|
|
|
int packetLength = rxbuf[0]; |
|
|
|
|
|
|
|
if (_onReceive) { _onReceive(packetLength); } |
|
|
|
if (_onReceive) { |
|
|
|
|
|
|
|
_onReceive(packetLength); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void ISR_VECT sx126x::onDio0Rise() |
|
|
|
void ISR_VECT sx126x::onDio0Rise() { sx126x_modem.handleDio0Rise(); } |
|
|
|
{ |
|
|
|
void sx126x::setSPIFrequency(uint32_t frequency) { _spiSettings = SPISettings(frequency, MSBFIRST, SPI_MODE0); } |
|
|
|
sx126x_modem.handleDio0Rise(); |
|
|
|
void sx126x::enableCrc() { _crcMode = 1; setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); } |
|
|
|
} |
|
|
|
void sx126x::disableCrc() { _crcMode = 0; setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); } |
|
|
|
|
|
|
|
void sx126x::explicitHeaderMode() { _implicitHeaderMode = 0; setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); } |
|
|
|
|
|
|
|
void sx126x::implicitHeaderMode() { _implicitHeaderMode = 1; setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); } |
|
|
|
|
|
|
|
byte sx126x::random() { return readRegister(REG_RANDOM_GEN_6X); } |
|
|
|
|
|
|
|
|
|
|
|
sx126x sx126x_modem; |
|
|
|
sx126x sx126x_modem; |
|
|
|
|
|
|
|
|
|
|
|