Skip to content

Commit 9921378

Browse files
committed
5GHz WiFi support for ESP32C5
1 parent aca454b commit 9921378

8 files changed

Lines changed: 307 additions & 20 deletions

File tree

components/cmd_router/cmd_router.c

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ static void register_set_oled_gpio(void);
9292
#if !CONFIG_ETH_UPLINK
9393
static void register_scan(void);
9494
#endif
95+
#if WIFI_HAS_5GHZ
96+
static void register_set_sta_band(void);
97+
#endif
9598
static void register_set_vpn(void);
9699
static void register_set_tz(void);
97100

@@ -298,6 +301,9 @@ void register_router(void)
298301
register_set_ap_channel();
299302
#endif
300303
register_set_hostname();
304+
#if WIFI_HAS_5GHZ
305+
register_set_sta_band();
306+
#endif
301307
#if defined(CONFIG_IDF_TARGET_ESP32C6)
302308
register_set_rf_switch();
303309
#endif
@@ -1244,7 +1250,14 @@ static int show(int argc, char **argv)
12441250
if (ap_connect) {
12451251
wifi_ap_record_t ap_info;
12461252
if (esp_wifi_sta_get_ap_info(&ap_info) == ESP_OK) {
1247-
printf("Uplink AP: connected (%d dBm)\n", ap_info.rssi);
1253+
#if WIFI_HAS_5GHZ
1254+
printf("Uplink AP: connected (ch %d, %s, %d dBm)\n",
1255+
ap_info.primary,
1256+
ap_info.primary > 14 ? "5 GHz" : "2.4 GHz",
1257+
ap_info.rssi);
1258+
#else
1259+
printf("Uplink AP: connected (ch %d, %d dBm)\n", ap_info.primary, ap_info.rssi);
1260+
#endif
12481261
} else {
12491262
printf("Uplink AP: connected\n");
12501263
}
@@ -1360,6 +1373,14 @@ static int show(int argc, char **argv)
13601373
printf(" Enterprise: <not active>\n");
13611374
}
13621375

1376+
1377+
#if WIFI_HAS_5GHZ
1378+
{
1379+
const char *band_names[] = {"auto", "2.4 GHz", "5 GHz"};
1380+
printf(" Band preference: %s\n", band_names[sta_band <= STA_BAND_5G ? sta_band : 0]);
1381+
}
1382+
#endif
1383+
13631384
if (ssid != NULL) free(ssid);
13641385
if (ent_username != NULL) free(ent_username);
13651386
if (ent_identity != NULL) free(ent_identity);
@@ -2248,6 +2269,52 @@ static void register_set_ap_channel(void)
22482269
}
22492270
#endif
22502271

2272+
#if WIFI_HAS_5GHZ
2273+
/* 'set_sta_band' command - set STA band preference (5 GHz capable targets) */
2274+
static int set_sta_band_cmd(int argc, char **argv)
2275+
{
2276+
if (argc < 2) {
2277+
const char *names[] = {"auto", "2.4 GHz", "5 GHz"};
2278+
printf("STA band preference: %s\n", names[sta_band <= STA_BAND_5G ? sta_band : 0]);
2279+
return 0;
2280+
}
2281+
2282+
int band_val;
2283+
if (strcmp(argv[1], "auto") == 0 || strcmp(argv[1], "0") == 0) {
2284+
band_val = STA_BAND_AUTO;
2285+
} else if (strcmp(argv[1], "2.4") == 0 || strcmp(argv[1], "1") == 0) {
2286+
band_val = STA_BAND_2G;
2287+
} else if (strcmp(argv[1], "5") == 0 || strcmp(argv[1], "2") == 0) {
2288+
band_val = STA_BAND_5G;
2289+
} else {
2290+
printf("Invalid band. Use: auto, 2.4, or 5\n");
2291+
return 1;
2292+
}
2293+
2294+
esp_err_t err = set_config_param_int("sta_band", band_val);
2295+
if (err == ESP_OK) {
2296+
sta_band = (uint8_t)band_val;
2297+
const char *names[] = {"auto", "2.4 GHz", "5 GHz"};
2298+
printf("STA band preference set to: %s\n", names[band_val]);
2299+
printf("Restart the device for changes to take effect.\n");
2300+
} else {
2301+
printf("Failed to save setting\n");
2302+
}
2303+
return err;
2304+
}
2305+
2306+
static void register_set_sta_band(void)
2307+
{
2308+
const esp_console_cmd_t cmd = {
2309+
.command = "set_sta_band",
2310+
.help = "Set STA band preference (auto, 2.4, 5; requires restart)",
2311+
.hint = NULL,
2312+
.func = &set_sta_band_cmd,
2313+
};
2314+
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
2315+
}
2316+
#endif /* WIFI_HAS_5GHZ */
2317+
22512318
/**
22522319
* @brief Format IP address with device name for /32 addresses
22532320
* If the IP has a full /32 mask and a matching DHCP reservation with a name,
@@ -3004,13 +3071,24 @@ static int scan_cmd(int argc, char **argv)
30043071

30053072
/* Print header */
30063073
printf("\nFound %d networks:\n", ap_count);
3074+
#if WIFI_HAS_5GHZ
3075+
printf("%-32s %3s %5s %4s %-12s\n", "SSID", "Ch", "Band", "RSSI", "Security");
3076+
printf("-------------------------------- --- ----- ---- ------------\n");
3077+
3078+
for (int i = 0; i < ap_count; i++) {
3079+
const char *auth = auth_mode_to_str(ap_list[i].authmode);
3080+
printf("%-32s %3d %5s %4d %s\n", ap_list[i].ssid, ap_list[i].primary,
3081+
ap_list[i].primary > 14 ? "5 GHz" : "2.4 G", ap_list[i].rssi, auth);
3082+
}
3083+
#else
30073084
printf("%-32s %3s %4s %-12s\n", "SSID", "Ch", "RSSI", "Security");
30083085
printf("-------------------------------- --- ---- ------------\n");
30093086

