Sming Framework API
Sming - Open Source framework for high efficiency WiFi SoC ESP8266 native development with C++ language.
MFRC522.h
1 
75 #ifndef MFRC522_h
76 #define MFRC522_h
77 #include <user_config.h>
78 #include <SmingCore.h>
79 #include <SPI.h>
80 
81 // Firmware data for self-test
82 // Reference values based on firmware version
83 // Hint: if needed, you can remove unused self-test data to save flash memory
84 //
85 // Version 0.0 (0x90)
86 // Philips Semiconductors; Preliminary Specification Revision 2.0 - 01 August 2005; 16.1 Sefttest
87 const byte MFRC522_firmware_referenceV0_0[] PROGMEM = {
88  0x00, 0x87, 0x98, 0x0f, 0x49, 0xFF, 0x07, 0x19,
89  0xBF, 0x22, 0x30, 0x49, 0x59, 0x63, 0xAD, 0xCA,
90  0x7F, 0xE3, 0x4E, 0x03, 0x5C, 0x4E, 0x49, 0x50,
91  0x47, 0x9A, 0x37, 0x61, 0xE7, 0xE2, 0xC6, 0x2E,
92  0x75, 0x5A, 0xED, 0x04, 0x3D, 0x02, 0x4B, 0x78,
93  0x32, 0xFF, 0x58, 0x3B, 0x7C, 0xE9, 0x00, 0x94,
94  0xB4, 0x4A, 0x59, 0x5B, 0xFD, 0xC9, 0x29, 0xDF,
95  0x35, 0x96, 0x98, 0x9E, 0x4F, 0x30, 0x32, 0x8D
96 };
97 // Version 1.0 (0x91)
98 // NXP Semiconductors; Rev. 3.8 - 17 September 2014; 16.1.1 Self test
99 const byte MFRC522_firmware_referenceV1_0[] PROGMEM = {
100  0x00, 0xC6, 0x37, 0xD5, 0x32, 0xB7, 0x57, 0x5C,
101  0xC2, 0xD8, 0x7C, 0x4D, 0xD9, 0x70, 0xC7, 0x73,
102  0x10, 0xE6, 0xD2, 0xAA, 0x5E, 0xA1, 0x3E, 0x5A,
103  0x14, 0xAF, 0x30, 0x61, 0xC9, 0x70, 0xDB, 0x2E,
104  0x64, 0x22, 0x72, 0xB5, 0xBD, 0x65, 0xF4, 0xEC,
105  0x22, 0xBC, 0xD3, 0x72, 0x35, 0xCD, 0xAA, 0x41,
106  0x1F, 0xA7, 0xF3, 0x53, 0x14, 0xDE, 0x7E, 0x02,
107  0xD9, 0x0F, 0xB5, 0x5E, 0x25, 0x1D, 0x29, 0x79
108 };
109 // Version 2.0 (0x92)
110 // NXP Semiconductors; Rev. 3.8 - 17 September 2014; 16.1.1 Self test
111 const byte MFRC522_firmware_referenceV2_0[] PROGMEM = {
112  0x00, 0xEB, 0x66, 0xBA, 0x57, 0xBF, 0x23, 0x95,
113  0xD0, 0xE3, 0x0D, 0x3D, 0x27, 0x89, 0x5C, 0xDE,
114  0x9D, 0x3B, 0xA7, 0x00, 0x21, 0x5B, 0x89, 0x82,
115  0x51, 0x3A, 0xEB, 0x02, 0x0C, 0xA5, 0x00, 0x49,
116  0x7C, 0x84, 0x4D, 0xB3, 0xCC, 0xD2, 0x1B, 0x81,
117  0x5D, 0x48, 0x76, 0xD5, 0x71, 0x61, 0x21, 0xA9,
118  0x86, 0x96, 0x83, 0x38, 0xCF, 0x9D, 0x5B, 0x6D,
119  0xDC, 0x15, 0xBA, 0x3E, 0x7D, 0x95, 0x3B, 0x2F
120 };
121 // Clone
122 // Fudan Semiconductor FM17522 (0x88)
123 const byte FM17522_firmware_reference[] PROGMEM = {
124  0x00, 0xD6, 0x78, 0x8C, 0xE2, 0xAA, 0x0C, 0x18,
125  0x2A, 0xB8, 0x7A, 0x7F, 0xD3, 0x6A, 0xCF, 0x0B,
126  0xB1, 0x37, 0x63, 0x4B, 0x69, 0xAE, 0x91, 0xC7,
127  0xC3, 0x97, 0xAE, 0x77, 0xF4, 0x37, 0xD7, 0x9B,
128  0x7C, 0xF5, 0x3C, 0x11, 0x8F, 0x15, 0xC3, 0xD7,
129  0xC1, 0x5B, 0x00, 0x2A, 0xD0, 0x75, 0xDE, 0x9E,
130  0x51, 0x64, 0xAB, 0x3E, 0xE9, 0x15, 0xB5, 0xAB,
131  0x56, 0x9A, 0x98, 0x82, 0x26, 0xEA, 0x2A, 0x62
132 };
133 
134 class MFRC522 {
135 public:
136  // MFRC522 registers. Described in chapter 9 of the datasheet.
137  // When using SPI all addresses are shifted one bit left in the "SPI address byte" (section 8.1.2.3)
138  enum PCD_Register {
139  // Page 0: Command and status
140  // 0x00 // reserved for future use
141  CommandReg = 0x01 << 1, // starts and stops command execution
142  ComIEnReg = 0x02 << 1, // enable and disable interrupt request control bits
143  DivIEnReg = 0x03 << 1, // enable and disable interrupt request control bits
144  ComIrqReg = 0x04 << 1, // interrupt request bits
145  DivIrqReg = 0x05 << 1, // interrupt request bits
146  ErrorReg = 0x06 << 1, // error bits showing the error status of the last command executed
147  Status1Reg = 0x07 << 1, // communication status bits
148  Status2Reg = 0x08 << 1, // receiver and transmitter status bits
149  FIFODataReg = 0x09 << 1, // input and output of 64 byte FIFO buffer
150  FIFOLevelReg = 0x0A << 1, // number of bytes stored in the FIFO buffer
151  WaterLevelReg = 0x0B << 1, // level for FIFO underflow and overflow warning
152  ControlReg = 0x0C << 1, // miscellaneous control registers
153  BitFramingReg = 0x0D << 1, // adjustments for bit-oriented frames
154  CollReg = 0x0E << 1, // bit position of the first bit-collision detected on the RF interface
155  // 0x0F // reserved for future use
156 
157  // Page 1: Command
158  // 0x10 // reserved for future use
159  ModeReg = 0x11 << 1, // defines general modes for transmitting and receiving
160  TxModeReg = 0x12 << 1, // defines transmission data rate and framing
161  RxModeReg = 0x13 << 1, // defines reception data rate and framing
162  TxControlReg = 0x14 << 1, // controls the logical behavior of the antenna driver pins TX1 and TX2
163  TxASKReg = 0x15 << 1, // controls the setting of the transmission modulation
164  TxSelReg = 0x16 << 1, // selects the internal sources for the antenna driver
165  RxSelReg = 0x17 << 1, // selects internal receiver settings
166  RxThresholdReg = 0x18 << 1, // selects thresholds for the bit decoder
167  DemodReg = 0x19 << 1, // defines demodulator settings
168  // 0x1A // reserved for future use
169  // 0x1B // reserved for future use
170  MfTxReg = 0x1C << 1, // controls some MIFARE communication transmit parameters
171  MfRxReg = 0x1D << 1, // controls some MIFARE communication receive parameters
172  // 0x1E // reserved for future use
173  SerialSpeedReg = 0x1F << 1, // selects the speed of the serial UART interface
174 
175  // Page 2: Configuration
176  // 0x20 // reserved for future use
177  CRCResultRegH = 0x21 << 1, // shows the MSB and LSB values of the CRC calculation
178  CRCResultRegL = 0x22 << 1,
179  // 0x23 // reserved for future use
180  ModWidthReg = 0x24 << 1, // controls the ModWidth setting?
181  // 0x25 // reserved for future use
182  RFCfgReg = 0x26 << 1, // configures the receiver gain
183  GsNReg = 0x27 << 1, // selects the conductance of the antenna driver pins TX1 and TX2 for modulation
184  CWGsPReg = 0x28 << 1, // defines the conductance of the p-driver output during periods of no modulation
185  ModGsPReg = 0x29 << 1, // defines the conductance of the p-driver output during periods of modulation
186  TModeReg = 0x2A << 1, // defines settings for the internal timer
187  TPrescalerReg = 0x2B << 1, // the lower 8 bits of the TPrescaler value. The 4 high bits are in TModeReg.
188  TReloadRegH = 0x2C << 1, // defines the 16-bit timer reload value
189  TReloadRegL = 0x2D << 1,
190  TCounterValueRegH = 0x2E << 1, // shows the 16-bit timer value
191  TCounterValueRegL = 0x2F << 1,
192 
193  // Page 3: Test Registers
194  // 0x30 // reserved for future use
195  TestSel1Reg = 0x31 << 1, // general test signal configuration
196  TestSel2Reg = 0x32 << 1, // general test signal configuration
197  TestPinEnReg = 0x33 << 1, // enables pin output driver on pins D1 to D7
198  TestPinValueReg = 0x34 << 1, // defines the values for D1 to D7 when it is used as an I/O bus
199  TestBusReg = 0x35 << 1, // shows the status of the internal test bus
200  AutoTestReg = 0x36 << 1, // controls the digital self test
201  VersionReg = 0x37 << 1, // shows the software version
202  AnalogTestReg = 0x38 << 1, // controls the pins AUX1 and AUX2
203  TestDAC1Reg = 0x39 << 1, // defines the test value for TestDAC1
204  TestDAC2Reg = 0x3A << 1, // defines the test value for TestDAC2
205  TestADCReg = 0x3B << 1 // shows the value of ADC I and Q channels
206  // 0x3C // reserved for production tests
207  // 0x3D // reserved for production tests
208  // 0x3E // reserved for production tests
209  // 0x3F // reserved for production tests
210  };
211 
212  // MFRC522 commands. Described in chapter 10 of the datasheet.
213  enum PCD_Command {
214  PCD_Idle = 0x00, // no action, cancels current command execution
215  PCD_Mem = 0x01, // stores 25 bytes into the internal buffer
216  PCD_GenerateRandomID = 0x02, // generates a 10-byte random ID number
217  PCD_CalcCRC = 0x03, // activates the CRC coprocessor or performs a self test
218  PCD_Transmit = 0x04, // transmits data from the FIFO buffer
219  PCD_NoCmdChange = 0x07, // no command change, can be used to modify the CommandReg register bits without affecting the command, for example, the PowerDown bit
220  PCD_Receive = 0x08, // activates the receiver circuits
221  PCD_Transceive = 0x0C, // transmits data from FIFO buffer to antenna and automatically activates the receiver after transmission
222  PCD_MFAuthent = 0x0E, // performs the MIFARE standard authentication as a reader
223  PCD_SoftReset = 0x0F // resets the MFRC522
224  };
225 
226  // MFRC522 RxGain[2:0] masks, defines the receiver's signal voltage gain factor (on the PCD).
227  // Described in 9.3.3.6 / table 98 of the datasheet at http://www.nxp.com/documents/data_sheet/MFRC522.pdf
228  enum PCD_RxGain {
229  RxGain_18dB = 0x00 << 4, // 000b - 18 dB, minimum
230  RxGain_23dB = 0x01 << 4, // 001b - 23 dB
231  RxGain_18dB_2 = 0x02 << 4, // 010b - 18 dB, it seems 010b is a duplicate for 000b
232  RxGain_23dB_2 = 0x03 << 4, // 011b - 23 dB, it seems 011b is a duplicate for 001b
233  RxGain_33dB = 0x04 << 4, // 100b - 33 dB, average, and typical default
234  RxGain_38dB = 0x05 << 4, // 101b - 38 dB
235  RxGain_43dB = 0x06 << 4, // 110b - 43 dB
236  RxGain_48dB = 0x07 << 4, // 111b - 48 dB, maximum
237  RxGain_min = 0x00 << 4, // 000b - 18 dB, minimum, convenience for RxGain_18dB
238  RxGain_avg = 0x04 << 4, // 100b - 33 dB, average, convenience for RxGain_33dB
239  RxGain_max = 0x07 << 4 // 111b - 48 dB, maximum, convenience for RxGain_48dB
240  };
241 
242  // Commands sent to the PICC.
243  enum PICC_Command {
244  // The commands used by the PCD to manage communication with several PICCs (ISO 14443-3, Type A, section 6.4)
245  PICC_CMD_REQA = 0x26, // REQuest command, Type A. Invites PICCs in state IDLE to go to READY and prepare for anticollision or selection. 7 bit frame.
246  PICC_CMD_WUPA = 0x52, // Wake-UP command, Type A. Invites PICCs in state IDLE and HALT to go to READY(*) and prepare for anticollision or selection. 7 bit frame.
247  PICC_CMD_CT = 0x88, // Cascade Tag. Not really a command, but used during anti collision.
248  PICC_CMD_SEL_CL1 = 0x93, // Anti collision/Select, Cascade Level 1
249  PICC_CMD_SEL_CL2 = 0x95, // Anti collision/Select, Cascade Level 2
250  PICC_CMD_SEL_CL3 = 0x97, // Anti collision/Select, Cascade Level 3
251  PICC_CMD_HLTA = 0x50, // HaLT command, Type A. Instructs an ACTIVE PICC to go to state HALT.
252  // The commands used for MIFARE Classic (from http://www.nxp.com/documents/data_sheet/MF1S503x.pdf, Section 9)
253  // Use PCD_MFAuthent to authenticate access to a sector, then use these commands to read/write/modify the blocks on the sector.
254  // The read/write commands can also be used for MIFARE Ultralight.
255  PICC_CMD_MF_AUTH_KEY_A = 0x60, // Perform authentication with Key A
256  PICC_CMD_MF_AUTH_KEY_B = 0x61, // Perform authentication with Key B
257  PICC_CMD_MF_READ = 0x30, // Reads one 16 byte block from the authenticated sector of the PICC. Also used for MIFARE Ultralight.
258  PICC_CMD_MF_WRITE = 0xA0, // Writes one 16 byte block to the authenticated sector of the PICC. Called "COMPATIBILITY WRITE" for MIFARE Ultralight.
259  PICC_CMD_MF_DECREMENT = 0xC0, // Decrements the contents of a block and stores the result in the internal data register.
260  PICC_CMD_MF_INCREMENT = 0xC1, // Increments the contents of a block and stores the result in the internal data register.
261  PICC_CMD_MF_RESTORE = 0xC2, // Reads the contents of a block into the internal data register.
262  PICC_CMD_MF_TRANSFER = 0xB0, // Writes the contents of the internal data register to a block.
263  // The commands used for MIFARE Ultralight (from http://www.nxp.com/documents/data_sheet/MF0ICU1.pdf, Section 8.6)
264  // The PICC_CMD_MF_READ and PICC_CMD_MF_WRITE can also be used for MIFARE Ultralight.
265  PICC_CMD_UL_WRITE = 0xA2 // Writes one 4 byte page to the PICC.
266  };
267 
268  // MIFARE constants that does not fit anywhere else
269  enum MIFARE_Misc {
270  MF_ACK = 0xA, // The MIFARE Classic uses a 4 bit ACK/NAK. Any other value than 0xA is NAK.
271  MF_KEY_SIZE = 6 // A Mifare Crypto1 key is 6 bytes.
272  };
273 
274  // PICC types we can detect. Remember to update PICC_GetTypeName() if you add more.
275  enum PICC_Type {
276  PICC_TYPE_UNKNOWN = 0,
277  PICC_TYPE_ISO_14443_4 = 1, // PICC compliant with ISO/IEC 14443-4
278  PICC_TYPE_ISO_18092 = 2, // PICC compliant with ISO/IEC 18092 (NFC)
279  PICC_TYPE_MIFARE_MINI = 3, // MIFARE Classic protocol, 320 bytes
280  PICC_TYPE_MIFARE_1K = 4, // MIFARE Classic protocol, 1KB
281  PICC_TYPE_MIFARE_4K = 5, // MIFARE Classic protocol, 4KB
282  PICC_TYPE_MIFARE_UL = 6, // MIFARE Ultralight or Ultralight C
283  PICC_TYPE_MIFARE_PLUS = 7, // MIFARE Plus
284  PICC_TYPE_TNP3XXX = 8, // Only mentioned in NXP AN 10833 MIFARE Type Identification Procedure
285  PICC_TYPE_NOT_COMPLETE = 255 // SAK indicates UID is not complete.
286  };
287 
288  // Return codes from the functions in this class. Remember to update GetStatusCodeName() if you add more.
289  enum StatusCode {
290  STATUS_OK = 1, // Success
291  STATUS_ERROR = 2, // Error in communication
292  STATUS_COLLISION = 3, // Collission detected
293  STATUS_TIMEOUT = 4, // Timeout in communication.
294  STATUS_NO_ROOM = 5, // A buffer is not big enough.
295  STATUS_INTERNAL_ERROR = 6, // Internal error in the code. Should not happen ;-)
296  STATUS_INVALID = 7, // Invalid argument.
297  STATUS_CRC_WRONG = 8, // The CRC_A does not match
298  STATUS_MIFARE_NACK = 9 // A MIFARE PICC responded with NAK.
299  };
300 
301  // A struct used for passing the UID of a PICC.
302  typedef struct {
303  byte size; // Number of bytes in the UID. 4, 7 or 10.
304  byte uidByte[10];
305  byte sak; // The SAK (Select acknowledge) byte returned from the PICC after successful selection.
306  } Uid;
307 
308  // A struct used for passing a MIFARE Crypto1 key
309  typedef struct {
310  byte keyByte[MF_KEY_SIZE];
311  } MIFARE_Key;
312 
313  // Member variables
314  Uid uid; // Used by PICC_ReadCardSerial().
315 
316  // Size of the MFRC522 FIFO
317  static const byte FIFO_SIZE = 64; // The FIFO is 64 bytes.
318 
320  // Functions for setting up the Arduino
322  MFRC522(byte chipSelectPin, byte resetPowerDownPin);
323  void setSPIConfig();
324 
326  // Basic interface functions for communicating with the MFRC522
328  void PCD_WriteRegister(byte reg, byte value);
329  void PCD_WriteRegister(byte reg, byte count, byte *values);
330  byte PCD_ReadRegister(byte reg);
331  void PCD_ReadRegister(byte reg, byte count, byte *values, byte rxAlign = 0);
332  void setBitMask(unsigned char reg, unsigned char mask);
333  void PCD_SetRegisterBitMask(byte reg, byte mask);
334  void PCD_ClearRegisterBitMask(byte reg, byte mask);
335  byte PCD_CalculateCRC(byte *data, byte length, byte *result);
336 
338  // Functions for manipulating the MFRC522
340  void PCD_Init();
341  void ICACHE_FLASH_ATTR setControlPins(byte csPin,byte pdPin);
342  void PCD_Reset();
343  void PCD_AntennaOn();
344  void PCD_AntennaOff();
345  byte PCD_GetAntennaGain();
346  void PCD_SetAntennaGain(byte mask);
347  bool PCD_PerformSelfTest();
348 
350  // Functions for communicating with PICCs
352  byte PCD_TransceiveData(byte *sendData, byte sendLen, byte *backData, byte *backLen, byte *validBits = NULL, byte rxAlign = 0, bool checkCRC = false);
353  byte PCD_CommunicateWithPICC(byte command, byte waitIRq, byte *sendData, byte sendLen, byte *backData = NULL, byte *backLen = NULL, byte *validBits = NULL, byte rxAlign = 0, bool checkCRC = false);
354  byte PICC_RequestA(byte *bufferATQA, byte *bufferSize);
355  byte PICC_WakeupA(byte *bufferATQA, byte *bufferSize);
356  byte PICC_REQA_or_WUPA(byte command, byte *bufferATQA, byte *bufferSize);
357  byte PICC_Select(Uid *uid, byte validBits = 0);
358  byte PICC_HaltA();
359 
361  // Functions for communicating with MIFARE PICCs
363  byte PCD_Authenticate(byte command, byte blockAddr, MIFARE_Key *key, Uid *uid);
364  void PCD_StopCrypto1();
365  byte MIFARE_Read(byte blockAddr, byte *buffer, byte *bufferSize);
366  byte MIFARE_Write(byte blockAddr, byte *buffer, byte bufferSize);
367  byte MIFARE_Decrement(byte blockAddr, long delta);
368  byte MIFARE_Increment(byte blockAddr, long delta);
369  byte MIFARE_Restore(byte blockAddr);
370  byte MIFARE_Transfer(byte blockAddr);
371  byte MIFARE_Ultralight_Write(byte page, byte *buffer, byte bufferSize);
372  byte MIFARE_GetValue(byte blockAddr, long *value);
373  byte MIFARE_SetValue(byte blockAddr, long value);
374 
376  // Support functions
378  byte PCD_MIFARE_Transceive(byte *sendData, byte sendLen, bool acceptTimeout = false);
379  // old function used too much memory, now name moved to flash; if you need char, copy from flash to memory
380  const char *GetStatusCodeName(byte code);
381  //const __FlashStringHelper *GetStatusCodeName(byte code);
382  byte PICC_GetType(byte sak);
383  // old function used too much memory, now name moved to flash; if you need char, copy from flash to memory
384  const char *PICC_GetTypeName(byte type);
385  //const __FlashStringHelper *PICC_GetTypeName(byte type);
386  void PICC_DumpToSerial(Uid *uid);
387  void PICC_DumpMifareClassicToSerial(Uid *uid, byte piccType, MIFARE_Key *key);
388  void PICC_DumpMifareClassicSectorToSerial(Uid *uid, MIFARE_Key *key, byte sector);
389  void PICC_DumpMifareUltralightToSerial();
390  void MIFARE_SetAccessBits(byte *accessBitBuffer, byte g0, byte g1, byte g2, byte g3);
391  bool MIFARE_OpenUidBackdoor(bool logErrors);
392  bool MIFARE_SetUid(byte *newUid, byte uidSize, bool logErrors);
393  bool MIFARE_UnbrickUidSector(bool logErrors);
394 
396  // Convenience functions - does not add extra functionality
398  bool PICC_IsNewCardPresent();
399  bool PICC_ReadCardSerial();
400 
401 private:
402  byte _chipSelectPin; // Arduino pin connected to MFRC522's SPI slave select input (Pin 24, NSS, active low)
403  byte _resetPowerDownPin; // Arduino pin connected to MFRC522's reset and power down input (Pin 6, NRSTPD, active low)
404  byte MIFARE_TwoStepHelper(byte command, byte blockAddr, long data);
405 };
406 
407 #endif
Definition: MFRC522.h:302
Definition: MFRC522.h:309
Definition: MFRC522.h:134