86 lines
2.5 KiB
Rust
86 lines
2.5 KiB
Rust
|
|
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);
|
|
}
|
|
});
|
|
}
|