[SX126x] Fixed config
This commit is contained in:
parent
56b636f54f
commit
ba82497c8e
3 changed files with 168 additions and 64 deletions
|
@ -6,7 +6,7 @@ SX1262::SX1262(Module* mod) : SX126x(mod) {
|
||||||
|
|
||||||
int16_t SX1262::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint16_t syncWord, int8_t power, float currentLimit, uint16_t preambleLength) {
|
int16_t SX1262::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
|
// execute common part
|
||||||
int16_t state = SX126x::begin(bw, sf, cr, syncWord, currentLimit, preambleLength);
|
int16_t state = SX126x::begin(bw, sf, cr, syncWord, preambleLength);
|
||||||
if(state != ERR_NONE) {
|
if(state != ERR_NONE) {
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,12 @@ int16_t SX1262::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint16_t syn
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OCP must be configured after PA
|
||||||
|
state = SX126x::setCurrentLimit(currentLimit);
|
||||||
|
if(state != ERR_NONE) {
|
||||||
|
return(state);
|
||||||
|
}
|
||||||
|
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +48,7 @@ int16_t SX1262::setOutputPower(int8_t power) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable high power PA for output power higher than 14 dBm
|
// enable high power PA for output power higher than 14 dBm
|
||||||
if(power > 14) {
|
if(power > 13) {
|
||||||
SX126x::setPaConfig(0x04, SX126X_PA_CONFIG_SX1262);
|
SX126x::setPaConfig(0x04, SX126X_PA_CONFIG_SX1262);
|
||||||
} else {
|
} else {
|
||||||
SX126x::setPaConfig(0x04, SX126X_PA_CONFIG_SX1261);
|
SX126x::setPaConfig(0x04, SX126X_PA_CONFIG_SX1261);
|
||||||
|
@ -53,4 +59,3 @@ int16_t SX1262::setOutputPower(int8_t power) {
|
||||||
SX126x::setTxParams(power);
|
SX126x::setTxParams(power);
|
||||||
return(ERR_NONE);
|
return(ERR_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,10 +12,18 @@ SX126x::SX126x(Module* mod) : PhysicalLayer(SX126X_CRYSTAL_FREQ, SX126X_DIV_EXPO
|
||||||
_preambleLength = 8;
|
_preambleLength = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t SX126x::begin(float bw, uint8_t sf, uint8_t cr, uint16_t syncWord, float currentLimit, uint16_t preambleLength) {
|
int16_t SX126x::begin(float bw, uint8_t sf, uint8_t cr, uint16_t syncWord, uint16_t preambleLength) {
|
||||||
// set module properties
|
// set module properties
|
||||||
_mod->init(USE_SPI, INT_BOTH);
|
_mod->init(USE_SPI, INT_BOTH);
|
||||||
pinMode(_mod->getRx(), INPUT);
|
pinMode(_mod->getRx(), INPUT);
|
||||||
|
pinMode(_mod->getTx(), INPUT);
|
||||||
|
|
||||||
|
// reset module
|
||||||
|
reset();
|
||||||
|
|
||||||
|
// get status and errors
|
||||||
|
getStatus();
|
||||||
|
getDeviceErrors();
|
||||||
|
|
||||||
// set mode to standby
|
// set mode to standby
|
||||||
standby();
|
standby();
|
||||||
|
@ -44,11 +52,6 @@ int16_t SX126x::begin(float bw, uint8_t sf, uint8_t cr, uint16_t syncWord, float
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
state = setCurrentLimit(currentLimit);
|
|
||||||
if(state != ERR_NONE) {
|
|
||||||
return(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
state = setPreambleLength(preambleLength);
|
state = setPreambleLength(preambleLength);
|
||||||
if(state != ERR_NONE) {
|
if(state != ERR_NONE) {
|
||||||
return(state);
|
return(state);
|
||||||
|
@ -97,6 +100,16 @@ int16_t SX126x::standby(uint8_t mode) {
|
||||||
return(ERR_NONE);
|
return(ERR_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SX126x::reset() {
|
||||||
|
delay(10);
|
||||||
|
pinMode(_mod->getTx(), OUTPUT);
|
||||||
|
digitalWrite(_mod->getTx(), LOW);
|
||||||
|
delay(20);
|
||||||
|
digitalWrite(_mod->getTx(), HIGH);
|
||||||
|
pinMode(_mod->getTx(), INPUT);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
|
||||||
int16_t SX126x::setBandwidth(float bw) {
|
int16_t SX126x::setBandwidth(float bw) {
|
||||||
// check active modem
|
// check active modem
|
||||||
if(getPacketType() != SX126X_PACKET_TYPE_LORA) {
|
if(getPacketType() != SX126X_PACKET_TYPE_LORA) {
|
||||||
|
@ -202,6 +215,7 @@ float SX126x::getDataRate() {
|
||||||
|
|
||||||
int16_t SX126x::setFrequencyDeviation(float freqDev) {
|
int16_t SX126x::setFrequencyDeviation(float freqDev) {
|
||||||
|
|
||||||
|
return(ERR_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SX126x::setTx(uint32_t timeout) {
|
void SX126x::setTx(uint32_t timeout) {
|
||||||
|
@ -219,7 +233,7 @@ void SX126x::setCad() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SX126x::setPaConfig(uint8_t paDutyCycle, uint8_t deviceSel, uint8_t hpMax, uint8_t paLut) {
|
void SX126x::setPaConfig(uint8_t paDutyCycle, uint8_t deviceSel, uint8_t hpMax, uint8_t paLut) {
|
||||||
uint8_t data[4] = {paDutyCycle, deviceSel, hpMax, paLut};
|
uint8_t data[4] = {paDutyCycle, hpMax, deviceSel, paLut};
|
||||||
SPIwriteCommand(SX126X_CMD_SET_PA_CONFIG, data, 4);
|
SPIwriteCommand(SX126X_CMD_SET_PA_CONFIG, data, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,9 +298,40 @@ void SX126x::setPacketParams(uint16_t preambleLength, uint8_t payloadLength, uin
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t SX126x::getStatus() {
|
uint8_t SX126x::getStatus() {
|
||||||
uint8_t data[1];
|
/*uint8_t data[1];
|
||||||
SPIreadCommand(SX126X_CMD_GET_STATUS, data, 1);
|
SPIreadCommand(SX126X_CMD_GET_STATUS, data, 1);
|
||||||
return(data[0]);
|
return(data[0]);*/
|
||||||
|
|
||||||
|
// get pointer to used SPI interface
|
||||||
|
SPIClass* spi = _mod->getSpi();
|
||||||
|
|
||||||
|
// ensure BUSY is low (state meachine ready)
|
||||||
|
// TODO timeout
|
||||||
|
while(digitalRead(_mod->getRx()));
|
||||||
|
|
||||||
|
// start transfer
|
||||||
|
digitalWrite(_mod->getCs(), LOW);
|
||||||
|
spi->beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));
|
||||||
|
|
||||||
|
// send command byte
|
||||||
|
spi->transfer(SX126X_CMD_GET_STATUS);
|
||||||
|
DEBUG_PRINT(SX126X_CMD_GET_STATUS, HEX);
|
||||||
|
DEBUG_PRINT('\t');
|
||||||
|
|
||||||
|
// get status
|
||||||
|
uint8_t status = spi->transfer(SX126X_CMD_NOP) & 0b01111110;
|
||||||
|
DEBUG_PRINTLN(status, HEX);
|
||||||
|
|
||||||
|
// stop transfer
|
||||||
|
spi->endTransaction();
|
||||||
|
digitalWrite(_mod->getCs(), HIGH);
|
||||||
|
|
||||||
|
// wait for BUSY to go high and then low
|
||||||
|
// TODO timeout
|
||||||
|
delayMicroseconds(1);
|
||||||
|
while(digitalRead(_mod->getRx()));
|
||||||
|
|
||||||
|
return(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t SX126x::getRssiInt() {
|
uint8_t SX126x::getRssiInt() {
|
||||||
|
@ -295,8 +340,41 @@ uint8_t SX126x::getRssiInt() {
|
||||||
return(data[0]);
|
return(data[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t SX126x::setFrequencyRaw(float freq) {
|
uint16_t SX126x::getDeviceErrors() {
|
||||||
// TODO CalibrateImage
|
uint8_t data[2];
|
||||||
|
SPIreadCommand(SX126X_CMD_GET_DEVICE_ERRORS, data, 2);
|
||||||
|
uint16_t opError = (((uint16_t)data[0] & 0xFF) << 8) & ((uint16_t)data[1]);
|
||||||
|
return(opError);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX126x::clearDeviceErrors() {
|
||||||
|
uint8_t data[1] = {SX126X_CMD_NOP};
|
||||||
|
SPIwriteCommand(SX126X_CMD_CLEAR_DEVICE_ERRORS, data, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t SX126x::setFrequencyRaw(float freq, bool calibrate) {
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
SPIwriteCommand(SX126X_CMD_CALIBRATE_IMAGE, data, 2);
|
||||||
|
}
|
||||||
|
|
||||||
// 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);
|
||||||
|
@ -304,8 +382,25 @@ int16_t SX126x::setFrequencyRaw(float freq) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t SX126x::config() {
|
int16_t SX126x::config() {
|
||||||
// set LoRa mode
|
// set DIO2 as RF switch
|
||||||
uint8_t* data = new uint8_t[1];
|
uint8_t* data = new uint8_t[1];
|
||||||
|
data[0] = SX126X_CMD_SET_DIO2_AS_RF_SWITCH_CTRL;
|
||||||
|
SPIwriteCommand(SX126X_DIO2_AS_RF_SWITCH, data, 1);
|
||||||
|
|
||||||
|
// set regulator mode
|
||||||
|
data[0] = SX126X_REGULATOR_DC_DC;
|
||||||
|
SPIwriteCommand(SX126X_CMD_SET_REGULATOR_MODE, data, 1);
|
||||||
|
|
||||||
|
// set buffer base address
|
||||||
|
delete[] data;
|
||||||
|
data = new uint8_t[2];
|
||||||
|
data[0] = 0x00;
|
||||||
|
data[1] = 0x00;
|
||||||
|
SPIwriteCommand(SX126X_CMD_SET_BUFFER_BASE_ADDRESS, data, 2);
|
||||||
|
|
||||||
|
// set LoRa mode
|
||||||
|
delete[] data;
|
||||||
|
data = new uint8_t[1];
|
||||||
data[0] = SX126X_PACKET_TYPE_LORA;
|
data[0] = SX126X_PACKET_TYPE_LORA;
|
||||||
SPIwriteCommand(SX126X_CMD_SET_PACKET_TYPE, data, 1);
|
SPIwriteCommand(SX126X_CMD_SET_PACKET_TYPE, data, 1);
|
||||||
|
|
||||||
|
@ -324,7 +419,6 @@ int16_t SX126x::config() {
|
||||||
data[5] = 0x00;
|
data[5] = 0x00;
|
||||||
data[6] = 0x00;
|
data[6] = 0x00;
|
||||||
SPIwriteCommand(SX126X_CMD_SET_CAD_PARAMS, data, 7);
|
SPIwriteCommand(SX126X_CMD_SET_CAD_PARAMS, data, 7);
|
||||||
delete[] data;
|
|
||||||
|
|
||||||
return(ERR_NONE);
|
return(ERR_NONE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,6 +165,8 @@
|
||||||
#define SX126X_IRQ_PREAMBLE_DETECTED 0b0000000100 // 2 2 preamble detected
|
#define SX126X_IRQ_PREAMBLE_DETECTED 0b0000000100 // 2 2 preamble detected
|
||||||
#define SX126X_IRQ_RX_DONE 0b0000000010 // 1 1 packet received
|
#define SX126X_IRQ_RX_DONE 0b0000000010 // 1 1 packet received
|
||||||
#define SX126X_IRQ_TX_DONE 0b0000000001 // 0 0 packet transmission completed
|
#define SX126X_IRQ_TX_DONE 0b0000000001 // 0 0 packet transmission completed
|
||||||
|
#define SX126X_IRQ_ALL 0b1111111111 // 9 0 all interrupts
|
||||||
|
#define SX126X_IRQ_NONE 0b0000000000 // 9 0 no interrupts
|
||||||
|
|
||||||
//SX126X_CMD_SET_DIO2_AS_RF_SWITCH_CTRL
|
//SX126X_CMD_SET_DIO2_AS_RF_SWITCH_CTRL
|
||||||
#define SX126X_DIO2_AS_IRQ 0x00 // 7 0 DIO2 configuration: IRQ
|
#define SX126X_DIO2_AS_IRQ 0x00 // 7 0 DIO2 configuration: IRQ
|
||||||
|
@ -321,13 +323,14 @@ class SX126x: public PhysicalLayer {
|
||||||
SX126x(Module* mod);
|
SX126x(Module* mod);
|
||||||
|
|
||||||
// basic methods
|
// basic methods
|
||||||
int16_t begin(float bw, uint8_t sf, uint8_t cr, uint16_t syncWord, float currentLimit, uint16_t preambleLength);
|
int16_t begin(float bw, uint8_t sf, uint8_t cr, uint16_t syncWord, uint16_t preambleLength);
|
||||||
int16_t transmit(uint8_t* data, size_t len, uint8_t addr = 0);
|
int16_t transmit(uint8_t* data, size_t len, uint8_t addr = 0);
|
||||||
int16_t receive(uint8_t* data, size_t len);
|
int16_t receive(uint8_t* data, size_t len);
|
||||||
int16_t transmitDirect(uint32_t frf = 0);
|
int16_t transmitDirect(uint32_t frf = 0);
|
||||||
int16_t receiveDirect();
|
int16_t receiveDirect();
|
||||||
int16_t sleep();
|
int16_t sleep();
|
||||||
int16_t standby(uint8_t mode = SX126X_STANDBY_RC);
|
int16_t standby(uint8_t mode = SX126X_STANDBY_RC);
|
||||||
|
void reset();
|
||||||
|
|
||||||
// configuration methods
|
// configuration methods
|
||||||
int16_t setBandwidth(float bw);
|
int16_t setBandwidth(float bw);
|
||||||
|
@ -350,13 +353,15 @@ class SX126x: public PhysicalLayer {
|
||||||
void clearIrqStatus(uint16_t clearIrqParams = 0xFFFF);
|
void clearIrqStatus(uint16_t clearIrqParams = 0xFFFF);
|
||||||
void setRfFrequency(uint32_t frf);
|
void setRfFrequency(uint32_t frf);
|
||||||
uint8_t getPacketType();
|
uint8_t getPacketType();
|
||||||
void setTxParams(uint8_t power, uint8_t rampTime = SX126X_PA_RAMP_80U);
|
void setTxParams(uint8_t power, uint8_t rampTime = SX126X_PA_RAMP_40U);
|
||||||
void setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr, uint8_t ldro = 0xFF);
|
void setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr, uint8_t ldro = 0xFF);
|
||||||
void setPacketParams(uint16_t preambleLength, uint8_t payloadLength, uint8_t crcType, uint8_t headerType = SX126X_LORA_HEADER_EXPLICIT, uint8_t invertIQ = SX126X_LORA_IQ_STANDARD);
|
void setPacketParams(uint16_t preambleLength, uint8_t payloadLength, uint8_t crcType, uint8_t headerType = SX126X_LORA_HEADER_EXPLICIT, uint8_t invertIQ = SX126X_LORA_IQ_INVERTED);
|
||||||
uint8_t getStatus();
|
uint8_t getStatus();
|
||||||
uint8_t getRssiInt();
|
uint8_t getRssiInt();
|
||||||
|
uint16_t getDeviceErrors();
|
||||||
|
void clearDeviceErrors();
|
||||||
|
|
||||||
int16_t setFrequencyRaw(float freq);
|
int16_t setFrequencyRaw(float freq, bool calibrate = true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Module* _mod;
|
Module* _mod;
|
||||||
|
|
Loading…
Add table
Reference in a new issue