[SX127x] Implemented fractional bit rate (#505)

This commit is contained in:
jgromes 2023-04-09 17:08:45 +02:00
parent 9d3a2bb72f
commit 8587f73bd9
11 changed files with 68 additions and 29 deletions

View file

@ -42,10 +42,10 @@ int16_t RFM95::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncW
int16_t RFM95::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, bool enableOOK) {
// execute common part
int16_t state = SX127x::beginFSK(RADIOLIB_RFM9X_CHIP_VERSION_OFFICIAL, br, freqDev, rxBw, preambleLength, enableOOK);
int16_t state = SX127x::beginFSK(RADIOLIB_RFM9X_CHIP_VERSION_OFFICIAL, freqDev, rxBw, preambleLength, enableOOK);
if(state == RADIOLIB_ERR_CHIP_NOT_FOUND) {
// SX127X_REG_VERSION might be set 0x12
state = SX127x::beginFSK(RADIOLIB_RFM9X_CHIP_VERSION_UNOFFICIAL, br, freqDev, rxBw, preambleLength, enableOOK);
state = SX127x::beginFSK(RADIOLIB_RFM9X_CHIP_VERSION_UNOFFICIAL, freqDev, rxBw, preambleLength, enableOOK);
RADIOLIB_ASSERT(state);
} else if(state != RADIOLIB_ERR_NONE) {
// some other error
@ -62,6 +62,9 @@ int16_t RFM95::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t
state = setFrequency(freq);
RADIOLIB_ASSERT(state);
state = setBitRate(br);
RADIOLIB_ASSERT(state);
state = setOutputPower(power);
RADIOLIB_ASSERT(state);

View file

@ -43,10 +43,10 @@ int16_t RFM96::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncW
int16_t RFM96::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, bool enableOOK) {
// execute common part
int16_t state = SX127x::beginFSK(RADIOLIB_RFM9X_CHIP_VERSION_OFFICIAL, br, freqDev, rxBw, preambleLength, enableOOK);
int16_t state = SX127x::beginFSK(RADIOLIB_RFM9X_CHIP_VERSION_OFFICIAL, freqDev, rxBw, preambleLength, enableOOK);
if(state == RADIOLIB_ERR_CHIP_NOT_FOUND) {
// SX127X_REG_VERSION might be set 0x12
state = SX127x::beginFSK(RADIOLIB_RFM9X_CHIP_VERSION_UNOFFICIAL, br, freqDev, rxBw, preambleLength, enableOOK);
state = SX127x::beginFSK(RADIOLIB_RFM9X_CHIP_VERSION_UNOFFICIAL, freqDev, rxBw, preambleLength, enableOOK);
RADIOLIB_ASSERT(state);
} else if(state != RADIOLIB_ERR_NONE) {
// some other error
@ -63,6 +63,9 @@ int16_t RFM96::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t
state = setFrequency(freq);
RADIOLIB_ASSERT(state);
state = setBitRate(br);
RADIOLIB_ASSERT(state);
state = setOutputPower(power);
RADIOLIB_ASSERT(state);

View file

@ -38,7 +38,7 @@ int16_t SX1272::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t sync
int16_t SX1272::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, bool enableOOK) {
// execute common part
int16_t state = SX127x::beginFSK(RADIOLIB_SX1272_CHIP_VERSION, br, freqDev, rxBw, preambleLength, enableOOK);
int16_t state = SX127x::beginFSK(RADIOLIB_SX1272_CHIP_VERSION, freqDev, rxBw, preambleLength, enableOOK);
RADIOLIB_ASSERT(state);
// configure settings not accessible by API
@ -49,6 +49,9 @@ int16_t SX1272::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t
state = setFrequency(freq);
RADIOLIB_ASSERT(state);
state = setBitRate(br);
RADIOLIB_ASSERT(state);
state = setOutputPower(power);
RADIOLIB_ASSERT(state);
@ -216,6 +219,10 @@ int16_t SX1272::setCodingRate(uint8_t cr) {
return(state);
}
int16_t SX1272::setBitRate(float br) {
return(SX127x::setBitRateCommon(br, RADIOLIB_SX1272_REG_BIT_RATE_FRAC));
}
int16_t SX1272::setOutputPower(int8_t power, bool useRfo) {
// check allowed power range
if(useRfo) {

View file

@ -197,6 +197,15 @@ class SX1272: public SX127x {
*/
int16_t setCodingRate(uint8_t cr);
/*!
\brief Sets FSK bit rate. Allowed values range from 0.5 to 300 kbps. Only available in FSK mode.
\param br Bit rate to be set (in kbps).
\returns \ref status_codes
*/
int16_t setBitRate(float br) override;
/*!
\brief Sets transmission output power. Allowed values range from -1 to 14 dBm (RFO pin) or +2 to +20 dBm (PA_BOOST pin).

View file

@ -34,7 +34,7 @@ int16_t SX1276::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t sync
int16_t SX1276::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, bool enableOOK) {
// execute common part
int16_t state = SX127x::beginFSK(RADIOLIB_SX1278_CHIP_VERSION, br, freqDev, rxBw, preambleLength, enableOOK);
int16_t state = SX127x::beginFSK(RADIOLIB_SX1278_CHIP_VERSION, freqDev, rxBw, preambleLength, enableOOK);
RADIOLIB_ASSERT(state);
// configure settings not accessible by API
@ -45,6 +45,9 @@ int16_t SX1276::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t
state = setFrequency(freq);
RADIOLIB_ASSERT(state);
state = setBitRate(br);
RADIOLIB_ASSERT(state);
state = setOutputPower(power);
RADIOLIB_ASSERT(state);

View file

@ -34,7 +34,7 @@ int16_t SX1277::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t sync
int16_t SX1277::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, bool enableOOK) {
// execute common part
int16_t state = SX127x::beginFSK(RADIOLIB_SX1278_CHIP_VERSION, br, freqDev, rxBw, preambleLength, enableOOK);
int16_t state = SX127x::beginFSK(RADIOLIB_SX1278_CHIP_VERSION, freqDev, rxBw, preambleLength, enableOOK);
RADIOLIB_ASSERT(state);
// configure settings not accessible by API
@ -45,6 +45,9 @@ int16_t SX1277::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t
state = setFrequency(freq);
RADIOLIB_ASSERT(state);
state = setBitRate(br);
RADIOLIB_ASSERT(state);
state = setOutputPower(power);
RADIOLIB_ASSERT(state);

View file

@ -38,7 +38,7 @@ int16_t SX1278::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t sync
int16_t SX1278::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, bool enableOOK) {
// execute common part
int16_t state = SX127x::beginFSK(RADIOLIB_SX1278_CHIP_VERSION, br, freqDev, rxBw, preambleLength, enableOOK);
int16_t state = SX127x::beginFSK(RADIOLIB_SX1278_CHIP_VERSION, freqDev, rxBw, preambleLength, enableOOK);
RADIOLIB_ASSERT(state);
// configure settings not accessible by API
@ -49,6 +49,9 @@ int16_t SX1278::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t
state = setFrequency(freq);
RADIOLIB_ASSERT(state);
state = setBitRate(br);
RADIOLIB_ASSERT(state);
state = setOutputPower(power);
RADIOLIB_ASSERT(state);
@ -230,6 +233,10 @@ int16_t SX1278::setCodingRate(uint8_t cr) {
return(state);
}
int16_t SX1278::setBitRate(float br) {
return(SX127x::setBitRateCommon(br, RADIOLIB_SX1278_REG_BIT_RATE_FRAC));
}
int16_t SX1278::setOutputPower(int8_t power, bool useRfo) {
// check allowed power range
if(useRfo) {

View file

@ -14,7 +14,7 @@
#define RADIOLIB_SX1278_REG_TCXO 0x4B
#define RADIOLIB_SX1278_REG_PA_DAC 0x4D
#define RADIOLIB_SX1278_REG_FORMER_TEMP 0x5B
#define RADIOLIB_SX1278_REG_REG_BIT_RATE_FRAC 0x5D
#define RADIOLIB_SX1278_REG_BIT_RATE_FRAC 0x5D
#define RADIOLIB_SX1278_REG_AGC_REF 0x61
#define RADIOLIB_SX1278_REG_AGC_THRESH_1 0x62
#define RADIOLIB_SX1278_REG_AGC_THRESH_2 0x63
@ -205,6 +205,15 @@ class SX1278: public SX127x {
*/
int16_t setCodingRate(uint8_t cr);
/*!
\brief Sets FSK bit rate. Allowed values range from 0.5 to 300 kbps. Only available in FSK mode.
\param br Bit rate to be set (in kbps).
\returns \ref status_codes
*/
int16_t setBitRate(float br) override;
/*!
\brief Sets transmission output power. Allowed values range from -3 to 15 dBm (RFO pin) or +2 to +17 dBm (PA_BOOST pin).
High power +20 dBm operation is also supported, on the PA_BOOST pin.

View file

@ -34,7 +34,7 @@ int16_t SX1279::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t sync
int16_t SX1279::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, bool enableOOK) {
// execute common part
int16_t state = SX127x::beginFSK(RADIOLIB_SX1278_CHIP_VERSION, br, freqDev, rxBw, preambleLength, enableOOK);
int16_t state = SX127x::beginFSK(RADIOLIB_SX1278_CHIP_VERSION, freqDev, rxBw, preambleLength, enableOOK);
RADIOLIB_ASSERT(state);
// configure settings not accessible by API
@ -45,6 +45,9 @@ int16_t SX1279::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t
state = setFrequency(freq);
RADIOLIB_ASSERT(state);
state = setBitRate(br);
RADIOLIB_ASSERT(state);
state = setOutputPower(power);
RADIOLIB_ASSERT(state);

View file

@ -56,7 +56,7 @@ int16_t SX127x::begin(uint8_t chipVersion, uint8_t syncWord, uint16_t preambleLe
return(state);
}
int16_t SX127x::beginFSK(uint8_t chipVersion, float br, float freqDev, float rxBw, uint16_t preambleLength, bool enableOOK) {
int16_t SX127x::beginFSK(uint8_t chipVersion, float freqDev, float rxBw, uint16_t preambleLength, bool enableOOK) {
// set module properties
_mod->init();
_mod->pinMode(_mod->getIrq(), INPUT);
@ -85,10 +85,6 @@ int16_t SX127x::beginFSK(uint8_t chipVersion, float br, float freqDev, float rxB
state = setOOK(enableOOK);
RADIOLIB_ASSERT(state);
// set bit rate
state = SX127x::setBitRate(br);
RADIOLIB_ASSERT(state);
// set frequency deviation
state = SX127x::setFrequencyDeviation(freqDev);
RADIOLIB_ASSERT(state);
@ -828,7 +824,7 @@ float SX127x::getDataRate() const {
return(_dataRate);
}
int16_t SX127x::setBitRate(float br) {
int16_t SX127x::setBitRateCommon(float br, uint8_t fracRegAddr) {
// check active modem
if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
return(RADIOLIB_ERR_WRONG_MODEM);
@ -851,7 +847,13 @@ int16_t SX127x::setBitRate(float br) {
state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_BITRATE_MSB, (bitRate & 0xFF00) >> 8, 7, 0);
state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_BITRATE_LSB, bitRate & 0x00FF, 7, 0);
/// \todo fractional part of bit rate setting (not in OOK)
// set fractional part of bit rate
if(!_ook) {
float bitRateRem = ((RADIOLIB_SX127X_CRYSTAL_FREQ * 1000.0) / (float)br) - (float)bitRate;
uint8_t bitRateFrac = bitRateRem * 16;
state |= _mod->SPIsetRegValue(fracRegAddr, bitRateFrac, 7, 0);
}
if(state == RADIOLIB_ERR_NONE) {
SX127x::_br = br;
}

View file

@ -624,8 +624,6 @@ class SX127x: public PhysicalLayer {
\param chipVersion Value in SPI version register. Used to verify the connection and hardware version.
\param br Bit rate of the FSK transmission in kbps (kilobits per second).
\param freqDev Frequency deviation of the FSK transmission in kHz.
\param rxBw Receiver bandwidth in kHz.
@ -636,7 +634,7 @@ class SX127x: public PhysicalLayer {
\returns \ref status_codes
*/
int16_t beginFSK(uint8_t chipVersion, float br, float freqDev, float rxBw, uint16_t preambleLength, bool enableOOK);
int16_t beginFSK(uint8_t chipVersion, float freqDev, float rxBw, uint16_t preambleLength, 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.
@ -925,15 +923,6 @@ class SX127x: public PhysicalLayer {
*/
float getDataRate() const;
/*!
\brief Sets FSK bit rate. Allowed values range from 0.5 to 300 kbps. Only available in FSK mode.
\param br Bit rate to be set (in kbps).
\returns \ref status_codes
*/
int16_t setBitRate(float br);
/*!
\brief Sets FSK frequency deviation from carrier frequency. Allowed values depend on bit rate setting and must be lower than 200 kHz. Only available in FSK mode.
@ -1298,6 +1287,7 @@ class SX127x: public PhysicalLayer {
size_t _packetLength = 0;
int16_t setFrequencyRaw(float newFreq);
int16_t setBitRateCommon(float br, uint8_t fracRegAddr);
int16_t config();
int16_t configFSK();
int16_t getActiveModem();