[SX126x] Added SX1268 implementation

pull/38/head
jgromes 2019-06-03 10:41:39 +02:00
rodzic 025d6d71a7
commit 5c2bd2bc32
6 zmienionych plików z 235 dodań i 45 usunięć

Wyświetl plik

@ -58,12 +58,39 @@ int16_t SX1262::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t
return(state); return(state);
} }
int16_t SX1262::setFrequency(float freq) { int16_t SX1262::setFrequency(float freq, bool calibrate) {
// check frequency range // check frequency range
if((freq < 150.0) || (freq > 960.0)) { if((freq < 150.0) || (freq > 960.0)) {
return(ERR_INVALID_FREQUENCY); return(ERR_INVALID_FREQUENCY);
} }
int16_t state = ERR_NONE;
// calibrate image
if(calibrate) {
uint8_t data[2];
if(freq > 900.0) {
data[0] = SX126X_CAL_IMG_902_MHZ_1;
data[1] = SX126X_CAL_IMG_902_MHZ_2;
} else if(freq > 850.0) {
data[0] = SX126X_CAL_IMG_863_MHZ_1;
data[1] = SX126X_CAL_IMG_863_MHZ_2;
} else if(freq > 770.0) {
data[0] = SX126X_CAL_IMG_779_MHZ_1;
data[1] = SX126X_CAL_IMG_779_MHZ_2;
} else if(freq > 460.0) {
data[0] = SX126X_CAL_IMG_470_MHZ_1;
data[1] = SX126X_CAL_IMG_470_MHZ_2;
} else {
data[0] = SX126X_CAL_IMG_430_MHZ_1;
data[1] = SX126X_CAL_IMG_430_MHZ_2;
}
state = SX126x::calibrateImage(data);
if(state != ERR_NONE) {
return(state);
}
}
// set frequency // set frequency
return(SX126x::setFrequencyRaw(freq)); return(SX126x::setFrequencyRaw(freq));
} }

Wyświetl plik

