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_NORMAL,
RUNMODE_WAKEUP,
RUNMODE_UPDATE
RUNMODE_UPDATE,
RUNMODE_SLEEP
};
// Struct holding devices's runtime configuration

View File

@ -23,6 +23,8 @@ typedef struct {
const bool store;
} cmd_t;
extern bool rcmd_busy;
void rcommand(const uint8_t cmd[], const uint8_t cmdlength);
void do_reset(bool warmstart);

View File

@ -254,8 +254,11 @@ void start_BLEscan(void) {
// Initialize BT controller to allocate task and other resource.
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_enable());
@ -269,10 +272,18 @@ void start_BLEscan(void) {
void stop_BLEscan(void) {
#if (BLECOUNTER)
ESP_LOGI(TAG, "Shutting down bluetooth scanner ...");
ESP_LOGD(TAG, "unregister GAP callback...");
ESP_ERROR_CHECK(esp_ble_gap_register_callback(NULL));
ESP_LOGD(TAG, "bluedroid disable...");
ESP_ERROR_CHECK(esp_bluedroid_disable());
ESP_LOGD(TAG, "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_LOGI(TAG, "Bluetooth scanner stopped");
#endif // BLECOUNTER

View File

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

View File

@ -292,7 +292,7 @@ void setup() {
macQueueInit();
// 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)
strcat_P(features, " BLE");
if (cfg.blescan) {
@ -412,16 +412,17 @@ void setup() {
#if (WIFICOUNTER)
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();
if (cfg.blescan) {
// start wifi sniffing, if enabled
if (cfg.wifiscan) {
ESP_LOGI(TAG, "Starting Wifi...");
switch_wifi_sniffer(1);
} else
switch_wifi_sniffer(0);
#else
// switch off wifi
// remove wifi driver from RAM, if option wifi not compiled
esp_wifi_deinit();
#endif

View File

@ -5,6 +5,9 @@
// Local logging tag
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
void set_reset(uint8_t val[]) {
switch (val[0]) {
@ -68,7 +71,8 @@ void set_wifichancycle(uint8_t val[]) {
xTimerStart(WifiChanTimer, (TickType_t)0);
xTimerChangePeriod(WifiChanTimer, pdMS_TO_TICKS(cfg.wifichancycle * 10),
100);
ESP_LOGI(TAG,
ESP_LOGI(
TAG,
"Remote command: set Wifi channel hopping interval to %.1f seconds",
cfg.wifichancycle / float(100));
} else {
@ -397,6 +401,7 @@ void rcommand(const uint8_t cmd[], const uint8_t cmdlength) {
uint8_t foundcmd[cmdlength], cursor = 0;
bool storeflag = false;
rcmd_busy = true;
while (cursor < cmdlength) {
@ -428,4 +433,7 @@ void rcommand(const uint8_t cmd[], const uint8_t cmdlength) {
if (storeflag)
saveConfig();
rcmd_busy = false;
} // 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;
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) {
if (warmstart) {
ESP_LOGI(TAG, "restarting device (warmstart), keeping runmode %s",
runmode[RTC_runmode]);
ESP_LOGI(TAG, "restarting device (warmstart)");
} else {
#if (HAS_LORA)
if (RTC_runmode == RUNMODE_NORMAL) {
@ -26,8 +25,7 @@ void do_reset(bool warmstart) {
}
#endif
RTC_runmode = RUNMODE_POWERCYCLE;
ESP_LOGI(TAG, "restarting device (coldstart), setting runmode %s",
runmode[RTC_runmode]);
ESP_LOGI(TAG, "restarting device (coldstart)");
}
esp_restart();
}
@ -78,41 +76,16 @@ void enter_deepsleep(const uint64_t wakeup_sec = 60,
if (!GPIO_IS_VALID_GPIO(wakeup_gpio))
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...");
RTC_runmode = RUNMODE_SLEEP;
// stop further enqueuing of senddata
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
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
ESP_LOGI(TAG, "Waiting until send queues are empty...");
for (i = 10; i > 0; i--) {
@ -136,11 +109,43 @@ void enter_deepsleep(const uint64_t wakeup_sec = 60,
}
if (i == 0)
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);
#endif // (HAS_LORA)
// switch off display
// set display to power save mode
#ifdef HAS_DISPLAY
dp_shutdown();
#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(true)); // now switch on monitor mode
// setup wifi channel rotation timer
// setup wifi channel hopping timer
WifiChanTimer =
xTimerCreate("WifiChannelTimer",
(cfg.wifichancycle > 0) ? pdMS_TO_TICKS(cfg.wifichancycle)
: pdMS_TO_TICKS(50),
pdTRUE, (void *)0, switchWifiChannel);
// start timer
if (cfg.wifichancycle > 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) {
if (state) {
// switch wifi sniffer on
ESP_ERROR_CHECK(esp_wifi_start());
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
esp_wifi_set_channel(WIFI_CHANNEL_MIN, WIFI_SECOND_CHAN_NONE);
esp_wifi_set_promiscuous(true);
} else {
// switch wifi sniffer off
macs_wifi = 0; // clear WIFI counter
if (xTimerIsTimerActive(WifiChanTimer) != pdFALSE)
xTimerStop(WifiChanTimer, (TickType_t)0);
esp_wifi_set_promiscuous(false);
ESP_ERROR_CHECK(esp_wifi_stop());
macs_wifi = 0; // clear WIFI counter
}
}