use core::sync::atomic::AtomicBool; use embassy_rp::gpio::Input; use embassy_rp::multicore::spawn_core1; use embassy_rp::multicore::Stack; use embassy_rp::peripherals::CORE1; use embassy_rp::peripherals::PIN_16; use embassy_rp::peripherals::PIN_17; use embassy_time::Timer; use log::info; use super::CHANNEL; use super::BIT; use super::READ_CARD; /// disable scanner when doing emf heavy operations pub static LOCKOUT: AtomicBool = AtomicBool::new(false); #[embassy_executor::task] pub(crate) async fn data_extractor() -> ! { let mut last_bit = 0; loop { Timer::after_millis(75).await; let card = critical_section::with(|cs| { READ_CARD.borrow(cs).clone().into_inner() }); let bit = BIT.load(core::sync::atomic::Ordering::SeqCst); if bit == last_bit { if card !=0 { info!("read a card: {card:#16x}"); if LOCKOUT.load(core::sync::atomic::Ordering::Relaxed) { info!("scanner disabled"); } else { CHANNEL.send(card).await; } } critical_section::with(|cs| { READ_CARD.replace(cs, 0); }); } last_bit = bit; } } pub fn spawn_poller(core: CORE1, data_0: PIN_17, data_1: PIN_16) { let data_0= Input::new(data_0, embassy_rp::gpio::Pull::None); let data_1= Input::new(data_1, embassy_rp::gpio::Pull::None); let mut partial: u64 = 0; let mut bit: u8 = 0; let mut prev: (bool,bool) = (false,false); static mut CORE1_STACK: Stack<4096> = Stack::new(); spawn_core1(core, unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, move || { loop { let current = (data_0.is_low(), data_1.is_low()); if current.1 && !prev.1 { partial |= 1 << bit; bit += 1; } if current.0 && !prev.0 { partial &= !(1u64).rotate_left(bit as u32); bit += 1; } prev=current; critical_section::with(|cs| { let mut foreign_partial = READ_CARD.borrow_ref_mut(cs); // may or may not be sound, should work fine given no noise on the signal if *foreign_partial != partial && !current.0 && !current.1 { bit = 0; partial = *foreign_partial; } *foreign_partial = partial; }); BIT.store(bit, core::sync::atomic::Ordering::SeqCst); } }); }