deep sleep further development

This commit is contained in:
Klaus K Wilting 2020-12-11 16:34:17 +01:00
parent 7631a96cac
commit b32e91317f
8 changed files with 83 additions and 58 deletions

View File

@ -64,7 +64,8 @@ enum runmode_t {
RUNMODE_POWERCYCLE, RUNMODE_POWERCYCLE,
RUNMODE_NORMAL, RUNMODE_NORMAL,
RUNMODE_WAKEUP, RUNMODE_WAKEUP,
RUNMODE_UPDATE RUNMODE_UPDATE,
RUNMODE_SLEEP
}; };
// Struct holding devices's runtime configuration // Struct holding devices's runtime configuration

View File

@ -18,11 +18,13 @@
// table of remote commands and assigned functions // table of remote commands and assigned functions
typedef struct { typedef struct {
const uint8_t opcode; const uint8_t opcode;
void (*func)(uint8_t []); void (*func)(uint8_t[]);
const uint8_t params; const uint8_t params;
const bool store; const bool store;
} cmd_t; } cmd_t;
extern bool rcmd_busy;
void rcommand(const uint8_t cmd[], const uint8_t cmdlength); void rcommand(const uint8_t cmd[], const uint8_t cmdlength);
void do_reset(bool warmstart); void do_reset(bool warmstart);

View File