30103087
for (int i = 0; i < ap_count; i++) {
30113088
const char *auth = auth_mode_to_str(ap_list[i].authmode);
30123089
printf("%-32s %3d %4d %s\n", ap_list[i].ssid, ap_list[i].primary, ap_list[i].rssi, auth);
30133090
}
3091+
#endif
30143092

30153093
free(ap_list);
30163094
return 0;

components/http_server/http_server.c

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,21 @@ static esp_err_t config_get_handler(httpd_req_t *req)
12101210
disable_time_check = tc_val;
12111211
}
12121212

1213+
#if WIFI_HAS_5GHZ
1214+
// Save STA band preference
1215+
{
1216+
char band_param[4] = "";
1217+
int band_val = STA_BAND_AUTO;
1218+
if (httpd_query_key_value(buf, "sta_band", band_param, sizeof(band_param)) == ESP_OK) {
1219+
band_val = atoi(band_param);
1220+
if (band_val < STA_BAND_AUTO || band_val > STA_BAND_5G)
1221+
band_val = STA_BAND_AUTO;
1222+
}
1223+
set_config_param_int("sta_band", band_val);
1224+
sta_band = (uint8_t)band_val;
1225+
}
1226+
#endif
1227+
12131228
// Check for optional STA MAC address
12141229
if (httpd_query_key_value(buf, "sta_mac", param5, sizeof(param5)) == ESP_OK && strlen(param5) > 0) {
12151230
ESP_LOGI(TAG, "Found URL query parameter => sta_mac=%s", param5);
@@ -1506,7 +1521,13 @@ static esp_err_t config_get_handler(httpd_req_t *req)
15061521
#else
15071522
/* Chunk 5: STA Settings */
15081523
snprintf(section, sizeof(section), CONFIG_CHUNK_STA,
1509-
safe_ssid, safe_ent_username, safe_ent_identity,
1524+
safe_ssid,
1525+
#if WIFI_HAS_5GHZ
1526+
sta_band == STA_BAND_AUTO ? "selected" : "",
1527+
sta_band == STA_BAND_2G ? "selected" : "",
1528+
sta_band == STA_BAND_5G ? "selected" : "",
1529+
#endif
1530+
safe_ent_username, safe_ent_identity,
15101531
eap_method == 0 ? "selected" : "", eap_method == 1 ? "selected" : "",
15111532
eap_method == 2 ? "selected" : "", eap_method == 3 ? "selected" : "",
15121533
ttls_phase2 == 0 ? "selected" : "", ttls_phase2 == 1 ? "selected" : "",
@@ -2482,11 +2503,11 @@ static esp_err_t scan_get_handler(httpd_req_t *req)
24822503
"<tr><td colspan='%d' style='text-align:center; color:#00d9ff;'>"
24832504
"<span style='display:inline-block; animation: pulse 1s infinite;'>📡 Scanning...</span>"
24842505
"</td></tr>",
2485-
can_connect ? 4 : 3);
2506+
can_connect ? 5 : 4);
24862507
} else {
24872508
snprintf(scan_html, sizeof(scan_html),
24882509
"<tr><td colspan='%d' style='text-align:center; color:#888;'>No networks found</td></tr>",
2489-
can_connect ? 4 : 3);
2510+
can_connect ? 5 : 4);
24902511
}
24912512
} else {
24922513
for (int i = 0; i < ap_count && html_offset < (int)(sizeof(scan_html) - 512); i++) {
@@ -2528,29 +2549,45 @@ static esp_err_t scan_get_handler(httpd_req_t *req)
25282549
encoded_ssid);
25292550
}
25302551

