Add read/write for felica

felica types refactor
This commit is contained in:
2026-08-27 10:02:50 +08:00
parent 0810cdb892
commit 86373a2d33
19 changed files with 875 additions and 184 deletions
+35 -10
View File
@@ -6,8 +6,8 @@ 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 pn532::felica::{FelicaBlock, FelicaPollingRequestCode, FelicaServiceCode};
use pn532::{BaudRate, Pn532};
static CARD_KEY: OnceLock<heapless::Vec<u8, 16>> = OnceLock::new();
@@ -21,17 +21,18 @@ fn get_card_key() -> &'static heapless::Vec<u8, 16> {
}
pub struct CardReader<'a> {
driver: Pn532<pn532::I2cInterface<SharedI2c<'a>, Delay, pn532::NoReset, gpio::Input<'a>>>
driver: Pn532<pn532::I2cInterface<SharedI2c<'a>, Delay, gpio::Output<'a>, gpio::Input<'a>>>
}
impl<'a> CardReader<'a> {
pub fn new(i2c: SharedI2c<'a>, irq: gpio::Input<'a>) -> Self {
pub fn new(i2c: SharedI2c<'a>, irq: gpio::Input<'a>, reset: gpio::Output<'a>) -> Self {
Self {
driver: Pn532::new(pn532::I2cInterface::with_irq(i2c, Delay, irq))
driver: Pn532::new(pn532::I2cInterface::with_reset_irq(i2c, Delay, reset, irq))
}
}
pub fn init(&mut self) -> Result<(), crate::error::Error> {
self.driver.begin()?;
self.driver.sam_config()?;
Ok(())
}
@@ -50,20 +51,43 @@ pub async fn start_card_reader(
loop {
Timer::after_millis(50).await;
let poll_result = match card_reader.driver.felica_polling(0xFFFF, 0x01, 1000) {
let Some(response) = (match card_reader.driver.felica_polling(
None,
BaudRate::Felica424kbps,
FelicaPollingRequestCode::SystemCode,
core::time::Duration::from_secs(1),
) {
Ok(v) => v,
Err(e) => {
defmt::error!("card_reader driver error: {}", e);
continue;
}
};
let Some(res) = poll_result else {
}) else {
defmt::trace!("No card detected");
continue;
};
defmt::info!("Polling card: {}", Debug2Format(&res));
defmt::info!("Polling card: {}", Debug2Format(&response));
let mut data = [[0u8; 16]; 3];
// user blocks 0x0000..0x000D via the raw u16 AsBlock impl; a single read
// is capped at 3 blocks by the 64-byte packet buffer (response = 14 + 16n).
let blocks: [u16; 3] = [0x0000, 0x0001, 0x0002];
match card_reader.driver.felica_read_without_encryption(
&response.idm,
&response.pmm,
&[FelicaServiceCode::Read],
&blocks,
&mut data,
) {
Ok(_) => {},
Err(e) => {
defmt::error!("unable to read blocks: {}", e);
continue;
}
}
defmt::debug!("Blocks: {:?}", data);
match card_reader.driver.felica_release() {
match card_reader.driver.release() {
Ok(_) => {},
Err(e) => {
defmt::error!("card_reader release error: {}", e);
@@ -76,5 +100,6 @@ pub async fn start_card_reader(
if let Err(e) = card_reader.driver.set_rf_field(0x00, 0x01) {
defmt::error!("card_reader RF field error: {}", e);
}
Timer::after_millis(200).await;
}
}