[SX126x] Fixed config

This commit is contained in:
jgromes 2019-05-12 19:24:07 +02:00
parent 56b636f54f
commit ba82497c8e
3 changed files with 168 additions and 64 deletions

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;