Class MFRC522

Class Documentation

class MFRC522

Public Types

using PCD_Register = MFRC522Constants::PCD_Register
using PCD_RxGain = MFRC522Constants::PCD_RxGain
using PICC_Command = MFRC522Constants::PICC_Command
using MIFARE_Misc = MFRC522Constants::MIFARE_Misc
using PICC_Type = MFRC522Constants::PICC_Type
using StatusCode = MFRC522Constants::StatusCode
using PCD_Command = MFRC522Constants::PCD_Command
using PCD_Version = MFRC522Constants::PCD_Version
using Uid = MFRC522Constants::Uid
using MIFARE_Key = MFRC522Constants::MIFARE_Key

Public Functions

inline MFRC522(MFRC522Driver &driver)
void PCD_SetRegisterBitMask(PCD_Register reg, byte mask)

Sets the bits given in mask in register reg.

Parameters:
  • reg – The register to update. One of the PCD_Register::Enums.

  • mask – The bits to set.

void PCD_ClearRegisterBitMask(PCD_Register reg, byte mask)

Clears the bits given in mask from register reg.

Parameters:
  • reg – The register to update. One of the PCD_Register::Enums.

  • mask – The bits to clear.

StatusCode PCD_CalculateCRC(byte *data, byte length, byte *result)

Use the CRC coprocessor in the MFRC522 to calculate a CRC_A.

Parameters:
  • data – In: Pointer to the data to transfer to the FIFO for CRC calculation.

  • length – In: The number of bytes to transfer.

  • result – Out: Pointer to result buffer. Result is written to result[0..1], low byte first.

Returns:

StatusCode::STATUS_OK on success, StatusCode::STATUS_??? otherwise.

bool PCD_Init()

Initializes the MFRC522 chip.

void PCD_Reset()

Performs a soft reset on the MFRC522 chip and waits for it to be ready again. TODO return result

void PCD_AntennaOn()

Turns the antenna on by enabling pins TX1 and TX2. After a reset these pins are disabled.

void PCD_AntennaOff()

Turns the antenna off by disabling pins TX1 and TX2.

byte PCD_GetAntennaGain()

Get the current MFRC522 Receiver Gain (RxGain[2:0]) value. See 9.3.3.6 / table 98 in https://www.nxp.com/docs/en/data-sheet/MFRC522.pdf NOTE: Return value scrubbed with (0x07<<4)=01110000b as RCFfgReg may use reserved bits.

Returns:

Value of the RxGain, scrubbed to the 3 bits used.

void PCD_SetAntennaGain(byte mask)

Set the MFRC522 Receiver Gain (RxGain) to value specified by given mask. See 9.3.3.6 / table 98 in https://www.nxp.com/docs/en/data-sheet/MFRC522.pdf NOTE: Given mask is scrubbed with (0x07<<4)=01110000b as RCFfgReg may use reserved bits.

PCD_Version PCD_GetVersion()

Determine firmware version. Firmware is equal to chip version.

Returns:

(Known) firmware version of MFRC522.

bool PCD_PerformSelfTest()

Performs a self-test of the MFRC522. See 16.1.1 in https://www.nxp.com/docs/en/data-sheet/MFRC522.pdf Warning: Re-inits the PCD.

Returns:

Whether or not the test passed. Or false if no firmware reference is available.

void PCD_SoftPowerDown()

Only soft power down mode is available through software. IMPORTANT NOTE!!!! Calling any other function that uses CommandReg will disable soft power down mode. For more details about power control, refer to the datasheet - page 33 (8.6).

void PCD_SoftPowerUp()

Power on the PCD again, after PCD_SoftPowerDown.

StatusCode PCD_TransceiveData(byte *sendData, byte sendLen, byte *backData, byte *backLen, byte *validBits = nullptr, byte rxAlign = 0, bool checkCRC = false)

Executes the Transceive command. CRC validation can only be done if backData and backLen are specified.

