75 lines
2.9 KiB
Rust
75 lines
2.9 KiB
Rust
use crate::commands::{PN532_COMMAND_TGGETDATA, PN532_COMMAND_TGINITASTARGET, PN532_COMMAND_TGSETDATA};
|
|
use crate::error::StatusCode;
|
|
use crate::{Error, Interface, Pn532, TargetInitStatus};
|
|
use core::time::Duration;
|
|
|
|
impl<B: Interface, const N: usize> Pn532<B, N> {
|
|
/// Initialize the PN532 as a target using a raw command frame.
|
|
pub fn tg_init_as_target(
|
|
&mut self,
|
|
command: &[u8],
|
|
timeout_ms: u16,
|
|
) -> Result<TargetInitStatus, Error<B::TransportError>> {
|
|
self.interface.write_command(command, &[])?;
|
|
match self.interface.read_response(&mut self.buffer, timeout_ms) {
|
|
Ok(_) => Ok(TargetInitStatus::Success),
|
|
Err(Error::Timeout) => Ok(TargetInitStatus::Timeout),
|
|
Err(_) => Ok(TargetInitStatus::Failed),
|
|
}
|
|
}
|
|
|
|
/// Initialize the PN532 as a target with the default LLCP parameters.
|
|
pub fn tg_init_as_target_default(
|
|
&mut self,
|
|
timeout_ms: u16,
|
|
) -> Result<TargetInitStatus, Error<B::TransportError>> {
|
|
const COMMAND: [u8; 44] = [
|
|
PN532_COMMAND_TGINITASTARGET, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0xFE,
|
|
0x0F, 0xBB, 0xBA, 0xA6, 0xC9, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0xFF, 0xFF, 0x01, 0xFE, 0x0F, 0xBB, 0xBA, 0xA6, 0xC9, 0x89, 0x00, 0x00, 0x06, 0x46,
|
|
0x66, 0x6D, 0x01, 0x01, 0x10, 0x00,
|
|
];
|
|
self.tg_init_as_target(&COMMAND, timeout_ms)
|
|
}
|
|
|
|
/// Retrieve data received from the initiator.
|
|
pub fn tg_get_data(&mut self, buf: &mut [u8]) -> Result<usize, Error<B::TransportError>> {
|
|
self.buffer[0] = PN532_COMMAND_TGGETDATA;
|
|
self.send(1)?;
|
|
|
|
let len = self.read_timeout(Duration::from_millis(3000))?;
|
|
if len == 0 {
|
|
return Ok(0);
|
|
}
|
|
if self.buffer[0] != 0 {
|
|
return Err(Error::Status(StatusCode::from_repr(self.buffer[0]).unwrap()));
|
|
}
|
|
let data_len = len - 1;
|
|
let copy_len = data_len.min(buf.len());
|
|
buf[..copy_len].copy_from_slice(&self.buffer[1..1 + copy_len]);
|
|
Ok(copy_len)
|
|
}
|
|
|
|
/// Send data to the initiator.
|
|
pub fn tg_set_data(
|
|
&mut self,
|
|
header: &[u8],
|
|
body: &[u8],
|
|
) -> Result<(), Error<B::TransportError>> {
|
|
if header.len() > N - 1 {
|
|
self.buffer[0] = PN532_COMMAND_TGSETDATA;
|
|
self.interface.write_command(&self.buffer[..1], header)?;
|
|
} else {
|
|
self.buffer[0] = PN532_COMMAND_TGSETDATA;
|
|
self.buffer[1..1 + header.len()].copy_from_slice(header);
|
|
self.interface
|
|
.write_command(&self.buffer[..1 + header.len()], body)?;
|
|
}
|
|
|
|
let len = self.read_timeout(Duration::from_millis(3000))?;
|
|
if len == 0 || self.buffer[0] != 0 {
|
|
return Err(Error::Status(StatusCode::from_repr(self.buffer[0]).unwrap()));
|
|
}
|
|
Ok(())
|
|
}
|
|
} |