Interface refactor 2
This commit is contained in:
+24
-3
@@ -1,26 +1,47 @@
|
||||
//! High-level PN532 command driver.
|
||||
|
||||
use core::marker::PhantomData;
|
||||
use crate::commands::*;
|
||||
use crate::error::Error;
|
||||
use crate::interface::Interface;
|
||||
use crate::StatusCode;
|
||||
use crate::{NoIrq, NoReset, StatusCode};
|
||||
use core::time::Duration;
|
||||
use embedded_hal::delay::DelayNs;
|
||||
use embedded_hal::digital::{InputPin, OutputPin};
|
||||
use crate::types::constants::{PN532_GPIO_P32, PN532_GPIO_P34, PN532_GPIO_VALIDATION_BIT};
|
||||
|
||||
/// Driver for the NXP PN532 NFC controller.
|
||||
pub struct Pn532<B: Interface, const N: usize = 64> {
|
||||
pub struct Pn532<RST, IRQ, DELAY, B, const N: usize = 64>
|
||||
where
|
||||
RST: OutputPin,
|
||||
IRQ: InputPin,
|
||||
DELAY: DelayNs,
|
||||
B: Interface<RST, IRQ, DELAY>
|
||||
{
|
||||
pub(crate) interface: B,
|
||||
pub(crate) in_listed_tag: u8,
|
||||
pub(crate) buffer: [u8; N],
|
||||
_rst: PhantomData<RST>,
|
||||
_irq: PhantomData<IRQ>,
|
||||
_delay: PhantomData<DELAY>,
|
||||
}
|
||||
|
||||
impl<B: Interface, const N: usize> Pn532<B, N> {
|
||||
impl<RST, IRQ, DELAY, B, const N: usize> Pn532<RST, IRQ, DELAY, B, N>
|
||||
where
|
||||
RST: OutputPin,
|
||||
IRQ: InputPin,
|
||||
DELAY: DelayNs,
|
||||
B: Interface<RST, IRQ, DELAY>
|
||||
{
|
||||
/// Create a driver over the given transport interface.
|
||||
pub fn new(interface: B) -> Self {
|
||||
Self {
|
||||
interface,
|
||||
in_listed_tag: 0,
|
||||
buffer: [0; N],
|
||||
_rst: PhantomData,
|
||||
_irq: PhantomData,
|
||||
_delay: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-12
@@ -77,7 +77,7 @@ impl<I2C, D, RST, IRQ> I2cInterface<I2C, D, RST, IRQ> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<I2C, D, RST, IRQ> Interface for I2cInterface<I2C, D, RST, IRQ>
|
||||
impl<I2C, D, RST, IRQ> Interface<RST, IRQ, D> for I2cInterface<I2C, D, RST, IRQ>
|
||||
where
|
||||
I2C: I2c,
|
||||
D: DelayNs,
|
||||
@@ -86,17 +86,16 @@ where
|
||||
{
|
||||
type TransportError = I2C::Error;
|
||||
|
||||
fn begin(&mut self) -> Result<(), Error<Self::TransportError>> {
|
||||
// Pulse RSTPD_N: high -> low -> wait -> high -> wait. This mirrors the
|
||||
// Adafruit library's begin() reset sequence.
|
||||
self.reset.set_high().map_err(|_| Error::UnusedPin)?;
|
||||
self.reset.set_low().map_err(|_| Error::UnusedPin)?;
|
||||
self.delay.delay_ms(400);
|
||||
self.reset.set_high().map_err(|_| Error::UnusedPin)?;
|
||||
// Let the PN532 boot after the reset is released. The Adafruit library
|
||||
// waits ~10 ms + a 500 ms wakeup here; give it a full 500 ms.
|
||||
self.delay.delay_ms(500);
|
||||
Ok(())
|
||||
fn rst(&mut self) -> &mut RST {
|
||||
&mut self.reset
|
||||
}
|
||||
|
||||
fn irq(&mut self) -> &mut IRQ {
|
||||
&mut self.irq
|
||||
}
|
||||
|
||||
fn delay(&mut self) -> &mut D {
|
||||
&mut self.delay
|
||||
}
|
||||
|
||||
fn write_command(
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
//! acknowledgement/response handshake.
|
||||
|
||||
mod i2c;
|
||||
|
||||
use embedded_hal::delay::DelayNs;
|
||||
pub use i2c::I2cInterface;
|
||||
|
||||
use embedded_hal::digital::{ErrorKind, ErrorType, InputPin, OutputPin};
|
||||
@@ -58,13 +60,28 @@ impl InputPin for NoIrq {
|
||||
///
|
||||
/// Implementations are responsible for the frame/ack handshake described in
|
||||
/// the PN532 user manual (UM0701-02).
|
||||
pub trait Interface {
|
||||
pub trait Interface<RST: OutputPin, IRQ: InputPin, DELAY: DelayNs> {
|
||||
/// The error type produced by the underlying physical transport.
|
||||
type TransportError;
|
||||
|
||||
/// Initialise the hardware: pulse the reset pin (if provided) and wait for
|
||||
/// Initialize the hardware: pulse the reset pin (if provided) and wait for
|
||||
/// the PN532 to become ready.
|
||||
fn begin(&mut self) -> Result<(), Error<Self::TransportError>>;
|
||||
fn begin(&mut self) -> Result<(), Error<Self::TransportError>> {
|
||||
// Pulse RSTPD_N: high -> low -> wait -> high -> wait. This mirrors the
|
||||
// Adafruit library's begin() reset sequence.
|
||||
self.rst().set_high().map_err(|_| Error::UnusedPin)?;
|
||||
self.rst().set_low().map_err(|_| Error::UnusedPin)?;
|
||||
self.delay().delay_ms(400);
|
||||
self.rst().set_high().map_err(|_| Error::UnusedPin)?;
|
||||
// Let the PN532 boot after the reset is released. The Adafruit library
|
||||
// waits ~10 ms + a 500 ms wakeup here; give it a full 500 ms.
|
||||
self.delay().delay_ms(500);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn rst(&mut self) -> &mut RST;
|
||||
fn irq(&mut self) -> &mut IRQ;
|
||||
fn delay(&mut self) -> &mut DELAY;
|
||||
|
||||
/// Write a command frame (`header` + optional `body`) and wait for the ACK.
|
||||
fn write_command(
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
use des::cipher::{Block, BlockCipherEncrypt, Key, KeyInit};
|
||||
use des::TdesEde2;
|
||||
use embedded_hal::delay::DelayNs;
|
||||
use embedded_hal::digital::{InputPin, OutputPin};
|
||||
use rand_core::Rng;
|
||||
use crate::{Interface, Pn532};
|
||||
use crate::types::felica::{CardSession, FelicaLiteSBlock, FelicaLiteSServiceCode};
|
||||
use crate::types::felica::felica_lite_s::auth::{AuthSession, CardKey, MacInput, RandomChallenge, SessionKeys};
|
||||
|
||||
impl<B: Interface, const N: usize> Pn532<B, N> {
|
||||
impl<RST, IRQ, DELAY, B, const N: usize> Pn532<RST, IRQ, DELAY, B, N>
|
||||
where
|
||||
RST: OutputPin,
|
||||
IRQ: InputPin,
|
||||
DELAY: DelayNs,
|
||||
B: Interface<RST, IRQ, DELAY>
|
||||
{
|
||||
pub(crate) fn set_random_challenge(&mut self, card: &CardSession, rng: &mut impl Rng)
|
||||
-> Result<RandomChallenge, crate::Error<B::TransportError>>
|
||||
{
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
use embedded_hal::delay::DelayNs;
|
||||
use embedded_hal::digital::{InputPin, OutputPin};
|
||||
use crate::{Interface, Pn532};
|
||||
|
||||
impl<B: Interface, const N: usize> Pn532<B, N> {
|
||||
impl<RST, IRQ, DELAY, B, const N: usize> Pn532<RST, IRQ, DELAY, B, N>
|
||||
where
|
||||
RST: OutputPin,
|
||||
IRQ: InputPin,
|
||||
DELAY: DelayNs,
|
||||
B: Interface<RST, IRQ, DELAY>
|
||||
{
|
||||
pub fn setup_first_issuance(&mut self) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
pub mod issuance;
|
||||
pub mod auth;
|
||||
|
||||
use embedded_hal::delay::DelayNs;
|
||||
use embedded_hal::digital::{InputPin, OutputPin};
|
||||
use rand_core::Rng;
|
||||
use crate::{Interface, Pn532};
|
||||
use crate::protocol::felica::error::Error;
|
||||
use crate::types::felica::{AsBlock, CardSession, FelicaLiteSBlock, FelicaLiteSServiceCode};
|
||||
use crate::types::felica::felica_lite_s::auth::{AuthSession, CardKey, MacInput};
|
||||
|
||||
impl<B: Interface, const N: usize> Pn532<B, N> {
|
||||
impl<RST, IRQ, DELAY, B, const N: usize> Pn532<RST, IRQ, DELAY, B, N>
|
||||
where
|
||||
RST: OutputPin,
|
||||
IRQ: InputPin,
|
||||
DELAY: DelayNs,
|
||||
B: Interface<RST, IRQ, DELAY>
|
||||
{
|
||||
pub fn try_authenticate(&mut self, rng: &mut impl Rng, card: &CardSession, key: &CardKey)
|
||||
-> Result<Option<AuthSession>, crate::Error<B::TransportError>>
|
||||
{
|
||||
|
||||
@@ -8,11 +8,19 @@ use crate::driver::Pn532;
|
||||
use crate::error::Error;
|
||||
use crate::interface::Interface;
|
||||
use core::time::Duration;
|
||||
use embedded_hal::delay::DelayNs;
|
||||
use embedded_hal::digital::{InputPin, OutputPin};
|
||||
use crate::types::felica::*;
|
||||
use crate::types::BaudRate;
|
||||
use crate::types::felica::constants::{FELICA_READ_MAX_BLOCK_NUM, FELICA_READ_MAX_SERVICE_NUM, FELICA_WRITE_MAX_BLOCK_NUM, FELICA_WRITE_MAX_SERVICE_NUM};
|
||||
|
||||
impl<B: Interface, const N: usize> Pn532<B, N> {
|
||||
impl<RST, IRQ, DELAY, B, const N: usize> Pn532<RST, IRQ, DELAY, B, N>
|
||||
where
|
||||
RST: OutputPin,
|
||||
IRQ: InputPin,
|
||||
DELAY: DelayNs,
|
||||
B: Interface<RST, IRQ, DELAY>
|
||||
{
|
||||
/// Poll for a FeliCa card.
|
||||
pub fn felica_polling(
|
||||
&mut self,
|
||||
|
||||
+9
-2
@@ -2,7 +2,8 @@ use crate::commands::*;
|
||||
use crate::error::StatusCode;
|
||||
use crate::{Error, Interface, Pn532};
|
||||
use core::time::Duration;
|
||||
|
||||
use embedded_hal::delay::DelayNs;
|
||||
use embedded_hal::digital::{InputPin, OutputPin};
|
||||
|
||||
/// Outcome of [`Pn532::tg_init_as_target`] / [`Pn532::tg_init_as_target_default`].
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
@@ -16,7 +17,13 @@ pub enum TargetInitStatus {
|
||||
Failed,
|
||||
}
|
||||
|
||||
impl<B: Interface, const N: usize> Pn532<B, N> {
|
||||
impl<RST, IRQ, DELAY, B, const N: usize> Pn532<RST, IRQ, DELAY, B, N>
|
||||
where
|
||||
RST: OutputPin,
|
||||
IRQ: InputPin,
|
||||
DELAY: DelayNs,
|
||||
B: Interface<RST, IRQ, DELAY>
|
||||
{
|
||||
/// Initialize the PN532 as a target using a raw command frame.
|
||||
pub fn tg_init_as_target(
|
||||
&mut self,
|
||||
|
||||
@@ -21,7 +21,7 @@ fn get_card_key() -> &'static CardKey {
|
||||
}
|
||||
|
||||
pub struct CardReader<'a> {
|
||||
driver: Pn532<pn532::I2cInterface<SharedI2c<'a>, Delay, gpio::Output<'a>, gpio::Input<'a>>>
|
||||
driver: Pn532<gpio::Output<'a>, gpio::Input<'a>, Delay, pn532::I2cInterface<SharedI2c<'a>, Delay, gpio::Output<'a>, gpio::Input<'a>>>
|
||||
}
|
||||
|
||||
impl<'a> CardReader<'a> {
|
||||
|
||||
Reference in New Issue
Block a user