make lora packet count persist in flash (also remove some unneeded init)

This commit is contained in:
geeksville 2020-01-18 12:37:39 -08:00
parent 73bac3be45
commit fdc0edee88
3 changed files with 48 additions and 19 deletions

View File

@ -36,9 +36,6 @@ String baChStatus = "No charging";
bool ssd1306_found = false; bool ssd1306_found = false;
bool axp192_found = false; bool axp192_found = false;
// Message counter, stored in RTC memory, survives deep sleep
RTC_DATA_ATTR uint32_t count = 0;
#if defined(PAYLOAD_USE_FULL) #if defined(PAYLOAD_USE_FULL)
// includes number of satellites and accuracy // includes number of satellites and accuracy
uint8_t txBuffer[10]; uint8_t txBuffer[10];
@ -70,10 +67,7 @@ void send() {
bool confirmed = false; bool confirmed = false;
#endif #endif
ttn_cnt(count);
ttn_send(txBuffer, sizeof(txBuffer), LORAWAN_PORT, confirmed); ttn_send(txBuffer, sizeof(txBuffer), LORAWAN_PORT, confirmed);
count++;
} }
void sleep() { void sleep() {
@ -170,9 +164,7 @@ void callback(uint8_t message) {
} }
} }
uint32_t get_count() {
return count;
}
void scanI2Cdevice(void) void scanI2Cdevice(void)
{ {
@ -281,8 +273,8 @@ void setup() {
// Init GPS // Init GPS
gps_setup(); gps_setup();
// Show logo on first boot // Show logo on first boot after removing battery
if (0 == count) { if (ttn_get_count() == 0) {
screen_print(APP_NAME " " APP_VERSION, 0, 0); screen_print(APP_NAME " " APP_VERSION, 0, 0);
screen_show_logo(); screen_show_logo();
screen_update(); screen_update();
@ -299,11 +291,7 @@ void setup() {
ttn_register(callback); ttn_register(callback);
ttn_join(); ttn_join();
ttn_sf(LORAWAN_SF);
ttn_adr(LORAWAN_ADR); ttn_adr(LORAWAN_ADR);
if(!LORAWAN_ADR){
LMIC_setLinkCheckMode(0); // Link check problematic if not using ADR. Must be set after join
}
} }
void loop() { void loop() {

View File

@ -35,7 +35,7 @@ void _screen_header() {
char buffer[20]; char buffer[20];
// Message count // Message count
snprintf(buffer, sizeof(buffer), "#%03d", get_count() % 1000); snprintf(buffer, sizeof(buffer), "#%03d", ttn_get_count() % 1000);
display->setTextAlignment(TEXT_ALIGN_LEFT); display->setTextAlignment(TEXT_ALIGN_LEFT);
display->drawString(0, 2, buffer); display->drawString(0, 2, buffer);

View File

@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <hal/hal.h> #include <hal/hal.h>
#include <SPI.h> #include <SPI.h>
#include <vector> #include <vector>
#include <Preferences.h>
#include "configuration.h" #include "configuration.h"
#include "credentials.h" #include "credentials.h"
@ -42,6 +43,10 @@ const lmic_pinmap lmic_pins = {
.dio = {DIO0_GPIO, DIO1_GPIO, DIO2_GPIO}, .dio = {DIO0_GPIO, DIO1_GPIO, DIO2_GPIO},
}; };
// Message counter, stored in RTC memory, survives deep sleep.
static RTC_DATA_ATTR uint32_t count = 0;
#ifdef USE_ABP #ifdef USE_ABP
// These callbacks are only used in over-the-air activation, so they are // These callbacks are only used in over-the-air activation, so they are
// left empty here (we cannot leave them out completely unless // left empty here (we cannot leave them out completely unless
@ -96,7 +101,9 @@ void onEvent(ev_t event) {
// Disable link check validation (automatically enabled // Disable link check validation (automatically enabled
// during join, but because slow data rates change max TX // during join, but because slow data rates change max TX
// size, we don't use it in this example. // size, we don't use it in this example.
LMIC_setLinkCheckMode(0); if(!LORAWAN_ADR){
LMIC_setLinkCheckMode(0); // Link check problematic if not using ADR. Must be set after join
}
break; break;
case EV_TXCOMPLETE: case EV_TXCOMPLETE:
Serial.println(F("EV_TXCOMPLETE (inc. RX win. wait)")); Serial.println(F("EV_TXCOMPLETE (inc. RX win. wait)"));
@ -137,7 +144,20 @@ void ttn_response(uint8_t * buffer, size_t len) {
} }
} }
// If the value for LORA packet counts is unknown, restore from flash
static void initCount() {
if(count == 0) {
Preferences p;
p.begin("lora", true);
count = p.getUInt("count", 0);
p.end();
}
}
bool ttn_setup() { bool ttn_setup() {
initCount();
// SPI interface // SPI interface
SPI.begin(SCK_GPIO, MISO_GPIO, MOSI_GPIO, NSS_GPIO); SPI.begin(SCK_GPIO, MISO_GPIO, MOSI_GPIO, NSS_GPIO);
@ -238,11 +258,31 @@ void ttn_adr(bool enabled) {
LMIC_setLinkCheckMode(!enabled); LMIC_setLinkCheckMode(!enabled);
} }
void ttn_cnt(uint32_t num) { uint32_t ttn_get_count() {
LMIC_setSeqnoUp(num); return count;
}
static void ttn_set_cnt() {
LMIC_setSeqnoUp(count);
// We occasionally mirror our count to flash, to ensure that if we lose power we will at least start with a count that is almost correct
// (otherwise the TNN network will discard packets until count once again reaches the value they've seen). We limit these writes to a max rate
// of one write every 5 minutes. Which should let the FLASH last for 300 years (given the ESP32 NVS algoritm)
static uint32_t lastWriteMsec = UINT32_MAX; // Ensure we write at least once
uint32_t now = millis();
if(now < lastWriteMsec || (now - lastWriteMsec) > 5 * 60 * 1000L) { // write if we roll over (50 days) or 5 mins
lastWriteMsec = now;
Preferences p;
p.begin("lora", false);
p.putUInt("count", count);
p.end();
}
} }
void ttn_send(uint8_t * data, uint8_t data_size, uint8_t port, bool confirmed){ void ttn_send(uint8_t * data, uint8_t data_size, uint8_t port, bool confirmed){
ttn_set_cnt(); // we are about to send using the current packet count
// Check if there is not a current TX/RX job running // Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND) { if (LMIC.opmode & OP_TXRXPEND) {
_ttn_callback(EV_PENDING); _ttn_callback(EV_PENDING);
@ -254,6 +294,7 @@ void ttn_send(uint8_t * data, uint8_t data_size, uint8_t port, bool confirmed){
LMIC_setTxData2(port, data, data_size, confirmed ? 1 : 0); LMIC_setTxData2(port, data, data_size, confirmed ? 1 : 0);
_ttn_callback(EV_QUEUED); _ttn_callback(EV_QUEUED);
count++;
} }
void ttn_loop() { void ttn_loop() {