@ -78,9 +78,11 @@ class SX1262: public SX126x {
\param freq Carrier frequency to be set in MHz. \param freq Carrier frequency to be set in MHz.
\param calibrate Run image calibration.
\returns \ref status_codes \returns \ref status_codes
*/ */
int16_t setFrequency(float freq); int16_t setFrequency(float freq, bool calibrate = true);
/*! /*!
\brief Sets output power. Allowed values are in range from -17 to 22 dBm. \brief Sets output power. Allowed values are in range from -17 to 22 dBm.

Wyświetl plik

@ -0,0 +1,104 @@
#include "SX1268.h"
SX1268::SX1268(Module* mod) : SX126x(mod) {
}
int16_t SX1268::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint16_t syncWord, int8_t power, float currentLimit, uint16_t preambleLength) {
// execute common part
int16_t state = SX126x::begin(bw, sf, cr, syncWord, preambleLength);
if(state != ERR_NONE) {
return(state);
}
// configure publicly accessible settings
state = setFrequency(freq);
if(state != ERR_NONE) {
return(state);
}
state = setOutputPower(power);
if(state != ERR_NONE) {
return(state);
}
// OCP must be configured after PA
state = SX126x::setCurrentLimit(currentLimit);
if(state != ERR_NONE) {
return(state);
}
return(state);
}
int16_t SX1268::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, float currentLimit, uint16_t preambleLength, float dataShaping) {
// execute common part
int16_t state = SX126x::beginFSK(br, freqDev, rxBw, preambleLength, dataShaping);
if(state != ERR_NONE) {
return(state);
}
// configure publicly accessible settings
state = setFrequency(freq);
if(state != ERR_NONE) {
return(state);
}
state = setOutputPower(power);
if(state != ERR_NONE) {
return(state);
}
// OCP must be configured after PA
state = SX126x::setCurrentLimit(currentLimit);
if(state != ERR_NONE) {
return(state);
}
return(state);
}
int16_t SX1268::setFrequency(float freq, bool calibrate) {
// check frequency range
if((freq < 410.0) || (freq > 810.0)) {
return(ERR_INVALID_FREQUENCY);
}
int16_t state = ERR_NONE;
// calibrate image
if(calibrate) {
uint8_t data[2];
if(freq > 770.0) {
data[0] = SX126X_CAL_IMG_779_MHZ_1;
data[1] = SX126X_CAL_IMG_779_MHZ_2;
} else if(freq > 460.0) {
data[0] = SX126X_CAL_IMG_470_MHZ_1;
data[1] = SX126X_CAL_IMG_470_MHZ_2;
} else {
data[0] = SX126X_CAL_IMG_430_MHZ_1;
data[1] = SX126X_CAL_IMG_430_MHZ_2;
}
state = SX126x::calibrateImage(data);
if(state != ERR_NONE) {
return(state);
}
}
// set frequency
return(SX126x::setFrequencyRaw(freq));
}
int16_t SX1268::setOutputPower(int8_t power) {
// check allowed power range
if(!((power >= -9) && (power <= 22))) {
return(ERR_INVALID_OUTPUT_POWER);
}
// enable high power PA
SX126x::setPaConfig(0x04, SX126X_PA_CONFIG_SX1268);
// set output power
// TODO power ramp time configuration
SX126x::setTxParams(power);
return(ERR_NONE);
}

Wyświetl plik

@ -4,13 +4,93 @@
#include "TypeDef.h" #include "TypeDef.h"
#include "Module.h" #include "Module.h"
#include "SX126x.h" #include "SX126x.h"
#include "SX1262.h"
//SX126X_CMD_SET_PA_CONFIG //SX126X_CMD_SET_PA_CONFIG
#define SX126X_PA_CONFIG_SX1261 0x01 #define SX126X_PA_CONFIG_SX1268 0x00
#define SX126X_PA_CONFIG_SX1262 0x00
// TODO: implement SX1268 class /*!
using SX1268 = SX1262; \class SX1268
\brief Derived class for %SX1268 modules.
*/
class SX1268: public SX126x {
public:
/*!
\brief Default constructor.
\param mod Instance of Module that will be used to communicate with the radio.
*/
SX1268(Module* mod);
// basic methods
/*!
\brief Initialization method for LoRa modem.
\param freq Carrier frequency in MHz. Defaults to 434.0 MHz.
\param bw LoRa bandwidth in kHz. Defaults to 125.0 kHz.
\param sf LoRa spreading factor. Defaults to 9.
\param cr LoRa coding rate denominator. Defaults to 7 (coding rate 4/7).
\param syncWord 2-byte LoRa sync word. Defaults to SX126X_SYNC_WORD_PRIVATE (0x1424).
\param power Output power in dBm. Defaults to 14 dBm.
\param currentLimit Current protection limit in mA. Defaults to 60.0 mA.
\param preambleLength LoRa preamble length in symbols.Defaults to 8 symbols.
\returns \ref status_codes
*/
int16_t begin(float freq = 434.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint16_t syncWord = SX126X_SYNC_WORD_PRIVATE, int8_t power = 14, float currentLimit = 60.0, uint16_t preambleLength = 8);
/*!
\brief Initialization method for FSK modem.
\param freq Carrier frequency in MHz. Defaults to 434.0 MHz.
\param br FSK bit rate in kbps. Defaults to 48.0 kbps.
\param freqDev Frequency deviation from carrier frequency in kHz. Defaults to 50.0 kHz.
\param rxBw Receiver bandwidth in kHz. Defaults to 156.2 kHz.
\param power Output power in dBm. Defaults to 14 dBm.
\param currentLimit Current protection limit in mA. Defaults to 60.0 mA.
\parma preambleLength FSK preamble length in bits. Defaults to 16 bits.
\param dataShaping Time-bandwidth product of the Gaussian filter to be used for shaping. Defaults to 0.5.
\returns \ref status_codes
*/
int16_t beginFSK(float freq = 434.0, float br = 48.0, float freqDev = 50.0, float rxBw = 156.2, int8_t power = 14, float currentLimit = 60.0, uint16_t preambleLength = 16, float dataShaping = 0.5);
// configuration methods
/*!
\brief Sets carrier frequency. Allowed values are in range from 150.0 to 960.0 MHz.
\param freq Carrier frequency to be set in MHz.
\param calibrate Run image calibration.
\returns \ref status_codes
*/
int16_t setFrequency(float freq, bool calibrate = true);
/*!
\brief Sets output power. Allowed values are in range from -17 to 22 dBm.
\param power Output power to be set in dBm.
\returns \ref status_codes
*/
int16_t setOutputPower(int8_t power);
};
#endif #endif

Wyświetl plik

@ -576,9 +576,9 @@ int16_t SX126x::setFrequencyDeviation(float freqDev) {
uint32_t freqDevRaw = (uint32_t)(((freqDev * 1000.0) * (float)((uint32_t)(1) << 25)) / (SX126X_CRYSTAL_FREQ * 1000000.0)); uint32_t freqDevRaw = (uint32_t)(((freqDev * 1000.0) * (float)((uint32_t)(1) << 25)) / (SX126X_CRYSTAL_FREQ * 1000000.0));
// check modulation parameters // check modulation parameters
if(2 * freqDevRaw + _br > _rxBwKhz * 1000.0) { /*if(2 * freqDevRaw + _br > _rxBwKhz * 1000.0) {
return(ERR_INVALID_MODULATION_PARAMETERS); return(ERR_INVALID_MODULATION_PARAMETERS);
} }*/
_freqDev = freqDevRaw; _freqDev = freqDevRaw;
// update modulation parameters // update modulation parameters
@ -600,9 +600,9 @@ int16_t SX126x::setBitRate(float br) {
uint32_t brRaw = (uint32_t)((SX126X_CRYSTAL_FREQ * 1000000.0 * 32.0) / (br * 1000.0)); uint32_t brRaw = (uint32_t)((SX126X_CRYSTAL_FREQ * 1000000.0 * 32.0) / (br * 1000.0));
// check modulation parameters // check modulation parameters
if(2 * _freqDev + brRaw > _rxBwKhz * 1000.0) { /*if(2 * _freqDev + brRaw > _rxBwKhz * 1000.0) {
return(ERR_INVALID_MODULATION_PARAMETERS); return(ERR_INVALID_MODULATION_PARAMETERS);
} }*/
_br = brRaw; _br = brRaw;
// update modulation parameters // update modulation parameters
@ -616,9 +616,9 @@ int16_t SX126x::setRxBandwidth(float rxBw) {
} }
// check modulation parameters // check modulation parameters
if(2 * _freqDev + _br > rxBw * 1000.0) { /*if(2 * _freqDev + _br > rxBw * 1000.0) {
return(ERR_INVALID_MODULATION_PARAMETERS); return(ERR_INVALID_MODULATION_PARAMETERS);
} }*/
_rxBwKhz = rxBw; _rxBwKhz = rxBw;
// check alowed receiver bandwidth values // check alowed receiver bandwidth values
@ -968,6 +968,10 @@ int16_t SX126x::setRfFrequency(uint32_t frf) {
return(SPIwriteCommand(SX126X_CMD_SET_RF_FREQUENCY, data, 4)); return(SPIwriteCommand(SX126X_CMD_SET_RF_FREQUENCY, data, 4));
} }
int16_t SX126x::calibrateImage(uint8_t* data) {
return(SPIwriteCommand(SX126X_CMD_CALIBRATE_IMAGE, data, 2));
}
uint8_t SX126x::getPacketType() { uint8_t SX126x::getPacketType() {
uint8_t data = 0xFF; uint8_t data = 0xFF;
SPIreadCommand(SX126X_CMD_GET_PACKET_TYPE, &data, 1); SPIreadCommand(SX126X_CMD_GET_PACKET_TYPE, &data, 1);
@ -1047,34 +1051,7 @@ int16_t SX126x::clearDeviceErrors() {
return(SPIwriteCommand(SX126X_CMD_CLEAR_DEVICE_ERRORS, data, 1)); return(SPIwriteCommand(SX126X_CMD_CLEAR_DEVICE_ERRORS, data, 1));
} }
int16_t SX126x::setFrequencyRaw(float freq, bool calibrate) { int16_t SX126x::setFrequencyRaw(float freq) {
int16_t state = ERR_NONE;
// calibrate image
if(calibrate) {
uint8_t data[2];
if(freq > 900.0) {
data[0] = SX126X_CAL_IMG_902_MHZ_1;
data[1] = SX126X_CAL_IMG_902_MHZ_2;
} else if(freq > 850.0) {
data[0] = SX126X_CAL_IMG_863_MHZ_1;
data[1] = SX126X_CAL_IMG_863_MHZ_2;
} else if(freq > 770.0) {
data[0] = SX126X_CAL_IMG_779_MHZ_1;
data[1] = SX126X_CAL_IMG_779_MHZ_2;
} else if(freq > 460.0) {
data[0] = SX126X_CAL_IMG_470_MHZ_1;
data[1] = SX126X_CAL_IMG_470_MHZ_2;
} else {
data[0] = SX126X_CAL_IMG_430_MHZ_1;
data[1] = SX126X_CAL_IMG_430_MHZ_2;
}
state = SPIwriteCommand(SX126X_CMD_CALIBRATE_IMAGE, data, 2);
if(state != ERR_NONE) {
return(state);
}
}
// calculate raw value // calculate raw value
uint32_t frf = (freq * (uint32_t(1) << SX126X_DIV_EXPONENT)) / SX126X_CRYSTAL_FREQ; uint32_t frf = (freq * (uint32_t(1) << SX126X_DIV_EXPONENT)) / SX126X_CRYSTAL_FREQ;
setRfFrequency(frf); setRfFrequency(frf);
@ -1184,7 +1161,7 @@ int16_t SX126x::SPItransfer(uint8_t cmd, bool write, uint8_t* dataOut, uint8_t*
DEBUG_PRINT('\t'); DEBUG_PRINT('\t');
// variable to save error during SPI transfer // variable to save error during SPI transfer
uint8_t status; uint8_t status = 0;
// send/receive all bytes // send/receive all bytes
if(write) { if(write) {

Wyświetl plik

@ -150,7 +150,6 @@
//SX126X_CMD_SET_PA_CONFIG //SX126X_CMD_SET_PA_CONFIG
#define SX126X_PA_CONFIG_HP_MAX 0x07 #define SX126X_PA_CONFIG_HP_MAX 0x07
#define SX126X_PA_CONFIG_SX1268 0x01
#define SX126X_PA_CONFIG_PA_LUT 0x01 #define SX126X_PA_CONFIG_PA_LUT 0x01
//SX126X_CMD_SET_RX_TX_FALLBACK_MODE //SX126X_CMD_SET_RX_TX_FALLBACK_MODE
@ -366,7 +365,7 @@ class SX126x: public PhysicalLayer {
\param rxBw Receiver bandwidth in kHz. Allowed values are 4.8, 5.8, 7.3, 9.7, 11.7, 14.6, 19.5, 23.4, 29.3, 39.0, 46.9, 58.6, 78.2, 93.8, 117.3, 156.2, 187.2, 234.3, 312.0, 373.6 and 467.0 kHz. \param rxBw Receiver bandwidth in kHz. Allowed values are 4.8, 5.8, 7.3, 9.7, 11.7, 14.6, 19.5, 23.4, 29.3, 39.0, 46.9, 58.6, 78.2, 93.8, 117.3, 156.2, 187.2, 234.3, 312.0, 373.6 and 467.0 kHz.
\parma preambleLength FSK preamble length in bits. Allowed values range from 0 to 65535. \param preambleLength FSK preamble length in bits. Allowed values range from 0 to 65535.
\param dataShaping Time-bandwidth product of the Gaussian filter to be used for shaping. Allowed values are 0.3, 0.5, 0.7 and 1.0. Set to 0 to disable shaping. \param dataShaping Time-bandwidth product of the Gaussian filter to be used for shaping. Allowed values are 0.3, 0.5, 0.7 and 1.0. Set to 0 to disable shaping.
@ -692,6 +691,7 @@ class SX126x: public PhysicalLayer {
uint16_t getIrqStatus(); uint16_t getIrqStatus();
int16_t clearIrqStatus(uint16_t clearIrqParams = SX126X_IRQ_ALL); int16_t clearIrqStatus(uint16_t clearIrqParams = SX126X_IRQ_ALL);
int16_t setRfFrequency(uint32_t frf); int16_t setRfFrequency(uint32_t frf);
int16_t calibrateImage(uint8_t* data);
uint8_t getPacketType(); uint8_t getPacketType();
int16_t setTxParams(uint8_t power, uint8_t rampTime = SX126X_PA_RAMP_200U); int16_t setTxParams(uint8_t power, uint8_t rampTime = SX126X_PA_RAMP_200U);
int16_t setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr, uint8_t ldro = 0xFF); int16_t setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr, uint8_t ldro = 0xFF);
@ -704,7 +704,7 @@ class SX126x: public PhysicalLayer {
uint16_t getDeviceErrors(); uint16_t getDeviceErrors();
int16_t clearDeviceErrors(); int16_t clearDeviceErrors();
int16_t setFrequencyRaw(float freq, bool calibrate = true); int16_t setFrequencyRaw(float freq);
private: private:
Module* _mod; Module* _mod;