optimize sleep mode
This commit is contained in:
parent
05a9721d46
commit
a4e3b1980e
@ -6,9 +6,6 @@
|
|||||||
// Local logging Tag
|
// Local logging Tag
|
||||||
static const char TAG[] = "lora";
|
static const char TAG[] = "lora";
|
||||||
|
|
||||||
// Saves the LMIC structure during deep sleep
|
|
||||||
RTC_DATA_ATTR lmic_t RTC_LMIC;
|
|
||||||
|
|
||||||
#if CLOCK_ERROR_PROCENTAGE > 7
|
#if CLOCK_ERROR_PROCENTAGE > 7
|
||||||
#warning CLOCK_ERROR_PROCENTAGE value in lmic_config.h is too high; values > 7 will cause side effects
|
#warning CLOCK_ERROR_PROCENTAGE value in lmic_config.h is too high; values > 7 will cause side effects
|
||||||
#endif
|
#endif
|
||||||
@ -484,14 +481,70 @@ const char *getCrName(rps_t rps) {
|
|||||||
return t[getCr(rps)];
|
return t[getCr(rps)];
|
||||||
}
|
}
|
||||||
|
|
||||||
// following code snippet was taken from
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* ttn-esp32 - The Things Network device library for ESP-IDF / SX127x
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018-2021 Manuel Bleichenbacher
|
||||||
|
*
|
||||||
|
* Licensed under MIT License
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*
|
||||||
|
* Functions for storing and retrieving TTN communication state from RTC memory.
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#define LMIC_OFFSET(field) __builtin_offsetof(struct lmic_t, field)
|
||||||
|
#define LMIC_DIST(field1, field2) (LMIC_OFFSET(field2) - LMIC_OFFSET(field1))
|
||||||
|
#define TTN_RTC_MEM_SIZE \
|
||||||
|
(sizeof(struct lmic_t) - LMIC_OFFSET(radio) - MAX_LEN_PAYLOAD - MAX_LEN_FRAME)
|
||||||
|
|
||||||
|
#define TTN_RTC_FLAG_VALUE 0xf8025b8a
|
||||||
|
|
||||||
|
RTC_DATA_ATTR uint8_t ttn_rtc_mem_buf[TTN_RTC_MEM_SIZE];
|
||||||
|
RTC_DATA_ATTR uint32_t ttn_rtc_flag;
|
||||||
|
|
||||||
|
void ttn_rtc_save() {
|
||||||
|
// Copy LMIC struct except client, osjob, pendTxData and frame
|
||||||
|
size_t len1 = LMIC_DIST(radio, pendTxData);
|
||||||
|
memcpy(ttn_rtc_mem_buf, &LMIC.radio, len1);
|
||||||
|
size_t len2 = LMIC_DIST(pendTxData, frame) - MAX_LEN_PAYLOAD;
|
||||||
|
memcpy(ttn_rtc_mem_buf + len1, (u1_t *)&LMIC.pendTxData + MAX_LEN_PAYLOAD,
|
||||||
|
len2);
|
||||||
|
size_t len3 = sizeof(struct lmic_t) - LMIC_OFFSET(frame) - MAX_LEN_FRAME;
|
||||||
|
memcpy(ttn_rtc_mem_buf + len1 + len2, (u1_t *)&LMIC.frame + MAX_LEN_FRAME,
|
||||||
|
len3);
|
||||||
|
|
||||||
|
ttn_rtc_flag = TTN_RTC_FLAG_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ttn_rtc_restore() {
|
||||||
|
if (ttn_rtc_flag != TTN_RTC_FLAG_VALUE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Restore data
|
||||||
|
size_t len1 = LMIC_DIST(radio, pendTxData);
|
||||||
|
memcpy(&LMIC.radio, ttn_rtc_mem_buf, len1);
|
||||||
|
memset(LMIC.pendTxData, 0, MAX_LEN_PAYLOAD);
|
||||||
|
size_t len2 = LMIC_DIST(pendTxData, frame) - MAX_LEN_PAYLOAD;
|
||||||
|
memcpy((u1_t *)&LMIC.pendTxData + MAX_LEN_PAYLOAD, ttn_rtc_mem_buf + len1,
|
||||||
|
len2);
|
||||||
|
memset(LMIC.frame, 0, MAX_LEN_FRAME);
|
||||||
|
size_t len3 = sizeof(struct lmic_t) - LMIC_OFFSET(frame) - MAX_LEN_FRAME;
|
||||||
|
memcpy((u1_t *)&LMIC.frame + MAX_LEN_FRAME, ttn_rtc_mem_buf + len1 + len2,
|
||||||
|
len3);
|
||||||
|
|
||||||
|
ttn_rtc_flag = 0xffffffff; // invalidate RTC data
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// following code includes snippets taken from
|
||||||
// https://github.com/JackGruber/ESP32-LMIC-DeepSleep-example/blob/master/src/main.cpp
|
// https://github.com/JackGruber/ESP32-LMIC-DeepSleep-example/blob/master/src/main.cpp
|
||||||
|
|
||||||
void SaveLMICToRTC(int deepsleep_sec) {
|
void SaveLMICToRTC(int deepsleep_sec) {
|
||||||
RTC_LMIC = LMIC;
|
|
||||||
|
|
||||||
// ESP32 can't track millis during DeepSleep and no option to advance
|
// ESP32 can't track millis during DeepSleep and no option to advance
|
||||||
// millis after DeepSleep. Therefore reset DutyCyles
|
// millis after DeepSleep. Therefore reset DutyCyles before saving LMIC struct
|
||||||
|
|
||||||
unsigned long now = millis();
|
unsigned long now = millis();
|
||||||
|
|
||||||
@ -499,29 +552,34 @@ void SaveLMICToRTC(int deepsleep_sec) {
|
|||||||
#if CFG_LMIC_EU_like
|
#if CFG_LMIC_EU_like
|
||||||
for (int i = 0; i < MAX_BANDS; i++) {
|
for (int i = 0; i < MAX_BANDS; i++) {
|
||||||
ostime_t correctedAvail =
|
ostime_t correctedAvail =
|
||||||
RTC_LMIC.bands[i].avail -
|
LMIC.bands[i].avail -
|
||||||
((now / 1000.0 + deepsleep_sec) * OSTICKS_PER_SEC);
|
((now / 1000.0 + deepsleep_sec) * OSTICKS_PER_SEC);
|
||||||
if (correctedAvail < 0) {
|
if (correctedAvail < 0) {
|
||||||
correctedAvail = 0;
|
correctedAvail = 0;
|
||||||
}
|
}
|
||||||
RTC_LMIC.bands[i].avail = correctedAvail;
|
LMIC.bands[i].avail = correctedAvail;
|
||||||
}
|
}
|
||||||
|
|
||||||
RTC_LMIC.globalDutyAvail = RTC_LMIC.globalDutyAvail -
|
LMIC.globalDutyAvail =
|
||||||
((now / 1000.0 + deepsleep_sec) * OSTICKS_PER_SEC);
|
LMIC.globalDutyAvail - ((now / 1000.0 + deepsleep_sec) * OSTICKS_PER_SEC);
|
||||||
if (RTC_LMIC.globalDutyAvail < 0) {
|
if (LMIC.globalDutyAvail < 0) {
|
||||||
RTC_LMIC.globalDutyAvail = 0;
|
LMIC.globalDutyAvail = 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
ESP_LOGW(TAG, "No DutyCycle recalculation function!");
|
ESP_LOGW(TAG, "No DutyCycle recalculation function!");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ttn_rtc_save();
|
||||||
ESP_LOGI(TAG, "LMIC state saved");
|
ESP_LOGI(TAG, "LMIC state saved");
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadLMICFromRTC() {
|
void LoadLMICFromRTC() {
|
||||||
LMIC = RTC_LMIC;
|
if (ttn_rtc_restore())
|
||||||
ESP_LOGI(TAG, "LMIC state loaded");
|
ESP_LOGI(TAG, "LMIC state loaded");
|
||||||
|
else {
|
||||||
|
ESP_LOGE(TAG, "LMIC state not found - resetting device");
|
||||||
|
do_reset(false); // coldstart
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HAS_LORA
|
#endif // HAS_LORA
|
Loading…
Reference in New Issue
Block a user