[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) {
|
||||
// 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) {
|
||||
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);
|
||||
}
|
||||
|
||||
// OCP must be configured after PA
|
||||
state = SX126x::setCurrentLimit(currentLimit);
|
||||
if(state != ERR_NONE) {
|
||||
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
|
||||
if(power > 14) {
|
||||
if(power > 13) {
|
||||
SX126x::setPaConfig(0x04, SX126X_PA_CONFIG_SX1262);
|
||||
} else {
|
||||
SX126x::setPaConfig(0x04, SX126X_PA_CONFIG_SX1261);
|
||||
|
@ -53,4 +59,3 @@ int16_t SX1262::setOutputPower(int8_t power) {
|
|||
SX126x::setTxParams(power);
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,10 +12,18 @@ SX126x::SX126x(Module* mod) : PhysicalLayer(SX126X_CRYSTAL_FREQ, SX126X_DIV_EXPO
|
|||
_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
|
||||
_mod->init(USE_SPI, INT_BOTH);
|
||||
pinMode(_mod->getRx(), INPUT);
|
||||
pinMode(_mod->getTx(), INPUT);
|
||||
|
||||
// reset module
|
||||
reset();
|
||||
|
||||
// get status and errors
|
||||
getStatus();
|
||||
getDeviceErrors();
|
||||
|
||||
// set mode to standby
|
||||
standby();
|
||||
|
@ -44,11 +52,6 @@ int16_t SX126x::begin(float bw, uint8_t sf, uint8_t cr, uint16_t syncWord, float
|
|||
return(state);
|
||||
}
|
||||
|
||||
state = setCurrentLimit(currentLimit);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
state = setPreambleLength(preambleLength);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
|
@ -97,6 +100,16 @@ int16_t SX126x::standby(uint8_t mode) {
|
|||
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) {
|
||||
// check active modem
|
||||
if(getPacketType() != SX126X_PACKET_TYPE_LORA) {
|
||||
|
@ -202,6 +215,7 @@ float SX126x::getDataRate() {
|
|||
|
||||
int16_t SX126x::setFrequencyDeviation(float freqDev) {
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
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) {
|
||||
uint8_t data[4] = {paDutyCycle, deviceSel, hpMax, paLut};
|
||||
uint8_t data[4] = {paDutyCycle, hpMax, deviceSel, paLut};
|
||||
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 data[1];
|
||||
/*uint8_t 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() {
|
||||
|
@ -295,8 +340,41 @@ uint8_t SX126x::getRssiInt() {
|
|||
return(data[0]);
|
||||
}
|
||||
|
||||
int16_t SX126x::setFrequencyRaw(float freq) {
|
||||
// TODO CalibrateImage
|
||||
uint16_t SX126x::getDeviceErrors() {
|
||||
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
|
||||
uint32_t frf = (freq * (uint32_t(1) << SX126X_DIV_EXPONENT)) / SX126X_CRYSTAL_FREQ;
|
||||
setRfFrequency(frf);
|
||||
|
@ -304,8 +382,25 @@ int16_t SX126x::setFrequencyRaw(float freq) {
|
|||
}
|
||||
|
||||
int16_t SX126x::config() {
|
||||
// set LoRa mode
|
||||
// set DIO2 as RF switch
|
||||
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;
|
||||
SPIwriteCommand(SX126X_CMD_SET_PACKET_TYPE, data, 1);
|
||||
|
||||
|
@ -324,7 +419,6 @@ int16_t SX126x::config() {
|
|||
data[5] = 0x00;
|
||||
data[6] = 0x00;
|
||||
SPIwriteCommand(SX126X_CMD_SET_CAD_PARAMS, data, 7);
|
||||
delete[] data;
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
|
|
@ -165,6 +165,8 @@
|
|||
#define SX126X_IRQ_PREAMBLE_DETECTED 0b0000000100 // 2 2 preamble detected
|
||||
#define SX126X_IRQ_RX_DONE 0b0000000010 // 1 1 packet received
|
||||
#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
|
||||
#define SX126X_DIO2_AS_IRQ 0x00 // 7 0 DIO2 configuration: IRQ
|
||||
|
@ -321,13 +323,14 @@ class SX126x: public PhysicalLayer {
|
|||
SX126x(Module* mod);
|
||||
|
||||
// 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 receive(uint8_t* data, size_t len);
|
||||
int16_t transmitDirect(uint32_t frf = 0);
|
||||
int16_t receiveDirect();
|
||||
int16_t sleep();
|
||||
int16_t standby(uint8_t mode = SX126X_STANDBY_RC);
|
||||
void reset();
|
||||
|
||||
// configuration methods
|
||||
int16_t setBandwidth(float bw);
|
||||
|
@ -350,13 +353,15 @@ class SX126x: public PhysicalLayer {
|
|||
void clearIrqStatus(uint16_t clearIrqParams = 0xFFFF);
|
||||
void setRfFrequency(uint32_t frf);
|
||||
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 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 getRssiInt();
|
||||
uint16_t getDeviceErrors();
|
||||
void clearDeviceErrors();
|
||||
|
||||
int16_t setFrequencyRaw(float freq);
|
||||
int16_t setFrequencyRaw(float freq, bool calibrate = true);
|
||||
|
||||
private:
|
||||
Module* _mod;
|
||||
|
|
Loading…
Add table
Reference in a new issue