feat: use the embedded-rpc library for the wifi service

This commit is contained in:
2026-08-17 17:38:00 -05:00
parent 8695d0abfa
commit aed1e41665
3 changed files with 83 additions and 62 deletions
+72 -62
View File
@@ -1,11 +1,10 @@
use defmt::{error, info};
use embassy_executor::Spawner;
use embassy_futures::select::Either::First;
use embassy_futures::select::select;
use embassy_futures::select::{Either, select};
use embassy_net::{Runner, Stack};
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::{channel::Channel};
use embassy_time::{Duration, Timer};
use embedded_rpc::{RequestDroppedError, RpcService};
use esp_hal::peripherals::WIFI;
use esp_radio::wifi::sta::StationConfig;
use esp_radio::wifi::{ControllerConfig, Interface, WifiController};
@@ -16,14 +15,16 @@ pub enum WifiCommand {
}
impl WifiCommand {
pub async fn set_station_config(config: esp_radio::wifi::Config) {
WIFI_CH
.send(WifiCommand::SetStationConfig(config))
.await;
pub async fn set_station_config(
config: esp_radio::wifi::Config,
) -> Result<(), RequestDroppedError> {
WIFI_SERVICE
.request(WifiCommand::SetStationConfig(config))
.await
}
}
pub static WIFI_CH: Channel<CriticalSectionRawMutex, WifiCommand, 4> = Channel::new();
pub static WIFI_SERVICE: RpcService<CriticalSectionRawMutex, WifiCommand, ()> = RpcService::new();
pub fn start_wifi(spawner: Spawner, wifi: WIFI<'static>) -> Stack<'static> {
let wifi_config = esp_radio::wifi::Config::Station(StationConfig::default());
@@ -52,78 +53,87 @@ pub fn start_wifi(spawner: Spawner, wifi: WIFI<'static>) -> Stack<'static> {
);
spawner.spawn(net_task(net_runner).unwrap());
spawner.spawn(handler(wifi_controller, net_stack).unwrap());
spawner.spawn(wifi_handler(wifi_controller).unwrap());
spawner.spawn(ip_logger(net_stack).unwrap());
spawner.spawn(handler(net_stack).unwrap());
net_stack
}
#[embassy_executor::task]
async fn handler(mut controller: WifiController<'static>, net_stack: Stack<'static>) {
let receiver = WIFI_CH.receiver();
async fn handler(net_stack: Stack<'static>) {
loop {
match select(receiver.receive(), connection(&mut controller, net_stack)).await {
First(WifiCommand::SetStationConfig(config)) => {
if controller.set_config(&config).is_err() {
error!("Set WiFi config failed: {:?}", config);
};
let (req, served) = WIFI_SERVICE.serve().await;
match req {
WifiCommand::SetStationConfig(config) => {
if WIFI_HANDLER_RPC.request(config).await.is_err() {
continue;
}
}
First(WifiCommand::SetDhcpConfig(dhcp_config)) => {
WifiCommand::SetDhcpConfig(dhcp_config) => {
net_stack.set_config_v4(embassy_net::ConfigV4::Dhcp(dhcp_config));
}
embassy_futures::select::Either::Second(_) => {
unreachable!("connection function should be infinite loop")
}
served.respond(());
}
}
static WIFI_HANDLER_RPC: RpcService<CriticalSectionRawMutex, esp_radio::wifi::Config, ()> =
RpcService::new();
#[embassy_executor::task]
async fn wifi_handler(mut controller: WifiController<'static>) {
let connection = async |controller: &mut WifiController<'static>| {
info!("Connecting to WiFi...");
match controller.connect_async().await {
Ok(info) => {
info!("Wifi connected to {:?}", info);
// wait until we're no longer connected
let info = controller.wait_for_disconnect_async().await.ok();
info!("Disconnected: {:?}", info);
}
Err(e) => {
error!("Failed to connect to wifi: {:?}", e);
}
}
};
loop {
if let Either::First((req, served)) =
select(WIFI_HANDLER_RPC.serve(), connection(&mut controller)).await
{
if controller.set_config(&req).is_ok() {
served.respond(());
}
}
}
}
async fn connection(controller: &mut WifiController<'static>, net_stack: Stack<'static>) {
info!("start connection task");
#[embassy_executor::task]
async fn ip_logger(net_stack: Stack<'static>) {
loop {
info!("Getting IP address...");
net_stack.wait_config_up().await;
select(
async {
loop {
info!("Connecting to WiFi...");
match net_stack.config_v4() {
Some(info) => {
info!("Got IP: {:?}", info);
match controller.connect_async().await {
Ok(info) => {
info!("Wifi connected to {:?}", info);
// wait until we're no longer connected
let info = controller.wait_for_disconnect_async().await.ok();
info!("Disconnected: {:?}", info);
}
Err(e) => {
error!("Failed to connect to wifi: {:?}", e);
}
}
Timer::after(Duration::from_millis(5000)).await
// wait until we're no longer connected
net_stack.wait_config_down().await;
info!("Address no longer configured");
}
},
async {
loop {
info!("Getting IP address...");
net_stack.wait_config_up().await;
match net_stack.config_v4() {
Some(info) => {
info!("Got IP: {:?}", info);
// wait until we're no longer connected
net_stack.wait_config_down().await;
info!("Address no longer configured");
}
None => {
error!("Failed to configure an address");
}
}
Timer::after(Duration::from_millis(5000)).await
None => {
error!("Failed to configure an address");
}
},
)
.await;
}
Timer::after(Duration::from_millis(5000)).await
}
}
#[embassy_executor::task]