[SX126x] Added OCP config reset

pull/25/head
jgromes 2019-06-22 16:37:57 +02:00
rodzic 2ca26d1a60
commit e1c79af18b
4 zmienionych plików z 112 dodań i 110 usunięć

Wyświetl plik

@ -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, preambleLength);
int16_t state = SX126x::begin(bw, sf, cr, syncWord, currentLimit, preambleLength);
if(state != ERR_NONE) {
return(state);
}
@ -22,18 +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);
}
int16_t SX1262::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);
int16_t state = SX126x::beginFSK(br, freqDev, rxBw, currentLimit, preambleLength, dataShaping);
if(state != ERR_NONE) {
return(state);
}
@ -49,12 +43,6 @@ int16_t SX1262::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t
return(state);
}
// OCP must be configured after PA
state = SX126x::setCurrentLimit(currentLimit);
if(state != ERR_NONE) {
return(state);
}
return(state);
}
@ -101,6 +89,13 @@ int16_t SX1262::setOutputPower(int8_t power) {
return(ERR_INVALID_OUTPUT_POWER);
}
// get current OCP configuration
uint8_t ocp = 0;
int16_t state = readRegister(SX126X_REG_OCP_CONFIGURATION, &ocp, 1);
if(state != ERR_NONE) {
return(state);
}
// enable high power PA for output power higher than 14 dBm
if(power > 13) {
SX126x::setPaConfig(0x04, SX126X_PA_CONFIG_SX1262);
@ -111,5 +106,7 @@ int16_t SX1262::setOutputPower(int8_t power) {
// set output power
// TODO power ramp time configuration
SX126x::setTxParams(power);
return(ERR_NONE);
// restore OCP configuration
return(writeRegister(SX126X_REG_OCP_CONFIGURATION, &ocp, 1));
}

Wyświetl plik

@ -6,7 +6,7 @@ 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);
int16_t state = SX126x::begin(bw, sf, cr, syncWord, currentLimit, preambleLength);
if(state != ERR_NONE) {
return(state);
}
@ -22,17 +22,11 @@ int16_t SX1268::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);
}
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);
int16_t state = SX126x::beginFSK(br, freqDev, rxBw, currentLimit, preambleLength, dataShaping);
if(state != ERR_NONE) {
return(state);
}
@ -48,12 +42,6 @@ int16_t SX1268::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t
return(state);
}
// OCP must be configured after PA
state = SX126x::setCurrentLimit(currentLimit);
if(state != ERR_NONE) {
return(state);
}
return(state);
}
@ -94,11 +82,20 @@ int16_t SX1268::setOutputPower(int8_t power) {
return(ERR_INVALID_OUTPUT_POWER);
}
// get current OCP configuration
uint8_t ocp = 0;
int16_t state = readRegister(SX126X_REG_OCP_CONFIGURATION, &ocp, 1);
if(state != ERR_NONE) {
return(state);
}
// 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);
// restore OCP configuration
return(writeRegister(SX126X_REG_OCP_CONFIGURATION, &ocp, 1));
}

Wyświetl plik

