use bitfield instead of strum

This commit is contained in:
2026-08-27 10:52:52 +08:00
parent 86373a2d33
commit f523b7d394
9 changed files with 83 additions and 80 deletions
+1 -1
View File
@@ -199,7 +199,7 @@ impl<B: Interface, const N: usize> Pn532<B, N> {
/// return error if current buffer contains an error code
pub(crate) fn validate_buffer(&self, len: usize) -> Result<(), Error<B::TransportError>> {
if len == 0 || (self.buffer[0] & 0x3F) != 0 {
Err(Error::Status(StatusCode::from_repr(self.buffer[0] & 0x3F).unwrap()))
Err(Error::Status(StatusCode::from_bits(self.buffer[0] & 0x3F)))
} else {
Ok(())
}
+5 -3
View File
@@ -1,6 +1,6 @@
use core::fmt::Debug;
use bitfields::bitflag;
use defmt::Debug2Format;
use strum::FromRepr;
/// Driver-level error type, generic over the transport (I2C) error.
#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
@@ -40,9 +40,11 @@ impl<E: Debug> defmt::Format for Error<E> {
}
}
#[repr(u8)]
#[derive(FromRepr, Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq)]
#[bitflag(u8)]
pub enum StatusCode {
#[base]
Unknown = 0x00,
TimeOut = 0x01,
CRC = 0x02,
Parity = 0x03,
+7 -7
View File
@@ -124,7 +124,7 @@ impl<B: Interface, const N: usize> Pn532<B, N> {
let mut j = 0;
cmd[j] = FELICA_CMD_REQUEST_SERVICE;
j += 1;
cmd[j..j + 8].copy_from_slice(&card.to_bytes());
cmd[j..j + 8].copy_from_slice(&card.into_be_bytes());
j += 8;
cmd[j] = num_node as u8;
j += 1;
@@ -153,7 +153,7 @@ impl<B: Interface, const N: usize> Pn532<B, N> {
pub fn felica_request_response(&mut self, card: &PollingResponse) -> Result<u8, Error<B::TransportError>> {
let mut cmd = [0u8; 9];
cmd[0] = FELICA_CMD_REQUEST_RESPONSE;
cmd[1..9].copy_from_slice(&card.idm.to_bytes());
cmd[1..9].copy_from_slice(&card.idm.into_be_bytes());
let mut response = [0u8; 10];
let response_len = self.felica_send_command(&cmd, &mut response, Duration::from_millis(200))?;
@@ -202,7 +202,7 @@ impl<B: Interface, const N: usize> Pn532<B, N> {
// command
let mut cmd = heapless::Vec::<u8, COMMAND_SIZE>::new();
cmd.push(FELICA_CMD_READ_WITHOUT_ENCRYPTION).unwrap();
cmd.extend_from_slice(&card.to_bytes()).unwrap();
cmd.extend_from_slice(&card.into_be_bytes()).unwrap();
cmd.push(num_service as u8).unwrap();
for sc in service_code_list {
let sc: [u8; 2] = sc.as_service_code().to_le_bytes();
@@ -228,7 +228,7 @@ impl<B: Interface, const N: usize> Pn532<B, N> {
return Err(Error::InvalidFrame);
}
if response[9] != 0 || response[10] != 0 {
return Err(Error::Status(StatusCode::from_repr(response[9]).unwrap()));
return Err(Error::Status(StatusCode::from_bits(response[9])));
}
let mut k = 12;
@@ -275,7 +275,7 @@ impl<B: Interface, const N: usize> Pn532<B, N> {
// command
let mut cmd = heapless::Vec::<u8, COMMAND_SIZE>::new();
cmd.push(FELICA_CMD_WRITE_WITHOUT_ENCRYPTION).unwrap();
cmd.extend_from_slice(&card.to_bytes()).unwrap();
cmd.extend_from_slice(&card.into_be_bytes()).unwrap();
cmd.push(num_service as u8).unwrap();
for sc in service_code_list {
let sc = sc.as_service_code().to_le_bytes();
@@ -301,7 +301,7 @@ impl<B: Interface, const N: usize> Pn532<B, N> {
return Err(Error::InvalidFrame);
}
if response[9] != 0 || response[10] != 0 {
return Err(Error::Status(StatusCode::from_repr(response[9]).unwrap()));
return Err(Error::Status(StatusCode::from_bits(response[9])));
}
Ok(())
}
@@ -316,7 +316,7 @@ impl<B: Interface, const N: usize> Pn532<B, N> {
) -> Result<usize, Error<B::TransportError>> {
let mut cmd = [0u8; 9];
cmd[0] = FELICA_CMD_REQUEST_SYSTEM_CODE;
cmd[1..9].copy_from_slice(&card.to_bytes());
cmd[1..9].copy_from_slice(&card.into_be_bytes());
let mut response = [0u8; 10 + 2 * 16];
let response_len = self.felica_send_command(&cmd, &mut response, Duration::from_millis(200))?;
+4 -26
View File
@@ -1,30 +1,8 @@
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
use bitfields::bitfield;
#[bitfield([u8; 8])]
#[derive(PartialEq, Eq)]
pub struct IDm {
pub manufacturer: u8,
pub card_id: [u8; 7]
}
impl IDm {
/// The raw 8 bytes in wire order (manufacturer, ic_type, card_id).
pub fn to_bytes(&self) -> [u8; 8] {
let mut data = [0u8; 8];
data[0] = self.manufacturer;
data[1..].copy_from_slice(&self.card_id);
data
}
}
impl From<[u8; 8]> for IDm {
fn from(value: [u8; 8]) -> Self {
Self {
manufacturer: value[0],
card_id: value[1..].try_into().unwrap()
}
}
}
impl Into<[u8; 8]> for IDm {
fn into(self) -> [u8; 8] {
self.to_bytes()
}
}
+45 -7
View File
@@ -2,20 +2,21 @@ mod polling;
mod pmm;
mod idm;
use bitfields::bitflag;
pub use idm::*;
pub use pmm::*;
pub use polling::*;
use strum::FromRepr;
pub trait AsServiceCode {
fn as_service_code(&self) -> u16;
fn from_service_code(val: u16) -> Self;
}
#[derive(FromRepr, Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u16)]
#[derive(Debug, PartialEq, Eq)]
#[bitflag(u16)]
pub enum ServiceCode {
#[base]
Unknown = 0,
/// FeliCa Lite read service code (read without key).
Read = 0x000B,
/// FeliCa Lite write service code (write without key).
@@ -28,7 +29,7 @@ impl AsServiceCode for ServiceCode {
}
fn from_service_code(val: u16) -> Self {
Self::from_repr(val).unwrap()
Self::from_bits(val)
}
}
@@ -47,9 +48,11 @@ pub trait AsBlock {
}
/// FeliCa Lite system block numbers.
#[derive(FromRepr, Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u16)]
#[derive(Debug, PartialEq, Eq)]
#[bitflag(u16)]
pub enum Block {
#[base]
Unknown = 0,
/// Random challenge block.
RC = 0x8080,
/// MAC block.
@@ -80,4 +83,39 @@ impl AsBlock for u16 {
// 2-byte element (access mode 0 = standard area, service list order 0).
*self | 0x8000
}
}
/// https://www.sony.co.jp/en/Products/felica/business/tech-support/list.html
#[derive(Debug, PartialEq, Eq)]
#[bitflag(u8)]
pub enum CardICType {
#[base]
Unknown = 0x00,
S140 = 0x50,
SA40_2P = 0x51,
SA41_2C = 0x52,
SA21_2 = 0x46,
SA20_2 = 0x45,
SA20_1 = 0x44,
SA01_2 = 0x35,
SA00_1 = 0x32,
S962 = 0x20,
S960 = 0x0D,
S953 = 0x09,
S952 = 0x08,
S915 = 0x01,
S982 = 0xF1,
S978F = 0xF0,
S967LiteS = 0xF2,
S967Plug = 0xE1,
S967NFC = 0xFF,
S926 = 0xE0
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum MobileICType {
V3(u8), // 0x14~0x1F
V2(u8), // 0x10~0x13
V1(u8) // 0x06~0x07
}
+9 -23
View File
@@ -1,42 +1,28 @@
use core::time::Duration;
use bitfields::bitfield;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[bitfield([u8; 8])]
#[derive(PartialEq, Eq)]
pub struct PMm {
pub rom_type: u8,
pub ic_type: u8,
_f1: u8,
_f2: u8,
_f3: u8,
pub read_timeout: u8,
pub write_timeout: u8,
}
impl From<[u8; 8]> for PMm {
fn from(value: [u8; 8]) -> Self {
Self {
rom_type: value[0],
ic_type: value[1],
read_timeout: value[5],
write_timeout: value[6],
}
}
_f4: u8,
}
impl PMm {
pub fn to_bytes(&self) -> [u8; 8] {
let mut data = [0u8; 8];
data[0] = self.rom_type;
data[1] = self.ic_type;
data[5] = self.read_timeout;
data[6] = self.write_timeout;
data
}
/// Maximum response time for a Read command over `block_len` blocks:
pub fn get_read_timeout(&self, block_len: usize, margin: Option<Duration>) -> Duration {
Self::response_time(self.read_timeout, block_len) + margin.unwrap_or(Duration::default())
Self::response_time(self.read_timeout(), block_len) + margin.unwrap_or(Duration::default())
}
/// Maximum response time for a Write command over `block_len` blocks.
pub fn get_write_timeout(&self, block_len: usize, margin: Option<Duration>) -> Duration {
Self::response_time(self.write_timeout, block_len) + margin.unwrap_or(Duration::default())
Self::response_time(self.write_timeout(), block_len) + margin.unwrap_or(Duration::default())
}
/// `T x [(B+1)*n + (A+1)] x 4^E`, with `T = 256*16/fc ~= 302.06 us`.
+8 -8
View File
@@ -1,17 +1,17 @@
use bitfields::bitflag;
use super::{IDm, PMm};
use strum::FromRepr;
#[derive(FromRepr, Copy, Clone, Debug, PartialEq, Eq, Default)]
#[repr(u8)]
#[derive(Debug, PartialEq, Eq, Default)]
#[bitflag(u8)]
pub enum PollingRequestCode {
NoRequest,
NoRequest = 0x00,
#[default]
SystemCode,
CommunicationPerformance
SystemCode = 0x01,
CommunicationPerformance = 0x02
}
#[derive(FromRepr, Copy, Clone, Debug, PartialEq, Eq, Default)]
#[repr(u8)]
#[derive(Debug, PartialEq, Eq, Default)]
#[bitflag(u8)]
pub enum PollingTimeSlot {
#[default]
_1 = 0x00,
+2 -2
View File
@@ -42,7 +42,7 @@ impl<B: Interface, const N: usize> Pn532<B, N> {
return Ok(0);
}
if self.buffer[0] != 0 {
return Err(Error::Status(StatusCode::from_repr(self.buffer[0]).unwrap()));
return Err(Error::Status(StatusCode::from_bits(self.buffer[0])));
}
let data_len = len - 1;
let copy_len = data_len.min(buf.len());
@@ -68,7 +68,7 @@ impl<B: Interface, const N: usize> Pn532<B, N> {
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()));
return Err(Error::Status(StatusCode::from_bits(self.buffer[0])));
}
Ok(())
}