master
Mark Qvist 2 months ago
parent b891932353
commit b02989e07a
  1. 8
      Utilities.h
  2. 450
      sx128x.cpp
  3. 5
      sx128x.h

@ -1214,13 +1214,7 @@ void setFrequency() {
} }
} }
uint8_t getRandom() { uint8_t getRandom() { return random(0xFF); }
if (radio_online) {
return LoRa->random();
} else {
return 0x00;
}
}
void promisc_enable() { void promisc_enable() {
promisc = true; promisc = true;

@ -1,7 +1,7 @@
// Copyright (c) Sandeep Mistry. All rights reserved. // Copyright (c) Sandeep Mistry. All rights reserved.
// Licensed under the MIT license. // Licensed under the MIT license.
// Modifications and additions copyright 2024 by Mark Qvist // Modifications and additions copyright 2024 by Mark Qvist & Jacob Eva
// Obviously still under the MIT license. // Obviously still under the MIT license.
#include "sx128x.h" #include "sx128x.h"
@ -114,19 +114,12 @@ sx128x::sx128x() :
bool ISR_VECT sx128x::getPacketValidity() { bool ISR_VECT sx128x::getPacketValidity() {
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_8X, buf, 2); executeOpcodeRead(OP_GET_IRQ_STATUS_8X, buf, 2);
executeOpcode(OP_CLEAR_IRQ_STATUS_8X, buf, 2); executeOpcode(OP_CLEAR_IRQ_STATUS_8X, buf, 2);
if ((buf[1] & IRQ_PAYLOAD_CRC_ERROR_MASK_8X) == 0) { return true; }
if ((buf[1] & IRQ_PAYLOAD_CRC_ERROR_MASK_8X) == 0) { else { return false; }
return true;
} else {
return false;
}
} }
void ISR_VECT sx128x::onDio0Rise() { void ISR_VECT sx128x::onDio0Rise() {
@ -162,9 +155,7 @@ void sx128x::handleDio0Rise() {
} }
bool sx128x::preInit() { bool sx128x::preInit() {
// setup pins
pinMode(_ss, OUTPUT); pinMode(_ss, OUTPUT);
// set SS high
digitalWrite(_ss, HIGH); digitalWrite(_ss, HIGH);
// todo: check if this change causes issues on any platforms // todo: check if this change causes issues on any platforms
@ -178,26 +169,18 @@ bool sx128x::preInit() {
SPI.begin(); SPI.begin();
#endif #endif
// check version (retry for up to 2 seconds) // Detect modem (retry for up to 2 seconds)
long start = millis(); long start = millis();
uint8_t version_msb; uint8_t version_msb;
uint8_t version_lsb; uint8_t version_lsb;
while (((millis() - start) < 2000) && (millis() >= start)) { while (((millis() - start) < 2000) && (millis() >= start)) {
version_msb = readRegister(REG_FIRM_VER_MSB); version_msb = readRegister(REG_FIRM_VER_MSB);
version_lsb = readRegister(REG_FIRM_VER_LSB); version_lsb = readRegister(REG_FIRM_VER_LSB);
if ((version_msb == 0xB7 && version_lsb == 0xA9) || (version_msb == 0xB5 && version_lsb == 0xA9)) { break; }
if ((version_msb == 0xB7 && version_lsb == 0xA9) || (version_msb == 0xB5 && version_lsb == 0xA9)) {
break;
}
delay(100); delay(100);
} }
if ((version_msb != 0xB7 || version_lsb != 0xA9) && (version_msb != 0xB5 || version_lsb != 0xA9)) {
return false;
}
if ((version_msb != 0xB7 || version_lsb != 0xA9) && (version_msb != 0xB5 || version_lsb != 0xA9)) { return false; }
_preinit_done = true; _preinit_done = true;
return true; return true;
} }
@ -205,144 +188,86 @@ bool sx128x::preInit() {
uint8_t ISR_VECT sx128x::readRegister(uint16_t address) { return singleTransfer(OP_READ_REGISTER_8X, address, 0x00); } uint8_t ISR_VECT sx128x::readRegister(uint16_t address) { return singleTransfer(OP_READ_REGISTER_8X, address, 0x00); }
void sx128x::writeRegister(uint16_t address, uint8_t value) { singleTransfer(OP_WRITE_REGISTER_8X, address, value); } void sx128x::writeRegister(uint16_t address, uint8_t value) { singleTransfer(OP_WRITE_REGISTER_8X, address, value); }
uint8_t ISR_VECT sx128x::singleTransfer(uint8_t opcode, uint16_t address, uint8_t value) uint8_t ISR_VECT sx128x::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_8X) { if (opcode == OP_READ_REGISTER_8X) { SPI.transfer(0x00); }
SPI.transfer(0x00);
}
response = SPI.transfer(value); response = SPI.transfer(value);
SPI.endTransaction(); SPI.endTransaction();
digitalWrite(_ss, HIGH); digitalWrite(_ss, HIGH);
return response; return response;
} }
void sx128x::rxAntEnable() void sx128x::rxAntEnable() {
{ if (_txen != -1) { digitalWrite(_txen, LOW); }
if (_txen != -1) { if (_rxen != -1) { digitalWrite(_rxen, HIGH); }
digitalWrite(_txen, LOW);
}
if (_rxen != -1) {
digitalWrite(_rxen, HIGH);
}
} }
void sx128x::txAntEnable() void sx128x::txAntEnable() {
{ if (_txen != -1) { digitalWrite(_txen, HIGH); }
if (_txen != -1) { if (_rxen != -1) { digitalWrite(_rxen, LOW); }
digitalWrite(_txen, HIGH);
}
if (_rxen != -1) {
digitalWrite(_rxen, LOW);
}
} }
void sx128x::loraMode() { void sx128x::loraMode() {
// enable lora mode on the SX1262 chip
uint8_t mode = MODE_LONG_RANGE_MODE_8X; uint8_t mode = MODE_LONG_RANGE_MODE_8X;
executeOpcode(OP_PACKET_TYPE_8X, &mode, 1); executeOpcode(OP_PACKET_TYPE_8X, &mode, 1);
} }
void sx128x::waitOnBusy() { void sx128x::waitOnBusy() {
unsigned long time = millis(); unsigned long time = millis();
while (digitalRead(_busy) == HIGH) while (digitalRead(_busy) == HIGH) {
{ if (millis() >= (time + 100)) { break; }
if (millis() >= (time + 100)) {
break;
}
// do nothing
} }
} }
void sx128x::executeOpcode(uint8_t opcode, uint8_t *buffer, uint8_t size) void sx128x::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 sx128x::executeOpcodeRead(uint8_t opcode, uint8_t *buffer, uint8_t size) void sx128x::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 sx128x::writeBuffer(const uint8_t* buffer, size_t size) void sx128x::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_8X); SPI.transfer(OP_FIFO_WRITE_8X);
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 sx128x::readBuffer(uint8_t* buffer, size_t size) void sx128x::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_8X); SPI.transfer(OP_FIFO_READ_8X);
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);
} }
@ -350,24 +275,19 @@ void sx128x::setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr) {
// because there is no access to these registers on the sx1280, we have // because there is no access to these registers on the sx1280, 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[3]; uint8_t buf[3];
buf[0] = sf << 4; buf[0] = sf << 4;
buf[1] = bw; buf[1] = bw;
buf[2] = cr; buf[2] = cr;
executeOpcode(OP_MODULATION_PARAMS_8X, buf, 3); executeOpcode(OP_MODULATION_PARAMS_8X, buf, 3);
if (sf <= 6) { if (sf <= 6) { writeRegister(0x925, 0x1E); }
writeRegister(0x925, 0x1E); else if (sf <= 8) { writeRegister(0x925, 0x37); }
} else if (sf <= 8) { else if (sf >= 9) { writeRegister(0x925, 0x32); }
writeRegister(0x925, 0x37);
} else if (sf >= 9) {
writeRegister(0x925, 0x32);
}
writeRegister(0x093C, 0x1); writeRegister(0x093C, 0x1);
} }
void sx128x::setPacketParams(uint32_t preamble, uint8_t headermode, uint8_t length, uint8_t crc) { void sx128x::setPacketParams(uint32_t preamble, uint8_t headermode, uint8_t length, uint8_t crc) {
// because there is no access to these registers on the sx1280, we have // Because there is no access to these registers on the sx1280, 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[7]; uint8_t buf[7];
// calculate exponent and mantissa values for modem // calculate exponent and mantissa values for modem
@ -390,21 +310,16 @@ void sx128x::setPacketParams(uint32_t preamble, uint8_t headermode, uint8_t leng
buf[1] = headermode; buf[1] = headermode;
buf[2] = length; buf[2] = length;
buf[3] = crc; buf[3] = crc;
// standard IQ setting (no inversion) buf[4] = 0x40; // standard IQ setting (no inversion)
buf[4] = 0x40; buf[5] = 0x00; // unused params
// unused params
buf[5] = 0x00;
buf[6] = 0x00; buf[6] = 0x00;
executeOpcode(OP_PACKET_PARAMS_8X, buf, 7); executeOpcode(OP_PACKET_PARAMS_8X, buf, 7);
} }
int sx128x::begin(unsigned long frequency) int sx128x::begin(unsigned long frequency) {
{
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);
@ -424,21 +339,16 @@ int sx128x::begin(unsigned long frequency)
standby(); standby();
loraMode(); loraMode();
rxAntEnable(); rxAntEnable();
Serial.printf("Setting freq to %d\r\n", _frequency);
Serial.printf("Should be %d\r\n", frequency);
setFrequency(frequency); setFrequency(frequency);
// set LNA boost // TODO: Implement LNA boost
// todo: implement this
//writeRegister(REG_LNA, 0x96); //writeRegister(REG_LNA, 0x96);
setModulationParams(_sf, _bw, _cr); setModulationParams(_sf, _bw, _cr);
setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode);
setTxPower(_txp); setTxPower(_txp);
// set base addresses // Set base addresses
uint8_t basebuf[2] = {0}; uint8_t basebuf[2] = {0};
executeOpcode(OP_BUFFER_BASE_ADDR_8X, basebuf, 2); executeOpcode(OP_BUFFER_BASE_ADDR_8X, basebuf, 2);
@ -446,28 +356,19 @@ int sx128x::begin(unsigned long frequency)
return 1; return 1;
} }
void sx128x::end() void sx128x::end() {
{
// put in sleep mode
sleep(); sleep();
// stop SPI
SPI.end(); SPI.end();
_bitrate = 0; _bitrate = 0;
_radio_online = false; _radio_online = false;
_preinit_done = false; _preinit_done = false;
} }
int sx128x::beginPacket(int implicitHeader) { int sx128x::beginPacket(int implicitHeader) {
// put in standby mode
standby(); standby();
if (implicitHeader) { if (implicitHeader) { implicitHeaderMode(); }
implicitHeaderMode(); else { explicitHeaderMode(); }
} else {
explicitHeaderMode();
}
_payloadLength = 0; _payloadLength = 0;
_fifo_tx_addr_ptr = 0; _fifo_tx_addr_ptr = 0;
@ -476,25 +377,22 @@ int sx128x::beginPacket(int implicitHeader) {
return 1; return 1;
} }
int sx128x::endPacket() int sx128x::endPacket() {
{
setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode);
txAntEnable(); txAntEnable();
// put in single TX mode // Put in single TX mode
uint8_t timeout[3] = {0}; uint8_t timeout[3] = {0};
executeOpcode(OP_TX_8X, timeout, 3); executeOpcode(OP_TX_8X, 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_8X, buf, 2); executeOpcodeRead(OP_GET_IRQ_STATUS_8X, 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_8X) == 0)) { while ((millis() < w_timeout) && ((buf[1] & IRQ_TX_DONE_MASK_8X) == 0)) {
buf[0] = 0x00; buf[0] = 0x00;
buf[1] = 0x00; buf[1] = 0x00;
@ -510,33 +408,24 @@ int sx128x::endPacket()
mask[1] = IRQ_TX_DONE_MASK_8X; mask[1] = IRQ_TX_DONE_MASK_8X;
executeOpcode(OP_CLEAR_IRQ_STATUS_8X, mask, 2); executeOpcode(OP_CLEAR_IRQ_STATUS_8X, mask, 2);
if (timed_out) { if (timed_out) { return 0; }
return 0; else { return 1; }
} else {
return 1;
}
} }
uint8_t sx128x::modemStatus() { uint8_t sx128x::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_8X, buf, 2); executeOpcodeRead(OP_GET_IRQ_STATUS_8X, buf, 2);
uint8_t clearbuf[2] = {0}; uint8_t clearbuf[2] = {0};
uint8_t byte = 0x00; uint8_t byte = 0x00;
if ((buf[0] & IRQ_PREAMBLE_DET_MASK_8X) != 0) { if ((buf[0] & IRQ_PREAMBLE_DET_MASK_8X) != 0) {
byte = byte | 0x01 | 0x04; byte = byte | 0x01 | 0x04;
// clear register after reading // Clear register after reading
clearbuf[0] = IRQ_PREAMBLE_DET_MASK_8X; clearbuf[0] = IRQ_PREAMBLE_DET_MASK_8X;
} }
if ((buf[1] & IRQ_HEADER_DET_MASK_8X) != 0) { if ((buf[1] & IRQ_HEADER_DET_MASK_8X) != 0) { byte = byte | 0x02 | 0x04; }
byte = byte | 0x02 | 0x04;
}
executeOpcode(OP_CLEAR_IRQ_STATUS_8X, clearbuf, 2); executeOpcode(OP_CLEAR_IRQ_STATUS_8X, clearbuf, 2);
return byte; return byte;
@ -563,7 +452,7 @@ uint8_t sx128x::packetRssiRaw() {
} }
int ISR_VECT sx128x::packetRssi(uint8_t pkt_snr_raw) { int ISR_VECT sx128x::packetRssi(uint8_t pkt_snr_raw) {
// may need more calculations here // TODO: May need more calculations here
uint8_t buf[5] = {0}; uint8_t buf[5] = {0};
executeOpcodeRead(OP_PACKET_STATUS_8X, buf, 5); executeOpcodeRead(OP_PACKET_STATUS_8X, buf, 5);
int pkt_rssi = -buf[0] / 2; int pkt_rssi = -buf[0] / 2;
@ -582,47 +471,38 @@ float ISR_VECT sx128x::packetSnr() {
return float(buf[1]) * 0.25; return float(buf[1]) * 0.25;
} }
long sx128x::packetFrequencyError() long sx128x::packetFrequencyError() {
{ // TODO: implement this, page 120 of sx1280 datasheet
int32_t freqError = 0; int32_t freqError = 0;
// todo: implement this, page 120 of sx1280 datasheet
const float fError = 0.0; const float fError = 0.0;
return static_cast<long>(fError); return static_cast<long>(fError);
} }
size_t sx128x::write(uint8_t byte) void sx128x::flush() { }
{
return write(&byte, sizeof(byte));
}
size_t sx128x::write(const uint8_t *buffer, size_t size) int ISR_VECT sx128x::available() { return _rxPacketLength - _packetIndex; }
{
size_t sx128x::write(uint8_t byte) { return write(&byte, sizeof(byte)); }
size_t sx128x::write(const uint8_t *buffer, size_t size) {
if ((_payloadLength + size) > MAX_PKT_LENGTH) { if ((_payloadLength + size) > MAX_PKT_LENGTH) {
size = MAX_PKT_LENGTH - _payloadLength; 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 sx128x::available() int ISR_VECT sx128x::read() {
{ if (!available()) { return -1; }
return _rxPacketLength - _packetIndex;
}
int ISR_VECT sx128x::read()
{
if (!available()) {
return -1;
}
// if received new packet // 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_8X, rxbuf, 2); executeOpcodeRead(OP_RX_BUFFER_STATUS_8X, rxbuf, 2);
int size; int size;
// If implicit header mode is enabled, read packet length as payload length instead. // If implicit header mode is enabled, read packet length as payload length instead.
// See SX1280 datasheet v3.2, page 92 // See SX1280 datasheet v3.2, page 92
if (_implicitHeaderMode == 0x80) { if (_implicitHeaderMode == 0x80) {
@ -630,11 +510,9 @@ int ISR_VECT sx128x::read()
} else { } else {
size = rxbuf[0]; size = rxbuf[0];
} }
_fifo_rx_addr_ptr = rxbuf[1];
if (size > 255) { _fifo_rx_addr_ptr = rxbuf[1];
size = 255; if (size > 255) { size = 255; }
}
readBuffer(_packet, size); readBuffer(_packet, size);
} }
@ -644,17 +522,12 @@ int ISR_VECT sx128x::read()
return byte; return byte;
} }
int sx128x::peek() int sx128x::peek() {
{ if (!available()) { return -1; }
if (!available()) {
return -1;
}
uint8_t b = _packet[_packetIndex]; uint8_t b = _packet[_packetIndex];
return b; return b;
} }
void sx128x::flush() { }
void sx128x::onReceive(void(*callback)(int)) { void sx128x::onReceive(void(*callback)(int)) {
_onReceive = callback; _onReceive = callback;
@ -662,10 +535,10 @@ void sx128x::onReceive(void(*callback)(int)) {
if (callback) { if (callback) {
pinMode(_dio0, INPUT); pinMode(_dio0, INPUT);
// set preamble and header detection irqs, plus dio0 mask // Set preamble and header detection irqs, plus dio0 mask
uint8_t buf[8]; uint8_t buf[8];
// set irq masks, enable all // Set irq masks, enable all
buf[0] = 0xFF; buf[0] = 0xFF;
buf[1] = 0xFF; buf[1] = 0xFF;
@ -680,11 +553,11 @@ void sx128x::onReceive(void(*callback)(int)) {
buf[2] = 0x00; buf[2] = 0x00;
buf[3] = IRQ_RX_DONE_MASK_8X | IRQ_HEADER_ERROR_MASK_8X; buf[3] = IRQ_RX_DONE_MASK_8X | IRQ_HEADER_ERROR_MASK_8X;
// set dio1 masks // Set dio1 masks
buf[4] = 0x00; buf[4] = 0x00;
buf[5] = 0x00; buf[5] = 0x00;
// set dio2 masks // Set dio2 masks
buf[6] = 0x00; buf[6] = 0x00;
buf[7] = 0x00; buf[7] = 0x00;
@ -704,12 +577,10 @@ void sx128x::onReceive(void(*callback)(int)) {
} }
} }
void sx128x::receive(int size) void sx128x::receive(int size) {
{
if (size > 0) { if (size > 0) {
implicitHeaderMode(); implicitHeaderMode();
// Tell radio payload length
// tell radio payload length
//_rxPacketLength = size; //_rxPacketLength = size;
//_payloadLength = size; //_payloadLength = size;
//setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); //setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode);
@ -728,33 +599,13 @@ void sx128x::receive(int size)
executeOpcode(OP_RX_8X, mode, 3); executeOpcode(OP_RX_8X, mode, 3);
} }
void sx128x::standby() void sx128x::standby() {
{
uint8_t byte; uint8_t byte;
if (_tcxo) { if (_tcxo) { byte = 0x01; } // STDBY_XOSC
// STDBY_XOSC else { byte = 0x00; } // STDBY_RC
byte = 0x01;
} else {
// STDBY_RC
byte = 0x00;
}
executeOpcode(OP_STANDBY_8X, &byte, 1); executeOpcode(OP_STANDBY_8X, &byte, 1);
} }
void sx128x::sleep()
{
uint8_t byte = 0x00;
executeOpcode(OP_SLEEP_8X, &byte, 1);
}
void sx128x::enableTCXO() {
// todo: need to check how to implement on sx1280
}
void sx128x::disableTCXO() {
// todo: need to check how to implement on sx1280
}
void sx128x::setPins(int ss, int reset, int dio0, int busy, int rxen, int txen) { void sx128x::setPins(int ss, int reset, int dio0, int busy, int rxen, int txen) {
_ss = ss; _ss = ss;
_reset = reset; _reset = reset;
@ -766,18 +617,14 @@ void sx128x::setPins(int ss, int reset, int dio0, int busy, int rxen, int txen)
void sx128x::setTxPower(int level, int outputPin) { void sx128x::setTxPower(int level, int outputPin) {
uint8_t tx_buf[2]; uint8_t tx_buf[2];
#if BOARD_VARIANT == MODEL_13 || BOARD_VARIANT == MODEL_21
// RAK4631 with WisBlock SX1280 module (LIBSYS002) // RAK4631 with WisBlock SX1280 module (LIBSYS002)
if (level > 27) { #if BOARD_VARIANT == MODEL_13 || BOARD_VARIANT == MODEL_21
level = 27; if (level > 27) { level = 27; }
} else if (level < 0) { else if (level < 0) { level = 0; }
level = 0;
}
_txp = level; _txp = level;
int reg_value; int reg_value;
switch (level) { switch (level) {
case 0: case 0:
reg_value = -18; reg_value = -18;
@ -870,20 +717,17 @@ void sx128x::setTxPower(int level, int outputPin) {
tx_buf[0] = reg_value + 18; tx_buf[0] = reg_value + 18;
tx_buf[1] = 0xE0; // ramping time - 20 microseconds tx_buf[1] = 0xE0; // ramping time - 20 microseconds
executeOpcode(OP_TX_PARAMS_8X, tx_buf, 2); executeOpcode(OP_TX_PARAMS_8X, tx_buf, 2);
#elif BOARD_VARIANT == MODEL_AC
// T3S3 SX1280 PA // T3S3 SX1280 PA
#elif BOARD_VARIANT == MODEL_AC
if (level > 20) { level = 20; } if (level > 20) { level = 20; }
else if (level < 0) { level = 0; } else if (level < 0) { level = 0; }
_txp = level; _txp = level;
int reg_value; int reg_value;
switch (level) { switch (level) {
/*case 0: case 0:
reg_value = -18; reg_value = -18;
break; break;
case 1: case 1:
@ -942,7 +786,7 @@ void sx128x::setTxPower(int level, int outputPin) {
break; break;
case 19: case 19:
reg_value = 2; reg_value = 2;
break;*/ break;
case 20: case 20:
reg_value = 3; reg_value = 3;
break; break;
@ -950,27 +794,19 @@ void sx128x::setTxPower(int level, int outputPin) {
reg_value = 0; reg_value = 0;
break; break;
} }
tx_buf[0] = reg_value; tx_buf[0] = reg_value;
tx_buf[1] = 0xE0; // ramping time - 20 microseconds tx_buf[1] = 0xE0; // ramping time - 20 microseconds
#else
// For SX1280 boards with no specific PA requirements
if (level > 13) {
level = 13;
} else if (level < -18) {
level = -18;
}
// For SX1280 boards with no specific PA requirements
#else
if (level > 13) { level = 13; }
else if (level < -18) { level = -18; }
_txp = level; _txp = level;
tx_buf[0] = level + 18; tx_buf[0] = level + 18;
tx_buf[1] = 0xE0; // ramping time - 20 microseconds tx_buf[1] = 0xE0; // ramping time - 20 microseconds
#endif #endif
executeOpcode(OP_TX_PARAMS_8X, tx_buf, 2);
}
uint8_t sx128x::getTxPower() { executeOpcode(OP_TX_PARAMS_8X, tx_buf, 2);
return _txp;
} }
void sx128x::setFrequency(uint32_t frequency) { void sx128x::setFrequency(uint32_t frequency) {
@ -991,20 +827,14 @@ uint32_t sx128x::getFrequency() {
} }
void sx128x::setSpreadingFactor(int sf) { void sx128x::setSpreadingFactor(int sf) {
if (sf < 5) { if (sf < 5) { sf = 5; }
sf = 5; else if (sf > 12) { sf = 12; }
} else if (sf > 12) {
sf = 12;
}
_sf = sf; _sf = sf;
setModulationParams(sf, _bw, _cr); setModulationParams(sf, _bw, _cr);
handleLowDataRate(); handleLowDataRate();
} }
uint8_t sx128x::getSpreadingFactor() { return _sf; }
uint32_t sx128x::getSignalBandwidth() { uint32_t sx128x::getSignalBandwidth() {
int bw = _bw; int bw = _bw;
switch (bw) { switch (bw) {
@ -1017,109 +847,65 @@ uint32_t sx128x::getSignalBandwidth() {
return 0; return 0;
} }
void sx128x::handleLowDataRate(){ // TODO: Is this needed for SX1280?
// todo: do i need this?? void sx128x::handleLowDataRate() { }
}
void sx128x::optimizeModemSensitivity(){ // TODO: Check if there's anything the sx1280 can do here
// todo: check if there's anything the sx1280 can do here void sx128x::optimizeModemSensitivity() { }
}
void sx128x::setSignalBandwidth(uint32_t sbw) void sx128x::setSignalBandwidth(uint32_t sbw) {
{ if (sbw <= 203.125E3) { _bw = 0x34; }
if (sbw <= 203.125E3) { else if (sbw <= 406.25E3) { _bw = 0x26; }
_bw = 0x34; else if (sbw <= 812.5E3) { _bw = 0x18; }
} else if (sbw <= 406.25E3) { else { _bw = 0x0A; }
_bw = 0x26;
} else if (sbw <= 812.5E3) {
_bw = 0x18;
} else {
_bw = 0x0A;
}
setModulationParams(_sf, _bw, _cr); setModulationParams(_sf, _bw, _cr);
handleLowDataRate(); handleLowDataRate();
optimizeModemSensitivity(); optimizeModemSensitivity();
} }
void sx128x::setCodingRate4(int denominator) // TODO: add support for new interleaving scheme, see page 117 of sx1280 datasheet
{ void sx128x::setCodingRate4(int denominator) {
if (denominator < 5) { if (denominator < 5) { denominator = 5; }
denominator = 5; else if (denominator > 8) { denominator = 8; }
} else if (denominator > 8) {
denominator = 8;
}
_cr = denominator - 4; _cr = denominator - 4;
// todo: add support for new interleaving scheme, see page 117 of sx1280
// datasheet
// update cr values for sx1280's use
setModulationParams(_sf, _bw, _cr); setModulationParams(_sf, _bw, _cr);
} }
uint8_t sx128x::getCodingRate4() uint8_t sx128x::getCodingRate4() { return _cr + 4; }
{
return _cr + 4;
}
void sx128x::setPreambleLength(long length) void sx128x::setPreambleLength(long length) {
{
_preambleLength = length; _preambleLength = length;
setPacketParams(length, _implicitHeaderMode, _payloadLength, _crcMode); setPacketParams(length, _implicitHeaderMode, _payloadLength, _crcMode);
} }
void sx128x::setSyncWord(int sw) // TODO: Implement
{ void sx128x::setSyncWord(int sw) { }
// not implemented
}
void sx128x::enableCrc() { // TODO: need to check how to implement on sx1280
_crcMode = 0x20; void sx128x::enableTCXO() { }
setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode);
}
void sx128x::disableCrc() { // TODO: need to check how to implement on sx1280
_crcMode = 0; void sx128x::disableTCXO() { }
setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode);
}
uint8_t sx128x::random() { void sx128x::sleep() { uint8_t byte = 0x00; executeOpcode(OP_SLEEP_8X, &byte, 1); }
// todo: implement
return 0x4; //chosen by fair die roll
//guarenteed to be random
//https://xkcd.com/221/
}
void sx128x::setSPIFrequency(uint32_t frequency) uint8_t sx128x::getTxPower() { return _txp; }
{
_spiSettings = SPISettings(frequency, MSBFIRST, SPI_MODE0);
}
void sx128x::dumpRegisters(Stream& out) uint8_t sx128x::getSpreadingFactor() { return _sf; }
{
for (int i = 0; i < 128; i++) {
out.print("0x");
out.print(i, HEX);
out.print(": 0x");
out.println(readRegister(i), HEX);
}
}
void sx128x::explicitHeaderMode() void sx128x::enableCrc() { _crcMode = 0x20; setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); }
{
_implicitHeaderMode = 0;
setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); void sx128x::disableCrc() { _crcMode = 0; setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); }
}
void sx128x::implicitHeaderMode() void sx128x::setSPIFrequency(uint32_t frequency) { _spiSettings = SPISettings(frequency, MSBFIRST, SPI_MODE0); }
{
_implicitHeaderMode = 0x80; void sx128x::explicitHeaderMode() { _implicitHeaderMode = 0; setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); }
setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode);
void sx128x::implicitHeaderMode() { _implicitHeaderMode = 0x80; setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); }
void sx128x::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); }
} }
sx128x sx128x_modem; sx128x sx128x_modem;

@ -17,7 +17,7 @@
#define LORA_DEFAULT_RXEN_PIN -1 #define LORA_DEFAULT_RXEN_PIN -1
#define LORA_DEFAULT_TXEN_PIN -1 #define LORA_DEFAULT_TXEN_PIN -1
#define LORA_DEFAULT_BUSY_PIN -1 #define LORA_DEFAULT_BUSY_PIN -1
#define LORA_MODEM_TIMEOUT_MS 5E3 #define LORA_MODEM_TIMEOUT_MS 15E3
#define PA_OUTPUT_RFO_PIN 0 #define PA_OUTPUT_RFO_PIN 0
#define PA_OUTPUT_PA_BOOST_PIN 1 #define PA_OUTPUT_PA_BOOST_PIN 1
@ -91,12 +91,9 @@ public:
void setPacketParams(uint32_t preamble, uint8_t headermode, uint8_t length, uint8_t crc); void setPacketParams(uint32_t preamble, uint8_t headermode, uint8_t length, uint8_t crc);
void setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr); void setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr);
// deprecated
void crc() { enableCrc(); } void crc() { enableCrc(); }
void noCrc() { disableCrc(); } void noCrc() { disableCrc(); }
byte random();
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, int rxen = LORA_DEFAULT_RXEN_PIN, int txen = LORA_DEFAULT_TXEN_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, int rxen = LORA_DEFAULT_RXEN_PIN, int txen = LORA_DEFAULT_TXEN_PIN);
void setSPIFrequency(uint32_t frequency); void setSPIFrequency(uint32_t frequency);

Loading…
Cancel
Save