Parameters:
  • sendData – Pointer to the data to transfer to the FIFO.

  • sendLen – Number of bytes to transfer to the FIFO.

  • backData – nullptr or pointer to buffer if data should be read back after executing the command.

  • backLen – In: Max number of bytes to write to *backData. Out: The number of bytes returned.

  • validBits – In/Out: The number of valid bits in the last byte. 0 for 8 valid bits. Default nullptr.

  • rxAlign – In: Defines the bit position in backData[0] for the first bit received. Default 0.

  • checkCRC – In: True => The last two bytes of the response is assumed to be a CRC_A that must be validated.

Returns:

StatusCode::STATUS_OK on success, StatusCode::STATUS_??? otherwise.

StatusCode PCD_CommunicateWithPICC(byte command, byte waitIRq, byte *sendData, byte sendLen, byte *backData = nullptr, byte *backLen = nullptr, byte *validBits = nullptr, byte rxAlign = 0, bool checkCRC = false)

Transfers data to the MFRC522 FIFO, executes a command, waits for completion and transfers data back from the FIFO. CRC validation can only be done if backData and backLen are specified.

Parameters:
  • command – The command to execute. One of the PCD_Command enums.

  • waitIRq – The bits in the ComIrqReg register that signals successful completion of the command.

  • sendData – Pointer to the data to transfer to the FIFO.

  • sendLen – Number of bytes to transfer to the FIFO.

  • backData – nullptr or pointer to buffer if data should be read back after executing the command.

  • backLen – In: Max number of bytes to write to *backData. Out: The number of bytes returned.

  • validBits – In/Out: The number of valid bits in the last byte. 0 for 8 valid bits.

  • rxAlign – In: Defines the bit position in backData[0] for the first bit received. Default 0.

  • checkCRC – In: True => The last two bytes of the response is assumed to be a CRC_A that must be validated.

Returns:

StatusCode::STATUS_OK on success, StatusCode::STATUS_??? otherwise.

StatusCode PICC_RequestA(byte *bufferATQA, byte *bufferSize)

Transmits a REQuest command, Type A. Invites PICCs in state IDLE to go to READY and prepare for anticollision or selection. 7 bit frame. Beware: When two PICCs are in the field at the same time I often get StatusCode::STATUS_TIMEOUT - probably due do bad antenna design.

Parameters:
  • bufferATQA – The buffer to store the ATQA (Answer to request) in

  • bufferSize – Buffer size, at least two bytes. Also number of bytes returned if StatusCode::STATUS_OK.

Returns:

StatusCode::STATUS_OK on success, StatusCode::STATUS_??? otherwise.

StatusCode PICC_WakeupA(byte *bufferATQA, byte *bufferSize)

Transmits a 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. Beware: When two PICCs are in the field at the same time I often get StatusCode::STATUS_TIMEOUT - probably due do bad antenna design.

Parameters:
  • bufferATQA – The buffer to store the ATQA (Answer to request) in

  • bufferSize – Buffer size, at least two bytes. Also number of bytes returned if StatusCode::STATUS_OK.

Returns:

StatusCode::STATUS_OK on success, StatusCode::STATUS_??? otherwise.

StatusCode PICC_REQA_or_WUPA(byte command, byte *bufferATQA, byte *bufferSize)

Transmits REQA or WUPA commands. Beware: When two PICCs are in the field at the same time I often get StatusCode::STATUS_TIMEOUT - probably due do bad antenna design.

Parameters:
  • command – The command to send - PICC_Command::PICC_CMD_REQA or PICC_Command::PICC_CMD_WUPA

  • bufferATQA – The buffer to store the ATQA (Answer to request) in

  • bufferSize – Buffer size, at least two bytes. Also number of bytes returned if StatusCode::STATUS_OK.

Returns:

StatusCode::STATUS_OK on success, StatusCode::STATUS_??? otherwise.

virtual StatusCode PICC_Select(Uid *uid, byte validBits = 0)

