Updating to ESP eco-system per Oct 23 2025
This commit is contained in:
17
.cargo/config.toml
Normal file
17
.cargo/config.toml
Normal file
@@ -0,0 +1,17 @@
|
||||
[target.riscv32imc-unknown-none-elf]
|
||||
runner = "espflash flash --monitor --chip esp32c3"
|
||||
|
||||
[env]
|
||||
|
||||
[build]
|
||||
rustflags = [
|
||||
# Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.)
|
||||
# NOTE: May negatively impact performance of produced code
|
||||
"-C", "force-frame-pointers",
|
||||
]
|
||||
|
||||
target = "riscv32imc-unknown-none-elf"
|
||||
|
||||
[unstable]
|
||||
build-std = ["core"]
|
||||
|
||||
1163
Cargo.lock
generated
1163
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
57
Cargo.toml
57
Cargo.toml
@@ -1,38 +1,35 @@
|
||||
[package]
|
||||
name = "wallas-esp32c3"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
version = "0.1.1"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
esp-backtrace = { version = "0.15.0", features = [
|
||||
esp-backtrace = { version = "0.18.0", features = [
|
||||
"esp32c3",
|
||||
"exception-handler",
|
||||
"panic-handler",
|
||||
"println",
|
||||
]}
|
||||
|
||||
esp-hal = { version = "0.23.1", features = [
|
||||
esp-hal = { version = "1.0.0-rc.1", features = [
|
||||
"esp32c3",
|
||||
"unstable",
|
||||
] }
|
||||
esp-println = { version = "0.13.0", features = ["esp32c3", "log"] }
|
||||
log = { version = "0.4.21" }
|
||||
esp-alloc = { version = "0.6.0" }
|
||||
embedded-io = "0.6.1"
|
||||
esp-println = { version = "0.16.0", features = ["esp32c3", "log-04"] }
|
||||
log = { version = "0.4.28" }
|
||||
esp-alloc = "0.9.0"
|
||||
esp-rtos = { version = "0.1.1", features = ["esp-radio", "embassy", "log-04", "esp32c3"] }
|
||||
embedded-io = "0.7.1"
|
||||
embedded-io-async = "0.7.0"
|
||||
embassy-net = { version = "0.7.1", features = [ "tcp", "udp", "dhcpv4", "dns", "medium-ethernet"] }
|
||||
|
||||
embedded-io-async = "0.6.1"
|
||||
embassy-net = { version = "0.6.0", features = [ "tcp", "udp", "dhcpv4", "dns", "medium-ethernet"] }
|
||||
|
||||
esp-wifi = { version = "0.12.0", default-features=false, features = [
|
||||
esp-radio = { version = "0.16.0", default-features=false, features = [
|
||||
"esp32c3",
|
||||
"utils",
|
||||
"wifi",
|
||||
"esp-alloc",
|
||||
"log",
|
||||
] }
|
||||
embassy-sync = "0.6.1"
|
||||
rand_core = "0.9.0"
|
||||
embassy-sync = "0.7.2"
|
||||
rand_core = "0.9.3"
|
||||
nom = { version = "8", default-features = false, features = [ "alloc" ] }
|
||||
heapless = { version = "0.8.0", default-features = false }
|
||||
heapless = { version = "0.9.1", default-features = false }
|
||||
smoltcp = { version = "0.12.0", default-features = false, features = [
|
||||
"medium-ethernet",
|
||||
"proto-dhcpv4",
|
||||
@@ -43,22 +40,19 @@ smoltcp = { version = "0.12.0", default-features = false, features = [
|
||||
"socket-tcp",
|
||||
"socket-udp",
|
||||
] }
|
||||
embassy-executor = { version = "0.7.0", features = [
|
||||
"task-arena-size-163840"
|
||||
] }
|
||||
embassy-time = { version = "0.4.0", features = ["generic-queue-8"] }
|
||||
esp-hal-embassy = { version = "0.6.0", features = ["esp32c3"] }
|
||||
static_cell = { version = "2.1.0", features = ["nightly"] }
|
||||
critical-section = "1.2.0"
|
||||
embassy-executor = "0.9.1"
|
||||
embassy-time = { version = "0.5.0", features = ["generic-queue-8"] }
|
||||
static_cell = { version = "2.1.1" }
|
||||
# critical-section = "1.2.0"
|
||||
maud = { git = "https://github.com/jakobdalsgaard/maud.git", features = ["alloc", "picoserve"] }
|
||||
picoserve = { version = "0.14.1", default-features = false, features = [
|
||||
picoserve = { version = "0.16.0", default-features = false, features = [
|
||||
"alloc",
|
||||
"embassy",
|
||||
"log",
|
||||
] }
|
||||
sntpc = { version = "0.5.1", default-features = false, features = [ "embassy-socket" ] }
|
||||
chrono = { version = "0.4.39", default-features = false, features = [ "alloc" ] }
|
||||
serde = { version = "1.0.217", default-features = false }
|
||||
sntpc = { version = "0.6.1", default-features = false, features = [ "embassy-socket" ] }
|
||||
chrono = { version = "0.4.42", default-features = false, features = [ "alloc" ] }
|
||||
serde = { version = "1.0.228", default-features = false }
|
||||
include_file_compress = "0.1.3"
|
||||
|
||||
[profile.dev]
|
||||
@@ -74,3 +68,6 @@ incremental = false
|
||||
lto = 'fat'
|
||||
opt-level = 's'
|
||||
overflow-checks = false
|
||||
|
||||
[profile.dev.package.esp-wifi]
|
||||
opt-level = 3
|
||||
|
||||
0
set-env.sh
Normal file → Executable file
0
set-env.sh
Normal file → Executable file
19
src/httpd.rs
19
src/httpd.rs
@@ -21,7 +21,8 @@ const APP_JS_FILENAME: &str = concat!("/app-", env!("CARGO_PKG_VERSION_SAFE"), "
|
||||
|
||||
static PICO_CONFIG : picoserve::Config<Duration> = picoserve::Config::new(
|
||||
picoserve::Timeouts {
|
||||
start_read_request: Some(Duration::from_secs(5)),
|
||||
start_read_request: Some(Duration::from_secs(1)),
|
||||
persistent_start_read_request: Some(Duration::from_secs(1)),
|
||||
read_request: Some(Duration::from_secs(1)),
|
||||
write: Some(Duration::from_secs(1)),
|
||||
}).keep_connection_alive();
|
||||
@@ -118,15 +119,15 @@ fn page(heading: &str, content: Markup) -> Markup {
|
||||
"RISC-V is a registered trademark of RISC-V International · Wallas is a registered trademark of Wallas-Marin Oy · Espressif is a registered trademark of Espressif Systems"
|
||||
}
|
||||
dialog #message .dialog-center {};
|
||||
dialog #"set-target" .dialog-center {
|
||||
dialog #set-target .dialog-center {
|
||||
span ."cancel-x" { "🗙" };
|
||||
form {
|
||||
div #"temperature-form" {
|
||||
div #temperature-form {
|
||||
input #target type="range" min="5" max="25" name="target";
|
||||
br;
|
||||
label #"target-label" for="target" { "Target temperature in °C" };
|
||||
label #target-label for="target" { "Target temperature in °C" };
|
||||
br;
|
||||
button #"set-target" { "Set" };
|
||||
button #set-target { "Set" };
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -231,10 +232,10 @@ fn index() -> impl IntoResponse {
|
||||
div .opaque { p .intro { "Beta version of ESP32C3 based Wifi extension to the Wallas 361062 Control Panel for the DT/GB Heaters" } }
|
||||
div .opaque { p #graph { "Waiting for data ..." } }
|
||||
div .opaque { p #latest { "Waiting for latest reading ..." } }
|
||||
button #"button-start" .button { "Start heater" }
|
||||
button #"button-stop" .button { "Stop heater" }
|
||||
button #"button-ventilate" .button { "Start ventilator" }
|
||||
button #"button-target" .button { "Set target temperature" }
|
||||
button #button-start .button { "Start heater" }
|
||||
button #button-stop .button { "Stop heater" }
|
||||
button #button-ventilate .button { "Start ventilator" }
|
||||
button #button-target .button { "Set target temperature" }
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
28
src/main.rs
28
src/main.rs
@@ -8,14 +8,11 @@ extern crate alloc;
|
||||
|
||||
use heapless::String;
|
||||
use esp_hal::rng::Rng;
|
||||
use esp_hal::timer::timg::TimerGroup;
|
||||
use esp_hal::clock::CpuClock;
|
||||
|
||||
/**
|
||||
* Embassy includes
|
||||
*/
|
||||
use esp_hal_embassy::init as initialize_embassy;
|
||||
use esp_hal_embassy::main;
|
||||
use embassy_executor::Spawner;
|
||||
|
||||
/**
|
||||
@@ -76,8 +73,9 @@ const SNTP_SOCKETS: usize = 1;
|
||||
const DNS_SOCKETS: usize = 1;
|
||||
const MAX_CONCURRENT_SOCKETS: usize = HTTPD_SOCKETS + DHCP_SOCKETS + DNS_SOCKETS + SNTP_SOCKETS;
|
||||
|
||||
// esp_bootloader_esp_idf::esp_app_desc!();
|
||||
|
||||
#[main]
|
||||
#[esp_rtos::main]
|
||||
async fn main(spawner: Spawner) {
|
||||
|
||||
info!("booting firmware version {}", VERSION);
|
||||
@@ -92,28 +90,20 @@ async fn main(spawner: Spawner) {
|
||||
async fn main_fallible(
|
||||
spawner: Spawner,
|
||||
) -> Result<(), Error> {
|
||||
let peripherals = esp_hal::init({
|
||||
let mut config = esp_hal::Config::default();
|
||||
config.cpu_clock = CpuClock::max();
|
||||
config
|
||||
});
|
||||
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
|
||||
let peripherals = esp_hal::init(config);
|
||||
|
||||
esp_alloc::heap_allocator!(HEAP_MEMORY_SIZE);
|
||||
esp_alloc::heap_allocator!(size: HEAP_MEMORY_SIZE);
|
||||
|
||||
esp_println::logger::init_logger_from_env();
|
||||
|
||||
// let systimer = SystemTimer::new(peripherals.SYSTIMER).split::<Target>();
|
||||
let tmg1 = TimerGroup::new(peripherals.TIMG1);
|
||||
initialize_embassy(tmg1.timer0);
|
||||
let rng = Rng::new();
|
||||
|
||||
let rng = Rng::new(peripherals.RNG);
|
||||
|
||||
let ssid = String::<32>::try_from(WIFI_SSID).map_err(|()| Error::ParseCredentials)?;
|
||||
let ssid = String::<32>::try_from(WIFI_SSID).map_err(|_| Error::ParseCredentials)?;
|
||||
let password =
|
||||
String::<64>::try_from(WIFI_PASSWORD).map_err(|()| Error::ParseCredentials)?;
|
||||
String::<64>::try_from(WIFI_PASSWORD).map_err(|_| Error::ParseCredentials)?;
|
||||
|
||||
let tmg0 = TimerGroup::new(peripherals.TIMG0);
|
||||
let stack = connect_to_wifi(spawner, tmg0, rng, peripherals.WIFI, peripherals.RADIO_CLK, (ssid, password)).await.unwrap();
|
||||
let stack = connect_to_wifi(spawner, peripherals.TIMG1, peripherals.SW_INTERRUPT, peripherals.WIFI, rng, (ssid, password)).await.unwrap();
|
||||
|
||||
let _ = httpd_spawn(spawner, HTTPD_SOCKETS, stack);
|
||||
|
||||
|
||||
@@ -40,9 +40,9 @@ type DomainCommandChannel = PubSubChannel<CriticalSectionRawMutex, DomainCommand
|
||||
|
||||
pub static DOMAIN_COMMAND_CHANNEL: DomainCommandChannel = DomainCommandChannel::new();
|
||||
|
||||
pub fn serial_spawn(spawner: embassy_executor::Spawner, peri_uart: AnyUart) {
|
||||
pub fn serial_spawn(spawner: embassy_executor::Spawner, peri_uart: AnyUart<'static>) {
|
||||
// Initialize and configure UART0
|
||||
let config = Config::default().with_rx_fifo_full_threshold(BUFFER_SIZE as u16);
|
||||
let config = Config::default();
|
||||
// removed rx_pin, tx_pin
|
||||
let my_uart = Uart::new(peri_uart, config).unwrap().into_async();
|
||||
// Split UART0 to create seperate Tx and Rx handles
|
||||
|
||||
100
src/wifi.rs
100
src/wifi.rs
@@ -1,36 +1,27 @@
|
||||
// Copyright Claudio Mattera 2024.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
//! Functions and task for WiFi connection
|
||||
|
||||
use alloc::string::ToString;
|
||||
use log::debug;
|
||||
use log::error;
|
||||
use log::info;
|
||||
|
||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use embassy_executor::Spawner;
|
||||
|
||||
use embassy_net::new as new_network_stack;
|
||||
|
||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use embassy_sync::signal::Signal;
|
||||
|
||||
use esp_wifi::init as initialize_wifi;
|
||||
use esp_wifi::wifi::new_with_mode as new_wifi_with_mode;
|
||||
use esp_wifi::wifi::wifi_state;
|
||||
use esp_wifi::wifi::ClientConfiguration;
|
||||
use esp_wifi::wifi::Configuration;
|
||||
use esp_wifi::wifi::WifiController;
|
||||
use esp_wifi::wifi::WifiDevice;
|
||||
use esp_wifi::wifi::WifiError as EspWifiError;
|
||||
use esp_wifi::wifi::WifiEvent;
|
||||
use esp_wifi::wifi::WifiStaDevice;
|
||||
use esp_wifi::wifi::WifiState;
|
||||
use esp_wifi::EspWifiController;
|
||||
use esp_wifi::InitializationError as WifiInitializationError;
|
||||
#[cfg(target_arch = "riscv32")]
|
||||
use esp_hal::interrupt::software::SoftwareInterruptControl;
|
||||
|
||||
use esp_radio::{
|
||||
Controller,
|
||||
wifi::{
|
||||
ClientConfig,
|
||||
ModeConfig,
|
||||
WifiController,
|
||||
WifiDevice,
|
||||
WifiEvent,
|
||||
WifiStaState,
|
||||
WifiError,
|
||||
},
|
||||
};
|
||||
use embassy_net::Config;
|
||||
use embassy_net::DhcpConfig;
|
||||
use embassy_net::Runner;
|
||||
@@ -40,11 +31,10 @@ use embassy_net::StackResources;
|
||||
use embassy_time::Duration;
|
||||
use embassy_time::Timer;
|
||||
|
||||
use esp_hal::peripherals::RADIO_CLK;
|
||||
use esp_hal::peripherals::TIMG0;
|
||||
use esp_hal::peripherals::WIFI;
|
||||
use esp_hal::peripherals::{WIFI, SW_INTERRUPT};
|
||||
use esp_hal::rng::Rng;
|
||||
use esp_hal::timer::timg::TimerGroup;
|
||||
use esp_hal::timer::timg::TimerGroupInstance;
|
||||
// use esp_hal::Blocking;
|
||||
|
||||
use heapless::String;
|
||||
@@ -62,34 +52,46 @@ static STACK_COUNT : usize = super::MAX_CONCURRENT_SOCKETS;
|
||||
static STACK_RESOURCES: StaticCell<StackResources<STACK_COUNT>> = StaticCell::new();
|
||||
|
||||
/// Static cell for WiFi controller
|
||||
static WIFI_CONTROLLER: StaticCell<EspWifiController<'static>> = StaticCell::new();
|
||||
static WIFI_CONTROLLER: StaticCell<Controller<'static>> = StaticCell::new();
|
||||
|
||||
/// Signal to request to stop WiFi
|
||||
pub static STOP_WIFI_SIGNAL: Signal<CriticalSectionRawMutex, ()> = Signal::new();
|
||||
|
||||
/// Connect to WiFi
|
||||
pub async fn connect(
|
||||
pub async fn connect<T>(
|
||||
spawner: Spawner,
|
||||
timg0: TimerGroup<TIMG0>,
|
||||
timer1: T,
|
||||
interrupt: SW_INTERRUPT<'static>,
|
||||
wifi: WIFI<'static>,
|
||||
rng: Rng,
|
||||
wifi: WIFI,
|
||||
radio_clock_control: RADIO_CLK,
|
||||
(ssid, password): (String<32>, String<64>),
|
||||
) -> Result<Stack<'static>, Error> {
|
||||
) -> Result<Stack<'static>, WifiError>
|
||||
where
|
||||
T: TimerGroupInstance + 'static,
|
||||
{
|
||||
let mut rng_wrapper = RngWrapper::from(rng);
|
||||
let seed = rng_wrapper.next_u64();
|
||||
debug!("Use random seed 0x{seed:016x}");
|
||||
|
||||
let wifi_controller = initialize_wifi(timg0.timer0, rng, radio_clock_control)?;
|
||||
let wifi_controller: &'static mut _ = WIFI_CONTROLLER.init(wifi_controller);
|
||||
|
||||
let (wifi_interface, controller) = new_wifi_with_mode(wifi_controller, wifi, WifiStaDevice)?;
|
||||
let timg0 = TimerGroup::new(timer1);
|
||||
#[cfg(target_arch = "riscv32")]
|
||||
let sw_int = SoftwareInterruptControl::new(interrupt);
|
||||
esp_rtos::start(
|
||||
timg0.timer0,
|
||||
#[cfg(target_arch = "riscv32")]
|
||||
sw_int.software_interrupt0,
|
||||
);
|
||||
|
||||
|
||||
let controller = WIFI_CONTROLLER.init(esp_radio::init().unwrap());
|
||||
let (controller, interfaces) = esp_radio::wifi::new(controller, wifi, Default::default()).unwrap();
|
||||
let wifi_interface = interfaces.sta;
|
||||
|
||||
let config = Config::dhcpv4(DhcpConfig::default());
|
||||
|
||||
debug!("Initialize network stack");
|
||||
let stack_resources: &'static mut _ = STACK_RESOURCES.init(StackResources::new());
|
||||
let (stack, runner) = new_network_stack(wifi_interface, config, stack_resources, seed);
|
||||
let (stack, runner) = embassy_net::new(wifi_interface, config, stack_resources, seed);
|
||||
|
||||
spawner.must_spawn(connection(controller, ssid, password));
|
||||
spawner.must_spawn(net_task(runner));
|
||||
@@ -116,7 +118,7 @@ pub async fn connect(
|
||||
|
||||
/// Task for ongoing network processing
|
||||
#[embassy_executor::task]
|
||||
async fn net_task(mut runner: Runner<'static, WifiDevice<'static, WifiStaDevice>>) {
|
||||
async fn net_task(mut runner: Runner<'static, WifiDevice<'static>>) {
|
||||
runner.run().await;
|
||||
}
|
||||
|
||||
@@ -135,23 +137,23 @@ async fn connection_fallible(
|
||||
mut controller: WifiController<'static>,
|
||||
ssid: String<32>,
|
||||
password: String<64>,
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<(), WifiError> {
|
||||
debug!("Start connection");
|
||||
debug!("Device capabilities: {:?}", controller.capabilities());
|
||||
loop {
|
||||
if wifi_state() == WifiState::StaConnected {
|
||||
if esp_radio::wifi::sta_state() == WifiStaState::Connected {
|
||||
// wait until we're no longer connected
|
||||
controller.wait_for_event(WifiEvent::StaDisconnected).await;
|
||||
Timer::after(Duration::from_millis(5000)).await;
|
||||
}
|
||||
|
||||
if !matches!(controller.is_started(), Ok(true)) {
|
||||
let client_config = Configuration::Client(ClientConfiguration {
|
||||
ssid: ssid.clone(),
|
||||
password: password.clone(),
|
||||
..Default::default()
|
||||
});
|
||||
controller.set_configuration(&client_config)?;
|
||||
let client_config = ModeConfig::Client(
|
||||
ClientConfig::default()
|
||||
.with_ssid(ssid.clone().to_string())
|
||||
.with_password(password.clone().to_string()),
|
||||
);
|
||||
controller.set_config(&client_config)?;
|
||||
debug!("Starting WiFi controller");
|
||||
controller.start_async().await?;
|
||||
debug!("WiFi controller started");
|
||||
@@ -180,6 +182,7 @@ async fn connection_fallible(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/*
|
||||
/// Error within WiFi connection
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
@@ -201,3 +204,4 @@ impl From<EspWifiError> for Error {
|
||||
Self::Wifi(error)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user