@ -447,7 +447,10 @@ int16_t SX126x::readData(uint8_t* data, size_t len) {
}
// get packet length
size_t length = getPacketLength();
size_t length = len;
if(len == SX126X_MAX_PACKET_LENGTH) {
length = getPacketLength();
}
// read packet data
int16_t state = readBuffer(data, length);
@ -774,67 +777,67 @@ int16_t SX126x::disableAddressFiltering() {
return(setPacketParamsFSK(_preambleLengthFSK, _crcTypeFSK, _syncWordLength, _addrComp));
}
int16_t SX126x::setCRC(bool enableCRC) {
// check active modem
if(getPacketType() != SX126X_PACKET_TYPE_LORA) {
return(ERR_WRONG_MODEM);
}
// update packet parameters
if(enableCRC) {
_crcType = SX126X_LORA_CRC_ON;
} else {
_crcType = SX126X_LORA_CRC_OFF;
}
return(setPacketParams(_preambleLength, _crcType));
}
int16_t SX126x::setCRC(uint8_t len, uint16_t initial, uint16_t polynomial, bool inverted) {
// check active modem
if(getPacketType() != SX126X_PACKET_TYPE_GFSK) {
return(ERR_WRONG_MODEM);
}
uint8_t modem = getPacketType();
if(modem == SX126X_PACKET_TYPE_GFSK) {
// update packet parameters
switch(len) {
case 0:
_crcTypeFSK = SX126X_GFSK_CRC_OFF;
break;
case 1:
if(inverted) {
_crcTypeFSK = SX126X_GFSK_CRC_1_BYTE_INV;
} else {
_crcTypeFSK = SX126X_GFSK_CRC_1_BYTE;
}
break;
case 2:
if(inverted) {
_crcTypeFSK = SX126X_GFSK_CRC_2_BYTE_INV;
} else {
_crcTypeFSK = SX126X_GFSK_CRC_2_BYTE;
}
break;
default:
return(ERR_INVALID_CRC_CONFIGURATION);
}
int16_t state = setPacketParamsFSK(_preambleLengthFSK, _crcTypeFSK, _syncWordLength, _addrComp);
if(state != ERR_NONE) {
return(state);
}
// write initial CRC value
uint8_t data[2] = {(uint8_t)((initial >> 8) & 0xFF), (uint8_t)(initial & 0xFF)};
state = writeRegister(SX126X_REG_CRC_INITIAL_MSB, data, 2);
if(state != ERR_NONE) {
return(state);
}
// write CRC polynomial value
data[0] = (uint8_t)((polynomial >> 8) & 0xFF);
data[1] = (uint8_t)(polynomial & 0xFF);
state = writeRegister(SX126X_REG_CRC_POLYNOMIAL_MSB, data, 2);
// update packet parameters
switch(len) {
case 0:
_crcTypeFSK = SX126X_GFSK_CRC_OFF;
break;
case 1:
if(inverted) {
_crcTypeFSK = SX126X_GFSK_CRC_1_BYTE_INV;
} else {
_crcTypeFSK = SX126X_GFSK_CRC_1_BYTE;
}
break;
case 2:
if(inverted) {
_crcTypeFSK = SX126X_GFSK_CRC_2_BYTE_INV;
} else {
_crcTypeFSK = SX126X_GFSK_CRC_2_BYTE;
}
break;
default:
return(ERR_INVALID_CRC_CONFIGURATION);
}
int16_t state = setPacketParamsFSK(_preambleLengthFSK, _crcTypeFSK, _syncWordLength, _addrComp);
if(state != ERR_NONE) {
return(state);
} else if(modem == SX126X_PACKET_TYPE_LORA) {
// LoRa CRC doesn't allow to set CRC polynomial, inital value, or inversion
// update packet parameters
if(len) {
_crcType = SX126X_LORA_CRC_ON;
} else {
_crcType = SX126X_LORA_CRC_OFF;
}
return(setPacketParams(_preambleLength, _crcType));
}
// write initial CRC value
uint8_t data[2] = {(uint8_t)((initial >> 8) & 0xFF), (uint8_t)(initial & 0xFF)};
state = writeRegister(SX126X_REG_CRC_INITIAL_MSB, data, 2);
if(state != ERR_NONE) {
return(state);
}
// write CRC polynomial value
data[0] = (uint8_t)((polynomial >> 8) & 0xFF);
data[1] = (uint8_t)(polynomial & 0xFF);
state = writeRegister(SX126X_REG_CRC_POLYNOMIAL_MSB, data, 2);
return(state);
return(ERR_UNKNOWN);
}
float SX126x::getDataRate() {
@ -944,6 +947,11 @@ int16_t SX126x::writeRegister(uint16_t addr, uint8_t* data, uint8_t numBytes) {
return(state);
}
int16_t SX126x::readRegister(uint16_t addr, uint8_t* data, uint8_t numBytes) {
uint8_t cmd[] = {SX126X_CMD_READ_REGISTER, (uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF)};
return(SX126x::SPItransfer(cmd, 3, false, NULL, data, numBytes, true));
}
int16_t SX126x::writeBuffer(uint8_t* data, uint8_t numBytes, uint8_t offset) {
uint8_t* dat = new uint8_t[1 + numBytes];
dat[0] = offset;
@ -1148,14 +1156,16 @@ int16_t SX126x::config(uint8_t modem) {
}
int16_t SX126x::SPIwriteCommand(uint8_t cmd, uint8_t* data, uint8_t numBytes, bool waitForBusy) {
return(SX126x::SPItransfer(cmd, true, data, NULL, numBytes, waitForBusy));
uint8_t cmdBuffer[] = {cmd};
return(SX126x::SPItransfer(cmdBuffer, 1, true, data, NULL, numBytes, waitForBusy));
}
int16_t SX126x::SPIreadCommand(uint8_t cmd, uint8_t* data, uint8_t numBytes, bool waitForBusy) {
return(SX126x::SPItransfer(cmd, false, NULL, data, numBytes, waitForBusy));
uint8_t cmdBuffer[] = {cmd};
return(SX126x::SPItransfer(cmdBuffer, 1, false, NULL, data, numBytes, waitForBusy));
}
int16_t SX126x::SPItransfer(uint8_t cmd, bool write, uint8_t* dataOut, uint8_t* dataIn, uint8_t numBytes, bool waitForBusy) {
int16_t SX126x::SPItransfer(uint8_t* cmd, uint8_t cmdLen, bool write, uint8_t* dataOut, uint8_t* dataIn, uint8_t numBytes, bool waitForBusy) {
// get pointer to used SPI interface and the settings
SPIClass* spi = _mod->getSpi();
SPISettings spiSettings = _mod->getSpiSettings();
@ -1168,10 +1178,12 @@ int16_t SX126x::SPItransfer(uint8_t cmd, bool write, uint8_t* dataOut, uint8_t*
digitalWrite(_mod->getCs(), LOW);
spi->beginTransaction(spiSettings);
// send command byte
spi->transfer(cmd);
DEBUG_PRINT(cmd, HEX);
DEBUG_PRINT('\t');
// send command byte(s)
for(uint8_t n = 0; n < cmdLen; n++) {
spi->transfer(cmd[n]);
DEBUG_PRINT(cmd[n], HEX);
DEBUG_PRINT('\t');
}
// variable to save error during SPI transfer
uint8_t status = 0;

Wyświetl plik

@ -351,11 +351,13 @@ class SX126x: public PhysicalLayer {
\param syncWord 2-byte LoRa sync word.
\param currentLimit Current protection limit in mA.
\param preambleLength LoRa preamble length in symbols. Allowed values range from 1 to 65535.
\returns \ref status_codes
*/
int16_t begin(float bw, uint8_t sf, uint8_t cr, uint16_t syncWord, uint16_t preambleLength);
int16_t begin(float bw, uint8_t sf, uint8_t cr, uint16_t syncWord, float currentLimit, uint16_t preambleLength);
/*!
\brief Initialization method for FSK modem.
@ -366,13 +368,15 @@ 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 currentLimit Current protection limit in mA.
\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.
\returns \ref status_codes
*/
int16_t beginFSK(float br, float freqDev, float rxBw, uint16_t preambleLength, float dataShaping);
int16_t beginFSK(float br, float freqDev, float rxBw, float currentLimit, uint16_t preambleLength, float dataShaping);
/*!
\brief Blocking binary transmit method.
@ -626,24 +630,15 @@ class SX126x: public PhysicalLayer {
int16_t disableAddressFiltering();
/*!
\brief Sets LoRa CRC.
\brief Sets CRC configuration.
\param enableCRC Enable or disable LoRa CRC.
\param len CRC length in bytes, Allowed values are 1 or 2, set to 0 to disable CRC.
\returns \ref status_codes
*/
int16_t setCRC(bool enableCRC);
\param initial Initial CRC value. FSK only. Defaults to 0x1D0F (CCIT CRC).
/*!
\brief Sets FSK CRC configuration.
\param polynomial Polynomial for CRC calculation. FSK only. Defaults to 0x1021 (CCIT CRC).
\param len CRC length in bytes, Allowed values are 1 or 2, set to 0 to disable FSK CRC.
\param initial Initial CRC value. Defaults to 0x1D0F (CCIT CRC).
\param polynomial Polynomial for CRC calculation. Defaults to 0x1021 (CCIT CRC).
\param inverted Invert CRC bytes. Defaults to true (CCIT CRC)
\param inverted Invert CRC bytes. FSK only. Defaults to true (CCIT CRC).
\returns \ref status_codes
*/
@ -702,6 +697,7 @@ class SX126x: public PhysicalLayer {
int16_t setCad();
int16_t setPaConfig(uint8_t paDutyCycle, uint8_t deviceSel, uint8_t hpMax = SX126X_PA_CONFIG_HP_MAX, uint8_t paLut = SX126X_PA_CONFIG_PA_LUT);
int16_t writeRegister(uint16_t addr, uint8_t* data, uint8_t numBytes);
int16_t readRegister(uint16_t addr, uint8_t* data, uint8_t numBytes);
int16_t writeBuffer(uint8_t* data, uint8_t numBytes, uint8_t offset = 0x00);
int16_t readBuffer(uint8_t* data, uint8_t numBytes);
int16_t setDioIrqParams(uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask = SX126X_IRQ_NONE, uint16_t dio3Mask = SX126X_IRQ_NONE);
@ -742,7 +738,7 @@ class SX126x: public PhysicalLayer {
// common low-level SPI interface
int16_t SPIwriteCommand(uint8_t cmd, uint8_t* data, uint8_t numBytes, bool waitForBusy = true);
int16_t SPIreadCommand(uint8_t cmd, uint8_t* data, uint8_t numBytes, bool waitForBusy = true);
int16_t SPItransfer(uint8_t cmd, bool write, uint8_t* dataOut, uint8_t* dataIn, uint8_t numBytes, bool waitForBusy);
int16_t SPItransfer(uint8_t* cmd, uint8_t cmdLen, bool write, uint8_t* dataOut, uint8_t* dataIn, uint8_t numBytes, bool waitForBusy);
};
#endif