Add card detection

This commit is contained in:
2026-08-26 00:08:47 +08:00
parent 5c95cc40f7
commit 261b04fec3
69 changed files with 2178 additions and 5928 deletions
+80
View File
@@ -0,0 +1,80 @@
use core::sync::atomic::{AtomicPtr, Ordering};
use defmt::Debug2Format;
use embassy_sync::once_lock::OnceLock;
use embassy_time::{Delay, Timer};
use esp_hal::gpio;
use esp_hal::rng::Trng;
use lorawan_device::RngCore;
use pn532::felica::FelicaBlock;
use pn532::Pn532;
use crate::types::{LoraPublisher, SharedI2c};
static CARD_KEY: OnceLock<heapless::Vec<u8, 16>> = OnceLock::new();
fn get_card_key() -> &'static heapless::Vec<u8, 16> {
CARD_KEY.get_or_init(|| {
let hex_string = env!("CARD_KEY");
let mut buffer = [0u8; 16];
hex::decode_to_slice(hex_string, &mut buffer).unwrap();
heapless::Vec::from_array(buffer)
})
}
pub struct CardReader<'a> {
driver: Pn532<pn532::I2cInterface<SharedI2c<'a>, Delay, pn532::NoReset, gpio::Input<'a>>>
}
impl<'a> CardReader<'a> {
pub fn new(i2c: SharedI2c<'a>, irq: gpio::Input<'a>) -> Self {
Self {
driver: Pn532::new(pn532::I2cInterface::with_irq(i2c, Delay, irq))
}
}
pub fn init(&mut self) -> Result<(), crate::error::Error> {
self.driver.sam_config()?;
Ok(())
}
}
#[embassy_executor::task]
pub async fn start_card_reader(
mut card_reader: CardReader<'static>,
mut publisher: LoraPublisher<'static>,
mut trng: Trng
) -> () {
let card_key = get_card_key();
let mut rc = [0u8; 16];
trng.fill_bytes(&mut rc);
defmt::trace!("card_key: {}", hex::encode_upper(card_key));
loop {
Timer::after_millis(50).await;
let poll_result = match card_reader.driver.felica_polling(0xFFFF, 0x01, 1000) {
Ok(v) => v,
Err(e) => {
defmt::error!("card_reader driver error: {}", e);
continue;
}
};
let Some(res) = poll_result else {
defmt::trace!("No card detected");
continue;
};
defmt::info!("Polling card: {}", Debug2Format(&res));
match card_reader.driver.felica_release() {
Ok(_) => {},
Err(e) => {
defmt::error!("card_reader release error: {}", e);
continue;
}
};
// InRelease switches the RF field off when no target remains
// (UM0701-02 §7.3.11), so re-enable it before the next poll.
if let Err(e) = card_reader.driver.set_rf_field(0x00, 0x01) {
defmt::error!("card_reader RF field error: {}", e);
}
}
}