diff --git a/src/modules/LR11x0/LR11x0.cpp b/src/modules/LR11x0/LR11x0.cpp index e744249f..ceb11c6c 100644 --- a/src/modules/LR11x0/LR11x0.cpp +++ b/src/modules/LR11x0/LR11x0.cpp @@ -2368,7 +2368,7 @@ int16_t LR11x0::setRangingReqAddr(uint32_t addr) { int16_t LR11x0::getRangingResult(uint8_t type, float* res) { uint8_t reqBuff[1] = { type }; uint8_t rplBuff[4] = { 0 }; - int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_NOP, false, rplBuff, sizeof(rplBuff), reqBuff, sizeof(reqBuff)); + int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GET_RANGING_RESULT, false, rplBuff, sizeof(rplBuff), reqBuff, sizeof(reqBuff)); RADIOLIB_ASSERT(state); if(res) { @@ -2420,6 +2420,22 @@ int16_t LR11x0::setRangingParameter(uint8_t symbolNum) { return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_RANGING_PARAMETER, true, buff, sizeof(buff))); } +int16_t LR11x0::setRssiCalibration(int8_t* tune, int16_t gainOffset) { + uint8_t buff[11] = { + (uint8_t)((tune[0] & 0x0F) | (uint8_t)(tune[1] & 0x0F) << 4), + (uint8_t)((tune[2] & 0x0F) | (uint8_t)(tune[3] & 0x0F) << 4), + (uint8_t)((tune[4] & 0x0F) | (uint8_t)(tune[5] & 0x0F) << 4), + (uint8_t)((tune[6] & 0x0F) | (uint8_t)(tune[7] & 0x0F) << 4), + (uint8_t)((tune[8] & 0x0F) | (uint8_t)(tune[9] & 0x0F) << 4), + (uint8_t)((tune[10] & 0x0F) | (uint8_t)(tune[11] & 0x0F) << 4), + (uint8_t)((tune[12] & 0x0F) | (uint8_t)(tune[13] & 0x0F) << 4), + (uint8_t)((tune[14] & 0x0F) | (uint8_t)(tune[15] & 0x0F) << 4), + (uint8_t)((tune[16] & 0x0F) | (uint8_t)(tune[17] & 0x0F) << 4), + (uint8_t)(((uint16_t)gainOffset >> 8) & 0xFF), (uint8_t)(gainOffset & 0xFF), + }; + return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_RSSI_CALIBRATION, true, buff, sizeof(buff))); +} + int16_t LR11x0::setLoRaSyncWord(uint8_t sync) { uint8_t buff[1] = { sync }; return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_LORA_SYNC_WORD, true, buff, sizeof(buff))); @@ -2837,6 +2853,196 @@ int16_t LR11x0::gnssGetSvVisible(uint32_t time, float lat, float lon, uint8_t co return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_GET_SV_VISIBLE, false, nbSv, 1, reqBuff, sizeof(reqBuff))); } +// TODO check version > 02.01 +int16_t LR11x0::gnssScan(uint8_t effort, uint8_t resMask, uint8_t nbSvMax) { + uint8_t buff[3] = { effort, resMask, nbSvMax }; + return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_SCAN, true, buff, sizeof(buff))); +} + +int16_t LR11x0::gnssReadLastScanModeLaunched(uint8_t* lastScanMode) { + uint8_t buff[1] = { 0 }; + int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_READ_LAST_SCAN_MODE_LAUNCHED, false, buff, sizeof(buff)); + + // pass the replies + if(lastScanMode) { *lastScanMode = buff[0]; } + + return(state); +} + +int16_t LR11x0::gnssFetchTime(uint8_t effort, uint8_t opt) { + uint8_t buff[2] = { effort, opt }; + return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_FETCH_TIME, true, buff, sizeof(buff))); +} + +int16_t LR11x0::gnssReadTime(uint8_t* err, uint32_t* time, uint32_t* nbUs, uint32_t* timeAccuracy) { + uint8_t buff[12] = { 0 }; + int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_READ_TIME, false, buff, sizeof(buff)); + + // pass the replies + if(err) { *err = buff[0]; } + if(time) { *time = ((uint32_t)(buff[1]) << 24) | ((uint32_t)(buff[2]) << 16) | ((uint32_t)(buff[3]) << 8) | (uint32_t)buff[4]; } + if(nbUs) { *nbUs = ((uint32_t)(buff[5]) << 16) | ((uint32_t)(buff[6]) << 8) | (uint32_t)buff[7]; } + if(timeAccuracy) { *timeAccuracy = ((uint32_t)(buff[8]) << 24) | ((uint32_t)(buff[9]) << 16) | ((uint32_t)(buff[10]) << 8) | (uint32_t)buff[11]; } + + return(state); +} + +int16_t LR11x0::gnssResetTime(void) { + return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_RESET_TIME, true, NULL, 0)); +} + +int16_t LR11x0::gnssResetPosition(void) { + return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_RESET_POSITION, true, NULL, 0)); +} + +int16_t LR11x0::gnssReadDemodStatus(int8_t* status, uint8_t* info) { + uint8_t buff[2] = { 0 }; + int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_READ_DEMOD_STATUS, false, buff, sizeof(buff)); + + // pass the replies + if(status) { *status = (int8_t)buff[0]; } + if(info) { *info = buff[1]; } + + return(state); +} + +int16_t LR11x0::gnssReadCumulTiming(uint32_t* timing, uint8_t* constDemod) { + uint8_t rplBuff[125] = { 0 }; + int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_READ_REG_MEM, false, rplBuff, 125); + RADIOLIB_ASSERT(state); + + // convert endians + if(timing) { + for(size_t i = 0; i < 31; i++) { + timing[i] = ((uint32_t)rplBuff[i*sizeof(uint32_t)] << 24) | ((uint32_t)rplBuff[1 + i*sizeof(uint32_t)] << 16) | ((uint32_t)rplBuff[2 + i*sizeof(uint32_t)] << 8) | (uint32_t)rplBuff[3 + i*sizeof(uint32_t)]; + } + } + + if(constDemod) { *constDemod = rplBuff[124]; } + + return(state); +} + +int16_t LR11x0::gnssSetTime(uint32_t time, uint16_t accuracy) { + uint8_t buff[6] = { + (uint8_t)((time >> 24) & 0xFF), (uint8_t)((time >> 16) & 0xFF), + (uint8_t)((time >> 8) & 0xFF), (uint8_t)(time & 0xFF), + (uint8_t)((accuracy >> 8) & 0xFF), (uint8_t)(accuracy & 0xFF), + }; + return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_SET_TIME, true, buff, sizeof(buff))); +} + +int16_t LR11x0::gnssReadDopplerSolverRes(uint8_t* error, uint8_t* nbSvUsed, float* lat, float* lon, uint16_t* accuracy, uint16_t* xtal, float* latFilt, float* lonFilt, uint16_t* accuracyFilt, uint16_t* xtalFilt) { + uint8_t buff[18] = { 0 }; + int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_READ_DOPPLER_SOLVER_RES, false, buff, sizeof(buff)); + + // pass the replies + if(error) { *error = buff[0]; } + if(nbSvUsed) { *nbSvUsed = buff[1]; } + if(lat) { + uint16_t latRaw = ((uint16_t)(buff[2]) << 8) | (uint16_t)buff[3]; + *lat = ((float)latRaw * 90.0f)/2048.0f; + } + if(lon) { + uint16_t lonRaw = ((uint16_t)(buff[4]) << 8) | (uint16_t)buff[5]; + *lon = ((float)lonRaw * 180.0f)/2048.0f; + } + if(accuracy) { *accuracy = ((uint16_t)(buff[6]) << 8) | (uint16_t)buff[7]; } + if(xtal) { *xtal = ((uint16_t)(buff[8]) << 8) | (uint16_t)buff[9]; } + if(latFilt) { + uint16_t latRaw = ((uint16_t)(buff[10]) << 8) | (uint16_t)buff[11]; + *latFilt = ((float)latRaw * 90.0f)/2048.0f; + } + if(lonFilt) { + uint16_t lonRaw = ((uint16_t)(buff[12]) << 8) | (uint16_t)buff[13]; + *lonFilt = ((float)lonRaw * 180.0f)/2048.0f; + } + if(accuracyFilt) { *accuracyFilt = ((uint16_t)(buff[14]) << 8) | (uint16_t)buff[15]; } + if(xtalFilt) { *xtalFilt = ((uint16_t)(buff[16]) << 8) | (uint16_t)buff[17]; } + + return(state); +} + +int16_t LR11x0::gnssReadDelayResetAP(uint32_t* delay) { + uint8_t buff[3] = { 0 }; + int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_READ_DELAY_RESET_AP, false, buff, sizeof(buff)); + + if(delay) { *delay = ((uint32_t)(buff[0]) << 16) | ((uint32_t)(buff[1]) << 8) | (uint32_t)buff[2]; } + + return(state); +} + +int16_t LR11x0::gnssAlmanacUpdateFromSat(uint8_t effort, uint8_t bitMask) { + uint8_t buff[2] = { effort, bitMask }; + return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_ALMANAC_UPDATE_FROM_SAT, true, buff, sizeof(buff))); +} + +int16_t LR11x0::gnssReadAlmanacStatus(uint8_t* status) { + // TODO parse the reply into some structure + return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_READ_ALMANAC_STATUS, false, status, 53)); +} + +int16_t LR11x0::gnssConfigAlmanacUpdatePeriod(uint8_t bitMask, uint8_t svType, uint16_t period) { + uint8_t buff[4] = { bitMask, svType, (uint8_t)((period >> 8) & 0xFF), (uint8_t)(period & 0xFF) }; + return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_CONFIG_ALMANAC_UPDATE_PERIOD, true, buff, sizeof(buff))); +} + +int16_t LR11x0::gnssReadAlmanacUpdatePeriod(uint8_t bitMask, uint8_t svType, uint16_t* period) { + uint8_t reqBuff[2] = { bitMask, svType }; + uint8_t rplBuff[2] = { 0 }; + int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_READ_ALMANAC_UPDATE_PERIOD, false, rplBuff, sizeof(rplBuff), reqBuff, sizeof(reqBuff)); + RADIOLIB_ASSERT(state); + + if(period) { *period = ((uint16_t)(rplBuff[0]) << 8) | (uint16_t)rplBuff[1]; } + + return(state); +} + +int16_t LR11x0::gnssConfigDelayResetAP(uint32_t delay) { + uint8_t buff[3] = { (uint8_t)((delay >> 16) & 0xFF), (uint8_t)((delay >> 8) & 0xFF), (uint8_t)(delay & 0xFF) }; + return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_CONFIG_DELAY_RESET_AP, true, buff, sizeof(buff))); +} + +int16_t LR11x0::gnssGetSvWarmStart(uint8_t bitMask, uint8_t* sv, uint8_t nbVisSat) { + uint8_t reqBuff[1] = { bitMask }; + return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_GET_SV_WARM_START, false, sv, nbVisSat, reqBuff, sizeof(reqBuff))); +} + +int16_t LR11x0::gnssReadWNRollover(uint8_t* status, uint8_t* rollover) { + uint8_t buff[2] = { 0 }; + int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_READ_WN_ROLLOVER, false, buff, sizeof(buff)); + + if(status) { *status = buff[0]; } + if(rollover) { *rollover = buff[1]; } + + return(state); +} + +int16_t LR11x0::gnssReadWarmStartStatus(uint8_t bitMask, uint8_t* nbVisSat, uint32_t* timeElapsed) { + uint8_t reqBuff[1] = { bitMask }; + uint8_t rplBuff[5] = { 0 }; + int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_READ_WARM_START_STATUS, false, rplBuff, sizeof(rplBuff), reqBuff, sizeof(reqBuff)); + RADIOLIB_ASSERT(state); + + if(nbVisSat) { *nbVisSat = rplBuff[0]; } + if(timeElapsed) { *timeElapsed = ((uint32_t)(rplBuff[1]) << 24) | ((uint32_t)(rplBuff[2]) << 16) | ((uint32_t)(rplBuff[3]) << 8) | (uint32_t)rplBuff[4]; } + + return(state); +} + +int16_t LR11x0::gnssWriteBitMaskSatActivated(uint8_t bitMask, uint32_t* bitMaskActivated0, uint32_t* bitMaskActivated1) { + uint8_t reqBuff[1] = { bitMask }; + uint8_t rplBuff[8] = { 0 }; + size_t rplLen = (bitMask & 0x01) ? 8 : 4; // GPS only has the first bit mask + int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_READ_WARM_START_STATUS, false, rplBuff, rplLen, reqBuff, sizeof(reqBuff)); + RADIOLIB_ASSERT(state); + + if(bitMaskActivated0) { *bitMaskActivated0 = ((uint32_t)(rplBuff[0]) << 24) | ((uint32_t)(rplBuff[1]) << 16) | ((uint32_t)(rplBuff[2]) << 8) | (uint32_t)rplBuff[3]; } + if(bitMaskActivated1) { *bitMaskActivated1 = ((uint32_t)(rplBuff[4]) << 24) | ((uint32_t)(rplBuff[5]) << 16) | ((uint32_t)(rplBuff[6]) << 8) | (uint32_t)rplBuff[7]; } + + return(state); +} + int16_t LR11x0::cryptoSetKey(uint8_t keyId, uint8_t* key) { if(!key) { return(RADIOLIB_ERR_MEMORY_ALLOCATION_FAILED); diff --git a/src/modules/LR11x0/LR11x0.h b/src/modules/LR11x0/LR11x0.h index 2ba8d269..efe4a749 100644 --- a/src/modules/LR11x0/LR11x0.h +++ b/src/modules/LR11x0/LR11x0.h @@ -84,6 +84,7 @@ #define RADIOLIB_LR11X0_CMD_SET_GFSK_WHIT_PARAMS (0x0225) #define RADIOLIB_LR11X0_CMD_SET_RX_BOOSTED (0x0227) #define RADIOLIB_LR11X0_CMD_SET_RANGING_PARAMETER (0x0228) +#define RADIOLIB_LR11X0_CMD_SET_RSSI_CALIBRATION (0x0229) #define RADIOLIB_LR11X0_CMD_SET_LORA_SYNC_WORD (0x022B) #define RADIOLIB_LR11X0_CMD_LR_FHSS_BUILD_FRAME (0x022C) #define RADIOLIB_LR11X0_CMD_LR_FHSS_SET_SYNC_WORD (0x022D) @@ -111,6 +112,10 @@ #define RADIOLIB_LR11X0_CMD_GNSS_SET_MODE (0x0408) #define RADIOLIB_LR11X0_CMD_GNSS_AUTONOMOUS (0x0409) #define RADIOLIB_LR11X0_CMD_GNSS_ASSISTED (0x040A) +#define RADIOLIB_LR11X0_CMD_GNSS_SCAN (0x040B) +#define RADIOLIB_LR11X0_CMD_GNSS_GET_RESULT_SIZE (0x040C) +#define RADIOLIB_LR11X0_CMD_GNSS_READ_RESULTS (0x040D) +#define RADIOLIB_LR11X0_CMD_GNSS_ALMANAC_FULL_UPDATE (0x040E) #define RADIOLIB_LR11X0_CMD_GNSS_SET_ASSISTANCE_POSITION (0x0410) #define RADIOLIB_LR11X0_CMD_GNSS_READ_ASSISTANCE_POSITION (0x0411) #define RADIOLIB_LR11X0_CMD_GNSS_PUSH_SOLVER_MSG (0x0414) @@ -119,10 +124,26 @@ #define RADIOLIB_LR11X0_CMD_GNSS_GET_NB_SV_DETECTED (0x0417) #define RADIOLIB_LR11X0_CMD_GNSS_GET_SV_DETECTED (0x0418) #define RADIOLIB_LR11X0_CMD_GNSS_GET_CONSUMPTION (0x0419) -#define RADIOLIB_LR11X0_CMD_GNSS_GET_RESULT_SIZE (0x040C) -#define RADIOLIB_LR11X0_CMD_GNSS_READ_RESULTS (0x040D) -#define RADIOLIB_LR11X0_CMD_GNSS_ALMANAC_FULL_UPDATE (0x040E) #define RADIOLIB_LR11X0_CMD_GNSS_GET_SV_VISIBLE (0x041F) +#define RADIOLIB_LR11X0_CMD_GNSS_READ_LAST_SCAN_MODE_LAUNCHED (0x0426) +#define RADIOLIB_LR11X0_CMD_GNSS_FETCH_TIME (0x0432) +#define RADIOLIB_LR11X0_CMD_GNSS_READ_TIME (0x0434) +#define RADIOLIB_LR11X0_CMD_GNSS_RESET_TIME (0x0435) +#define RADIOLIB_LR11X0_CMD_GNSS_RESET_POSITION (0x0437) +#define RADIOLIB_LR11X0_CMD_GNSS_READ_DEMOD_STATUS (0x0439) +#define RADIOLIB_LR11X0_CMD_GNSS_READ_CUMUL_TIMING (0x044A) +#define RADIOLIB_LR11X0_CMD_GNSS_SET_TIME (0x044B) +#define RADIOLIB_LR11X0_CMD_GNSS_READ_DOPPLER_SOLVER_RES (0x044F) +#define RADIOLIB_LR11X0_CMD_GNSS_READ_DELAY_RESET_AP (0x0453) +#define RADIOLIB_LR11X0_CMD_GNSS_ALMANAC_UPDATE_FROM_SAT (0x0455) +#define RADIOLIB_LR11X0_CMD_GNSS_READ_ALMANAC_STATUS (0x0457) +#define RADIOLIB_LR11X0_CMD_GNSS_CONFIG_ALMANAC_UPDATE_PERIOD (0x0463) +#define RADIOLIB_LR11X0_CMD_GNSS_READ_ALMANAC_UPDATE_PERIOD (0x0464) +#define RADIOLIB_LR11X0_CMD_GNSS_CONFIG_DELAY_RESET_AP (0x0465) +#define RADIOLIB_LR11X0_CMD_GNSS_GET_SV_WARM_START (0x0466) +#define RADIOLIB_LR11X0_CMD_GNSS_READ_WN_ROLLOVER (0x0467) +#define RADIOLIB_LR11X0_CMD_GNSS_READ_WARM_START_STATUS (0x0469) +#define RADIOLIB_LR11X0_CMD_GNSS_WRITE_BIT_MASK_SAT_ACTIVATED (0x0472) #define RADIOLIB_LR11X0_CMD_CRYPTO_SET_KEY (0x0502) #define RADIOLIB_LR11X0_CMD_CRYPTO_DERIVE_KEY (0x0503) #define RADIOLIB_LR11X0_CMD_CRYPTO_PROCESS_JOIN_ACCEPT (0x0504) @@ -147,6 +168,7 @@ // LR11X0 register map #define RADIOLIB_LR11X0_REG_SF6_SX127X_COMPAT (0x00F20414) #define RADIOLIB_LR11X0_REG_LORA_HIGH_POWER_FIX (0x00F30054) +// TODO add fix for br 600/1200 bps // LR11X0 SPI command variables @@ -1347,6 +1369,7 @@ class LR11x0: public PhysicalLayer { int16_t setGfskWhitParams(uint16_t seed); int16_t setRxBoosted(bool en); int16_t setRangingParameter(uint8_t symbolNum); + int16_t setRssiCalibration(int8_t* tune, int16_t gainOffset); int16_t setLoRaSyncWord(uint8_t sync); int16_t lrFhssBuildFrame(uint8_t hdrCount, uint8_t cr, uint8_t grid, bool hop, uint8_t bw, uint16_t hopSeq, int8_t devOffset, uint8_t* payload, size_t len); int16_t lrFhssSetSyncWord(uint32_t sync); @@ -1389,6 +1412,26 @@ class LR11x0: public PhysicalLayer { int16_t gnssAlmanacFullUpdateHeader(uint16_t date, uint32_t globalCrc); int16_t gnssAlmanacFullUpdateSV(uint8_t svn, uint8_t* svnAlmanac); int16_t gnssGetSvVisible(uint32_t time, float lat, float lon, uint8_t constellation, uint8_t* nbSv); + int16_t gnssScan(uint8_t effort, uint8_t resMask, uint8_t nbSvMax); + int16_t gnssReadLastScanModeLaunched(uint8_t* lastScanMode); + int16_t gnssFetchTime(uint8_t effort, uint8_t opt); + int16_t gnssReadTime(uint8_t* err, uint32_t* time, uint32_t* nbUs, uint32_t* timeAccuracy); + int16_t gnssResetTime(void); + int16_t gnssResetPosition(void); + int16_t gnssReadDemodStatus(int8_t* status, uint8_t* info); + int16_t gnssReadCumulTiming(uint32_t* timing, uint8_t* constDemod); + int16_t gnssSetTime(uint32_t time, uint16_t accuracy); + int16_t gnssReadDopplerSolverRes(uint8_t* error, uint8_t* nbSvUsed, float* lat, float* lon, uint16_t* accuracy, uint16_t* xtal, float* latFilt, float* lonFilt, uint16_t* accuracyFilt, uint16_t* xtalFilt); + int16_t gnssReadDelayResetAP(uint32_t* delay); + int16_t gnssAlmanacUpdateFromSat(uint8_t effort, uint8_t bitMask); + int16_t gnssReadAlmanacStatus(uint8_t* status); + int16_t gnssConfigAlmanacUpdatePeriod(uint8_t bitMask, uint8_t svType, uint16_t period); + int16_t gnssReadAlmanacUpdatePeriod(uint8_t bitMask, uint8_t svType, uint16_t* period); + int16_t gnssConfigDelayResetAP(uint32_t delay); + int16_t gnssGetSvWarmStart(uint8_t bitMask, uint8_t* sv, uint8_t nbVisSat); + int16_t gnssReadWNRollover(uint8_t* status, uint8_t* rollover); + int16_t gnssReadWarmStartStatus(uint8_t bitMask, uint8_t* nbVisSat, uint32_t* timeElapsed); + int16_t gnssWriteBitMaskSatActivated(uint8_t bitMask, uint32_t* bitMaskActivated0, uint32_t* bitMaskActivated1); int16_t cryptoSetKey(uint8_t keyId, uint8_t* key); int16_t cryptoDeriveKey(uint8_t srcKeyId, uint8_t dstKeyId, uint8_t* key);