2531-
/* Build signal bars HTML with active/inactive styling */
2532-
char signal_bars_html[128];
2533-
const char *bar_chars[] = {"▂", "▄", "▆", "█"};
2552+
/* Build signal bars HTML with CSS divs */
2553+
char signal_bars_html[384];
2554+
const int bar_heights[] = {4, 8, 12, 16}; /* px */
25342555
int sb_offset = 0;
2556+
sb_offset += snprintf(signal_bars_html, sizeof(signal_bars_html),
2557+
"<span class='signal-bars'>");
25352558
for (int b = 0; b < 4; b++) {
25362559
if (b < bars) {
25372560
sb_offset += snprintf(signal_bars_html + sb_offset, sizeof(signal_bars_html) - sb_offset,
2538-
"<span class='%s'>%s</span>", signal_class, bar_chars[b]);
2561+
"<span class='bar active %s' style='height:%dpx;'></span>",
2562+
signal_class, bar_heights[b]);
25392563
} else {
25402564
sb_offset += snprintf(signal_bars_html + sb_offset, sizeof(signal_bars_html) - sb_offset,
2541-
"<span style='color:#444;'>%s</span>", bar_chars[b]);
2565+
"<span class='bar' style='height:%dpx;'></span>", bar_heights[b]);
25422566
}
25432567
}
2568+
sb_offset += snprintf(signal_bars_html + sb_offset, sizeof(signal_bars_html) - sb_offset,
2569+
"</span>");
2570+
2571+
/* Channel / band info */
2572+
char ch_info[80];
2573+
#if WIFI_HAS_5GHZ
2574+
snprintf(ch_info, sizeof(ch_info), "%d <span style='color:#888;font-size:0.75rem;'>%s</span>",
2575+
ap_list[i].primary, ap_list[i].primary > 14 ? "5G" : "2.4G");
2576+
#else
2577+
snprintf(ch_info, sizeof(ch_info), "%d", ap_list[i].primary);
2578+
#endif
25442579

25452580
html_offset += snprintf(scan_html + html_offset, sizeof(scan_html) - html_offset,
25462581
"<tr>"
25472582
"<td>%s</td>"
2548-
"<td>%s <span style='color:#888;font-size:0.8rem;'>%d dBm</span></td>"
2583+
"<td style='white-space:nowrap;'>%s<span style='color:#888;font-size:0.8rem;margin-left:0.5em;'>%d dBm</span></td>"
2584+
"<td>%s</td>"
25492585
"<td>%s</td>"
25502586
"%s"
25512587
"</tr>",
25522588
safe_ssid,
25532589
signal_bars_html, rssi,
2590+
ch_info,
25542591
web_auth_mode_to_str(ap_list[i].authmode),
25552592
connect_cell
25562593
);

components/http_server/pages/page_config.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* Configuration page templates */
22
#include "router_config.h"
3+
#include "wifi_config.h"
34