Transmits SELECT/ANTICOLLISION commands to select a single PICC. Before calling this function the PICCs must be placed in the READY(*) state by calling PICC_RequestA() or PICC_WakeupA(). On success:

  • The chosen PICC is in state ACTIVE(*) and all other PICCs have returned to state IDLE/HALT. (Figure 7 of the ISO/IEC 14443-3 draft.)

  • The UID size and value of the chosen PICC is returned in *uid along with the SAK.

A PICC UID consists of 4, 7 or 10 bytes. Only 4 bytes can be specified in a SELECT command, so for the longer UIDs two or three iterations are used: UID size Number of UID bytes Cascade levels Example of PICC ======== =================== ============== =============== single 4 1 MIFARE Classic double 7 2 MIFARE Ultralight triple 10 3 Not currently in use?

Parameters:
  • uid – Pointer to Uid struct. Normally output, but can also be used to supply a known UID.

  • validBits – The number of known UID bits supplied in *uid. Normally 0. If set you must also supply uid->size.

Returns:

StatusCode::STATUS_OK on success, StatusCode::STATUS_??? otherwise.

StatusCode PICC_HaltA()

Instructs a PICC in state ACTIVE(*) to go to state HALT.

Returns:

StatusCode::STATUS_OK on success, StatusCode::STATUS_??? otherwise.

StatusCode PCD_Authenticate(byte command, byte blockAddr, MIFARE_Key *key, Uid *uid)

Executes the MFRC522 MFAuthent command. This command manages MIFARE authentication to enable a secure communication to any MIFARE Mini, MIFARE 1K and MIFARE 4K card. The authentication is described in the MFRC522 datasheet section 10.3.1.9 and http://www.nxp.com/documents/data_sheet/MF1S503x.pdf section 10.1. For use with MIFARE Classic PICCs. The PICC must be selected - ie in state ACTIVE(*) - before calling this function. Remember to call PCD_StopCrypto1() after communicating with the authenticated PICC - otherwise no new communications can start.

All keys are set to FFFFFFFFFFFFh at chip delivery.

Parameters:
  • command – PICC_Command::PICC_CMD_MF_AUTH_KEY_A or PICC_Command::PICC_CMD_MF_AUTH_KEY_B

  • blockAddr – The block number. See numbering in the comments in the .h file.

  • key – Pointer to the Crypto1 key to use (6 bytes).

  • uid – Pointer to Uid struct. The first 4 bytes of the UID is used.

Returns:

StatusCode::STATUS_OK on success, StatusCode::STATUS_??? otherwise. Probably StatusCode::STATUS_TIMEOUT if you supply the wrong key.

void PCD_StopCrypto1()

Used to exit the PCD from its authenticated state. Remember to call this function after communicating with an authenticated PICC - otherwise no new communications can start.

StatusCode MIFARE_Read(byte blockAddr, byte *buffer, byte *bufferSize)

Reads 16 bytes (+ 2 bytes CRC_A) from the active PICC.

For MIFARE Classic the sector containing the block must be authenticated before calling this function.

For MIFARE Ultralight only addresses 00h to 0Fh are decoded. The MF0ICU1 returns a NAK for higher addresses. The MF0ICU1 responds to the READ command by sending 16 bytes starting from the page address defined by the command argument. For example; if blockAddr is 03h then pages 03h, 04h, 05h, 06h are returned. A roll-back is implemented: If blockAddr is 0Eh, then the contents of pages 0Eh, 0Fh, 00h and 01h are returned.

The buffer must be at least 18 bytes because a CRC_A is also returned. Checks the CRC_A before returning StatusCode::STATUS_OK.

Parameters:
  • blockAddr – MIFARE Classic: The block (0-0xff) number. MIFARE Ultralight: The first page to return data from.

  • buffer – The buffer to store the data in.

  • bufferSize – Buffer size, at least 18 bytes. Also number of bytes returned if StatusCode::STATUS_OK.

Returns:

StatusCode::STATUS_OK on success, StatusCode::STATUS_??? otherwise.

