#![no_std]
#![no_main]
use embassy_executor::Spawner;
use embassy_futures::join::join;
use embassy_time::{with_timeout, Duration, Instant, Timer};
use esp_csi_rs::{
config::CsiConfig, logging::logging::init_logger, CSINode, CollectionMode, EspNowConfig,
PeripheralOpMode,
};
use esp_csi_rs::{
CSINodeClient, CSINodeHardware, get_pps_rx, get_pps_tx, get_dropped_packets_rx, get_one_way_latency, get_two_way_latency, log_ln,
};
use esp_hal::clock::CpuClock;
use esp_hal::timer::timg::TimerGroup;
use esp_println::println;
use esp_radio::{
wifi::{ClientConfig, Interfaces, WifiController},
Controller,
};
use {esp_backtrace as _, esp_println as _};
extern crate alloc;
static WIFI_CONTROLLER: static_cell::StaticCell<WifiController<'static>> =
static_cell::StaticCell::new();
esp_bootloader_esp_idf::esp_app_desc!();
#[allow(
clippy::large_stack_frames,
reason = "it's not unusual to allocate larger buffers etc. in main"
)]
macro_rules! mk_static {
($t:ty,$val:expr) => {{
static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new();
#[deny(unused_attributes)]
let x = STATIC_CELL.uninit().write(($val));
x
}};
}
async fn node_task_listener(mut client: &mut CSINodeClient) {
log_ln!("Starting Listener Task");
let mut last_log_time = Instant::now();
with_timeout(Duration::from_secs(10), async {
loop {
Timer::after(Duration::from_millis(10)).await;
}
})
.await
.unwrap_err();
client.send_stop().await;
}
async fn node_task_collector(mut client: &mut CSINodeClient) {
log_ln!("Starting Collector Task");
with_timeout(Duration::from_secs(10), async {
loop {
Timer::after_secs(1).await;
log_ln!(
"RX PPS: {}, TX PPS: {}, RX Dropped Packets: {}, One Way Latency: {}, Two Way Latency: {}",
get_pps_rx(),
get_pps_tx(),
get_dropped_packets_rx(),
get_one_way_latency(),
get_two_way_latency()
)
}
})
.await
.unwrap_err();
client.send_stop().await;
}
#[esp_rtos::main]
async fn main(spawner: Spawner) -> ! {
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config);
init_logger(spawner, LogMode::Text);
esp_alloc::heap_allocator!(#[esp_hal::ram(reclaimed)] size: 61440);
let timg0 = TimerGroup::new(peripherals.TIMG0);
#[cfg(any(feature = "esp32c6", feature = "esp32c3"))]
{
let sw_interrupt =
esp_hal::interrupt::software::SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
esp_rtos::start(timg0.timer0, sw_interrupt.software_interrupt0);
}
#[cfg(not(any(feature = "esp32c6", feature = "esp32c3")))]
esp_rtos::start(timg0.timer0);
log_ln!("Embassy initialized!");
log_ln!("Starting Runtime Config Node");
let radio_init = mk_static!(
Controller<'static>,
esp_radio::init().expect("Failed to initialize Wi-Fi/BLE controller")
);
let mut config_radio = esp_radio::wifi::Config::default();
config_radio = config_radio.with_power_save_mode(esp_radio::wifi::PowerSaveMode::None);
let (wifi_controller, mut interfaces) =
esp_radio::wifi::new(radio_init, peripherals.WIFI, config_radio)
.expect("Failed to initialize Wi-Fi controller");
let controller = WIFI_CONTROLLER.init(wifi_controller);
let mut node_handle = CSINodeClient::new();
let mut csi_hardware = CSINodeHardware::new(&mut interfaces, controller);
let mut node = CSINode::new(
esp_csi_rs::Node::Central(esp_csi_rs::CentralOpMode::EspNow(
(EspNowConfig::default()),
)),
CollectionMode::Collector,
Some(CsiConfig::default()),
Some(1000),
csi_hardware,
);
node.set_protocol(esp_radio::wifi::Protocol::P802D11BGNLR);
node.set_rate(esp_radio::esp_now::WifiPhyRate::RateMcs0Lgi);
join(node.run(), node_task_collector(&mut node_handle)).await;
node.set_collection_mode(CollectionMode::Listener);
join(node.run(), node_task_listener(&mut node_handle)).await;
loop {
log_ln!("Hello world!");
Timer::after(Duration::from_secs(1)).await;
}
}