From 744a844f75d5f9ad694ac23932ff9061655691f8 Mon Sep 17 00:00:00 2001 From: ede1998 Date: Wed, 29 Jul 2026 22:24:36 +0200 Subject: [PATCH] compiling nfc code --- Cargo.lock | 11 +++++ Cargo.toml | 1 + src/bin/main.rs | 124 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 135 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 71a35fd..9ccd996 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,6 +125,7 @@ dependencies = [ "esp-rtos", "ili9341", "log", + "pn532", "smoltcp", ] @@ -1217,6 +1218,16 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "pn532" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce656b2f9335bedbd8806597f6f78e644a955366673cd9280a0fb67a0d7b35a1" +dependencies = [ + "embedded-hal 1.0.0", + "nb 1.1.0", +] + [[package]] name = "portable-atomic" version = "1.14.0" diff --git a/Cargo.toml b/Cargo.toml index 5a40134..d9d4185 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ embedded-hal = "1.0.0" embedded-hal-bus = "0.3.0" embedded-graphics = "0.8.2" embedded-graphics-core = "0.4.1" +pn532 = "0.5.0" # For fine tuning these settings, please refer to https://doc.rust-lang.org/cargo/reference/profiles.html diff --git a/src/bin/main.rs b/src/bin/main.rs index 4361eef..7299d03 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -7,6 +7,8 @@ )] #![deny(clippy::large_stack_frames)] +use core::convert::Infallible; + use display_interface_spi::SPIInterface; use embedded_graphics::Drawable; use embedded_graphics::mono_font::MonoTextStyle; @@ -27,12 +29,14 @@ use esp_hal::spi::{ Mode, master::{Config, Spi}, }; -use esp_hal::time::Rate; use esp_hal::time::{Duration, Instant}; use esp_hal::timer::timg::TimerGroup; +use esp_println::dbg; use ili9341::Ili9341; use ili9341::Orientation; use log::{error, info}; +use pn532::i2c::I2CInterface; +use pn532::nb; #[panic_handler] fn panic(panic_info: &core::panic::PanicInfo) -> ! { @@ -67,6 +71,9 @@ fn main() -> ! { let dc = peripherals.GPIO17; let reset_main = peripherals.GPIO16; + let sda = peripherals.GPIO21; + let scl = peripherals.GPIO22; + esp_alloc::heap_allocator!(#[esp_hal::ram(reclaimed)] size: 73744); let timg0 = TimerGroup::new(peripherals.TIMG0); @@ -112,11 +119,126 @@ fn main() -> ! { .draw(&mut display) .unwrap(); + use pn532::{Pn532, Request, requests::SAMMode}; + + // spi is a struct implementing embedded_hal::spi::SpiDevice + // timer is a struct implementing pn532::CountDown + + use esp_hal::{ + i2c::master::{Config as I2cConfig, I2c}, + time::Rate, + }; + + let config = I2cConfig::default().with_frequency(Rate::from_khz(100)); + let i2c = I2c::new(peripherals.I2C0, config) + .expect("Failed to init I2C") + .with_sda(sda) + .with_scl(scl); + + let mut pn532: Pn532<_, _, 32> = Pn532::new(I2CInterface { i2c }, TimerWrapper::new()); + + let ms_50 = Duration::from_millis(50); + let ms_1000 = Duration::from_millis(1000); loop { info!("Hello world!"); + + if let Err(e) = pn532.process( + &Request::sam_configuration(SAMMode::Normal, false), + 0, + ms_1000, + ) { + error!("Could not initialize PN532: {e:?}") + } else { + info!("Successfully init'ed PN532"); + } + if let Ok(uid) = pn532.process(&Request::INLIST_ONE_ISO_A_TARGET, 7, ms_1000) { + info!("uid = {uid:?}"); + let result = pn532.process(&Request::ntag_read(10), 17, ms_1000).unwrap(); + // if result[0] == 0x00 { + info!("page 10: {:?}", &result[1..5]); + // } + } + else { + info!("No NFC card found."); + } + let delay_start = Instant::now(); while delay_start.elapsed() < Duration::from_millis(500) {} } // for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/esp-hal-v1.1.0/examples } + +struct TimerWrapper { + // TODO Is that timer accurate enough? + start: Instant, + duration: Duration, + counter: u32, +} + +impl TimerWrapper { + pub fn new() -> Self { + Self { + start: Instant::now(), + duration: Duration::ZERO, + counter: 0, + } + } +} + +impl pn532::CountDown for TimerWrapper { + type Time = Duration; + + fn start(&mut self, timeout: T) + where + T: Into, + { + // without this debug log, it works worse: stuck in NFC card search without ever returning. + self.start = dbg!(Instant::now()); + self.duration = timeout.into(); + self.counter = 0; + } + + fn wait(&mut self) -> nb::Result<(), Infallible> { + let elapsed = self.start.elapsed(); + self.counter += 1; + if self.counter.is_multiple_of(1) { + info!("Elapsed: {elapsed}"); + } + if elapsed >= self.duration { + Ok(()) + } else { + Err(nb::Error::WouldBlock) + } + } +} + +/* +struct TimerWrapper<'a, T> +where + T: esp_hal::DriverMode, +{ + timer: esp_hal::timer::PeriodicTimer<'a, T>, +} + +impl<'a, TIM> pn532::CountDown for TimerWrapper<'a, TIM> +where + TIM: esp_hal::DriverMode, +{ + type Time = Duration; + fn start(&mut self, timeout: T) + where + T: Into, + { + self.timer.start(timeout.into()).unwrap(); + } + + fn wait(&mut self) -> nb::Result<(), Infallible> { + // convert nb::Result<(), void::Void> to nb::Result<(), Infallible> + match self.timer.wait() { + Ok(_) => Ok(()), + Err(_) => Err(nb::Error::WouldBlock), + } + } +} + */