@ -254,8 +254,11 @@ void start_BLEscan(void) {
// Initialize BT controller to allocate task and other resource. // Initialize BT controller to allocate task and other resource.
ESP_ERROR_CHECK(esp_coex_preference_set(ESP_COEX_PREFER_BT)); ESP_ERROR_CHECK(esp_coex_preference_set(ESP_COEX_PREFER_BT));
if (!btStart()) { // enable bt_controller
ESP_LOGE(TAG, "Bluetooth controller start failed. Resetting device");
do_reset(true);
}
btStart();
ESP_ERROR_CHECK(esp_bluedroid_init()); ESP_ERROR_CHECK(esp_bluedroid_init());
ESP_ERROR_CHECK(esp_bluedroid_enable()); ESP_ERROR_CHECK(esp_bluedroid_enable());
@ -269,10 +272,18 @@ void start_BLEscan(void) {
void stop_BLEscan(void) { void stop_BLEscan(void) {
#if (BLECOUNTER) #if (BLECOUNTER)
ESP_LOGI(TAG, "Shutting down bluetooth scanner ..."); ESP_LOGI(TAG, "Shutting down bluetooth scanner ...");
ESP_LOGD(TAG, "unregister GAP callback...");
ESP_ERROR_CHECK(esp_ble_gap_register_callback(NULL)); ESP_ERROR_CHECK(esp_ble_gap_register_callback(NULL));
ESP_LOGD(TAG, "bluedroid disable...");
ESP_ERROR_CHECK(esp_bluedroid_disable()); ESP_ERROR_CHECK(esp_bluedroid_disable());
ESP_LOGD(TAG, "bluedroid deinit...");
ESP_ERROR_CHECK(esp_bluedroid_deinit()); ESP_ERROR_CHECK(esp_bluedroid_deinit());
btStop(); // disable bt_controller
if (!btStop()) { // disable bt_controller
ESP_LOGE(TAG, "Bluetooth controller stop failed. Resetting device");
do_reset(true);
}
ESP_ERROR_CHECK(esp_coex_preference_set(ESP_COEX_PREFER_WIFI)); ESP_ERROR_CHECK(esp_coex_preference_set(ESP_COEX_PREFER_WIFI));
ESP_LOGI(TAG, "Bluetooth scanner stopped"); ESP_LOGI(TAG, "Bluetooth scanner stopped");
#endif // BLECOUNTER #endif // BLECOUNTER

View File

@ -603,7 +603,6 @@ void dp_shutdown(void) {
if (!I2C_MUTEX_LOCK()) if (!I2C_MUTEX_LOCK())
ESP_LOGV(TAG, "[%0.3f] i2c mutex lock failed", _seconds()); ESP_LOGV(TAG, "[%0.3f] i2c mutex lock failed", _seconds());
else { else {
cfg.screenon = 0;
obdPower(&ssoled, false); obdPower(&ssoled, false);
delay(DISPLAYREFRESH_MS / 1000 * 1.1); delay(DISPLAYREFRESH_MS / 1000 * 1.1);
I2C_MUTEX_UNLOCK(); // release i2c bus access I2C_MUTEX_UNLOCK(); // release i2c bus access

View File

@ -292,7 +292,7 @@ void setup() {
macQueueInit(); macQueueInit();
// start BLE scan callback if BLE function is enabled in NVRAM configuration // start BLE scan callback if BLE function is enabled in NVRAM configuration
// or switch off bluetooth, if not compiled // or remove bluetooth stack from RAM, if option bluetooth is not compiled
#if (BLECOUNTER) #if (BLECOUNTER)
strcat_P(features, " BLE"); strcat_P(features, " BLE");
if (cfg.blescan) { if (cfg.blescan) {
@ -412,16 +412,17 @@ void setup() {
#if (WIFICOUNTER) #if (WIFICOUNTER)
strcat_P(features, " WIFI"); strcat_P(features, " WIFI");
// start wifi in monitor mode and start channel rotation timer // install wifi driver in RAM and start channel hopping
wifi_sniffer_init(); wifi_sniffer_init();
if (cfg.blescan) {
// start wifi sniffing, if enabled
if (cfg.wifiscan) {
ESP_LOGI(TAG, "Starting Wifi..."); ESP_LOGI(TAG, "Starting Wifi...");
switch_wifi_sniffer(1); switch_wifi_sniffer(1);
} else } else
switch_wifi_sniffer(0); switch_wifi_sniffer(0);
#else #else
// switch off wifi // remove wifi driver from RAM, if option wifi not compiled
esp_wifi_deinit(); esp_wifi_deinit();
#endif #endif

View File

@ -5,6 +5,9 @@
// Local logging tag // Local logging tag
static const char TAG[] = __FILE__; static const char TAG[] = __FILE__;
// global variable indicating if rcommand() is executing
bool rcmd_busy = false;
// set of functions that can be triggered by remote commands // set of functions that can be triggered by remote commands
void set_reset(uint8_t val[]) { void set_reset(uint8_t val[]) {
switch (val[0]) { switch (val[0]) {
@ -65,14 +68,15 @@ void set_wifichancycle(uint8_t val[]) {
// update Wifi channel rotation timer period // update Wifi channel rotation timer period
if (cfg.wifichancycle > 0) { if (cfg.wifichancycle > 0) {
if (xTimerIsTimerActive(WifiChanTimer) == pdFALSE) if (xTimerIsTimerActive(WifiChanTimer) == pdFALSE)
xTimerStart(WifiChanTimer, (TickType_t) 0); xTimerStart(WifiChanTimer, (TickType_t)0);
xTimerChangePeriod(WifiChanTimer, pdMS_TO_TICKS(cfg.wifichancycle * 10), xTimerChangePeriod(WifiChanTimer, pdMS_TO_TICKS(cfg.wifichancycle * 10),
100); 100);
ESP_LOGI(TAG, ESP_LOGI(
TAG,
"Remote command: set Wifi channel hopping interval to %.1f seconds", "Remote command: set Wifi channel hopping interval to %.1f seconds",
cfg.wifichancycle / float(100)); cfg.wifichancycle / float(100));
} else { } else {
xTimerStop(WifiChanTimer, (TickType_t) 0); xTimerStop(WifiChanTimer, (TickType_t)0);
esp_wifi_set_channel(WIFI_CHANNEL_MIN, WIFI_SECOND_CHAN_NONE); esp_wifi_set_channel(WIFI_CHANNEL_MIN, WIFI_SECOND_CHAN_NONE);
channel = WIFI_CHANNEL_MIN; channel = WIFI_CHANNEL_MIN;
ESP_LOGI(TAG, "Remote command: set Wifi channel hopping to off"); ESP_LOGI(TAG, "Remote command: set Wifi channel hopping to off");
@ -397,6 +401,7 @@ void rcommand(const uint8_t cmd[], const uint8_t cmdlength) {
uint8_t foundcmd[cmdlength], cursor = 0; uint8_t foundcmd[cmdlength], cursor = 0;
bool storeflag = false; bool storeflag = false;
rcmd_busy = true;
while (cursor < cmdlength) { while (cursor < cmdlength) {
@ -428,4 +433,7 @@ void rcommand(const uint8_t cmd[], const uint8_t cmdlength) {
if (storeflag) if (storeflag)
saveConfig(); saveConfig();
rcmd_busy = false;
} // rcommand() } // rcommand()

View File

@ -13,12 +13,11 @@ RTC_DATA_ATTR runmode_t RTC_runmode = RUNMODE_POWERCYCLE;
RTC_DATA_ATTR struct timeval RTC_sleep_start_time; RTC_DATA_ATTR struct timeval RTC_sleep_start_time;
timeval sleep_stop_time; timeval sleep_stop_time;
const char *runmode[4] = {"powercycle", "normal", "wakeup", "update"}; const char *runmode[5] = {"powercycle", "normal", "wakeup", "update", "sleep"};
void do_reset(bool warmstart) { void do_reset(bool warmstart) {
if (warmstart) { if (warmstart) {
ESP_LOGI(TAG, "restarting device (warmstart), keeping runmode %s", ESP_LOGI(TAG, "restarting device (warmstart)");
runmode[RTC_runmode]);
} else { } else {
#if (HAS_LORA) #if (HAS_LORA)
if (RTC_runmode == RUNMODE_NORMAL) { if (RTC_runmode == RUNMODE_NORMAL) {
@ -26,8 +25,7 @@ void do_reset(bool warmstart) {
} }
#endif #endif
RTC_runmode = RUNMODE_POWERCYCLE; RTC_runmode = RUNMODE_POWERCYCLE;
ESP_LOGI(TAG, "restarting device (coldstart), setting runmode %s", ESP_LOGI(TAG, "restarting device (coldstart)");
runmode[RTC_runmode]);
} }
esp_restart(); esp_restart();
} }
@ -78,41 +76,16 @@ void enter_deepsleep(const uint64_t wakeup_sec = 60,
if (!GPIO_IS_VALID_GPIO(wakeup_gpio)) if (!GPIO_IS_VALID_GPIO(wakeup_gpio))
wakeup_gpio = GPIO_NUM_MAX; wakeup_gpio = GPIO_NUM_MAX;
// ensure we are in normal runmode, not udpate or wakeup
if ((RTC_runmode != RUNMODE_NORMAL)
#if (HAS_LORA)
|| (LMIC.opmode & (OP_JOINING | OP_REJOIN))
#endif
)
return;
ESP_LOGI(TAG, "Preparing to sleep..."); ESP_LOGI(TAG, "Preparing to sleep...");
RTC_runmode = RUNMODE_SLEEP;
// stop further enqueuing of senddata // stop further enqueuing of senddata
sendTimer.detach(); sendTimer.detach();
// shutdown MQTT safely
#ifdef HAS_MQTT
// to come
#endif
// shutdown SPI safely
#ifdef HAS_SPI
// to come
#endif
// halt interrupts accessing i2c bus // halt interrupts accessing i2c bus
mask_user_IRQ(); mask_user_IRQ();
// switch off radio
#if (BLECOUNTER)
stop_BLEscan();
btStop();
#endif
#if (WIFICOUNTER)
switch_wifi_sniffer(0);
#endif
// wait a while (max 100 sec) to clear send queues // wait a while (max 100 sec) to clear send queues
ESP_LOGI(TAG, "Waiting until send queues are empty..."); ESP_LOGI(TAG, "Waiting until send queues are empty...");
for (i = 10; i > 0; i--) { for (i = 10; i > 0; i--) {
@ -136,11 +109,43 @@ void enter_deepsleep(const uint64_t wakeup_sec = 60,
} }
if (i == 0) if (i == 0)
goto Error; goto Error;
#endif // (HAS_LORA)
// shutdown MQTT safely
#ifdef HAS_MQTT
// to come
#endif
// shutdown SPI safely
#ifdef HAS_SPI
// to come
#endif
// wait until rcommands are all done
for (i = 10; i > 0; i--) {
if (rcmd_busy)
vTaskDelay(pdMS_TO_TICKS(1000));
else
break;
}
if (i == 0)
goto Error;
// switch off radio
#if (WIFICOUNTER)
switch_wifi_sniffer(0);
#endif
#if (BLECOUNTER)
stop_BLEscan();
btStop();
#endif
// save LMIC state to RTC RAM
#if (HAS_LORA)
SaveLMICToRTC(wakeup_sec); SaveLMICToRTC(wakeup_sec);
#endif // (HAS_LORA) #endif // (HAS_LORA)
// switch off display // set display to power save mode
#ifdef HAS_DISPLAY #ifdef HAS_DISPLAY
dp_shutdown(); dp_shutdown();
#endif #endif

View File

@ -70,33 +70,31 @@ void wifi_sniffer_init(void) {
ESP_ERROR_CHECK(esp_wifi_set_promiscuous_rx_cb(&wifi_sniffer_packet_handler)); ESP_ERROR_CHECK(esp_wifi_set_promiscuous_rx_cb(&wifi_sniffer_packet_handler));
ESP_ERROR_CHECK(esp_wifi_set_promiscuous(true)); // now switch on monitor mode ESP_ERROR_CHECK(esp_wifi_set_promiscuous(true)); // now switch on monitor mode
// setup wifi channel rotation timer // setup wifi channel hopping timer
WifiChanTimer = WifiChanTimer =
xTimerCreate("WifiChannelTimer", xTimerCreate("WifiChannelTimer",
(cfg.wifichancycle > 0) ? pdMS_TO_TICKS(cfg.wifichancycle) (cfg.wifichancycle > 0) ? pdMS_TO_TICKS(cfg.wifichancycle)
: pdMS_TO_TICKS(50), : pdMS_TO_TICKS(50),
pdTRUE, (void *)0, switchWifiChannel); pdTRUE, (void *)0, switchWifiChannel);
// start timer
if (cfg.wifichancycle > 0) if (cfg.wifichancycle > 0)
xTimerStart(WifiChanTimer, (TickType_t) 0); xTimerStart(WifiChanTimer, (TickType_t)0);
else
esp_wifi_set_channel(WIFI_CHANNEL_MIN, WIFI_SECOND_CHAN_NONE);
} }
void switch_wifi_sniffer(uint8_t state) { void switch_wifi_sniffer(uint8_t state) {
if (state) { if (state) {
// switch wifi sniffer on // switch wifi sniffer on
ESP_ERROR_CHECK(esp_wifi_start()); ESP_ERROR_CHECK(esp_wifi_start());
if (cfg.wifichancycle > 0)
xTimerStart(WifiChanTimer, (TickType_t) 0);
else
esp_wifi_set_channel(WIFI_CHANNEL_MIN, WIFI_SECOND_CHAN_NONE);
esp_wifi_set_promiscuous(true); esp_wifi_set_promiscuous(true);
esp_wifi_set_channel(WIFI_CHANNEL_MIN, WIFI_SECOND_CHAN_NONE);
if (cfg.wifichancycle > 0)
xTimerStart(WifiChanTimer, (TickType_t)0);
} else { } else {
// switch wifi sniffer off // switch wifi sniffer off
macs_wifi = 0; // clear WIFI counter
if (xTimerIsTimerActive(WifiChanTimer) != pdFALSE) if (xTimerIsTimerActive(WifiChanTimer) != pdFALSE)
xTimerStop(WifiChanTimer, (TickType_t) 0); xTimerStop(WifiChanTimer, (TickType_t)0);
esp_wifi_set_promiscuous(false); esp_wifi_set_promiscuous(false);
ESP_ERROR_CHECK(esp_wifi_stop()); ESP_ERROR_CHECK(esp_wifi_stop());
macs_wifi = 0; // clear WIFI counter
} }
} }