Support for wifi, including Wokwi simulated wifi

This commit is contained in:
2026-07-27 19:10:53 +02:00
parent 6201fcaab1
commit 95a0c0fe63
5 changed files with 2021 additions and 105 deletions
+1
View File
@@ -3,6 +3,7 @@ runner = "espflash flash --monitor --chip esp32s3"
[env] [env]
ESP_LOG="info" ESP_LOG="info"
WM_CONN = '{"ssid": "Wokwi-GUEST", "psk": "", "data": {}}'
[build] [build]
rustflags = [ rustflags = [
Generated
+1915 -76
View File
File diff suppressed because it is too large Load Diff
+10 -19
View File
@@ -12,6 +12,7 @@ path = "./src/bin/main.rs"
esp-hal = { version = "~1.1.0", features = ["esp32s3", "log-04", "unstable"] } esp-hal = { version = "~1.1.0", features = ["esp32s3", "log-04", "unstable"] }
esp-rtos = { version = "0.3.0", features = [ esp-rtos = { version = "0.3.0", features = [
"embassy",
"esp-alloc", "esp-alloc",
"esp-radio", "esp-radio",
"esp32s3", "esp32s3",
@@ -23,28 +24,14 @@ log = "0.4.27"
critical-section = "1.2.0" critical-section = "1.2.0"
embedded-io = "0.7.1" embedded-io = "0.7.1"
embassy-executor = { version = "0.10.0", default-features = false }
embassy-time = { version = "0.5.1", default-features = false }
esp-alloc = "0.10.0" esp-alloc = "0.10.0"
esp-println = { version = "0.17.0", features = ["esp32s3", "log-04"] } esp-hal-wifimanager = { git = "https://github.com/InvisibleUSA/esp-hal-wifimanager", default-features = false, features = [
esp-radio = { version = "0.18.0", features = [ "ap",
"esp-alloc",
"esp32s3", "esp32s3",
"log-04",
"unstable",
"wifi",
] }
smoltcp = { version = "0.13.0", default-features = false, features = [
"log",
"medium-ethernet",
"multicast",
"proto-dhcpv4",
"proto-dns",
"proto-ipv4",
"socket-dns",
"socket-icmp",
"socket-raw",
"socket-tcp",
"socket-udp",
] } ] }
esp-println = { version = "0.17.0", features = ["esp32s3", "log-04"] }
display-interface-spi = "0.5.0" display-interface-spi = "0.5.0"
ili9341 = "0.6.0" ili9341 = "0.6.0"
embedded-hal = "1.0.0" embedded-hal = "1.0.0"
@@ -64,3 +51,7 @@ codegen-units = 1 # LLVM can perform better optimizations using a single thr
debug = 2 # prefer slower builds but better debugging experience debug = 2 # prefer slower builds but better debugging experience
lto = 'fat' lto = 'fat'
opt-level = 's' opt-level = 's'
[features]
default = []
wokwi = []
+3
View File
@@ -1,5 +1,6 @@
{ {
"version": 1, "version": 1,
"author": "CreatureDex",
"editor": "wokwi", "editor": "wokwi",
"parts": [ "parts": [
{ "type": "board-esp32-s3-devkitc-1", "id": "esp1", "top": 67.2, "left": -263.96, "attrs": {} }, { "type": "board-esp32-s3-devkitc-1", "id": "esp1", "top": 67.2, "left": -263.96, "attrs": {} },
@@ -26,6 +27,8 @@
} }
], ],
"connections": [ "connections": [
[ "esp1:TX", "$serialMonitor:RX", "", [] ],
[ "esp1:RX", "$serialMonitor:TX", "", [] ],
[ "lcd1:VCC", "esp1:3V3", "red", [ "v19.2", "h-57.6", "v-105.6", "h-124.95" ] ], [ "lcd1:VCC", "esp1:3V3", "red", [ "v19.2", "h-57.6", "v-105.6", "h-124.95" ] ],
[ "lcd1:GND", "esp1:GND.2", "black", [ "v28.8", "h-76.8", "v-76.8" ] ], [ "lcd1:GND", "esp1:GND.2", "black", [ "v28.8", "h-76.8", "v-76.8" ] ],
[ "lcd1:CS", "esp1:11", "orange", [ "v0" ] ], [ "lcd1:CS", "esp1:11", "orange", [ "v0" ] ],
+92 -10
View File
@@ -7,6 +7,8 @@
)] )]
#![deny(clippy::large_stack_frames)] #![deny(clippy::large_stack_frames)]
use embassy_executor::Spawner;
use embassy_time::Timer;
use display_interface_spi::SPIInterface; use display_interface_spi::SPIInterface;
use embedded_graphics::Drawable; use embedded_graphics::Drawable;
use embedded_graphics::mono_font::MonoTextStyle; use embedded_graphics::mono_font::MonoTextStyle;
@@ -22,13 +24,11 @@ use esp_hal::delay::Delay;
use esp_hal::gpio::Level; use esp_hal::gpio::Level;
use esp_hal::gpio::Output; use esp_hal::gpio::Output;
use esp_hal::gpio::OutputConfig; use esp_hal::gpio::OutputConfig;
use esp_hal::main;
use esp_hal::spi::{ use esp_hal::spi::{
Mode, Mode,
master::{Config, Spi}, master::{Config, Spi},
}; };
use esp_hal::time::Rate; use esp_hal::time::Rate;
use esp_hal::time::{Duration, Instant};
use esp_hal::timer::timg::TimerGroup; use esp_hal::timer::timg::TimerGroup;
use ili9341::Ili9341; use ili9341::Ili9341;
use ili9341::Orientation; use ili9341::Orientation;
@@ -46,15 +46,96 @@ extern crate alloc;
// For more information see: <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/app_image_format.html#application-description> // For more information see: <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/app_image_format.html#application-description>
esp_bootloader_esp_idf::esp_app_desc!(); esp_bootloader_esp_idf::esp_app_desc!();
#[cfg(not(feature = "wokwi"))]
async fn setup_wifi(
wifi: esp_hal::peripherals::WIFI<'static>,
flash: esp_hal::peripherals::FLASH<'static>,
spawner: &Spawner,
) {
let nvs = esp_hal_wifimanager::Nvs::new(0x9000, 0x6000, flash).unwrap();
let mut wm_settings = esp_hal_wifimanager::WmSettings::default();
wm_settings.ssid.clear();
_ = core::fmt::write(
&mut wm_settings.ssid,
format_args!("CreatureDex-{:X}", esp_hal_wifimanager::get_efuse_mac()),
);
wm_settings.wifi_conn_timeout = 30000;
wm_settings.esp_reset_timeout = Some(300000); // 5min
let wifi_res = esp_hal_wifimanager::init_wm(
wm_settings,
spawner,
Some(&nvs),
wifi,
None,
)
.await;
log::info!("wifi_res: {wifi_res:?}");
}
#[cfg(feature = "wokwi")]
async fn setup_wifi(
wifi: esp_hal::peripherals::WIFI<'static>,
flash: esp_hal::peripherals::FLASH<'static>,
spawner: &Spawner,
) {
log::info!("Wokwi mode active: pre-seeding WiFi Manager with Wokwi credentials");
// Preload connection data so init_wm can connect immediately without AP setup.
let nvs = match esp_hal_wifimanager::Nvs::new(0x9000, 0x6000, flash) {
Ok(nvs) => nvs,
Err(e) => {
log::error!("Failed to initialize NVS for Wokwi: {e:?}");
return;
}
};
if let Err(e) = nvs
.set(
esp_hal_wifimanager::WIFI_NVS_KEY,
"{\"ssid\":\"Wokwi-GUEST\",\"psk\":\"\",\"data\":{}}",
)
.await
{
log::error!("Failed to store Wokwi WiFi config in NVS: {e:?}");
return;
}
let mut wm_settings = esp_hal_wifimanager::WmSettings::default();
// Wokwi simulation uses a default open network called "Wokwi-GUEST"
wm_settings.ssid.clear();
_ = core::fmt::write(&mut wm_settings.ssid, format_args!("Wokwi-GUEST"));
wm_settings.wifi_conn_timeout = 30000;
// Initialize Wi-Fi connection through WiFi Manager using the pre-seeded NVS data.
let wifi_res = esp_hal_wifimanager::init_wm(
wm_settings,
spawner,
Some(&nvs),
wifi,
None,
)
.await;
log::info!("Wokwi wifi_res: {wifi_res:?}");
}
#[allow( #[allow(
clippy::large_stack_frames, clippy::large_stack_frames,
reason = "it's not unusual to allocate larger buffers etc. in main" reason = "it's not unusual to allocate larger buffers etc. in main"
)] )]
#[main] #[esp_rtos::main]
fn main() -> ! { async fn main(spawner: Spawner) {
// generator version: 1.3.0 // generator version: 1.3.0
// generator parameters: --chip esp32s3 -o esp32s3-wroom-1-octal-psram -o unstable-hal -o alloc -o wifi -o log -o wokwi -o neovim -o vscode -o esp // generator parameters: --chip esp32s3 -o esp32s3-wroom-1-octal-psram -o unstable-hal -o alloc -o wifi -o log -o wokwi -o neovim -o vscode -o esp
esp_println::logger::init_logger_from_env(); esp_println::logger::init_logger_from_env();
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
@@ -85,9 +166,7 @@ fn main() -> ! {
let sw_interrupt = let sw_interrupt =
esp_hal::interrupt::software::SoftwareInterruptControl::new(peripherals.SW_INTERRUPT); esp_hal::interrupt::software::SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
esp_rtos::start(timg0.timer0, sw_interrupt.software_interrupt0); esp_rtos::start(timg0.timer0, sw_interrupt.software_interrupt0);
let (mut _wifi_controller, _interfaces) =
esp_radio::wifi::new(peripherals.WIFI, Default::default())
.expect("Failed to initialize Wi-Fi controller");
let spi_bus = Spi::new( let spi_bus = Spi::new(
peripherals.SPI2, peripherals.SPI2,
@@ -124,10 +203,13 @@ fn main() -> ! {
.draw(&mut display) .draw(&mut display)
.unwrap(); .unwrap();
setup_wifi(peripherals.WIFI, peripherals.FLASH, &spawner).await;
log::info!("Setup complete, entering main loop");
loop { loop {
info!("Hello world!"); info!("Hello world!");
let delay_start = Instant::now(); Timer::after_millis(500).await;
while delay_start.elapsed() < Duration::from_millis(500) {}
} }
// for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/esp-hal-v1.1.0/examples // for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/esp-hal-v1.1.0/examples