[SX127x] Sync with LoRaLib v8.0.1
This commit is contained in:
parent
943ea7ac03
commit
7a768c8ed6
13 changed files with 307 additions and 78 deletions
|
@ -29,6 +29,7 @@ void setup() {
|
|||
// current limit: 100 mA
|
||||
// data shaping: Gaussian, BT = 0.3
|
||||
// sync word: 0x2D 0x01
|
||||
// OOK modulation: false
|
||||
int state = fsk.beginFSK();
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
|
@ -61,6 +62,19 @@ void setup() {
|
|||
while (true);
|
||||
}
|
||||
|
||||
// FSK modulation can be changed to OOK
|
||||
// NOTE: When using OOK, the maximum bit rate is only 32.768 kbps!
|
||||
// Also, data shaping changes from Gaussian filter to
|
||||
// simple filter with cutoff frequency. Make sure to call
|
||||
// setDataShapingOOK() to set the correct shaping!
|
||||
state = fsk.setOOK(true);
|
||||
state = fsk.setDataShapingOOK(1);
|
||||
if (state != ERR_NONE) {
|
||||
Serial.print(F("Unable to change modulation, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
#warning "This sketch is just an API guide! Read the note at line 6."
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,9 @@ void loop() {
|
|||
Serial.print(F("[SX1278] Waiting for incoming transmission ... "));
|
||||
|
||||
// you can receive data as an Arduino String
|
||||
// NOTE: receive() is a blocking method!
|
||||
// See example ReceiveInterrupt for details
|
||||
// on non-blocking reception method.
|
||||
String str;
|
||||
int state = lora.receive(str);
|
||||
|
||||
|
|
|
@ -45,6 +45,9 @@ void loop() {
|
|||
|
||||
// you can transmit C-string or Arduino string up to
|
||||
// 256 characters long
|
||||
// NOTE: transmit() is a blocking method!
|
||||
// See example SX127x_Transmit_Interrupt for details
|
||||
// on non-blocking transmission method.
|
||||
int state = lora.transmit("Hello World!");
|
||||
|
||||
// you can also transmit byte array up to 256 bytes long
|
||||
|
|
|
@ -79,6 +79,9 @@ setNodeAddress KEYWORD2
|
|||
setBroadcastAddress KEYWORD2
|
||||
disableAddressFiltering KEYWORD2
|
||||
setDataShaping KEYWORD2
|
||||
setOOK KEYWORD2
|
||||
setDataShapingOOK KEYWORD2
|
||||
setCRC KEYWORD2
|
||||
|
||||
# RF69-specific
|
||||
setAESKey KEYWORD2
|
||||
|
@ -162,6 +165,7 @@ ERR_INVALID_BIT_RATE_BW_RATIO LITERAL1
|
|||
ERR_INVALID_RX_BANDWIDTH LITERAL1
|
||||
ERR_INVALID_SYNC_WORD LITERAL1
|
||||
ERR_INVALID_DATA_SHAPING LITERAL1
|
||||
ERR_INVALID_MODULATION LITERAL1
|
||||
|
||||
ERR_AT_FAILED LITERAL1
|
||||
ERR_URL_MALFORMED LITERAL1
|
||||
|
|
|
@ -10,20 +10,22 @@ Module::Module(int rx, int tx) {
|
|||
ModuleSerial = new SoftwareSerial(_rx, _tx);
|
||||
}
|
||||
|
||||
Module::Module(int cs, int int0, int int1) {
|
||||
Module::Module(int cs, int int0, int int1, SPIClass& spi) {
|
||||
_cs = cs;
|
||||
_rx = -1;
|
||||
_tx = -1;
|
||||
_int0 = int0;
|
||||
_int1 = int1;
|
||||
_spi = &spi;
|
||||
}
|
||||
|
||||
Module::Module(int cs, int rx, int tx, int int0, int int1) {
|
||||
Module::Module(int cs, int rx, int tx, int int0, int int1, SPIClass& spi) {
|
||||
_cs = cs;
|
||||
_rx = rx;
|
||||
_tx = tx;
|
||||
_int0 = int0;
|
||||
_int1 = int1;
|
||||
_spi = &spi;
|
||||
|
||||
ModuleSerial = new SoftwareSerial(_rx, _tx);
|
||||
}
|
||||
|
@ -33,7 +35,7 @@ void Module::init(uint8_t interface, uint8_t gpio) {
|
|||
case USE_SPI:
|
||||
pinMode(_cs, OUTPUT);
|
||||
digitalWrite(_cs, HIGH);
|
||||
SPI.begin();
|
||||
_spi->begin();
|
||||
break;
|
||||
case USE_UART:
|
||||
ModuleSerial->begin(baudrate);
|
||||
|
@ -58,6 +60,11 @@ void Module::init(uint8_t interface, uint8_t gpio) {
|
|||
}
|
||||
}
|
||||
|
||||
void Module::term() {
|
||||
// stop SPI
|
||||
_spi->end();
|
||||
}
|
||||
|
||||
void Module::ATemptyBuffer() {
|
||||
while(ModuleSerial->available() > 0) {
|
||||
ModuleSerial->read();
|
||||
|
@ -160,39 +167,47 @@ int16_t Module::SPIsetRegValue(uint8_t reg, uint8_t value, uint8_t msb, uint8_t
|
|||
}
|
||||
|
||||
void Module::SPIreadRegisterBurst(uint8_t reg, uint8_t numBytes, uint8_t* inBytes) {
|
||||
digitalWrite(_cs, LOW);
|
||||
SPI.transfer(reg | SPIreadCommand);
|
||||
for(uint8_t i = 0; i < numBytes; i++) {
|
||||
inBytes[i] = SPI.transfer(reg);
|
||||
}
|
||||
digitalWrite(_cs, HIGH);
|
||||
SPItransfer(SPIreadCommand, reg, NULL, inBytes, numBytes);
|
||||
}
|
||||
|
||||
uint8_t Module::SPIreadRegister(uint8_t reg) {
|
||||
uint8_t inByte;
|
||||
digitalWrite(_cs, LOW);
|
||||
SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));
|
||||
SPI.transfer(reg | SPIreadCommand);
|
||||
SPI.endTransaction();
|
||||
inByte = SPI.transfer(0x00);
|
||||
digitalWrite(_cs, HIGH);
|
||||
return(inByte);
|
||||
uint8_t resp;
|
||||
SPItransfer(SPIreadCommand, reg, NULL, &resp, 1);
|
||||
return(resp);
|
||||
}
|
||||
|
||||
void Module::SPIwriteRegisterBurst(uint8_t reg, uint8_t* data, uint8_t numBytes) {
|
||||
digitalWrite(_cs, LOW);
|
||||
SPI.transfer(reg | SPIwriteCommand);
|
||||
for(uint8_t i = 0; i < numBytes; i++) {
|
||||
SPI.transfer(data[i]);
|
||||
}
|
||||
digitalWrite(_cs, HIGH);
|
||||
SPItransfer(SPIwriteCommand, reg, data, NULL, numBytes);
|
||||
}
|
||||
|
||||
void Module::SPIwriteRegister(uint8_t reg, uint8_t data) {
|
||||
digitalWrite(_cs, LOW);
|
||||
SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));
|
||||
SPI.transfer(reg | SPIwriteCommand);
|
||||
SPI.transfer(data);
|
||||
SPI.endTransaction();
|
||||
digitalWrite(_cs, HIGH);
|
||||
SPItransfer(SPIwriteCommand, reg, &data, NULL, 1);
|
||||
}
|
||||
|
||||
void Module::SPItransfer(uint8_t cmd, uint8_t reg, uint8_t* dataOut, uint8_t* dataIn, uint8_t numBytes) {
|
||||
// start SPI transaction
|
||||
_spi->beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));
|
||||
|
||||
// pull CS low
|
||||
digitalWrite(_cs, LOW);
|
||||
|
||||
// send SPI register address with access command
|
||||
_spi->transfer(reg | cmd);
|
||||
|
||||
// send data or get response
|
||||
if(cmd == SPIwriteCommand) {
|
||||
for(size_t n = 0; n < numBytes; n++) {
|
||||
_spi->transfer(dataOut[n]);
|
||||
}
|
||||
} else if (cmd == SPIreadCommand) {
|
||||
for(size_t n = 0; n < numBytes; n++) {
|
||||
dataIn[n] = _spi->transfer(0x00);
|
||||
}
|
||||
}
|
||||
|
||||
// release CS
|
||||
digitalWrite(_cs, HIGH);
|
||||
|
||||
// end SPI transaction
|
||||
_spi->endTransaction();
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
class Module {
|
||||
public:
|
||||
Module(int tx, int rx);
|
||||
Module(int cs, int int0, int int1);
|
||||
Module(int cs, int rx, int tx, int int0, int int1);
|
||||
Module(int cs, int int0, int int1, SPIClass& spi = SPI);
|
||||
Module(int cs, int rx, int tx, int int0, int int1, SPIClass& spi = SPI);
|
||||
|
||||
SoftwareSerial* ModuleSerial;
|
||||
|
||||
|
@ -22,6 +22,7 @@ class Module {
|
|||
uint8_t SPIwriteCommand = 0b10000000;
|
||||
|
||||
void init(uint8_t interface, uint8_t gpio);
|
||||
void term();
|
||||
|
||||
void ATemptyBuffer();
|
||||
bool ATgetResponse();
|
||||
|
@ -37,6 +38,8 @@ class Module {
|
|||
void SPIwriteRegisterBurst(uint8_t reg, uint8_t* data, uint8_t numBytes);
|
||||
void SPIwriteRegister(uint8_t reg, uint8_t data);
|
||||
|
||||
void SPItransfer(uint8_t cmd, uint8_t reg, uint8_t* dataOut, uint8_t* dataIn, uint8_t numBytes);
|
||||
|
||||
int getCs() const { return(_cs); }
|
||||
int getInt0() const { return(_int0); }
|
||||
int getInt1() const { return(_int1); }
|
||||
|
@ -48,6 +51,8 @@ class Module {
|
|||
int _int0;
|
||||
int _int1;
|
||||
|
||||
SPIClass* _spi;
|
||||
|
||||
uint32_t _ATtimeout = 15000;
|
||||
};
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
#define ERR_INVALID_RX_BANDWIDTH -104
|
||||
#define ERR_INVALID_SYNC_WORD -105
|
||||
#define ERR_INVALID_DATA_SHAPING -106
|
||||
#define ERR_INVALID_MODULATION -107
|
||||
|
||||
// ESP8266 status codes
|
||||
#define ERR_AT_FAILED -201
|
||||
|
|
|
@ -58,9 +58,9 @@ int16_t SX1272::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t sync
|
|||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX1272::beginFSK(float freq, float br, float rxBw, float freqDev, int8_t power, uint8_t currentLimit, float sh) {
|
||||
int16_t SX1272::beginFSK(float freq, float br, float rxBw, float freqDev, int8_t power, uint8_t currentLimit, bool enableOOK) {
|
||||
// execute common part
|
||||
int16_t state = SX127x::beginFSK(SX1272_CHIP_VERSION, br, rxBw, freqDev, currentLimit);
|
||||
int16_t state = SX127x::beginFSK(SX1272_CHIP_VERSION, br, rxBw, freqDev, currentLimit, enableOOK);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
@ -82,11 +82,6 @@ int16_t SX1272::beginFSK(float freq, float br, float rxBw, float freqDev, int8_t
|
|||
return(state);
|
||||
}
|
||||
|
||||
state = setDataShaping(sh);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
|
@ -268,6 +263,11 @@ int16_t SX1272::setDataShaping(float sh) {
|
|||
return(ERR_WRONG_MODEM);
|
||||
}
|
||||
|
||||
// check modulation
|
||||
if(!SX127x::_ook) {
|
||||
return(ERR_INVALID_MODULATION);
|
||||
}
|
||||
|
||||
// set mode to standby
|
||||
int16_t state = SX127x::standby();
|
||||
|
||||
|
@ -286,6 +286,39 @@ int16_t SX1272::setDataShaping(float sh) {
|
|||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX1272::setDataShapingOOK(uint8_t sh) {
|
||||
// check active modem
|
||||
if(getActiveModem() != SX127X_FSK_OOK) {
|
||||
return(ERR_WRONG_MODEM);
|
||||
}
|
||||
|
||||
// check modulation
|
||||
if(!SX127x::_ook) {
|
||||
return(ERR_INVALID_MODULATION);
|
||||
}
|
||||
|
||||
// set mode to standby
|
||||
int16_t state = SX127x::standby();
|
||||
|
||||
// set data shaping
|
||||
switch(sh) {
|
||||
case 0:
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PA_RAMP, SX1272_NO_SHAPING, 4, 3);
|
||||
break;
|
||||
case 1:
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PA_RAMP, SX1272_OOK_FILTER_BR, 4, 3);
|
||||
break;
|
||||
case 2:
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PA_RAMP, SX1272_OOK_FILTER_2BR, 4, 3);
|
||||
break;
|
||||
default:
|
||||
state = ERR_INVALID_DATA_SHAPING;
|
||||
break;
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int8_t SX1272::getRSSI() {
|
||||
// check active modem
|
||||
if(getActiveModem() != SX127X_LORA) {
|
||||
|
@ -304,6 +337,24 @@ int8_t SX1272::getRSSI() {
|
|||
return(lastPacketRSSI);
|
||||
}
|
||||
|
||||
int16_t SX1272::setCRC(bool enableCRC) {
|
||||
if(getActiveModem() == SX127X_LORA) {
|
||||
// set LoRa CRC
|
||||
if(enableCRC) {
|
||||
return(_mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, SX1272_RX_CRC_MODE_ON, 2, 2));
|
||||
} else {
|
||||
return(_mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, SX1272_RX_CRC_MODE_OFF, 2, 2));
|
||||
}
|
||||
} else {
|
||||
// set FSK CRC
|
||||
if(enableCRC) {
|
||||
return(_mod->SPIsetRegValue(SX127X_REG_PACKET_CONFIG_1, SX127X_CRC_ON, 4, 4));
|
||||
} else {
|
||||
return(_mod->SPIsetRegValue(SX127X_REG_PACKET_CONFIG_1, SX127X_CRC_OFF, 4, 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int16_t SX1272::setBandwidthRaw(uint8_t newBandwidth) {
|
||||
// set mode to standby
|
||||
int16_t state = SX127x::standby();
|
||||
|
@ -319,7 +370,7 @@ int16_t SX1272::setSpreadingFactorRaw(uint8_t newSpreadingFactor) {
|
|||
|
||||
// write registers
|
||||
if(newSpreadingFactor == SX127X_SF_6) {
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_HEADER_IMPL_MODE | SX1272_RX_CRC_MODE_OFF, 2, 1);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_HEADER_IMPL_MODE | SX1272_RX_CRC_MODE_ON, 2, 1);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, SX127X_SF_6 | SX127X_TX_MODE_SINGLE, 7, 3);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_DETECT_OPTIMIZE, SX127X_DETECT_OPTIMIZE_SF_6, 2, 0);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_DETECTION_THRESHOLD, SX127X_DETECTION_THRESHOLD_SF_6);
|
||||
|
|
|
@ -148,11 +148,11 @@ class SX1272: public SX127x {
|
|||
\param currentLimit Trim value for OCP (over current protection) in mA. Can be set to multiplies of 5 in range 45 to 120 mA and to multiples of 10 in range 120 to 240 mA.
|
||||
Set to 0 to disable OCP (not recommended).
|
||||
|
||||
\param sh Gaussian shaping bandwidth-time product that will be used for data shaping. Allowed values are 0.3, 0.5 or 1.0. Set to 0 to disable data shaping.
|
||||
\param enableOOK Use OOK modulation instead of FSK.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t beginFSK(float freq = 915.0, float br = 48.0, float rxBw = 125.0, float freqDev = 50.0, int8_t power = 13, uint8_t currentLimit = 100, float sh = 0.3);
|
||||
int16_t beginFSK(float freq = 915.0, float br = 48.0, float rxBw = 125.0, float freqDev = 50.0, int8_t power = 13, uint8_t currentLimit = 100, bool enableOOK = false);
|
||||
|
||||
// configuration methods
|
||||
|
||||
|
@ -212,8 +212,8 @@ class SX1272: public SX127x {
|
|||
int16_t setGain(uint8_t gain);
|
||||
|
||||
/*!
|
||||
\brief Sets gaussian shaping bandwidth-time product that will be used for data shaping.
|
||||
Allowed values are 0.3, 0.5 or 1.0. Set to 0 to disable data shaping. Only available in FSK mode.
|
||||
\brief Sets Gaussian filter bandwidth-time product that will be used for data shaping.
|
||||
Allowed values are 0.3, 0.5 or 1.0. Set to 0 to disable data shaping. Only available in FSK mode with FSK modulation.
|
||||
|
||||
\param sh Gaussian shaping bandwidth-time product that will be used for data shaping
|
||||
|
||||
|
@ -221,12 +221,32 @@ class SX1272: public SX127x {
|
|||
*/
|
||||
int16_t setDataShaping(float sh);
|
||||
|
||||
/*!
|
||||
\brief Sets filter cutoff frequency that will be used for data shaping.
|
||||
Allowed values are 1 for frequency equal to bit rate and 2 for frequency equal to 2x bit rate. Set to 0 to disable data shaping.
|
||||
Only available in FSK mode with OOK modulation.
|
||||
|
||||
\param sh Cutoff frequency that will be used for data shaping
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setDataShapingOOK(uint8_t sh);
|
||||
|
||||
/*!
|
||||
\brief Gets recorded signal strength indicator of the latest received packet.
|
||||
|
||||
\returns Last packet recorded signal strength indicator (RSSI).
|
||||
*/
|
||||
int8_t getRSSI();
|
||||
|
||||
/*!
|
||||
\brief Enables/disables CRC check of received packets.
|
||||
|
||||
\param enableCRC Enable (true) or disable (false) CRC.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setCRC(bool enableCRC);
|
||||
|
||||
protected:
|
||||
int16_t setBandwidthRaw(uint8_t newBandwidth);
|
||||
|
|
|
@ -51,9 +51,9 @@ int16_t SX1278::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t sync
|
|||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX1278::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint8_t currentLimit, float sh) {
|
||||
int16_t SX1278::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint8_t currentLimit, bool enableOOK) {
|
||||
// execute common part
|
||||
int16_t state = SX127x::beginFSK(SX1278_CHIP_VERSION, br, freqDev, rxBw, currentLimit);
|
||||
int16_t state = SX127x::beginFSK(SX1278_CHIP_VERSION, br, freqDev, rxBw, currentLimit, enableOOK);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
@ -75,11 +75,6 @@ int16_t SX1278::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t
|
|||
return(state);
|
||||
}
|
||||
|
||||
state = setDataShaping(sh);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
|
@ -338,6 +333,11 @@ int16_t SX1278::setDataShaping(float sh) {
|
|||
return(ERR_WRONG_MODEM);
|
||||
}
|
||||
|
||||
// check modulation
|
||||
if(SX127x::_ook) {
|
||||
return(ERR_INVALID_MODULATION);
|
||||
}
|
||||
|
||||
// set mode to standby
|
||||
int16_t state = SX127x::standby();
|
||||
|
||||
|
@ -356,6 +356,38 @@ int16_t SX1278::setDataShaping(float sh) {
|
|||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX1278::setDataShapingOOK(uint8_t sh) {
|
||||
// check active modem
|
||||
if(getActiveModem() != SX127X_FSK_OOK) {
|
||||
return(ERR_WRONG_MODEM);
|
||||
}
|
||||
|
||||
// check modulation
|
||||
if(!SX127x::_ook) {
|
||||
return(ERR_INVALID_MODULATION);
|
||||
}
|
||||
|
||||
// set mode to standby
|
||||
int16_t state = SX127x::standby();
|
||||
|
||||
// set data shaping
|
||||
switch(sh) {
|
||||
case 0:
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PA_RAMP, SX1278_NO_SHAPING, 6, 5);
|
||||
break;
|
||||
case 1:
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PA_RAMP, SX1278_OOK_FILTER_BR, 6, 5);
|
||||
break;
|
||||
case 2:
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PA_RAMP, SX1278_OOK_FILTER_2BR, 6, 5);
|
||||
break;
|
||||
default:
|
||||
return(ERR_INVALID_DATA_SHAPING);
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int8_t SX1278::getRSSI() {
|
||||
// check active modem
|
||||
if(getActiveModem() != SX127X_LORA) {
|
||||
|
@ -381,6 +413,24 @@ int8_t SX1278::getRSSI() {
|
|||
return(lastPacketRSSI);
|
||||
}
|
||||
|
||||
int16_t SX1278::setCRC(bool enableCRC) {
|
||||
if(getActiveModem() == SX127X_LORA) {
|
||||
// set LoRa CRC
|
||||
if(enableCRC) {
|
||||
return(_mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, SX1278_RX_CRC_MODE_ON, 2, 2));
|
||||
} else {
|
||||
return(_mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, SX1278_RX_CRC_MODE_OFF, 2, 2));
|
||||
}
|
||||
} else {
|
||||
// set FSK CRC
|
||||
if(enableCRC) {
|
||||
return(_mod->SPIsetRegValue(SX127X_REG_PACKET_CONFIG_1, SX127X_CRC_ON, 4, 4));
|
||||
} else {
|
||||
return(_mod->SPIsetRegValue(SX127X_REG_PACKET_CONFIG_1, SX127X_CRC_OFF, 4, 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int16_t SX1278::setBandwidthRaw(uint8_t newBandwidth) {
|
||||
// set mode to standby
|
||||
int16_t state = SX127x::standby();
|
||||
|
@ -397,12 +447,12 @@ int16_t SX1278::setSpreadingFactorRaw(uint8_t newSpreadingFactor) {
|
|||
// write registers
|
||||
if(newSpreadingFactor == SX127X_SF_6) {
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1278_HEADER_IMPL_MODE, 0, 0);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, SX127X_SF_6 | SX127X_TX_MODE_SINGLE | SX1278_RX_CRC_MODE_OFF, 7, 2);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, SX127X_SF_6 | SX127X_TX_MODE_SINGLE | SX1278_RX_CRC_MODE_ON, 7, 2);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_DETECT_OPTIMIZE, SX127X_DETECT_OPTIMIZE_SF_6, 2, 0);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_DETECTION_THRESHOLD, SX127X_DETECTION_THRESHOLD_SF_6);
|
||||
} else {
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1278_HEADER_EXPL_MODE, 0, 0);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, newSpreadingFactor | SX127X_TX_MODE_SINGLE | SX1278_RX_CRC_MODE_OFF, 7, 2);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, newSpreadingFactor | SX127X_TX_MODE_SINGLE | SX1278_RX_CRC_MODE_ON, 7, 2);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_DETECT_OPTIMIZE, SX127X_DETECT_OPTIMIZE_SF_7_12, 2, 0);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_DETECTION_THRESHOLD, SX127X_DETECTION_THRESHOLD_SF_7_12);
|
||||
}
|
||||
|
|
|
@ -157,11 +157,11 @@ class SX1278: public SX127x {
|
|||
\param currentLimit Trim value for OCP (over current protection) in mA. Can be set to multiplies of 5 in range 45 to 120 mA and to multiples of 10 in range 120 to 240 mA.
|
||||
Set to 0 to disable OCP (not recommended).
|
||||
|
||||
\param sh Gaussian shaping bandwidth-time product that will be used for data shaping. Allowed values are 0.3, 0.5 or 1.0. Set to 0 to disable data shaping.
|
||||
\param enableOOK Use OOK modulation instead of FSK.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t beginFSK(float freq = 434.0, float br = 48.0, float freqDev = 50.0, float rxBw = 125.0, int8_t power = 13, uint8_t currentLimit = 100, float sh = 0.3);
|
||||
int16_t beginFSK(float freq = 434.0, float br = 48.0, float freqDev = 50.0, float rxBw = 125.0, int8_t power = 13, uint8_t currentLimit = 100, bool enableOOK = false);
|
||||
|
||||
// configuration methods
|
||||
|
||||
|
@ -221,8 +221,8 @@ class SX1278: public SX127x {
|
|||
int16_t setGain(uint8_t gain);
|
||||
|
||||
/*!
|
||||
\brief Sets gaussian shaping bandwidth-time product that will be used for data shaping.
|
||||
Allowed values are 0.3, 0.5 or 1.0. Set to 0 to disable data shaping. Only available in FSK mode.
|
||||
\brief Sets Gaussian filter bandwidth-time product that will be used for data shaping.
|
||||
Allowed values are 0.3, 0.5 or 1.0. Set to 0 to disable data shaping. Only available in FSK mode with FSK modulation.
|
||||
|
||||
\param sh Gaussian shaping bandwidth-time product that will be used for data shaping
|
||||
|
||||
|
@ -230,12 +230,32 @@ class SX1278: public SX127x {
|
|||
*/
|
||||
int16_t setDataShaping(float sh);
|
||||
|
||||
/*!
|
||||
\brief Sets filter cutoff frequency that will be used for data shaping.
|
||||
Allowed values are 1 for frequency equal to bit rate and 2 for frequency equal to 2x bit rate. Set to 0 to disable data shaping.
|
||||
Only available in FSK mode with OOK modulation.
|
||||
|
||||
\param sh Cutoff frequency that will be used for data shaping
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setDataShapingOOK(uint8_t sh);
|
||||
|
||||
/*!
|
||||
\brief Gets recorded signal strength indicator of the latest received packet.
|
||||
|
||||
\returns Last packet recorded signal strength indicator (RSSI).
|
||||
*/
|
||||
int8_t getRSSI();
|
||||
|
||||
/*!
|
||||
\brief Enables/disables CRC check of received packets.
|
||||
|
||||
\param enableCRC Enable (true) or disable (false) CRC.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setCRC(bool enableCRC);
|
||||
|
||||
protected:
|
||||
int16_t setBandwidthRaw(uint8_t newBandwidth);
|
||||
|
|
|
@ -10,11 +10,11 @@ int16_t SX127x::begin(uint8_t chipVersion, uint8_t syncWord, uint8_t currentLimi
|
|||
|
||||
// try to find the SX127x chip
|
||||
if(!SX127x::findChip(chipVersion)) {
|
||||
DEBUG_PRINTLN(F("No SX127x found!"));
|
||||
SPI.end();
|
||||
DEBUG_PRINTLN("No SX127x found!");
|
||||
_mod->term();
|
||||
return(ERR_CHIP_NOT_FOUND);
|
||||
} else {
|
||||
DEBUG_PRINTLN(F("Found SX127x!"));
|
||||
DEBUG_PRINTLN("Found SX127x!");
|
||||
}
|
||||
|
||||
// check active modem
|
||||
|
@ -48,17 +48,17 @@ int16_t SX127x::begin(uint8_t chipVersion, uint8_t syncWord, uint8_t currentLimi
|
|||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX127x::beginFSK(uint8_t chipVersion, float br, float freqDev, float rxBw, uint8_t currentLimit) {
|
||||
int16_t SX127x::beginFSK(uint8_t chipVersion, float br, float freqDev, float rxBw, uint8_t currentLimit, bool enableOOK) {
|
||||
// set module properties
|
||||
_mod->init(USE_SPI, INT_BOTH);
|
||||
|
||||
// try to find the SX127x chip
|
||||
if(!SX127x::findChip(chipVersion)) {
|
||||
DEBUG_PRINTLN(F("No SX127x found!"));
|
||||
SPI.end();
|
||||
DEBUG_PRINTLN("No SX127x found!");
|
||||
_mod->term();
|
||||
return(ERR_CHIP_NOT_FOUND);
|
||||
} else {
|
||||
DEBUG_PRINTLN(F("Found SX127x!"));
|
||||
DEBUG_PRINTLN("Found SX127x!");
|
||||
}
|
||||
|
||||
// check currently active modem
|
||||
|
@ -104,6 +104,12 @@ int16_t SX127x::beginFSK(uint8_t chipVersion, float br, float freqDev, float rxB
|
|||
|
||||
// disable address filtering
|
||||
state = disableAddressFiltering();
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// enable/disable OOK
|
||||
state = setOOK(enableOOK);
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
@ -208,6 +214,7 @@ int16_t SX127x::transmit(uint8_t* data, size_t len, uint8_t addr) {
|
|||
while(!digitalRead(_mod->getInt0())) {
|
||||
if(millis() - start > timeout) {
|
||||
clearIRQFlags();
|
||||
standby();
|
||||
return(ERR_TX_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
@ -215,7 +222,10 @@ int16_t SX127x::transmit(uint8_t* data, size_t len, uint8_t addr) {
|
|||
// clear interrupt flags
|
||||
clearIRQFlags();
|
||||
|
||||
return(ERR_NONE);
|
||||
// set mode to standby to disable transmitter
|
||||
state |= standby();
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
return(ERR_UNKNOWN);
|
||||
|
@ -785,8 +795,14 @@ int16_t SX127x::setBitRate(float br) {
|
|||
}
|
||||
|
||||
// check allowed bitrate
|
||||
if((br < 1.2) || (br > 300.0)) {
|
||||
return(ERR_INVALID_BIT_RATE);
|
||||
if(_ook) {
|
||||
if((br < 1.2) || (br > 32.768)) {
|
||||
return(ERR_INVALID_BIT_RATE);
|
||||
}
|
||||
} else {
|
||||
if((br < 1.2) || (br > 300.0)) {
|
||||
return(ERR_INVALID_BIT_RATE);
|
||||
}
|
||||
}
|
||||
|
||||
// set mode to STANDBY
|
||||
|
@ -794,12 +810,13 @@ int16_t SX127x::setBitRate(float br) {
|
|||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
|
||||
// set bit rate
|
||||
uint16_t bitRate = 32000 / br;
|
||||
uint16_t bitRate = (SX127X_CRYSTAL_FREQ * 1000.0) / br;
|
||||
state = _mod->SPIsetRegValue(SX127X_REG_BITRATE_MSB, (bitRate & 0xFF00) >> 8, 7, 0);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_BITRATE_LSB, bitRate & 0x00FF, 7, 0);
|
||||
// TODO: fractional part of bit rate setting
|
||||
|
||||
// TODO: fractional part of bit rate setting (not in OOK)
|
||||
if(state == ERR_NONE) {
|
||||
SX127x::_br = br;
|
||||
}
|
||||
|
@ -899,7 +916,7 @@ int16_t SX127x::setSyncWord(uint8_t* syncWord, size_t len) {
|
|||
}
|
||||
|
||||
// set sync word
|
||||
_mod->SPIwriteRegisterBurst(SX127X_SYNC_VALUE_1, syncWord, len);
|
||||
_mod->SPIwriteRegisterBurst(SX127X_REG_SYNC_VALUE_1, syncWord, len);
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
|
@ -957,6 +974,26 @@ int16_t SX127x::disableAddressFiltering() {
|
|||
return(_mod->SPIsetRegValue(SX127X_REG_BROADCAST_ADRS, 0x00));
|
||||
}
|
||||
|
||||
int16_t SX127x::setOOK(bool enableOOK) {
|
||||
// check active modem
|
||||
if(getActiveModem() != SX127X_FSK_OOK) {
|
||||
return(ERR_WRONG_MODEM);
|
||||
}
|
||||
|
||||
// set OOK and if successful, save the new setting
|
||||
int16_t state = ERR_NONE;
|
||||
if(enableOOK) {
|
||||
state = _mod->SPIsetRegValue(SX127X_REG_OP_MODE, SX127X_MODULATION_OOK, 6, 5, 5);
|
||||
} else {
|
||||
state = _mod->SPIsetRegValue(SX127X_REG_OP_MODE, SX127X_MODULATION_FSK, 6, 5, 5);
|
||||
}
|
||||
if(state == ERR_NONE) {
|
||||
_ook = enableOOK;
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX127x::setFrequencyRaw(float newFreq) {
|
||||
// set mode to standby
|
||||
int16_t state = setMode(SX127X_STANDBY);
|
||||
|
@ -978,14 +1015,8 @@ int16_t SX127x::config() {
|
|||
}
|
||||
|
||||
int16_t SX127x::configFSK() {
|
||||
// set FSK modulation
|
||||
int16_t state = _mod->SPIsetRegValue(SX127X_REG_OP_MODE, SX127X_MODULATION_FSK, 6, 5, 5);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// set RSSI threshold
|
||||
state = _mod->SPIsetRegValue(SX127X_REG_RSSI_THRESH, SX127X_RSSI_THRESHOLD);
|
||||
int16_t state = _mod->SPIsetRegValue(SX127X_REG_RSSI_THRESH, SX127X_RSSI_THRESHOLD);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
|
|
@ -572,9 +572,11 @@ class SX127x: public PhysicalLayer {
|
|||
|
||||
\param currentLimit Trim value for OCP (over current protection) in mA.
|
||||
|
||||
\param enableOOK Flag to specify OOK mode. This modulation is similar to FSK.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t beginFSK(uint8_t chipVersion, float br, float freqDev, float rxBw, uint8_t currentLimit);
|
||||
int16_t beginFSK(uint8_t chipVersion, float br, float freqDev, float rxBw, uint8_t currentLimit, bool enableOOK);
|
||||
|
||||
/*!
|
||||
\brief Binary transmit method. Will transmit arbitrary binary data up to 255 bytes long using %LoRa or up to 63 bytes using FSK modem.
|
||||
|
@ -848,6 +850,15 @@ class SX127x: public PhysicalLayer {
|
|||
*/
|
||||
int16_t disableAddressFiltering();
|
||||
|
||||
/*!
|
||||
\brief Enables/disables OOK modulation instead of FSK.
|
||||
|
||||
\param enableOOK Enable (true) or disable (false) OOK.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setOOK(bool enableOOK);
|
||||
|
||||
#ifdef RADIOLIB_DEBUG
|
||||
void regDump();
|
||||
#endif
|
||||
|
@ -861,6 +872,7 @@ class SX127x: public PhysicalLayer {
|
|||
uint8_t _cr;
|
||||
float _br;
|
||||
float _rxBw;
|
||||
bool _ook;
|
||||
|
||||
int16_t tx(char* data, uint8_t length);
|
||||
int16_t rxSingle(char* data, uint8_t* length);
|
||||
|
|
Loading…
Add table
Reference in a new issue