AVR library
Macros | Functions
mfrc522.c File Reference

MFRC522 Mifare routines. More...

#include <util/delay.h>
#include <string.h>
#include <stddef.h>
#include "mfrc522.h"
#include "spi.h"
#include "hwdefs.h"

Macros

#define SPI_CS_LOW   MFRC522_SS_PORT &= ~_BV(MFRC522_SS_BIT)
 
#define SPI_CS_HIGH   MFRC522_SS_PORT |= _BV(MFRC522_SS_BIT)
 

Functions

void MFRC522_init ()
 
void PCD_WriteRegister (byte reg, byte value)
 
void PCD_WriteRegister2 (byte reg, byte count, byte *values)
 
byte PCD_ReadRegister (byte reg)
 
void PCD_ReadRegister2 (byte reg, byte count, byte *values, byte rxAlign)
 
void PCD_SetRegisterBitMask (byte reg, byte mask)
 
void PCD_ClearRegisterBitMask (byte reg, byte mask)
 
byte PCD_CalculateCRC (byte *data, byte length, byte *result)
 
byte PCD_Init ()
 
byte PCD_Reset ()
 
void PCD_AntennaOn ()
 
byte PCD_TransceiveData (byte *sendData, byte sendLen, byte *backData, byte *backLen, byte *validBits, byte rxAlign, bool checkCRC)
 
byte PCD_CommunicateWithPICC (byte command, byte waitIRq, byte *sendData, byte sendLen, byte *backData, byte *backLen, byte *validBits, byte rxAlign, bool checkCRC)
 
byte PICC_RequestA (byte *bufferATQA, byte *bufferSize)
 
byte PICC_WakeupA (byte *bufferATQA, byte *bufferSize)
 
byte PICC_REQA_or_WUPA (byte command, byte *bufferATQA, byte *bufferSize)
 
byte PICC_Select (Uid *uid, byte validBits)
 
byte PICC_HaltA ()
 
byte PCD_Authenticate (byte command, byte blockAddr, MIFARE_Key *key, Uid *uid)
 
void PCD_StopCrypto1 ()
 
byte MIFARE_Read (byte blockAddr, byte *buffer, byte *bufferSize)
 
byte MIFARE_Write (byte blockAddr, byte *buffer, byte bufferSize)
 
byte PCD_MIFARE_Transceive (byte *sendData, byte sendLen, bool acceptTimeout)
 
bool PICC_IsNewCardPresent ()
 
bool PICC_ReadCardSerial (Uid *uid)
 

Detailed Description

MFRC522 Mifare routines.

Author
Matej Kogovsek (matej.nosp@m.@ham.nosp@m.radio.nosp@m..si)
Note
This file is part of mat-avr-lib
This file was not written by me from scratch. It was adapted from code by Miguel Balboa at https://github.com/miguelbalboa/rfid

Function Documentation

byte 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 STATUS_OK.

Returns
STATUS_OK on success, STATUS_??? otherwise.
Parameters
blockAddrMIFARE Classic: The block (0-0xff) number. MIFARE Ultralight: The first page to return data from.
bufferThe buffer to store the data in
bufferSizeBuffer size, at least 18 bytes. Also number of bytes returned if STATUS_OK.
byte 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 opretaion 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.

  • Returns
    STATUS_OK on success, STATUS_??? otherwise.
Parameters
blockAddrMIFARE Classic: The block (0-0xff) number. MIFARE Ultralight: The page (2-15) to write to.
bufferThe 16 bytes to write to the PICC
bufferSizeBuffer size, must be at least 16 bytes. Exactly 16 bytes are written.
void PCD_AntennaOn ( void  )

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

byte 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.

Returns
STATUS_OK on success, STATUS_??? otherwise. Probably STATUS_TIMEOUT if you supply the wrong key.
Parameters
commandPICC_CMD_MF_AUTH_KEY_A or PICC_CMD_MF_AUTH_KEY_B
blockAddrThe block number. See numbering in the comments in the .h file.
keyPointer to the Crypteo1 key to use (6 bytes)
uidPointer to Uid struct. The first 4 bytes of the UID is used.
byte PCD_CalculateCRC ( byte *  data,
byte  length,
byte *  result 
)

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

