power save, sdkconfig.defaults

This commit is contained in:
Bob 2025-11-22 12:33:22 -08:00
parent e825cd54b0
commit d173b95966
5 changed files with 141 additions and 33 deletions

View File

@ -45,7 +45,7 @@ static esp_err_t nvs_set_str2(nvs_handle_t h, const char *key, const char *val){
return val ? nvs_set_str(h, key, val) : nvs_erase_key(h, key);
}
static void save_cfg(const char* ssid, const char* pass, const char* ip, const char* mask, const char* gw, bool dhcp, const char* band, const char* bw){
static void save_cfg(const char* ssid, const char* pass, const char* ip, const char* mask, const char* gw, bool dhcp, const char* band, const char* bw, const char* powersave){
nvs_handle_t h;
if (nvs_open("netcfg", NVS_READWRITE, &h) != ESP_OK) return;
if (ssid) nvs_set_str2(h, "ssid", ssid);
@ -55,16 +55,17 @@ static void save_cfg(const char* ssid, const char* pass, const char* ip, const c
if (gw) nvs_set_str2(h, "gw", gw);
if (band) nvs_set_str2(h, "band", band);
if (bw) nvs_set_str2(h, "bw", bw);
if (powersave) nvs_set_str2(h, "powersave", powersave);
nvs_set_u8(h, "dhcp", dhcp ? 1 : 0);
nvs_commit(h);
nvs_close(h);
cfg_dhcp = dhcp;
ESP_LOGI(TAG, "Config saved to NVS: SSID=%s Band=%s BW=%s", ssid?ssid:"", band?band:"", bw?bw:"");
ESP_LOGI(TAG, "Config saved to NVS: SSID=%s Band=%s BW=%s PowerSave=%s", ssid?ssid:"", band?band:"", bw?bw:"", powersave?powersave:"NONE");
}
static bool load_cfg(char* ssid, size_t ssz, char* pass, size_t psz,
char* ip, size_t isz, char* mask, size_t msz, char* gw, size_t gsz,
char* band, size_t bsz, char* bw, size_t bwsz, bool* dhcp){
char* band, size_t bsz, char* bw, size_t bwsz, char* powersave, size_t pssz, bool* dhcp){
nvs_handle_t h;
if (nvs_open("netcfg", NVS_READONLY, &h) != ESP_OK) return false;
size_t len;
@ -78,6 +79,7 @@ static bool load_cfg(char* ssid, size_t ssz, char* pass, size_t psz,
len = gsz; e = nvs_get_str(h, "gw", gw, &len); if (e!=ESP_OK) gw[0]=0;
len = bsz; e = nvs_get_str(h, "band", band, &len); if (e!=ESP_OK) strcpy(band, "2.4G");
len = bwsz; e = nvs_get_str(h, "bw", bw, &len); if (e!=ESP_OK) strcpy(bw, "HT20");
len = pssz; e = nvs_get_str(h, "powersave", powersave, &len); if (e!=ESP_OK) strcpy(powersave, "NONE");
uint8_t d=1; nvs_get_u8(h, "dhcp", &d); *dhcp = (d!=0);
nvs_close(h);
return true;
@ -142,10 +144,10 @@ static void apply_ip_static(const char* ip, const char* mask, const char* gw){
bool wifi_cfg_apply_from_nvs(void) {
char ssid[64]={0}, pass[64]={0}, ip[32]={0}, mask[32]={0}, gw[32]={0};
char band[16]={0}, bw[16]={0};
char band[16]={0}, bw[16]={0}, powersave[16]={0};
bool dhcp = true;
if (!load_cfg(ssid,sizeof(ssid), pass,sizeof(pass), ip,sizeof(ip), mask,sizeof(mask), gw,sizeof(gw),
band,sizeof(band), bw,sizeof(bw), &dhcp)){
band,sizeof(band), bw,sizeof(bw), powersave,sizeof(powersave), &dhcp)){
ESP_LOGW(TAG, "No WiFi config in NVS");
return false;
}
@ -154,10 +156,11 @@ bool wifi_cfg_apply_from_nvs(void) {
ESP_LOGW(TAG, "SSID in NVS is empty; treating as no Wi-Fi config");
return false;
}
ESP_LOGI(TAG, "Applying Wi-Fi config: SSID=%s DHCP=%d IP=%s Band=%s BW=%s",
ssid, dhcp, ip, band, bw);
ESP_LOGI(TAG, "Applying Wi-Fi config: SSID=%s DHCP=%d IP=%s Band=%s BW=%s PowerSave=%s",
ssid, dhcp, ip, band, bw, powersave);
ESP_LOGI(TAG, "Applying WiFi config: SSID=%s DHCP=%d IP=%s Band=%s BW=%s", ssid, dhcp, ip, band, bw);
ESP_LOGI(TAG, "Applying WiFi config: SSID=%s DHCP=%d IP=%s Band=%s BW=%s PowerSave=%s",
ssid, dhcp, ip, band, bw, powersave);
static bool inited = false;
if (!inited){
@ -297,7 +300,7 @@ typedef struct {
bool (*fetch_line)(char *buf, size_t sz, void *ctx);
} cfg_io_t;
static void on_cfg_line(const char *line, char *ssid, char *pass, char *ip, char *mask, char *gw, char *band, char *bw, bool *dhcp){
static void on_cfg_line(const char *line, char *ssid, char *pass, char *ip, char *mask, char *gw, char *band, char *bw, char *powersave, bool *dhcp){
if (strncmp(line, "SSID:",5)==0){ strncpy(ssid, line+5, 63); ssid[63]=0; return; }
if (strncmp(line, "PASS:",5)==0){ strncpy(pass, line+5, 63); pass[63]=0; return; }
if (strncmp(line, "IP:",3)==0){ strncpy(ip, line+3, 31); ip[31]=0; return; }
@ -305,13 +308,14 @@ static void on_cfg_line(const char *line, char *ssid, char *pass, char *ip, char
if (strncmp(line, "GW:",3)==0){ strncpy(gw, line+3, 31); gw[31]=0; return; }
if (strncmp(line, "BAND:",5)==0){ strncpy(band, line+5, 15); band[15]=0; return; }
if (strncmp(line, "BW:",3)==0){ strncpy(bw, line+3, 15); bw[15]=0; return; }
if (strncmp(line, "POWERSAVE:",10)==0){ strncpy(powersave, line+10, 15); powersave[15]=0; return; }
if (strncmp(line, "DHCP:",5)==0){ *dhcp = atoi(line+5) ? true:false; return; }
}
static void cfg_worker(const cfg_io_t *io){
char line[160];
char ssid[64]={0}, pass[64]={0}, ip[32]={0}, mask[32]={0}, gw[32]={0};
char band[16]={0}, bw[16]={0};
char band[16]={0}, bw[16]={0}, powersave[16]={0};
bool dhcp = true;
bool in_cfg = false;
@ -325,7 +329,7 @@ static void cfg_worker(const cfg_io_t *io){
if (strcmp(line, "CFG")==0){
in_cfg = true;
ssid[0]=pass[0]=ip[0]=mask[0]=gw[0]=0;
band[0]=bw[0]=0;
band[0]=bw[0]=powersave[0]=0;
dhcp = true;
}
continue;
@ -334,14 +338,15 @@ static void cfg_worker(const cfg_io_t *io){
// Set defaults if not specified
if (!band[0]) strcpy(band, "2.4G");
if (!bw[0]) strcpy(bw, "HT20");
if (!powersave[0]) strcpy(powersave, "NONE");
save_cfg(ssid, pass, ip, mask, gw, dhcp, band, bw);
save_cfg(ssid, pass, ip, mask, gw, dhcp, band, bw, powersave);
if (io->emit) io->emit("OK\n", io->ctx);
wifi_cfg_apply_from_nvs();
in_cfg = false;
continue;
}
on_cfg_line(line, ssid, pass, ip, mask, gw, band, bw, &dhcp);
on_cfg_line(line, ssid, pass, ip, mask, gw, band, bw, powersave, &dhcp);
}
}
@ -413,3 +418,34 @@ void wifi_cfg_init(void){
xTaskCreatePinnedToCore(cfg_listener_usb_task, "cfg_usb",
6144, NULL, 5, NULL, tskNO_AFFINITY);
}
wifi_ps_type_t wifi_cfg_get_power_save_mode(void) {
char powersave[16] = {0};
nvs_handle_t h;
if (nvs_open("netcfg", NVS_READONLY, &h) != ESP_OK) {
ESP_LOGW(TAG, "Failed to open NVS for power save - defaulting to NONE");
return WIFI_PS_NONE;
}
size_t len = sizeof(powersave);
esp_err_t err = nvs_get_str(h, "powersave", powersave, &len);
nvs_close(h);
if (err != ESP_OK) {
ESP_LOGI(TAG, "No power save setting in NVS - defaulting to NONE");
return WIFI_PS_NONE;
}
// Parse the power save string
if (strcmp(powersave, "MIN") == 0 || strcmp(powersave, "MIN_MODEM") == 0) {
ESP_LOGI(TAG, "Power save mode: MIN_MODEM");
return WIFI_PS_MIN_MODEM;
} else if (strcmp(powersave, "MAX") == 0 || strcmp(powersave, "MAX_MODEM") == 0) {
ESP_LOGI(TAG, "Power save mode: MAX_MODEM");
return WIFI_PS_MAX_MODEM;
} else {
ESP_LOGI(TAG, "Power save mode: NONE (no power saving)");
return WIFI_PS_NONE;
}
}

View File

@ -1,15 +1,51 @@
#ifndef WIFI_CFG_H
#define WIFI_CFG_H
#include "esp_wifi.h"
#include <stdbool.h>
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
/**
* @brief Initialize the WiFi configuration system
*
* Spawns listener tasks for both UART and USB-Serial/JTAG interfaces
* to receive configuration commands.
*/
void wifi_cfg_init(void);
void wifi_cfg_init(void); // starts serial listener task
bool wifi_cfg_apply_from_nvs(void); // reads saved config and connects WiFi
void wifi_cfg_force_dhcp(bool enable); // for testing
/**
* @brief Apply WiFi configuration from NVS
*
* @return true if configuration was found and applied, false otherwise
*/
bool wifi_cfg_apply_from_nvs(void);
/**
* @brief Force DHCP mode enable/disable
*
* @param enable true to enable DHCP, false to disable
*/
void wifi_cfg_force_dhcp(bool enable);
/**
* @brief Get the configured power save mode from NVS
*
* @return wifi_ps_type_t Power save mode (WIFI_PS_NONE, WIFI_PS_MIN_MODEM, or WIFI_PS_MAX_MODEM)
*/
wifi_ps_type_t wifi_cfg_get_power_save_mode(void);
/**
* @brief Ensure WiFi driver is initialized (thread-safe, idempotent)
*
* @return ESP_OK on success, error code otherwise
*/
esp_err_t wifi_ensure_inited(void);
#ifdef __cplusplus
}
#endif
#endif // WIFI_CFG_H

View File

@ -15,22 +15,23 @@ def log_verbose(message, verbose=False):
def config_device(port, ip, ssid="ClubHouse2G", password="ez2remember",
gateway="192.168.1.1", netmask="255.255.255.0",
band="2.4G", bandwidth="HT20", reboot=True, verbose=False):
band="2.4G", bandwidth="HT20", powersave="NONE", reboot=True, verbose=False):
"""Configure ESP32 device via serial"""
print(f"\n{'='*70}")
print(f"ESP32 WiFi Configuration")
print(f"{'='*70}")
print(f"Port: {port}")
print(f"SSID: {ssid}")
print(f"Password: {'*' * len(password)}")
print(f"IP: {ip}")
print(f"Gateway: {gateway}")
print(f"Netmask: {netmask}")
print(f"Band: {band}")
print(f"Bandwidth: {bandwidth}")
print(f"Reboot: {'Yes' if reboot else 'No'}")
print(f"Verbose: {verbose}")
print(f"Port: {port}")
print(f"SSID: {ssid}")
print(f"Password: {'*' * len(password)}")
print(f"IP: {ip}")
print(f"Gateway: {gateway}")
print(f"Netmask: {netmask}")
print(f"Band: {band}")
print(f"Bandwidth: {bandwidth}")
print(f"PowerSave: {powersave}")
print(f"Reboot: {'Yes' if reboot else 'No'}")
print(f"Verbose: {verbose}")
print(f"{'='*70}\n")
try:
@ -59,6 +60,7 @@ def config_device(port, ip, ssid="ClubHouse2G", password="ez2remember",
"DHCP:0",
f"BAND:{band}",
f"BW:{bandwidth}",
f"POWERSAVE:{powersave}",
"END"
]
@ -232,6 +234,7 @@ def config_device(port, ip, ssid="ClubHouse2G", password="ez2remember",
print(f"SSID: {ssid}")
print(f"Band: {band}")
print(f"Bandwidth: {bandwidth}")
print(f"PowerSave: {powersave}")
print(f"{'='*70}")
print("\nNext steps:")
print(f" 1. Check LED color:")
@ -280,6 +283,15 @@ Examples:
# 5GHz with HT40 bandwidth and auto-reboot
%(prog)s -p /dev/ttyUSB0 -i 192.168.1.81 -s ClubHouse5G -b 5G -B HT40
# Disable power save for best CSI quality (default)
%(prog)s -p /dev/ttyUSB0 -i 192.168.1.51 -ps NONE
# Enable minimum power save (useful for battery-powered devices)
%(prog)s -p /dev/ttyUSB0 -i 192.168.1.51 -ps MIN
# Enable maximum power save (lowest power consumption)
%(prog)s -p /dev/ttyUSB0 -i 192.168.1.51 -ps MAX
# Configure without rebooting (manual reboot required)
%(prog)s -p /dev/ttyUSB0 -i 192.168.1.51 -r
@ -311,6 +323,9 @@ Examples:
parser.add_argument('-B', '--bandwidth', default='HT20',
choices=['HT20', 'HT40'],
help='Channel bandwidth: HT20 or HT40 (default: HT20)')
parser.add_argument('-ps', '--powersave', default='NONE',
choices=['NONE', 'MIN', 'MIN_MODEM', 'MAX', 'MAX_MODEM'],
help='Power save mode: NONE (no PS, best for CSI), MIN/MIN_MODEM, MAX/MAX_MODEM (default: NONE)')
parser.add_argument('-r', '--no-reboot', action='store_true',
help='Do NOT reboot device after configuration (default: will reboot)')
parser.add_argument('-v', '--verbose', action='store_true',
@ -327,6 +342,7 @@ Examples:
netmask=args.netmask,
band=args.band,
bandwidth=args.bandwidth,
powersave=args.powersave,
reboot=not args.no_reboot, # Invert since flag is --no-reboot
verbose=args.verbose
)

View File

@ -151,12 +151,15 @@ static void wifi_enable_csi_once(void) {
ESP_LOGI("CSI", "Waiting 500ms for WiFi to stabilize...");
vTaskDelay(pdMS_TO_TICKS(500));
// Disable power save for CSI
err = esp_wifi_set_ps(WIFI_PS_NONE);
// Get power save mode from NVS configuration
wifi_ps_type_t ps_mode = wifi_cfg_get_power_save_mode();
err = esp_wifi_set_ps(ps_mode);
if (err != ESP_OK) {
ESP_LOGW("CSI", "Failed to disable power save: %s", esp_err_to_name(err));
ESP_LOGW("CSI", "Failed to set power save mode: %s", esp_err_to_name(err));
} else {
ESP_LOGI("CSI", "WiFi power save disabled");
const char *ps_str = (ps_mode == WIFI_PS_NONE) ? "NONE (disabled)" :
(ps_mode == WIFI_PS_MIN_MODEM) ? "MIN_MODEM" : "MAX_MODEM";
ESP_LOGI("CSI", "WiFi power save set to: %s", ps_str);
}
wifi_csi_config_t csi_cfg;

17
sdkconfig.defaults Normal file
View File

@ -0,0 +1,17 @@
# UART console @115200 on UART0
CONFIG_ESP_CONSOLE_UART_DEFAULT=y
CONFIG_ESP_CONSOLE_UART_NUM=0
CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200
# Logging: INFO by default (quiet enough but useful)
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
CONFIG_LOG_DEFAULT_LEVEL=3
# Make backtraces visible and reboot automatically on panic
CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y
# Give the main task a bit more room (iperf + console parsing)
CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192
# Slightly smaller binaries without hurting you
CONFIG_COMPILER_OPTIMIZATION_SIZE=y