diff --git a/code/espurna/config/general.h b/code/espurna/config/general.h index 1ee6283f..01e4b269 100644 --- a/code/espurna/config/general.h +++ b/code/espurna/config/general.h @@ -582,7 +582,13 @@ #endif #ifndef WIFI_SLEEP_MODE -#define WIFI_SLEEP_MODE WIFI_NONE_SLEEP // WIFI_NONE_SLEEP, WIFI_LIGHT_SLEEP or WIFI_MODEM_SLEEP +#define WIFI_SLEEP_MODE WIFI_SLEEP_MODE_NONE // WIFI_SLEEP_MODE_NONE - disable all WiFi passive power saving modes (default) + // WIFI_SLEEP_MODE_MODEM - allow WiFi modem to periodially sleep, based on DTIM + // beacon interval time (usually between .1s and 1s) + // WIFI_SLEEP_MODE_LIGHT - in addition to the MODEM sleep also allow CPU to sleep + // between .5s and 3s (varies, depends on active timers) + // + // (ref. https://www.espressif.com/sites/default/files/9b-esp8266-low_power_solutions_en_0.pdf) #endif #ifndef WIFI_SCAN_NETWORKS diff --git a/code/espurna/config/types.h b/code/espurna/config/types.h index 58180131..8ead2eb5 100644 --- a/code/espurna/config/types.h +++ b/code/espurna/config/types.h @@ -426,3 +426,11 @@ #define SECURE_CLIENT_CHECK_NONE 0 // !!! INSECURE CONNECTION !!! #define SECURE_CLIENT_CHECK_FINGERPRINT 1 // legacy fingerprint validation #define SECURE_CLIENT_CHECK_CA 2 // set trust anchor from PROGMEM CA certificate + +//------------------------------------------------------------------------------ +// WiFi +//------------------------------------------------------------------------------ + +#define WIFI_SLEEP_MODE_NONE NONE_SLEEP_T +#define WIFI_SLEEP_MODE_MODEM MODEM_SLEEP_T +#define WIFI_SLEEP_MODE_LIGHT LIGHT_SLEEP_T diff --git a/code/espurna/wifi.cpp b/code/espurna/wifi.cpp index a19e601f..131a7175 100644 --- a/code/espurna/wifi.cpp +++ b/code/espurna/wifi.cpp @@ -53,13 +53,26 @@ using Mac = std::array; namespace { namespace build { +namespace compat { + +[[gnu::unused, gnu::deprecated("WIFI_MODEM_SLEEP_{NONE, MODEM, LIGHT} should be used instead, see config/general.h")]] +constexpr sleep_type_t arduino_sleep(WiFiSleepType type) { + return static_cast(type); +} + +[[gnu::unused]] +constexpr sleep_type_t arduino_sleep(sleep_type_t type) { + return type; +} + +} // namespace compat constexpr float txPower() { return WIFI_OUTPUT_POWER_DBM; } -constexpr WiFiSleepType_t sleep() { - return WIFI_SLEEP_MODE; +constexpr sleep_type_t sleep() { + return compat::arduino_sleep(WIFI_SLEEP_MODE); } } // namespace build @@ -89,10 +102,10 @@ PROGMEM_STRING(None, "none"); PROGMEM_STRING(Modem, "modem"); PROGMEM_STRING(Light, "light"); -static constexpr espurna::settings::options::Enumeration WiFiSleepTypeOptions[] PROGMEM { - {WIFI_NONE_SLEEP, None}, - {WIFI_MODEM_SLEEP, Modem}, - {WIFI_LIGHT_SLEEP, Light}, +static constexpr espurna::settings::options::Enumeration SleepTypeOptions[] PROGMEM { + {NONE_SLEEP_T, None}, + {MODEM_SLEEP_T, Modem}, + {LIGHT_SLEEP_T, Light}, }; } // namespace options @@ -125,12 +138,12 @@ String serialize(wifi::ApMode mode) { } template <> -WiFiSleepType_t convert(const String& value) { - return convert(wifi::settings::options::WiFiSleepTypeOptions, value, wifi::build::sleep()); +sleep_type_t convert(const String& value) { + return convert(wifi::settings::options::SleepTypeOptions, value, wifi::build::sleep()); } -String serialize(WiFiSleepType_t sleep) { - return serialize(wifi::settings::options::WiFiSleepTypeOptions, sleep); +String serialize(sleep_type_t sleep) { + return serialize(wifi::settings::options::SleepTypeOptions, sleep); } template <> @@ -261,6 +274,28 @@ ActionsQueue actions; } // namespace internal +void tx_power(float dbm) { + if (std::isinf(dbm) || std::isnan(dbm)) { + return; + } + + // system_phy_set_max_tpw() unit is .25dBm + constexpr auto Min = float{ 0.0f }; + constexpr auto Max = float{ 20.5f }; + dbm = std::clamp(dbm, Min, Max); + dbm *= 4.0f; + + system_phy_set_max_tpw(dbm); +} + +sleep_type_t sleep_type() { + return wifi_get_sleep_type(); +} + +bool sleep_type(sleep_type_t type) { + return wifi_set_sleep_type(type); +} + uint8_t opmode() { return wifi_get_opmode(); } @@ -428,6 +463,10 @@ String opmode(uint8_t mode) { return out.toString(); } +String sleep_type(sleep_type_t type) { + return espurna::settings::internal::serialize(type); +} + } // namespace debug namespace settings { @@ -439,11 +478,11 @@ PROGMEM_STRING(Sleep, "wifiSleep"); } // namespace keys float txPower() { - return getSetting(keys::TxPower, wifi::build::txPower()); + return getSetting(keys::TxPower, build::txPower()); } -WiFiSleepType_t sleep() { - return getSetting(keys::Sleep, wifi::build::sleep()); +sleep_type_t sleep() { + return getSetting(keys::Sleep, build::sleep()); } namespace query { @@ -2207,8 +2246,8 @@ void configure() { wifi::ap::configure(); wifi::sta::configure(); - WiFi.setSleepMode(wifi::settings::sleep()); - WiFi.setOutputPower(wifi::settings::txPower()); + sleep_type(settings::sleep()); + tx_power(settings::txPower()); } } // namespace settings @@ -2295,7 +2334,15 @@ void wifi(::terminal::CommandContext&& ctx) { } const auto mode = wifi::opmode(); - ctx.output.printf_P(PSTR("OPMODE: %s\n"), wifi::debug::opmode(mode).c_str()); + ctx.output.printf_P(PSTR("OPMODE: %s\n"), + debug::opmode(mode).c_str()); + + const auto sleep = wifi::sleep_type(); + if (sleep != NONE_SLEEP_T) { + ctx.output.printf_P(PSTR("SLEEP: %s\n"), + debug::sleep_type(sleep).c_str()); + } + if (mode & OpmodeAp) { auto current = wifi::ap::current();