Returns
STATUS_OK on success, STATUS_??? otherwise.
Parameters
dataIn: Pointer to the data to transfer to the FIFO for CRC calculation.
lengthIn: The number of bytes to transfer.
resultOut: Pointer to result buffer. Result is written to result[0..1], low byte first.
void PCD_ClearRegisterBitMask ( byte  reg,
byte  mask 
)

Clears the bits given in mask from register reg.

Parameters
regThe register to update. One of the PCD_Register enums.
maskThe bits to clear.
byte PCD_CommunicateWithPICC ( byte  command,
byte  waitIRq,
byte *  sendData,
byte  sendLen,
byte *  backData,
byte *  backLen,
byte *  validBits,
byte  rxAlign,
bool  checkCRC 
)

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.

Returns
STATUS_OK on success, STATUS_??? otherwise.
Parameters
commandThe command to execute. One of the PCD_Command enums.
waitIRqThe bits in the ComIrqReg register that signals successful completion of the command.
sendDataPointer to the data to transfer to the FIFO.
sendLenNumber of bytes to transfer to the FIFO.
backDataNULL or pointer to buffer if data should be read back after executing the command.
backLenIn: Max number of bytes to write to *backData. Out: The number of bytes returned.
validBitsIn/Out: The number of valid bits in the last byte. 0 for 8 valid bits.
rxAlignIn: Defines the bit position in backData[0] for the first bit received. Default 0.
checkCRCIn: True => The last two bytes of the response is assumed to be a CRC_A that must be validated.
byte PCD_Init ( void  )

Initializes the MFRC522 chip.

byte PCD_MIFARE_Transceive ( byte *  sendData,
byte  sendLen,
bool  acceptTimeout 
)

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

Returns
STATUS_OK on success, STATUS_??? otherwise. 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.
STATUS_OK on success, STATUS_??? otherwise. 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.
STATUS_OK on success, STATUS_??? otherwise. 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.
STATUS_OK on success, STATUS_??? otherwise. Helper function for the two-step MIFARE Classic protocol operations Decrement, Increment and Restore.
STATUS_OK on success, STATUS_??? otherwise. 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].
STATUS_OK on success, STATUS_??? otherwise. Wrapper for MIFARE protocol communication. Adds CRC_A, executes the Transceive command and checks that the response is MF_ACK or a timeout.
STATUS_OK on success, STATUS_??? otherwise.
Parameters
sendDataPointer to the data to transfer to the FIFO. Do NOT include the CRC_A.
sendLenNumber of bytes in sendData.
acceptTimeoutTrue => A timeout is also success
byte PCD_ReadRegister ( byte  reg)

Reads a byte from the specified register in the MFRC522 chip. The interface is described in the datasheet section 8.1.2.

Parameters
regThe register to read from. One of the PCD_Register enums.
void PCD_ReadRegister2 ( byte  reg,
byte  count,
byte *  values,
byte  rxAlign 
)

Reads a number of bytes from the specified register in the MFRC522 chip. The interface is described in the datasheet section 8.1.2.

Parameters
regThe register to read from. One of the PCD_Register enums.
countThe number of bytes to read
valuesByte array to store the values in.
rxAlignOnly bit positions rxAlign..7 in values[0] are updated.
byte PCD_Reset ( void  )

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

void PCD_SetRegisterBitMask ( byte  reg,
byte  mask 
)

Sets the bits given in mask in register reg.

Parameters
regThe register to update. One of the PCD_Register enums.
maskThe bits to set.
void PCD_StopCrypto1 ( void  )

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.

byte PCD_TransceiveData ( byte *  sendData,
byte  sendLen,
byte *  backData,
byte *  backLen,
byte *  validBits,
byte  rxAlign,
bool  checkCRC 
)

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

