M5Unit-RFID 0.0.1 git rev:d8076ed
Loading...
Searching...
No Matches
unit_MFRC522.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
10#ifndef M5_UNIT_RFID_UNIT_MFRC522_HPP
11#define M5_UNIT_RFID_UNIT_MFRC522_HPP
12
13#include <M5UnitComponent.hpp>
14// M5Unit-NFC
15#include <nfc/nfc.hpp>
16#include <nfc/a/nfca.hpp>
17
18namespace m5 {
19namespace unit {
20
21namespace nfc {
22struct AdapterMFRC522; // For layer
23}
24
25namespace mfrc522 {
26
27constexpr uint16_t MAX_FIFO_DEPTH{64};
28
33enum class Command : uint8_t {
34 Idle,
35 Mem,
37 CalcCRC,
38 Transmit,
39 NoCmdChange = 0x07,
40 Receive,
41 Transceive = 0x0C,
43 MFAuthent = 0x0E,
44 SoftReset,
45};
46
51enum class ReceiverGain : uint8_t {
52 dB18,
53 dB23,
54 // 2 = dB18 (duplicated),
55 // 3 = dB23 (duplicated)
56 dB33 = 0x04,
57 dB38,
58 dB43,
59 dB48,
60};
61
66enum class Error : uint8_t {
69 ARGUMENT = 0x80,
71 REGISTER,
72 TIMEOUT,
74 CRC,
75 AUTH,
77 INTERNAL = 0xFE,
78 UNKNOWN = 0xFF
79};
80
81} // namespace mfrc522
82
89class UnitMFRC522 : public Component {
90 M5_UNIT_COMPONENT_HPP_BUILDER(UnitMFRC522, 0x28);
91
92public:
97 struct config_t {
99 uint8_t mode_reg{0x3D};
101 bool enable_antenna{true};
103 mfrc522::ReceiverGain receiver_gain{mfrc522::ReceiverGain::dB48};
105 bool software_crc{false};
106 };
107
112 explicit UnitMFRC522(const uint8_t addr = DEFAULT_ADDRESS) : Component(addr)
113 {
114 auto ccfg = component_config();
115 ccfg.clock = 400 * 1000U;
116 component_config(ccfg);
117 }
121 virtual ~UnitMFRC522()
122 {
123 }
124
129 virtual bool begin() override;
134 virtual void update(const bool force = false) override;
135
138
140 {
141 return _cfg;
142 }
144 inline void config(const config_t& cfg)
145 {
146 _cfg = cfg;
147 }
149
154 inline m5::nfc::NFC NFCMode() const
155 {
156 return m5::nfc::NFC::A;
157 }
164 inline bool configureNFCMode(const m5::nfc::NFC mode)
165 {
166 // Nop
167 return mode == m5::nfc::NFC::A;
168 }
169
175 bool softReset(const bool blocking = true);
176
182 inline bool selfTest()
183 {
184 bool ret = self_test();
185 return ret && begin();
186 }
187
190
195 bool readAntennaStatus(bool& status);
200 bool turnOnAntenna();
205 bool turnOffAntenna();
219
222
227 bool readTPrescaler(uint16_t& tprescale);
233 bool writeTPrescaler(const uint16_t tprescale);
235
238
245 bool calculateCRC(uint16_t& result, const uint8_t* buf, const uint8_t len);
253 bool calculateSoftwareCRC(uint16_t& result, const uint8_t* buf, const uint8_t len);
255
258
267 bool nfcaTransceive(uint8_t* rx, uint16_t& rx_len, const uint8_t* tx, const uint16_t tx_len,
268 const uint32_t timeout_ms);
269
275 inline bool request(uint16_t& atqa)
276 {
277 return request_wakeup(atqa, true);
278 }
284 inline bool wakeup(uint16_t& atqa)
285 {
286 return request_wakeup(atqa, false);
287 }
288
296 bool selectWithAnticollision(bool& completed, m5::nfc::a::PICC& picc, const uint8_t lv);
302 bool select(const m5::nfc::a::PICC& picc);
303
310 bool readBlock(uint8_t rx[16], const uint8_t block);
317 bool writeBlock(const uint8_t block, const uint8_t tx[16]);
322 bool hlt();
324
327
335 const m5::nfc::a::PICC& picc, const uint8_t block,
336 const m5::nfc::a::mifare::classic::Key& key = m5::nfc::a::mifare::classic::DEFAULT_KEY)
337 {
338 return mifare_classic_authenticate(m5::nfc::a::Command::AUTH_WITH_KEY_A, picc, block, key);
339 }
348 const m5::nfc::a::PICC& picc, const uint8_t block,
349 const m5::nfc::a::mifare::classic::Key& key = m5::nfc::a::mifare::classic::DEFAULT_KEY)
350 {
351 return mifare_classic_authenticate(m5::nfc::a::Command::AUTH_WITH_KEY_B, picc, block, key);
352 }
353
359
367 bool mifareClassicValueBlock(const m5::nfc::a::Command cmd, const uint8_t block, const uint32_t arg = 0);
369
370protected:
371 // register operation
372 bool modify_bit_register8(const uint8_t reg, const uint8_t set_mask, const uint8_t clear_mask);
373 bool set_bit_register8(const uint8_t reg, const uint8_t bits);
374 bool clear_bit_register8(const uint8_t reg, const uint8_t bits);
375 inline bool change_bit_register8(const uint8_t reg, const uint8_t bits, const uint8_t mask)
376 {
377 return modify_bit_register8(reg, mask & bits, mask);
378 }
379 bool read_register_with_align(const uint8_t reg, uint8_t* buf, const uint8_t len, const uint8_t align);
380 bool write_pcd_command(const mfrc522::Command cmd);
381
382 bool reset_baud_rates();
383 bool flush_fifo_buffer();
384 bool wait_comm_irq(const uint8_t irq, const uint32_t duration);
385 bool wait_div_irq(const uint8_t irq, const uint32_t duration);
386
387 // transceive
388 bool transmit_command(const mfrc522::Command cmd, const uint8_t* buf, const uint8_t len, const uint8_t txLast = 0,
389 const uint8_t rxAlign = 0);
390 bool transceive(uint8_t* rbuf, uint16_t& rlen, const uint8_t* buf, const uint16_t len, const uint32_t timeout_ms,
391 uint8_t& validBits, const uint8_t rxAlign = 0, const bool crc = false, uint8_t* err = nullptr);
392
393 bool picc_haltA();
394
395 // Read/Write
396 bool read_block(uint8_t* rbuf, uint8_t& rlen, const uint8_t addr);
397 bool write_block(const uint8_t block, const uint8_t* buf, const uint8_t len);
398 bool write_page(const uint8_t page, const uint8_t* buf, const uint8_t len);
399
400 // NFC-A
401 bool request_wakeup(uint16_t& atqa, const bool request);
402 bool anti_collision(const uint8_t cascadeLevel, uint8_t* buf);
403
404 // MIFARE classic
405 bool mifare_classic_authenticate(const m5::nfc::a::Command cmd, const m5::nfc::a::PICC& picc, const uint8_t block,
406 const m5::nfc::a::mifare::classic::Key& key);
407 bool mifare_classic_transceive(const m5::nfc::a::Command cmd, const uint8_t block, const uint32_t timeout_ms);
408 bool mifare_classic_transceive(const uint8_t* buf, const uint8_t len, const uint32_t timeout_ms,
409 const bool usingtimeout = false);
410
411 // crc
412 inline bool calculate_crc(uint16_t& result, const uint8_t* buf, const uint8_t len)
413 {
414 return (this->*(_cfg.software_crc ? &UnitMFRC522::calculateSoftwareCRC : &UnitMFRC522::calculateCRC))(result,
415 buf, len);
416 }
417
418 virtual bool self_test();
419
420protected:
421 config_t _cfg{};
422 uint16_t _tprescaler{};
423};
424
426namespace mfrc522 {
427namespace command {
428// Command and status
429constexpr uint8_t COMMAND_REG{0x01};
430constexpr uint8_t COM_IEN_REG{0x02};
431constexpr uint8_t DIV_IEN_REG{0x03};
432constexpr uint8_t COM_IRQ_REG{0x04};
433constexpr uint8_t DIV_IRQ_REG{0x05};
434constexpr uint8_t ERROR_REG{0x06};
435constexpr uint8_t STATUS2_REG{0x08};
436constexpr uint8_t FIFO_DATA_REG{0x09};
437constexpr uint8_t FIFO_LEVEL_REG{0x0A};
438constexpr uint8_t WATER_LEVEL_REG{0x0B};
439constexpr uint8_t CONTROL_REG{0x0C};
440constexpr uint8_t BIT_FRAMING_REG{0x0D};
441constexpr uint8_t COLL_REG{0x0E};
442
443// Communication
444constexpr uint8_t MODE_REG{0x11};
445constexpr uint8_t TX_MODE_REG{0x12};
446constexpr uint8_t RX_MODE_REG{0x13};
447constexpr uint8_t TX_CONTROL_REG{0x14};
448constexpr uint8_t TX_ASK_REG{0x15};
449constexpr uint8_t TX_SEL_REG{0x16};
450constexpr uint8_t RX_SEL_REG{0x17};
451constexpr uint8_t RX_THRESHOLD_REG{0x18};
452constexpr uint8_t DEMOD_REG{0x19};
453constexpr uint8_t MF_TX_REG{0x1C};
454constexpr uint8_t MF_RX_REG{0x1D};
455
456// Configuration
457constexpr uint8_t CRC_RESULT_REGH{0x21};
458constexpr uint8_t CRC_RESULT_REGL{0x22};
459constexpr uint8_t MOD_WIDTH_REG{0x24};
460constexpr uint8_t RFC_FG_REG{0x26};
461constexpr uint8_t GSN_REG{0x27};
462constexpr uint8_t CW_GSP_REG{0x28};
463constexpr uint8_t MOD_GSP_REG{0x29};
464constexpr uint8_t TMODE_REG{0x2A};
465constexpr uint8_t TPRESCALER_REG_L{0x2B};
466constexpr uint8_t TRELOAD_REG_H{0x2C};
467constexpr uint8_t TRELOAD_REG_L{0x2D};
468
469// Test
470constexpr uint8_t AUTO_TEST_REG{0x36};
471constexpr uint8_t VERSION_REG{0x37};
472
473} // namespace command
474} // namespace mfrc522
476
477} // namespace unit
478} // namespace m5
479#endif
Radio frequency identification unit.
Definition unit_MFRC522.hpp:89
config_t config()
Gets the configuration.
Definition unit_MFRC522.hpp:139
bool readAntennaStatus(bool &status)
Read the antenna status.
Definition unit_MFRC522.cpp:316
bool mifareClassicAuthenticateA(const m5::nfc::a::PICC &picc, const uint8_t block, const m5::nfc::a::mifare::classic::Key &key=m5::nfc::a::mifare::classic::DEFAULT_KEY)
Authentication using keyA of the specified block.
Definition unit_MFRC522.hpp:334
bool selectWithAnticollision(bool &completed, m5::nfc::a::PICC &picc, const uint8_t lv)
Select PICC with anti-collision.
Definition unit_MFRC522.cpp:507
bool configureNFCMode(const m5::nfc::NFC mode)
Configure NFC mode.
Definition unit_MFRC522.hpp:164
bool turnOnAntenna()
Turn on the antenna.
Definition unit_MFRC522.cpp:327
virtual ~UnitMFRC522()
Destructor.
Definition unit_MFRC522.hpp:121
bool writeTPrescaler(const uint16_t tprescale)
Write the TPrescaler.
Definition unit_MFRC522.cpp:303
bool readReceiverGain(mfrc522::ReceiverGain &gain)
Gets the receiver gain.
Definition unit_MFRC522.cpp:353
m5::nfc::NFC NFCMode() const
Gets the current operating mode.
Definition unit_MFRC522.hpp:154
bool select(const m5::nfc::a::PICC &picc)
Select specific PICC.
Definition unit_MFRC522.cpp:579
bool readBlock(uint8_t rx[16], const uint8_t block)
Read the 1 block / 4 page (16 bytes)
Definition unit_MFRC522.cpp:619
bool mifareClassicAuthenticateB(const m5::nfc::a::PICC &picc, const uint8_t block, const m5::nfc::a::mifare::classic::Key &key=m5::nfc::a::mifare::classic::DEFAULT_KEY)
Authentication using keyB of the specified block.
Definition unit_MFRC522.hpp:347
UnitMFRC522(const uint8_t addr=DEFAULT_ADDRESS)
Constructor.
Definition unit_MFRC522.hpp:112
void config(const config_t &cfg)
Set the configuration.
Definition unit_MFRC522.hpp:144
bool nfcaTransceive(uint8_t *rx, uint16_t &rx_len, const uint8_t *tx, const uint16_t tx_len, const uint32_t timeout_ms)
Transceive.
Definition unit_MFRC522.cpp:214
bool selfTest()
Self test.
Definition unit_MFRC522.hpp:182
bool writeReceiverGain(const mfrc522::ReceiverGain gain)
Write the receiver gain.
Definition unit_MFRC522.cpp:363
bool calculateSoftwareCRC(uint16_t &result, const uint8_t *buf, const uint8_t len)
Calculate CRC by software.
Definition unit_MFRC522.cpp:410
bool calculateCRC(uint16_t &result, const uint8_t *buf, const uint8_t len)
Calculate CRC by hardware.
Definition unit_MFRC522.cpp:373
bool request(uint16_t &atqa)
Request for idle PICC.
Definition unit_MFRC522.hpp:275
bool readTPrescaler(uint16_t &tprescale)
Read the TPrescaler.
Definition unit_MFRC522.cpp:293
bool mifareClassicValueBlock(const m5::nfc::a::Command cmd, const uint8_t block, const uint32_t arg=0)
Operation for the value block.
Definition unit_MFRC522.cpp:675
bool turnOffAntenna()
Turn off the antenna.
Definition unit_MFRC522.cpp:340
virtual void update(const bool force=false) override
Update internal state.
Definition unit_MFRC522.cpp:209
bool writeBlock(const uint8_t block, const uint8_t tx[16])
Write the 1 block.
Definition unit_MFRC522.cpp:644
bool hlt()
Hlt for PICC.
Definition unit_MFRC522.cpp:653
bool wakeup(uint16_t &atqa)
Wakeup for idle/halt PICC.
Definition unit_MFRC522.hpp:284
virtual bool begin() override
Begin the unit.
Definition unit_MFRC522.cpp:152
bool softReset(const bool blocking=true)
Software reset.
Definition unit_MFRC522.cpp:271
bool mifareClassicStopCrypto1()
Exit from authenticated state for MIFARE classic.
Definition unit_MFRC522.cpp:670
Top level namespace of M5Stack.
Unit-related namespace.
Settings for begin.
Definition unit_MFRC522.hpp:97
bool enable_antenna
Enable antenna on begin if true.
Definition unit_MFRC522.hpp:101
uint8_t mode_reg
mode reg value. See also 9.3.2.2 ModeReg register
Definition unit_MFRC522.hpp:99
mfrc522::ReceiverGain receiver_gain
The receiver’s signal voltage gain factor.
Definition unit_MFRC522.hpp:103
bool software_crc
Using software CRC.
Definition unit_MFRC522.hpp:105
ReceiverGain
The receiver’s signal voltage gain factor.
Definition unit_MFRC522.hpp:51
Error
API error code.
Definition unit_MFRC522.hpp:66
@ TIMEOUT
Timeout occurs (0x83)
@ INTERNAL
Internal error.
@ CRC
CRC error (0x85)
@ CANNOT_RESOLVE_COLLISION
Collision resolution failed (0x87)
@ COMMUNICATION
Error in communication (0x81)
@ UID_NOT_COMPLETED
UID is not yet complete.
@ OCCUR_COLLISION
Collision occurs.
@ MIFARE_NACK
MIFARE NACK detection (0x84)
@ ARGUMENT
Error caused by arguments (0x80)
@ REGISTER
Error by error register value (0x82)
@ AUTH
Authentication error(0x86)
constexpr uint16_t MAX_FIFO_DEPTH
Maximum FIFO depth.
Definition unit_MFRC522.hpp:27
Command
PCD command.
Definition unit_MFRC522.hpp:33
@ SoftReset
Resets the MFRC522.
@ CalcCRC
Activates the CRC coprocessor or performs a self test.
@ NoCmdChange
No command change.
@ Receive
Activates the receiver circuits.
@ GenerateRandomID
Generates a 10-byte random ID number.
@ Transmit
Transmits data from the FIFO buffer.
@ MFAuthent
Performs the MIFARE standard authentication as a reader.
@ Mem
Stores 25 bytes into the internal buffer.
@ Idle
No action, cancels current command execution.