StatusCode MIFARE_Write(byte blockAddr, byte *buffer, byte bufferSize)

Writes 16 bytes to the active PICC.

For MIFARE Classic the sector containing the block must be authenticated before calling this function.

For MIFARE Ultralight the operation is called “COMPATIBILITY WRITE”. Even though 16 bytes are transferred to the Ultralight PICC, only the least significant 4 bytes (bytes 0 to 3) are written to the specified address. It is recommended to set the remaining bytes 04h to 0Fh to all logic 0.

Parameters:
  • blockAddr – MIFARE Classic: The block (0-0xff) number. MIFARE Ultralight: The page (2-15) to write to.

  • buffer – The 16 bytes to write to the PICC.

  • bufferSize – Buffer size, must be at least 16 bytes. Exactly 16 bytes are written.

Returns:

StatusCode::STATUS_OK on success, StatusCode::STATUS_??? otherwise.

StatusCode MIFARE_Ultralight_Write(byte page, byte *buffer, byte bufferSize)

Writes a 4 byte page to the active MIFARE Ultralight PICC.

Parameters:
  • page – The page (2-15) to write to.

  • buffer – The 4 bytes to write to the PICC

  • bufferSize – Buffer size, must be at least 4 bytes. Exactly 4 bytes are written.

Returns:

StatusCode::STATUS_OK on success, StatusCode::STATUS_??? otherwise.

StatusCode MIFARE_Decrement(byte blockAddr, int32_t delta)

MIFARE Decrement subtracts the delta from the value of the addressed block, and stores the result in a volatile memory. For MIFARE Classic only. The sector containing the block must be authenticated before calling this function. Only for blocks in “value block” mode, ie with access bits [C1 C2 C3] = [110] or [001]. Use MIFARE_Transfer() to store the result in a block.

Parameters:
  • blockAddr – The block (0-0xff) number.

  • delta – This number is subtracted from the value of block blockAddr.

Returns:

StatusCode::STATUS_OK on success, StatusCode::STATUS_??? otherwise.

StatusCode MIFARE_Increment(byte blockAddr, int32_t delta)

MIFARE Increment adds the delta to the value of the addressed block, and stores the result in a volatile memory. For MIFARE Classic only. The sector containing the block must be authenticated before calling this function. Only for blocks in “value block” mode, ie with access bits [C1 C2 C3] = [110] or [001]. Use MIFARE_Transfer() to store the result in a block.

Parameters:
  • blockAddr – The block (0-0xff) number.

  • delta – This number is added to the value of block blockAddr.

Returns:

StatusCode::STATUS_OK on success, StatusCode::STATUS_??? otherwise.

StatusCode MIFARE_Restore(byte blockAddr)

MIFARE Restore copies the value of the addressed block into a volatile memory. For MIFARE Classic only. The sector containing the block must be authenticated before calling this function. Only for blocks in “value block” mode, ie with access bits [C1 C2 C3] = [110] or [001]. Use MIFARE_Transfer() to store the result in a block.

Parameters:

blockAddr – The block (0-0xff) number.

Returns:

StatusCode::STATUS_OK on success, StatusCode::STATUS_??? otherwise.

StatusCode MIFARE_Transfer(byte blockAddr)

MIFARE Transfer writes the value stored in the volatile memory into one MIFARE Classic block. For MIFARE Classic only. The sector containing the block must be authenticated before calling this function. Only for blocks in “value block” mode, ie with access bits [C1 C2 C3] = [110] or [001].

Parameters:

blockAddr – The block (0-0xff) number.

Returns:

StatusCode::STATUS_OK on success, StatusCode::STATUS_??? otherwise.

StatusCode MIFARE_GetValue(byte blockAddr, int32_t *value)

Helper routine to read the current value from a Value Block.

Only for MIFARE Classic and only for blocks in “value block” mode, that is: with access bits [C1 C2 C3] = [110] or [001]. The sector containing the block must be authenticated before calling this function.

