use crate::navigation::navigation::display_error; use crate::{ navigation::{navigation::Mutex, outputs::Outputs, state::NavigationState}, peripherals::Peripherals, }; use alloc::string::ToString; use embedded_hal_bus::i2c::AtomicDevice; use esp_hal::{Blocking, i2c::master::I2c, time::Instant}; use crate::{ card::{decoder::split_nfc_hex, model::Card}, drivers::nfc_pn532::NfcPn532Driver, navigation::navigation::CARD_DATA, }; #[embassy_executor::task] #[allow( clippy::large_stack_frames, reason = "ignoring this for now because it still works" )] pub async fn nfc_scanner( mut nfc_driver: NfcPn532Driver>>, outputs: &'static Mutex, peripherals: &'static Peripherals, navigation_state: &'static Mutex, ) { loop { while CARD_DATA.lock().await.is_none() { let start = Instant::now(); match nfc_driver.read_card_data().await { Ok(card_data) => { let Some(split_data) = split_nfc_hex(&card_data) else { log::error!("Failed to split NFC card data"); continue; }; let card = match Card::try_from(split_data) { Ok(card) => card, Err(err) => { log::error!("Invalid card data: {err}"); continue; } }; CARD_DATA.lock().await.replace(card); match peripherals .store .lock() .await .card_store .save_raw_card(split_data, peripherals.rtc.current_time_us()) .await { Ok(()) => {} Err(error) => { log::error!("Error storing card in flash: {:?}", error); display_error( error.to_string(), navigation_state, outputs, peripherals, ) .await; } } let elapsed_ms = start.elapsed().as_millis(); log::info!( "NFC read duration: {} ms, card data length: {}", elapsed_ms, card_data.len() ); } Err(_) => { log::info!("No NFC card found"); } } } embassy_time::Timer::after(embassy_time::Duration::from_millis(1000)).await; } }