45
/* Configuration Page - WiFi settings and MAC addresses */
56
/* Config Page - Chunked for streaming */
@@ -83,14 +84,30 @@ setTimeout(\"location.href = '/'\", 10000);\
8384
</form>"
8485

8586
#if !CONFIG_ETH_UPLINK
87+
/* STA band preference row (5 GHz capable targets only) */
88+
/* Uses %s x3 for: auto_selected, 2.4_selected, 5_selected */
89+
#if WIFI_HAS_5GHZ
90+
#define CONFIG_CHUNK_STA_BAND_ROW \
91+
"<tr><td>Band</td><td><select name='sta_band'>\
92+
<option value='0' %s>Auto (strongest signal)</option>\
93+
<option value='1' %s>2.4 GHz only</option>\
94+
<option value='2' %s>5 GHz only</option>\
95+
</select></td></tr>"
96+
#else
97+
#define CONFIG_CHUNK_STA_BAND_ROW ""
98+
#endif
99+
86100
/* STA Settings section - uses %s for: ssid, ent_username, ent_identity,
87-
eap_method selected x4, ttls_phase2 selected x4, cert_bundle checked, no_time_chk checked, sta_mac */
101+
eap_method selected x4, ttls_phase2 selected x4, cert_bundle checked, no_time_chk checked,
102+
[if WIFI_HAS_5GHZ: band_auto_sel, band_2g_sel, band_5g_sel,]
103+
sta_mac */
88104
#define CONFIG_CHUNK_STA "\
89105
<h2>Station Settings (Uplink)</h2>\
90106
<form action='' method='GET'>\
91107
<table>\
92108
<tr><td>SSID</td><td><input type='text' name='ssid' value='%s' placeholder='Uplink network'/></td></tr>\
93109
<tr><td>Password</td><td><input type='text' name='password' placeholder='unchanged'/></td></tr>\
110+
" CONFIG_CHUNK_STA_BAND_ROW "\
94111
<tr><td colspan='2' style='padding-top: 1rem; color: #888; font-size: 0.85rem;'>WPA2 Enterprise (optional)</td></tr>\
95112
<tr><td>Username</td><td><input type='text' name='ent_username' value='%s' placeholder='Enterprise username'/></td></tr>\
96113
<tr><td>Identity</td><td><input type='text' name='ent_identity' value='%s' placeholder='Optional (defaults to username)'/></td></tr>\

components/http_server/pages/page_scan.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,13 @@ h1 { font-size: 1.5rem; font-weight: 600; color: #00d9ff; margin-bottom: 1rem; t
2626
.data-table td { padding: 0.75rem 0.5rem; border-bottom: 1px solid rgba(255, 255, 255, 0.05); font-size: 0.9rem; }\
2727
.data-table tbody tr:last-child td { border-bottom: none; }\
2828
.data-table tbody tr:hover { background: rgba(0, 217, 255, 0.05); }\
29-
.signal-excellent { color: #4caf50; }\
30-
.signal-good { color: #8bc34a; }\
31-
.signal-fair { color: #ffc107; }\
32-
.signal-weak { color: #ff9800; }\
33-
.signal-poor { color: #f44336; }\
29+
.signal-bars { display: inline-flex; align-items: flex-end; gap: 2px; height: 16px; vertical-align: middle; }\
30+
.signal-bars .bar { width: 4px; border-radius: 1px; background: #444; }\
31+
.signal-bars .bar.active.signal-excellent { background: #4caf50; }\
32+
.signal-bars .bar.active.signal-good { background: #8bc34a; }\
33+
.signal-bars .bar.active.signal-fair { background: #ffc107; }\
34+
.signal-bars .bar.active.signal-weak { background: #ff9800; }\
35+
.signal-bars .bar.active.signal-poor { background: #f44336; }\
3436
.connect-button { background: linear-gradient(135deg, #667eea 0%%, #764ba2 100%%); color: #fff; border: none; border-radius: 6px; padding: 0.4rem 0.8rem; font-size: 0.8rem; font-weight: 600; cursor: pointer; text-decoration: none; display: inline-block; }\
3537
.connect-button:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4); }\
3638
.refresh-note { color: #888; font-size: 0.8rem; margin-bottom: 1rem; }\
@@ -51,6 +53,7 @@ h1 { font-size: 1.5rem; font-weight: 600; color: #00d9ff; margin-bottom: 1rem; t
5153
<tr>\
5254
<th>SSID</th>\
5355
<th>Signal</th>\
56+
<th>Ch</th>\
5457
<th>Security</th>\
5558
%s\
5659
</tr>\

include/wifi_config.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,22 @@
1212
extern "C" {
1313
#endif
1414

15+
/* 5 GHz band support — currently only ESP32-C5 has dual-band WiFi */
16+
#if defined(CONFIG_IDF_TARGET_ESP32C5)
17+
#define WIFI_HAS_5GHZ 1
18+
#else
19+
#define WIFI_HAS_5GHZ 0
20+
#endif
21+
22+
/* STA band preference (only meaningful when WIFI_HAS_5GHZ) */
23+
#define STA_BAND_AUTO 0 /* Connect to strongest signal regardless of band */
24+
#define STA_BAND_2G 1 /* Prefer 2.4 GHz (channels 1-14) */
25+
#define STA_BAND_5G 2 /* Prefer 5 GHz (channels > 14) */
26+
27+
#if WIFI_HAS_5GHZ
28+
extern uint8_t sta_band; /* STA_BAND_AUTO / STA_BAND_2G / STA_BAND_5G */
29+
#endif
30+
1531
#if !CONFIG_ETH_UPLINK
1632
extern char* ssid;
1733
extern char* ent_username;

0 commit comments

Comments
 (0)