Skip to content

Commit 26c6b95

Browse files
committed
explore: esp-now communication
1 parent 0d452cf commit 26c6b95

File tree

3 files changed

+163
-88
lines changed

3 files changed

+163
-88
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ dyn-smooth = "0.2.0"
4040
esp-hal-ota = { version = "0.4.0", features = [] }
4141
esp32c3 = { version = "0.28.0", optional = true }
4242
esp32 = { version = "0.36.0", optional = true }
43-
anyhow = { version = "1.0.97", default-features = false }
43+
anyhow = { version = "1.0.98", default-features = false }
4444
embedded-hal-bus = { version = "0.3.0", features = ["async"] }
4545
embedded-tls = { version = "0.17.0", default-features = false, features = ["alloc", "embedded-io-adapters", "log"] }
4646
rand_core = { version = "0.6.4", features = ["getrandom"] }
@@ -54,6 +54,7 @@ mfrc522-02 = { version = "0.2.1", features = ["embassy-time"], package = "esp-ha
5454
default = ["esp32c3", "sleep"]
5555
esp32 = ["esp-backtrace/esp32", "esp-hal/esp32", "esp-println/esp32", "esp-wifi/esp32", "esp-hal-embassy/esp32", "esp-storage/esp32", "esp-hal-wifimanager/esp32", "esp-hal-ota/esp32", "dep:esp32", "dep:mfrc522-01", "dep:port-expander", "ag-lcd-async/i2c"]
5656
esp32c3 = ["esp-backtrace/esp32c3", "esp-hal/esp32c3", "esp-println/esp32c3", "esp-wifi/esp32c3", "esp-hal-embassy/esp32c3", "esp-storage/esp32c3", "esp-hal-wifimanager/esp32c3", "esp-hal-ota/esp32c3", "dep:esp32c3", "dep:mfrc522-02"]
57+
esp_now = ["esp-wifi/esp-now"]
5758
gen_version = []
5859
bat_dev_lcd = []
5960
release_build = ["sleep"]

src/main.rs

Lines changed: 159 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use embassy_time::{Instant, Timer};
1414
use esp_backtrace as _;
1515
use esp_hal_wifimanager::{Nvs, WIFI_NVS_KEY};
1616
use esp_storage::FlashStorage;
17+
use esp_wifi::esp_now::{EspNowManager, EspNowSender};
1718
use state::{ota_state, sleep_state, GlobalState, GlobalStateInner, SavedGlobalState, Scene};
1819
use structs::ConnSettings;
1920
use utils::{logger::FkmLogger, set_brownout_detection};
@@ -52,6 +53,16 @@ pub fn custom_rng(buf: &mut [u8]) -> Result<(), getrandom::Error> {
5253
}
5354
getrandom::register_custom_getrandom!(custom_rng);
5455

56+
const ESP_NOW_DST: &[u8; 6] = &[156, 158, 110, 52, 70, 200];
57+
macro_rules! mk_static {
58+
($t:ty,$val:expr) => {{
59+
static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new();
60+
#[deny(unused_attributes)]
61+
let x = STATIC_CELL.uninit().write(($val));
62+
x
63+
}};
64+
}
65+
5566
#[esp_hal_embassy::main]
5667
async fn main(spawner: Spawner) {
5768
let peripherals = esp_hal::init({
@@ -176,101 +187,142 @@ async fn main(spawner: Spawner) {
176187
}
177188
}
178189

179-
let wifi_res = esp_hal_wifimanager::init_wm(
180-
wm_settings,
181-
&spawner,
182-
#[cfg(feature = "qa")]
183-
None,
184-
#[cfg(not(feature = "qa"))]
185-
Some(&nvs),
186-
board.rng,
187-
board.timg0.timer0,
188-
board.radio_clk,
189-
board.wifi,
190-
board.bt,
191-
Some(wifi_setup_sig),
192-
)
193-
.await;
194-
195-
let Ok(mut wifi_res) = wifi_res else {
196-
log::error!("WifiManager failed!!! Restarting in 1s!");
197-
Timer::after_millis(1000).await;
198-
esp_hal::system::software_reset();
199-
};
190+
#[cfg(feature = "esp_now")]
191+
{
192+
let init = &*mk_static!(
193+
esp_wifi::EspWifiController<'static>,
194+
esp_wifi::init(board.timg0.timer0, board.rng.clone(), board.radio_clk).unwrap()
195+
);
196+
197+
let (manager, tx, mut rx) = esp_wifi::esp_now::EspNow::new(&init, board.wifi)
198+
.unwrap()
199+
.split();
200+
201+
_ = manager.set_power_saving(esp_wifi::config::PowerSaveMode::None);
202+
//_ = manager.set_rate(esp_wifi::esp_now::WifiPhyRate::RateMax);
203+
_ = manager.set_pmk(&[69, 4, 2, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
204+
205+
spawner.must_spawn(bc_test_task(tx, manager));
206+
let mut last_counter = 0;
207+
loop {
208+
let recv = rx.receive_async().await;
209+
log::info!("ESP_NOW frame recv: {:?}", recv.info);
210+
log::info!("{:?}", recv.data());
211+
212+
if &recv.info.dst_address == ESP_NOW_DST {
213+
if recv.data().len() == 16 {
214+
let counter = u128::from_be_bytes(recv.data().try_into().unwrap());
215+
if counter - last_counter == 0 {
216+
log::warn!("First packet?");
217+
} else if counter - last_counter > 1 {
218+
log::error!("PACKET LOST!");
219+
}
220+
221+
last_counter = counter;
222+
}
223+
}
224+
}
225+
}
200226

201-
#[cfg(feature = "qa")]
202-
crate::qa::send_qa_resp(crate::qa::QaSignal::WifiSetup);
203-
204-
let conn_settings: ConnSettings = wifi_res
205-
.data
206-
.take()
207-
.and_then(|d| serde_json::from_value(d).ok())
208-
.unwrap_or_default();
209-
210-
let mut parse_retry_count = 0;
211-
let ws_url = loop {
212-
let url = if conn_settings.mdns || conn_settings.ws_url.is_none() || parse_retry_count > 0 {
213-
log::info!("Starting mdns lookup...");
214-
global_state.state.lock().await.scene = Scene::MdnsWait;
215-
let mdns_res = mdns::mdns_query(wifi_res.sta_stack).await;
216-
log::info!("Mdns result: {:?}", mdns_res);
217-
218-
mdns_res.to_string()
219-
} else {
220-
conn_settings.ws_url.clone().expect("")
227+
#[cfg(not(feature = "esp_now"))]
228+
{
229+
let wifi_res = esp_hal_wifimanager::init_wm(
230+
wm_settings,
231+
&spawner,
232+
#[cfg(feature = "qa")]
233+
None,
234+
#[cfg(not(feature = "qa"))]
235+
Some(&nvs),
236+
board.rng,
237+
board.timg0.timer0,
238+
board.radio_clk,
239+
board.wifi,
240+
board.bt,
241+
Some(wifi_setup_sig),
242+
)
243+
.await;
244+
245+
let Ok(mut wifi_res) = wifi_res else {
246+
log::error!("WifiManager failed!!! Restarting in 1s!");
247+
Timer::after_millis(1000).await;
248+
esp_hal::system::software_reset();
221249
};
222250

223-
let ws_url = WsUrl::from_str(&url);
224-
match ws_url {
225-
Some(ws_url) => break WsUrlOwned::new(&ws_url),
226-
None => {
227-
parse_retry_count += 1;
228-
log::error!("Mdns parse failed! Retry ({parse_retry_count})..");
229-
Timer::after_millis(1000).await;
230-
if parse_retry_count > 3 {
231-
log::error!("Cannot parse wsurl! Reseting wifi configuration!");
232-
_ = nvs.invalidate_key(WIFI_NVS_KEY).await;
251+
#[cfg(feature = "qa")]
252+
crate::qa::send_qa_resp(crate::qa::QaSignal::WifiSetup);
253+
254+
let conn_settings: ConnSettings = wifi_res
255+
.data
256+
.take()
257+
.and_then(|d| serde_json::from_value(d).ok())
258+
.unwrap_or_default();
259+
260+
let mut parse_retry_count = 0;
261+
let ws_url = loop {
262+
let url =
263+
if conn_settings.mdns || conn_settings.ws_url.is_none() || parse_retry_count > 0 {
264+
log::info!("Starting mdns lookup...");
265+
global_state.state.lock().await.scene = Scene::MdnsWait;
266+
let mdns_res = mdns::mdns_query(wifi_res.sta_stack).await;
267+
log::info!("Mdns result: {:?}", mdns_res);
268+
269+
mdns_res.to_string()
270+
} else {
271+
conn_settings.ws_url.clone().expect("")
272+
};
273+
274+
let ws_url = WsUrl::from_str(&url);
275+
match ws_url {
276+
Some(ws_url) => break WsUrlOwned::new(&ws_url),
277+
None => {
278+
parse_retry_count += 1;
279+
log::error!("Mdns parse failed! Retry ({parse_retry_count})..");
233280
Timer::after_millis(1000).await;
281+
if parse_retry_count > 3 {
282+
log::error!("Cannot parse wsurl! Reseting wifi configuration!");
283+
_ = nvs.invalidate_key(WIFI_NVS_KEY).await;
284+
Timer::after_millis(1000).await;
234285

235-
esp_hal::system::software_reset();
236-
}
286+
esp_hal::system::software_reset();
287+
}
237288

238-
continue;
289+
continue;
290+
}
239291
}
240-
}
241-
};
292+
};
242293

243-
utils::backtrace_store::read_saved_backtrace().await;
294+
utils::backtrace_store::read_saved_backtrace().await;
295+
296+
let ws_sleep_sig = Rc::new(Signal::new());
297+
spawner.must_spawn(ws::ws_task(
298+
wifi_res.sta_stack,
299+
ws_url,
300+
global_state.clone(),
301+
ws_sleep_sig.clone(),
302+
));
303+
spawner.must_spawn(logger_task(global_state.clone()));
304+
305+
set_brownout_detection(true);
306+
global_state.state.lock().await.scene = Scene::WaitingForCompetitor;
307+
if let Some(saved_state) = SavedGlobalState::from_nvs(&nvs).await {
308+
global_state
309+
.state
310+
.lock()
311+
.await
312+
.parse_saved_state(saved_state);
313+
}
244314

245-
let ws_sleep_sig = Rc::new(Signal::new());
246-
spawner.must_spawn(ws::ws_task(
247-
wifi_res.sta_stack,
248-
ws_url,
249-
global_state.clone(),
250-
ws_sleep_sig.clone(),
251-
));
252-
spawner.must_spawn(logger_task(global_state.clone()));
253-
254-
set_brownout_detection(true);
255-
global_state.state.lock().await.scene = Scene::WaitingForCompetitor;
256-
if let Some(saved_state) = SavedGlobalState::from_nvs(&nvs).await {
257-
global_state
258-
.state
259-
.lock()
260-
.await
261-
.parse_saved_state(saved_state);
262-
}
315+
let mut last_sleep = false;
316+
loop {
317+
Timer::after_millis(100).await;
318+
if sleep_state() != last_sleep {
319+
last_sleep = sleep_state();
320+
ws_sleep_sig.signal(last_sleep);
263321

264-
let mut last_sleep = false;
265-
loop {
266-
Timer::after_millis(100).await;
267-
if sleep_state() != last_sleep {
268-
last_sleep = sleep_state();
269-
ws_sleep_sig.signal(last_sleep);
270-
271-
match last_sleep {
272-
true => wifi_res.stop_radio(),
273-
false => wifi_res.restart_radio(),
322+
match last_sleep {
323+
true => wifi_res.stop_radio(),
324+
false => wifi_res.restart_radio(),
325+
}
274326
}
275327
}
276328
}
@@ -313,3 +365,25 @@ async fn logger_task(global_state: GlobalState) {
313365
}
314366
}
315367
}
368+
369+
#[cfg(feature = "esp_now")]
370+
#[embassy_executor::task]
371+
async fn bc_test_task(mut tx: EspNowSender<'static>, manager: EspNowManager<'static>) {
372+
let mut counter = 0u128;
373+
loop {
374+
manager
375+
.add_peer(esp_wifi::esp_now::PeerInfo {
376+
peer_address: *ESP_NOW_DST,
377+
lmk: None,
378+
channel: None,
379+
encrypt: false,
380+
})
381+
.unwrap();
382+
383+
let r = tx.send_async(ESP_NOW_DST, &counter.to_be_bytes()).await;
384+
manager.remove_peer(ESP_NOW_DST).unwrap();
385+
386+
counter += 1;
387+
Timer::after_millis(1000).await;
388+
}
389+
}

0 commit comments

Comments
 (0)