Returns
STATUS_OK on success, STATUS_??? otherwise.
Parameters
sendDataPointer to the data to transfer to the FIFO.
sendLenNumber of bytes to transfer to the FIFO.
backDataNULL or pointer to buffer if data should be read back after executing the command.
backLenIn: Max number of bytes to write to *backData. Out: The number of bytes returned.
validBitsIn/Out: The number of valid bits in the last byte. 0 for 8 valid bits. Default NULL.
rxAlignIn: Defines the bit position in backData[0] for the first bit received. Default 0.
checkCRCIn: True => The last two bytes of the response is assumed to be a CRC_A that must be validated.
void PCD_WriteRegister ( byte  reg,
byte  value 
)

Writes a byte to the specified register in the MFRC522 chip. The interface is described in the datasheet section 8.1.2.

Parameters
regThe register to write to. One of the PCD_Register enums.
valueThe value to write.
void PCD_WriteRegister2 ( byte  reg,
byte  count,
byte *  values 
)

Writes a number of bytes to the specified register in the MFRC522 chip. The interface is described in the datasheet section 8.1.2.

Parameters
regThe register to write to. One of the PCD_Register enums.
countThe number of bytes to write to the register
valuesThe values to write. Byte array.
byte PICC_HaltA ( void  )

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

Returns
STATUS_OK on success, STATUS_??? otherwise.
bool PICC_IsNewCardPresent ( void  )

Returns a string pointer to a status code name. Translates the SAK (Select Acknowledge) to a PICC type.

Returns
PICC_Type Returns a string pointer to the PICC type name. Dumps debug info about the selected PICC to Serial. On success the PICC is halted after dumping the data. For MIFARE Classic the factory default key of 0xFFFFFFFFFFFF is tried. Dumps memory contents of a MIFARE Classic PICC. On success the PICC is halted after dumping the data. Dumps memory contents of a sector of a MIFARE Classic PICC. Uses PCD_Authenticate(), MIFARE_Read() and PCD_StopCrypto1. Always uses PICC_CMD_MF_AUTH_KEY_A because only Key A can always read the sector trailer access bits. Dumps memory contents of a MIFARE Ultralight PICC. Calculates the bit pattern needed for the specified access bits. In the [C1 C2 C3] tupples C1 is MSB (=4) and C3 is LSB (=1). Returns true if a PICC responds to PICC_CMD_REQA. Only "new" cards in state IDLE are invited. Sleeping cards in state HALT are ignored.
bool
bool PICC_ReadCardSerial ( Uid uid)

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
byte 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 STATUS_TIMEOUT - probably due do bad antenna design.

Returns
STATUS_OK on success, STATUS_??? otherwise.
Parameters
commandThe command to send - PICC_CMD_REQA or PICC_CMD_WUPA
bufferATQAThe buffer to store the ATQA (Answer to request) in
bufferSizeBuffer size, at least two bytes. Also number of bytes returned if STATUS_OK.
byte 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 STATUS_TIMEOUT - probably due do bad antenna design.

Returns
STATUS_OK on success, STATUS_??? otherwise.
Parameters
bufferATQAThe buffer to store the ATQA (Answer to request) in
bufferSizeBuffer size, at least two bytes. Also number of bytes returned if STATUS_OK.
byte PICC_Select ( Uid uid,
byte  validBits 
)

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?

Returns
STATUS_OK on success, STATUS_??? otherwise.
Parameters
uidPointer to Uid struct. Normally output, but can also be used to supply a known UID.
validBitsThe number of known UID bits supplied in *uid. Normally 0. If set you must also supply uid->size.
byte 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 STATUS_TIMEOUT - probably due do bad antenna design.

Returns
STATUS_OK on success, STATUS_??? otherwise.
Parameters
bufferATQAThe buffer to store the ATQA (Answer to request) in
bufferSizeBuffer size, at least two bytes. Also number of bytes returned if STATUS_OK.