1#![no_std]
2
3use consts::{PCDErrorCode, Uid, UidSize};
4
5pub mod consts;
6pub mod debug;
7pub mod drivers;
8pub mod mifare;
9pub mod pcd;
10pub mod picc;
11
12pub trait MfrcDriver {
13 fn write_reg(&mut self, reg: u8, val: u8) -> impl Future<Output = Result<(), PCDErrorCode>>;
14 fn write_reg_buff(
15 &mut self,
16 reg: u8,
17 count: usize,
18 values: &[u8],
19 ) -> impl Future<Output = Result<(), PCDErrorCode>>;
20 fn read_reg(&mut self, reg: u8) -> impl Future<Output = Result<u8, PCDErrorCode>>;
21 fn read_reg_buff(
22 &mut self,
23 reg: u8,
24 count: usize,
25 output_buff: &mut [u8],
26 rx_align: u8,
27 ) -> impl Future<Output = Result<(), PCDErrorCode>>;
28}
29
30pub struct MFRC522<D>
31where
32 D: MfrcDriver,
33{
34 driver: D,
35 get_current_time: fn() -> u64,
36}
37
38impl<D> MFRC522<D>
39where
40 D: MfrcDriver,
41{
42 #[cfg(not(feature = "embassy-time"))]
43 pub fn new(driver: D, get_current_time: fn() -> u64) -> Self {
44 Self {
45 driver,
46 get_current_time,
47 }
48 }
49
50 #[cfg(feature = "embassy-time")]
51 pub fn new(driver: D) -> Self {
52 Self {
53 driver,
54 get_current_time: || embassy_time::Instant::now().as_micros(),
55 }
56 }
57
58 #[cfg(not(feature = "embassy-time"))]
59 pub async fn sleep(&self, time_ms: u64) {
60 let start_time = (self.get_current_time)(); while (self.get_current_time)() - start_time < time_ms * 1_000 {}
62 }
63
64 #[cfg(feature = "embassy-time")]
65 pub async fn sleep(&self, time_ms: u64) {
66 embassy_time::Timer::after_millis(time_ms).await;
67 }
68
69 pub async fn get_card(&mut self, size: UidSize) -> Result<Uid, PCDErrorCode> {
70 let mut uid = Uid {
71 size: size.to_byte(),
72 sak: 0,
73 uid_bytes: [0; 10],
74 };
75
76 self.picc_select(&mut uid, 0).await?;
77 Ok(uid)
78 }
79
80 pub async fn write_reg(&mut self, reg: u8, val: u8) -> Result<(), PCDErrorCode> {
81 self.driver.write_reg(reg, val).await
82 }
83
84 pub async fn write_reg_buff(
85 &mut self,
86 reg: u8,
87 count: usize,
88 values: &[u8],
89 ) -> Result<(), PCDErrorCode> {
90 self.driver.write_reg_buff(reg, count, values).await
91 }
92
93 pub async fn read_reg(&mut self, reg: u8) -> Result<u8, PCDErrorCode> {
94 self.driver.read_reg(reg).await
95 }
96
97 pub async fn read_reg_buff(
98 &mut self,
99 reg: u8,
100 count: usize,
101 output_buff: &mut [u8],
102 rx_align: u8,
103 ) -> Result<(), PCDErrorCode> {
104 self.driver
105 .read_reg_buff(reg, count, output_buff, rx_align)
106 .await
107 }
108}
109
110#[inline(always)]
111pub fn tif<T>(expr: bool, true_val: T, false_val: T) -> T {
112 if expr { true_val } else { false_val }
113}