Parameters:
  • blockAddr[in] The block (0x00-0xff) number.

  • value[out] Current value of the Value Block.

Returns:

StatusCode::STATUS_OK on success, StatusCode::STATUS_??? otherwise.

StatusCode MIFARE_SetValue(byte blockAddr, int32_t value)

Helper routine to write a specific value into a Value Block.

Only for MIFARE Classic and only for blocks in “value block” mode, that is: with access bits [C1 C2 C3] = [110] or [001]. The sector containing the block must be authenticated before calling this function.

Parameters:
  • blockAddr[in] The block (0x00-0xff) number.

  • value[in] New value of the Value Block.

Returns:

StatusCode::STATUS_OK on success, StatusCode::STATUS_??? otherwise.

StatusCode PCD_NTAG216_AUTH(const byte password[4], byte pACK[])

Authenticate with a NTAG216.

Only for NTAG216. Authenticate with 32bit password. First implemented by Gargantuanman.

Parameters:
  • password[in] password (32bit).

  • pACK[in] result success???.

Returns:

StatusCode::STATUS_OK on success, StatusCode::STATUS_??? otherwise.

StatusCode PCD_MIFARE_Transceive(byte *sendData, byte sendLen, bool acceptTimeout = false)

Wrapper for MIFARE protocol communication. Adds CRC_A, executes the Transceive command and checks that the response is MF_ACK or a timeout.

Parameters:
  • sendData – Pointer to the data to transfer to the FIFO. Do NOT include the CRC_A.

  • sendLen – Number of bytes in sendData.

  • acceptTimeout – True => A timeout is also success

Returns:

StatusCode::STATUS_OK on success, StatusCode::STATUS_??? otherwise.

void MIFARE_CalculateAccessBits(byte accessBitBuffer[3], const byte g0, const byte g1, const byte g2, const byte g3) const

Calculates the bit pattern needed for the specified access bits. In the [C1 C2 C3] tuples C1 is MSB (=4) and C3 is LSB (=1).

Parameters:
  • accessBitBuffer – Pointer to byte 6, 7 and 8 in the sector trailer. Bytes [0..2] will be set.

  • g0 – Access bits [C1 C2 C3] for block 0 (for sectors 0-31) or blocks 0-4 (for sectors 32-39)

  • g1 – Access bits C1 C2 C3] for block 1 (for sectors 0-31) or blocks 5-9 (for sectors 32-39)

  • g2 – Access bits C1 C2 C3] for block 2 (for sectors 0-31) or blocks 10-14 (for sectors 32-39)

  • g3 – Access bits C1 C2 C3] for the sector trailer, block 3 (for sectors 0-31) or block 15 (for sectors 32-39)

virtual bool PICC_IsNewCardPresent()

Returns true if a PICC responds to PICC_Command::PICC_CMD_REQA. Only “new” cards in state IDLE are invited. Sleeping cards in state HALT are ignored.

Returns:

bool

virtual bool PICC_ReadCardSerial()

Simple wrapper around PICC_Select. Returns true if a UID could be read. Remember to call PICC_IsNewCardPresent(), PICC_RequestA() or PICC_WakeupA() first. The read UID is available in the class variable uid.

Returns:

bool

Public Members

Uid uid

Public Static Functions

static PICC_Type PICC_GetType(byte sak)

Translates the SAK (Select Acknowledge) to a PICC type.

Parameters:

sak – The SAK byte returned from PICC_Select().

Returns:

PICC_Type

Public Static Attributes

static constexpr byte FIFO_SIZE = 64

Protected Functions

StatusCode MIFARE_TwoStepHelper(byte command, byte blockAddr, int32_t data)

Helper function for the two-step MIFARE Classic protocol operations Decrement, Increment and Restore.

Parameters:
  • command – The command to use

  • blockAddr – The block (0-0xff) number.

  • data – The data to transfer in step 2

Returns:

StatusCode::STATUS_OK on success, StatusCode::STATUS_??? otherwise.

Protected Attributes

MFRC522Driver &_driver