From f3b3838e09366f08172e166daeb547ea37186080 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sat, 19 Oct 2019 21:14:04 +0200 Subject: [PATCH] deep sleep, clock error rate, static callbacks --- include/lorawan.h | 9 +++++---- include/ota.h | 2 +- include/power.h | 2 +- include/wifiscan.h | 2 +- platformio.ini | 4 ++-- src/irqhandler.cpp | 6 +++++- src/lmic_config.h | 9 ++++----- src/lorawan.cpp | 26 +++++++++++++------------- src/main.cpp | 34 ++++++++++++++++++---------------- src/ota.cpp | 2 +- src/paxcounter.conf | 4 ++-- src/power.cpp | 18 +++++++++--------- src/wifiscan.cpp | 2 +- 13 files changed, 63 insertions(+), 57 deletions(-) diff --git a/include/lorawan.h b/include/lorawan.h index ead91d5c..e459cbf3 100644 --- a/include/lorawan.h +++ b/include/lorawan.h @@ -4,6 +4,7 @@ #include "globals.h" #include "rcommand.h" #include "timekeeper.h" +#include #if (TIME_SYNC_LORASERVER) #include "timesync.h" #endif @@ -43,10 +44,10 @@ void showLoraKeys(void); void lora_send(void *pvParameters); void lora_enqueuedata(MessageBuffer_t *message); void lora_queuereset(void); -void myEventCallback(void *pUserData, ev_t ev); -void myRxCallback(void *pUserData, uint8_t port, const uint8_t *pMsg, +static void IRAM_ATTR myEventCallback(void *pUserData, ev_t ev); +static void IRAM_ATTR myRxCallback(void *pUserData, uint8_t port, const uint8_t *pMsg, size_t nMsg); -void myTxCallback(void *pUserData, int fSuccess); +static void IRAM_ATTR myTxCallback(void *pUserData, int fSuccess); void mac_decode(const uint8_t cmd[], const uint8_t cmdlen, const mac_t table[], const uint8_t tablesize); uint8_t getBattLevel(void); @@ -55,7 +56,7 @@ const char *getBwName(rps_t rps); const char *getCrName(rps_t rps); #if (TIME_SYNC_LORAWAN) -void user_request_network_time_callback(void *pVoidUserUTCTime, +static void user_request_network_time_callback(void *pVoidUserUTCTime, int flagSuccess); #endif diff --git a/include/ota.h b/include/ota.h index cec28750..6a92720d 100644 --- a/include/ota.h +++ b/include/ota.h @@ -17,7 +17,7 @@ void start_ota_update(); int version_compare(const String v1, const String v2); void ota_display(const uint8_t row, const std::string status, const std::string msg); -void show_progress(unsigned long current, unsigned long size); +static void show_progress(unsigned long current, unsigned long size); #endif // USE_OTA diff --git a/include/power.h b/include/power.h index 8737e963..89595727 100644 --- a/include/power.h +++ b/include/power.h @@ -16,7 +16,7 @@ uint16_t read_voltage(void); void calibrate_voltage(void); bool batt_sufficient(void); void enter_deepsleep(const int wakeup_sec, const gpio_num_t wakeup_gpio); -int exit_deepsleep(void); +int64_t exit_deepsleep(void); #ifdef HAS_PMU #include diff --git a/include/wifiscan.h b/include/wifiscan.h index 0a6e7b6c..35c42e06 100644 --- a/include/wifiscan.h +++ b/include/wifiscan.h @@ -8,7 +8,7 @@ #include "hash.h" void wifi_sniffer_init(void); -void IRAM_ATTR wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type); +static void IRAM_ATTR wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type); void switchWifiChannel(TimerHandle_t xTimer); #endif \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index fd717815..8cb0728f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -43,7 +43,7 @@ description = Paxcounter is a device for metering passenger flows in realtime. I [common] ; for release_version use max. 10 chars total, use any decimal format like "a.b.c" -release_version = 1.9.63 +release_version = 1.9.64 ; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running! ; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose debug_level = 4 @@ -51,7 +51,7 @@ extra_scripts = pre:build.py otakeyfile = ota.conf lorakeyfile = loraconf.h lmicconfigfile = lmic_config.h -platform_espressif32 = espressif32@1.8.0 +platform_espressif32 = espressif32@1.11.0 monitor_speed = 115200 upload_speed = 115200 lib_deps_lora = diff --git a/src/irqhandler.cpp b/src/irqhandler.cpp index 63b85821..64375ab8 100644 --- a/src/irqhandler.cpp +++ b/src/irqhandler.cpp @@ -20,7 +20,11 @@ void irqHandler(void *pvParameters) { if (InterruptStatus & UNMASK_IRQ) // interrupt handler to be enabled? mask_irq = false; - else if (mask_irq) // suppress processing if interrupt handler is disabled + // else if (mask_irq) // suppress processing if interrupt handler is + // disabled + else if (mask_irq || os_queryTimeCriticalJobs(ms2osticks(100))) + // suppress processing if interrupt handler is disabled + // or time critical lmic jobs are pending in next 100ms continue; else if (InterruptStatus & MASK_IRQ) { // interrupt handler to be disabled? mask_irq = true; diff --git a/src/lmic_config.h b/src/lmic_config.h index 18b3c6b3..fb3a5816 100644 --- a/src/lmic_config.h +++ b/src/lmic_config.h @@ -28,14 +28,14 @@ // so consuming more power. You may sharpen (reduce) this value if you are // limited on battery. // ATTN: VALUES > 7 WILL CAUSE RECEPTION AND JOIN PROBLEMS WITH HIGH SF RATES -//#define CLOCK_ERROR_PROCENTAGE 5 +#define CLOCK_ERROR_PROCENTAGE 5 // Set this to 1 to enable some basic debug output (using printf) about // RF settings used during transmission and reception. Set to 2 to // enable more verbose output. Make sure that printf is actually // configured (e.g. on AVR it is not by default), otherwise using it can // cause crashing. -//#define LMIC_DEBUG_LEVEL 1 +//#define LMIC_DEBUG_LEVEL 2 // Enable this to allow using printf() to print to the given serial port // (or any other Print object). This can be easy for debugging. The @@ -57,8 +57,7 @@ // Uncomment this to disable all code related to ping #define DISABLE_PING // Uncomment this to disable all code related to beacon tracking. -// Requires ping to be disabled too -#define DISABLE_BEACONS +// Requires ping to be disabled too#define DISABLE_BEACONS // Uncomment these to disable the corresponding MAC commands. // Class A @@ -88,7 +87,7 @@ // implementation is optimized for speed on 32-bit processors using // fairly big lookup tables, but it takes up big amounts of flash on the // AVR architecture. -//#define USE_ORIGINAL_AES +#define USE_ORIGINAL_AES // // This selects the AES implementation written by Ideetroon for their // own LoRaWAN library. It also uses lookup tables, but smaller diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 7e47ab0e..5f89c787 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -18,6 +18,10 @@ static const char TAG[] = "lora"; #endif #endif +RTC_DATA_ATTR u4_t RTCnetid, RTCdevaddr; +RTC_DATA_ATTR u1_t RTCnwkKey[16], RTCartKey[16]; +RTC_DATA_ATTR int RTCseqnoUp, RTCseqnoDn; + QueueHandle_t LoraSendQueue; TaskHandle_t lmicTask = NULL, lorasendTask = NULL; @@ -73,10 +77,6 @@ static const lmic_pinmap myPinmap = { .spi_freq = 8000000, // 8MHz .pConfig = &myHalConfig}; -RTC_DATA_ATTR u4_t RTCnetid, RTCdevaddr; -RTC_DATA_ATTR u1_t RTCnwkKey[16], RTCartKey[16]; -RTC_DATA_ATTR int RTCseqnoUp, RTCseqnoDn; - void lora_setupForNetwork(bool preJoin) { if (preJoin) { @@ -311,7 +311,7 @@ esp_err_t lora_stack_init(bool joined) { "lmictask", // name of task 4096, // stack size of task (void *)1, // parameter of the task - 5, // priority of the task + 2, // priority of the task &lmicTask, // task handle 1); // CPU core @@ -325,7 +325,7 @@ esp_err_t lora_stack_init(bool joined) { LMIC.seqnoUp = RTCseqnoUp; LMIC.seqnoDn = RTCseqnoDn; lora_setupForNetwork(true); - } + } // start lmic send task xTaskCreatePinnedToCore(lora_send, // task function @@ -373,8 +373,8 @@ void lora_enqueuedata(MessageBuffer_t *message) { void lora_queuereset(void) { xQueueReset(LoraSendQueue); } #if (TIME_SYNC_LORAWAN) -void IRAM_ATTR user_request_network_time_callback(void *pVoidUserUTCTime, - int flagSuccess) { +static void IRAM_ATTR user_request_network_time_callback(void *pVoidUserUTCTime, + int flagSuccess) { // Explicit conversion from void* to uint32_t* to avoid compiler errors time_t *pUserUTCTime = (time_t *)pVoidUserUTCTime; @@ -444,7 +444,7 @@ void lmictask(void *pvParameters) { // so consuming more power. You may sharpen (reduce) CLOCK_ERROR_PERCENTAGE // in src/lmic_config.h if you are limited on battery. #ifdef CLOCK_ERROR_PROCENTAGE - LMIC_setClockError(CLOCK_ERROR_PROCENTAGE * MAX_CLOCK_ERROR / 100); + LMIC_setClockError(CLOCK_ERROR_PROCENTAGE * MAX_CLOCK_ERROR / 1000); #endif while (1) { @@ -454,7 +454,7 @@ void lmictask(void *pvParameters) { } // lmictask // lmic event handler -void myEventCallback(void *pUserData, ev_t ev) { +static void myEventCallback(void *pUserData, ev_t ev) { // using message descriptors from LMIC library static const char *const evNames[] = {LMIC_EVENT_NAME_TABLE__INIT}; @@ -498,8 +498,8 @@ void myEventCallback(void *pUserData, ev_t ev) { } // receive message handler -void myRxCallback(void *pUserData, uint8_t port, const uint8_t *pMsg, - size_t nMsg) { +static void myRxCallback(void *pUserData, uint8_t port, + const uint8_t *pMsg, size_t nMsg) { // display type of received data if (nMsg) @@ -553,7 +553,7 @@ void myRxCallback(void *pUserData, uint8_t port, const uint8_t *pMsg, } // transmit complete message handler -void myTxCallback(void *pUserData, int fSuccess) { +static void myTxCallback(void *pUserData, int fSuccess) { #if (TIME_SYNC_LORASERVER) // if last packet sent was a timesync request, store TX timestamp diff --git a/src/main.cpp b/src/main.cpp index d366a762..86dc8279 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -175,6 +175,8 @@ void setup() { #if (HAS_GPS) ESP_LOGI(TAG, "TinyGPS+ version %s", TinyGPSPlus::libraryVersion()); #endif + +#endif // VERBOSE } // open i2c bus @@ -191,8 +193,6 @@ void setup() { strcat_P(features, " PMU"); #endif -#endif // verbose - // read (and initialize on first run) runtime settings from NVRAM loadConfig(); // includes initialize if necessary @@ -200,7 +200,8 @@ void setup() { #ifdef HAS_DISPLAY strcat_P(features, " OLED"); DisplayIsOn = cfg.screenon; - init_display(RTC_runmode == RUNMODE_NORMAL); // note: blocking call + init_display(RTC_runmode == RUNMODE_NORMAL ? true + : false); // note: blocking call #endif // scan i2c bus for devices @@ -285,11 +286,11 @@ void setup() { } else btStop(); #else - // remove bluetooth stack to gain more free memory - btStop(); - ESP_ERROR_CHECK(esp_bt_mem_release(ESP_BT_MODE_BTDM)); - ESP_ERROR_CHECK(esp_coex_preference_set( - ESP_COEX_PREFER_WIFI)); // configure Wifi/BT coexist lib + // remove bluetooth stack to gain more free memory + btStop(); + ESP_ERROR_CHECK(esp_bt_mem_release(ESP_BT_MODE_BTDM)); + ESP_ERROR_CHECK(esp_coex_preference_set( + ESP_COEX_PREFER_WIFI)); // configure Wifi/BT coexist lib #endif // initialize gps @@ -316,7 +317,8 @@ void setup() { // initialize LoRa #if (HAS_LORA) strcat_P(features, " LORA"); - assert(lora_stack_init(RTC_runmode == RUNMODE_WAKEUP) == ESP_OK); + assert(lora_stack_init(RTC_runmode == RUNMODE_WAKEUP ? true : false) == + ESP_OK); #endif // initialize SPI @@ -340,11 +342,11 @@ void setup() { #if PAYLOAD_ENCODER == 1 strcat_P(features, " PLAIN"); #elif PAYLOAD_ENCODER == 2 - strcat_P(features, " PACKED"); + strcat_P(features, " PACKED"); #elif PAYLOAD_ENCODER == 3 - strcat_P(features, " LPPDYN"); + strcat_P(features, " LPPDYN"); #elif PAYLOAD_ENCODER == 4 - strcat_P(features, " LPPPKD"); + strcat_P(features, " LPPPKD"); #endif // initialize RTC @@ -371,10 +373,10 @@ void setup() { // function gets it's seed from RF noise get_salt(); // get new 16bit for salting hashes #else - // switch off wifi - WiFi.mode(WIFI_OFF); - esp_wifi_stop(); - esp_wifi_deinit(); + // switch off wifi + WiFi.mode(WIFI_OFF); + esp_wifi_stop(); + esp_wifi_deinit(); #endif // start state machine diff --git a/src/ota.cpp b/src/ota.cpp index f27b4a8c..e904cdcf 100644 --- a/src/ota.cpp +++ b/src/ota.cpp @@ -320,7 +320,7 @@ void ota_display(const uint8_t row, const std::string status, } // callback function to show download progress while streaming data -void show_progress(unsigned long current, unsigned long size) { +static void show_progress(unsigned long current, unsigned long size) { #ifdef HAS_DISPLAY char buf[17]; snprintf(buf, 17, "%-9lu (%3lu%%)", current, current * 100 / size); diff --git a/src/paxcounter.conf b/src/paxcounter.conf index c29d5d77..ed47257c 100644 --- a/src/paxcounter.conf +++ b/src/paxcounter.conf @@ -7,7 +7,7 @@ // Note: After editing, before "build", use "clean" button in PlatformIO! // Verbose enables serial output -#define VERBOSE 1 // set to 0 to silence the device, for mute use build option +#define VERBOSE 0 // set to 0 to silence the device, for mute use build option // Payload send cycle and encoding #define SENDCYCLE 30 // payload send cycle [seconds/2], 0 .. 255 @@ -75,7 +75,7 @@ #define TIME_SYNC_INTERVAL_RETRY 10 // retry time sync after lost sync each .. minutes [default = 10], 0 means off #define TIME_SYNC_COMPILEDATE 0 // set to 1 to use compile date to initialize RTC after power outage [default = 0] #define TIME_SYNC_LORAWAN 0 // set to 1 to use LORA network as time source, 0 means off [default = 0] -#define TIME_SYNC_LORASERVER 0 // set to 1 to use LORA timeserver as time source, 0 means off [default = 0] +#define TIME_SYNC_LORASERVER 1 // set to 1 to use LORA timeserver as time source, 0 means off [default = 0] // settings for syncing time with timeserver applications #define TIME_SYNC_SAMPLES 1 // number of time requests for averaging diff --git a/src/power.cpp b/src/power.cpp index 73b3991f..ce025e7f 100644 --- a/src/power.cpp +++ b/src/power.cpp @@ -5,7 +5,7 @@ // Local logging tag static const char TAG[] = __FILE__; -RTC_DATA_ATTR struct timeval sleep_enter_time; +RTC_DATA_ATTR int64_t sleep_enter_time; RTC_DATA_ATTR runmode_t RTC_runmode = RUNMODE_NORMAL; #ifdef HAS_PMU @@ -61,8 +61,8 @@ void AXP192_power(bool on) { pmu.setPowerOutPut(AXP192_LDO2, AXP202_ON); // Lora on T-Beam V1.0 pmu.setPowerOutPut(AXP192_LDO3, AXP202_ON); // Gps on T-Beam V1.0 pmu.setPowerOutPut(AXP192_DCDC1, AXP202_ON); // OLED on T-Beam v1.0 - // pmu.setChgLEDMode(AXP20X_LED_LOW_LEVEL); - pmu.setChgLEDMode(AXP20X_LED_BLINK_1HZ); + pmu.setChgLEDMode(AXP20X_LED_LOW_LEVEL); + // pmu.setChgLEDMode(AXP20X_LED_BLINK_1HZ); } else { pmu.setChgLEDMode(AXP20X_LED_OFF); // we don't cut off power of display, because then display blocks i2c bus @@ -196,6 +196,9 @@ void enter_deepsleep(const int wakeup_sec, const gpio_num_t wakeup_gpio) { if ((!wakeup_sec) && (!wakeup_gpio) && (RTC_runmode == RUNMODE_NORMAL)) return; + // set up power domains + esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_ON); + // set wakeup timer if (wakeup_sec) esp_sleep_enable_timer_wakeup(wakeup_sec * 1000000); @@ -211,7 +214,7 @@ void enter_deepsleep(const int wakeup_sec, const gpio_num_t wakeup_gpio) { RTCseqnoDn = LMIC.seqnoDn; // store sleep enter time - gettimeofday(&sleep_enter_time, NULL); + sleep_enter_time = esp_timer_get_time(); // halt interrupts accessing i2c bus mask_user_IRQ(); @@ -238,12 +241,9 @@ void enter_deepsleep(const int wakeup_sec, const gpio_num_t wakeup_gpio) { esp_deep_sleep_start(); } -int exit_deepsleep(void) { +int64_t exit_deepsleep(void) { - struct timeval now; - gettimeofday(&now, NULL); - int sleep_time_ms = (now.tv_sec - sleep_enter_time.tv_sec) * 1000 + - (now.tv_usec - sleep_enter_time.tv_usec) / 1000; + int64_t sleep_time_ms = (esp_timer_get_time() - sleep_enter_time) / 1000; // switch on power if has PMU #ifdef HAS_PMU diff --git a/src/wifiscan.cpp b/src/wifiscan.cpp index b22fe5f2..d24116fc 100644 --- a/src/wifiscan.cpp +++ b/src/wifiscan.cpp @@ -29,7 +29,7 @@ typedef struct { } wifi_ieee80211_packet_t; // using IRAM_:ATTR here to speed up callback function -IRAM_ATTR void wifi_sniffer_packet_handler(void *buff, +static IRAM_ATTR void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type) { const wifi_promiscuous_pkt_t *ppkt = (wifi_promiscuous_pkt_t *)buff;