Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
Ingo Lohs
Published © GPL3+

RFID-Kit & Particle Photon - A First Introduction

How a radio frequency identification (RFID) - Kit works with Particle Photon?

BeginnerProtip1 hour3,737
RFID-Kit & Particle Photon - A First Introduction

Things used in this project

Hardware components

Photon
Particle Photon
×1
Jumper wires (generic)
Jumper wires (generic)
8 wires female/female
×1
RFID-Kit "S50 RC522"
×1

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
solder the PINs to the PCB

Story

Read more

Code

1/3 "rc522test.ino"

C/C++
/* FILE:    RC522_RFID_Module_Example
   DATE:    23/03/14
  https://build.particle.io/build/5a37b640e59b62ae52000fb8#flash VERSION: 0.2.1 Spark
REVISIONS:
29/08/16    Version 0.2.1, modified by ScruffR: corrected Software SPI sample
23/03/14    Version 0.2, modified by Paul Kourany to run on Spark Core
            with added support for Software SPI
24/07/13    Created version 0.1
This is an example of how to use the RC522 RFID module. The module allows reading
and writing to various types of RFID devices and can be found in our MFRC-522 
(HCMODU0016) and Ultimate RFID (HCARDU0068) kits. This example Arduino sketch uses
the RFID library written by Miguel Balboa to read the pre-programmed serial number 
from RFID cards and tags supplied with our RFID kits. Snapshots and links to the 
library are available on our support forum.
PINOUT:
RC522 MODULE    SPARK HARD SPI  SPARK SOFT SPI
SS                  A2              ANY
SCK                 A3              ANY
MOSI                A5              ANY
MISO                A4              ANY
IRQ                 N/A             N/A
GND                 GND             GND
RST                 D9              ANY
3.3V                3.3V            3.3V
You may copy, alter and reuse this code in any way you like, but please leave
reference to HobbyComponents.com in your comments if you redistribute this code.
This software may not be used directly for the purpose of selling products that
directly compete with Hobby Components Ltd's own range of products.
THIS SOFTWARE IS PROVIDED "AS IS". HOBBY COMPONENTS MAKES NO WARRANTIES, WHETHER
EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ACCURACY OR LACK OF NEGLIGENCE.
HOBBY COMPONENTS SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR ANY DAMAGES,
INCLUDING, BUT NOT LIMITED TO, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY
REASON WHATSOEVER.
*/


/* Include the RFID library */
/* SEE RFID.h for selecting Hardware or Software SPI modes */
#include "RFID.h"

/* Define the pins used for the SS (SDA) and RST (reset) pins for BOTH hardware and software SPI */
/* Change as required */
#define SS_PIN      A2      // Same pin used as hardware SPI (SS)
#define RST_PIN     D2

/* Define the pins used for the DATA OUT (MOSI), DATA IN (MISO) and CLOCK (SCK) pins for SOFTWARE SPI ONLY */
/* Change as required and may be same as hardware SPI as listed in comments */
#define MOSI_PIN    D3      // hardware SPI: A5
#define MISO_PIN    D4      //     "     " : A4
#define SCK_PIN     D5      //     "     " : A3

/* Create an instance of the RFID library */
#if defined(_USE_SOFT_SPI_)
    RFID RC522(SS_PIN, RST_PIN, MOSI_PIN, MISO_PIN, SCK_PIN);    // Software SPI
#else
    RFID RC522(SS_PIN, RST_PIN);                                 // Hardware SPI
#endif


void setup()
{ 
  Serial.begin(9600);
  
#if !defined(_USE_SOFT_SPI_)
  /* Enable the HW SPI interface */
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV8);
  SPI.begin();
#endif

  /* Initialise the RFID reader */
  RC522.init();
}

void loop()
{
  /* Temporary loop counter */
  uint8_t i;

  /* Has a card been detected? */
  if (RC522.isCard())
  {
    /* If so then get its serial number */
    RC522.readCardSerial();

    Serial.println("Card detected:");

    /* Output the serial number to the UART */
    for(i = 0; i <= 4; i++)
    {
      Serial.print(RC522.serNum[i],HEX);
      Serial.print(" ");
    }
    Serial.println();
  }
  else
      Serial.println("Card NOT detected:");
      
  delay(1000);
}

2/3 "RFID.cpp"

C/C++
/*
 * RFID.cpp - Library to use ARDUINO RFID MODULE KIT 13.56 MHZ WITH TAGS SPI W AND R BY COOQROBOT.
 * Based on code Dr.Leong   ( WWW.B2CQSHOP.COM )
 * Created by Miguel Balboa, Jan, 2012. 
 * Modified by Paul Kourany to run on Spark Core with added support for Software SPI, Mar, 2014.
 * Released into the public domain.
 */

/******************************************************************************
 * Includes
 ******************************************************************************/
#include "RFID.h"

/******************************************************************************
 * User API
 ******************************************************************************/

/**
 * Construct RFID
 * uint8_t chipSelectPin RFID /ENABLE pin
 */
RFID::RFID(uint8_t chipSelectPin, uint8_t NRSTPD)
{
	_chipSelectPin = chipSelectPin;

  pinMode(_chipSelectPin,OUTPUT);			// Set digital as OUTPUT to connect it to the RFID /ENABLE pin 
  digitalWrite(_chipSelectPin, LOW); 


  pinMode(NRSTPD,OUTPUT);					// Set digital pin, Not Reset and Power-down
  digitalWrite(NRSTPD, HIGH);
  _NRSTPD = NRSTPD;
}


RFID::RFID(uint8_t chipSelectPin, uint8_t NRSTPD, uint8_t mosiPin, uint8_t misoPin, uint8_t clockPin) {
  _mosiPin = mosiPin;
  _misoPin = misoPin;
  _clockPin = clockPin;
  _chipSelectPin = chipSelectPin;
  _NRSTPD = NRSTPD;  

  pinMode(NRSTPD,OUTPUT);					// Set digital pin, Not Reset and Power-down
  digitalWrite(NRSTPD, HIGH);
  
  pinMode(_clockPin, OUTPUT);
  pinMode(_mosiPin, OUTPUT);
  pinMode(_misoPin, INPUT);
  
  pinMode(_chipSelectPin, OUTPUT);
  digitalWrite(_chipSelectPin, LOW); 
}

/******************************************************************************
 * User API
 ******************************************************************************/

 bool RFID::isCard() 
 {
	uint8_t status;
	uint8_t str[MAX_LEN];

	status = MFRC522Request(PICC_REQIDL, str);	
    if (status == MI_OK) {
		return true;
	} else { 
		return false; 
	}
 }

 bool RFID::readCardSerial(){

	uint8_t status;
	uint8_t str[MAX_LEN];

	// Anti-colisión, devuelva el número de serie de tarjeta de 4 bytes
	status = anticoll(str);
	memcpy(serNum, str, 5);

	if (status == MI_OK) {
		return true;
	} else {
		return false;
	}

 }

/******************************************************************************
 * Dr.Leong   ( WWW.B2CQSHOP.COM )
 ******************************************************************************/

void RFID::init()
{
    digitalWrite(_NRSTPD,HIGH);

	reset();

	//Timer: TPrescaler*TreloadVal/6.78MHz = 24ms
    writeMFRC522(TModeReg, 0x8D);		//Tauto=1; f(Timer) = 6.78MHz/TPreScaler
    writeMFRC522(TPrescalerReg, 0x3E);	//TModeReg[3..0] + TPrescalerReg
    writeMFRC522(TReloadRegL, 30);           
    writeMFRC522(TReloadRegH, 0);

	writeMFRC522(TxAutoReg, 0x40);		//100%ASK
	writeMFRC522(ModeReg, 0x3D);		// CRC valor inicial de 0x6363

	//ClearBitMask(Status2Reg, 0x08);	//MFCrypto1On=0
	//writeMFRC522(RxSelReg, 0x86);		//RxWait = RxSelReg[5..0]
	//writeMFRC522(RFCfgReg, 0x7F);   	//RxGain = 48dB

	antennaOn();		//Abre  la antena


}
void RFID::reset()
{
	writeMFRC522(CommandReg, PCD_RESETPHASE);
}


void RFID::writeMFRC522(uint8_t addr, uint8_t val)
{
    digitalWrite(_chipSelectPin, LOW);

#if defined(_USE_SOFT_SPI_)
    softSPITranser((addr<<1)&0x7E);	
    softSPITranser(val);
#else
    //0XXXXXX0 formato de dirección
    SPI.transfer((addr<<1)&0x7E);	
    SPI.transfer(val);
#endif	

	digitalWrite(_chipSelectPin, HIGH);
}


/*
 *  Read_MFRC522 Nombre de la función: Read_MFRC522
 *  Descripción: Desde el MFRC522 leer un byte de un registro de datos
 *  Los parámetros de entrada: addr - la dirección de registro
 *  Valor de retorno: Devuelve un byte de datos de lectura
 */
uint8_t RFID::readMFRC522(uint8_t addr)
{
    uint8_t val;
    digitalWrite(_chipSelectPin, LOW);
	
#if defined(_USE_SOFT_SPI_)
    softSPITranser(((addr<<1)&0x7E) | 0x80);	
    val = softSPITranser(0x00);
#else	
    SPI.transfer(((addr<<1)&0x7E) | 0x80);	
    val = SPI.transfer(0x00);
#endif

    digitalWrite(_chipSelectPin, HIGH);
    return val;	
}


void RFID::antennaOn(void)
{
	uint8_t temp;

	temp = readMFRC522(TxControlReg);
	if (!(temp & 0x03))
	{
		setBitMask(TxControlReg, 0x03);
	}
}


void RFID::setBitMask(uint8_t reg, uint8_t mask)  
{ 
    uint8_t tmp;
    tmp = readMFRC522(reg);
    writeMFRC522(reg, tmp | mask);  // set bit mask
}

void RFID::clearBitMask(uint8_t reg, uint8_t mask)  
{
    uint8_t tmp;
    tmp = readMFRC522(reg);
    writeMFRC522(reg, tmp & (~mask));  // clear bit mask
} 

void RFID::calculateCRC(uint8_t *pIndata, uint8_t len, uint8_t *pOutData)
{
    uint8_t i, n;

    clearBitMask(DivIrqReg, 0x04);			//CRCIrq = 0
    setBitMask(FIFOLevelReg, 0x80);			//Claro puntero FIFO
    //Write_MFRC522(CommandReg, PCD_IDLE);

	//Escribir datos en el FIFO	
    for (i=0; i<len; i++)
    {   
		writeMFRC522(FIFODataReg, *(pIndata+i));   
	}
    writeMFRC522(CommandReg, PCD_CALCCRC);

	// Esperar a la finalización de cálculo del CRC
    i = 0xFF;
    do 
    {
        n = readMFRC522(DivIrqReg);
        i--;
    }
    while ((i!=0) && !(n&0x04));			//CRCIrq = 1

	//Lea el cálculo de CRC
    pOutData[0] = readMFRC522(CRCResultRegL);
    pOutData[1] = readMFRC522(CRCResultRegM);
}

uint8_t RFID::MFRC522ToCard(uint8_t command, uint8_t *sendData, uint8_t sendLen, uint8_t *backData, uint16_t *backLen)
{
    uint8_t status = MI_ERR;
    uint8_t irqEn = 0x00;
    uint8_t waitIRq = 0x00;
	uint8_t lastBits;
    uint8_t n;
    uint16_t i;

    switch (command)
    {
        case PCD_AUTHENT:		// Tarjetas de certificación cerca
		{
			irqEn = 0x12;
			waitIRq = 0x10;
			break;
		}
		case PCD_TRANSCEIVE:	//La transmisión de datos FIFO
		{
			irqEn = 0x77;
			waitIRq = 0x30;
			break;
		}
		default:
			break;
    }

    writeMFRC522(CommIEnReg, irqEn|0x80);	//De solicitud de interrupción
    clearBitMask(CommIrqReg, 0x80);			// Borrar todos los bits de petición de interrupción
    setBitMask(FIFOLevelReg, 0x80);			//FlushBuffer=1, FIFO de inicialización

	writeMFRC522(CommandReg, PCD_IDLE);	//NO action;Y cancelar el comando

	//Escribir datos en el FIFO
    for (i=0; i<sendLen; i++)
    {   
		writeMFRC522(FIFODataReg, sendData[i]);    
	}

	//???? ejecutar el comando
	writeMFRC522(CommandReg, command);
    if (command == PCD_TRANSCEIVE)
    {    
		setBitMask(BitFramingReg, 0x80);		//StartSend=1,transmission of data starts  
	}   

	// A la espera de recibir datos para completar
	i = 2000;	//i????????,??M1???????25ms	??? i De acuerdo con el ajuste de frecuencia de reloj, el tiempo máximo de espera operación M1 25ms tarjeta??
    do 
    {
		//CommIrqReg[7..0]
		//Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
        n = readMFRC522(CommIrqReg);
        i--;
    }
    while ((i!=0) && !(n&0x01) && !(n&waitIRq));

    clearBitMask(BitFramingReg, 0x80);			//StartSend=0

    if (i != 0)
    {    
        if(!(readMFRC522(ErrorReg) & 0x1B))	//BufferOvfl Collerr CRCErr ProtecolErr
        {
            status = MI_OK;
            if (n & irqEn & 0x01)
            {   
				status = MI_NOTAGERR;			//??   
			}

            if (command == PCD_TRANSCEIVE)
            {
               	n = readMFRC522(FIFOLevelReg);
              	lastBits = readMFRC522(ControlReg) & 0x07;
                if (lastBits)
                {   
					*backLen = (n-1)*8 + lastBits;   
				}
                else
                {   
					*backLen = n*8;   
				}

                if (n == 0)
                {   
					n = 1;    
				}
                if (n > MAX_LEN)
                {   
					n = MAX_LEN;   
				}

				//??FIFO??????? Lea los datos recibidos en el FIFO
                for (i=0; i<n; i++)
                {   
					backData[i] = readMFRC522(FIFODataReg);    
				}
            }
        }
        else
        {   
			status = MI_ERR;  
		}

    }

    //SetBitMask(ControlReg,0x80);           //timer stops
    //Write_MFRC522(CommandReg, PCD_IDLE); 

    return status;
}


/*
 *  Nombre de la función: MFRC522_Request
 *  Descripción: Buscar las cartas, leer el número de tipo de tarjeta
 *  Los parámetros de entrada: reqMode - encontrar el modo de tarjeta,
 *			   Tagtype - Devuelve el tipo de tarjeta
 *			 	0x4400 = Mifare_UltraLight
 *				0x0400 = Mifare_One(S50)
 *				0x0200 = Mifare_One(S70)
 *				0x0800 = Mifare_Pro(X)
 *				0x4403 = Mifare_DESFire
 *  Valor de retorno: el retorno exitoso MI_OK
 */
uint8_t  RFID::MFRC522Request(uint8_t reqMode, uint8_t *TagType)
{
	uint8_t status;  
	uint16_t backBits;			//   Recibió bits de datos

	writeMFRC522(BitFramingReg, 0x07);		//TxLastBists = BitFramingReg[2..0]	???

	TagType[0] = reqMode;
	status = MFRC522ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);

	if ((status != MI_OK) || (backBits != 0x10))
	{    
		status = MI_ERR;
	}

	return status;
}

/**
 *  MFRC522Anticoll -> anticoll
 *  Anti-detección de colisiones, la lectura del número de serie de la tarjeta de tarjeta
 *  @param serNum - devuelve el número de tarjeta 4 bytes de serie, los primeros 5 bytes de bytes de paridad
 *  @return retorno exitoso MI_OK
 */
uint8_t RFID::anticoll(uint8_t *serNum)
{
    uint8_t status;
    uint8_t i;
	uint8_t serNumCheck=0;
    uint16_t unLen;


    //ClearBitMask(Status2Reg, 0x08);		//TempSensclear
    //ClearBitMask(CollReg,0x80);			//ValuesAfterColl
	writeMFRC522(BitFramingReg, 0x00);		//TxLastBists = BitFramingReg[2..0]

    serNum[0] = PICC_ANTICOLL;
    serNum[1] = 0x20;
    status = MFRC522ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);

    if (status == MI_OK)
	{
		//?????? Compruebe el número de serie de la tarjeta
		for (i=0; i<4; i++)
		{   
		 	serNumCheck ^= serNum[i];
		}
		if (serNumCheck != serNum[i])
		{   
			status = MI_ERR;    
		}
    }

    //SetBitMask(CollReg, 0x80);		//ValuesAfterColl=1

    return status;
}

/* 
 * MFRC522Auth -> auth
 * Verificar la contraseña de la tarjeta
 * Los parámetros de entrada: AuthMode - Modo de autenticación de contraseña
                 0x60 = A 0x60 = validación KeyA
                 0x61 = B 0x61 = validación KeyB
             BlockAddr--  bloque de direcciones
             Sectorkey-- sector contraseña
             serNum--,4? Tarjeta de número de serie, 4 bytes
 * MI_OK Valor de retorno: el retorno exitoso MI_OK
 */
uint8_t RFID::auth(uint8_t authMode, uint8_t BlockAddr, uint8_t *Sectorkey, uint8_t *serNum)
{
    uint8_t status;
    uint16_t recvBits;
    uint8_t i;
	uint8_t buff[12]; 

	//????+???+????+???? Verifique la dirección de comandos de bloques del sector + + contraseña + número de la tarjeta de serie
    buff[0] = authMode;
    buff[1] = BlockAddr;
    for (i=0; i<6; i++)
    {    
		buff[i+2] = *(Sectorkey+i);   
	}
    for (i=0; i<4; i++)
    {    
		buff[i+8] = *(serNum+i);   
	}
    status = MFRC522ToCard(PCD_AUTHENT, buff, 12, buff, &recvBits);

    if ((status != MI_OK) || (!(readMFRC522(Status2Reg) & 0x08)))
    {   
		status = MI_ERR;   
	}

    return status;
}

/*
 * MFRC522Read -> read
 * Lectura de datos de bloque
 * Los parámetros de entrada: blockAddr - dirección del bloque; recvData - leer un bloque de datos
 * MI_OK Valor de retorno: el retorno exitoso MI_OK
 */
uint8_t RFID::read(uint8_t blockAddr, uint8_t *recvData)
{
    uint8_t status;
    uint16_t unLen;

    recvData[0] = PICC_READ;
    recvData[1] = blockAddr;
    calculateCRC(recvData,2, &recvData[2]);
    status = MFRC522ToCard(PCD_TRANSCEIVE, recvData, 4, recvData, &unLen);

    if ((status != MI_OK) || (unLen != 0x90))
    {
        status = MI_ERR;
    }

    return status;
}

/*
 * MFRC522Write -> write
 * La escritura de datos de bloque
 * blockAddr - dirección del bloque; WriteData - para escribir 16 bytes del bloque de datos
 * Valor de retorno: el retorno exitoso MI_OK
 */
uint8_t RFID::write(uint8_t blockAddr, uint8_t *writeData)
{
    uint8_t status;
    uint16_t recvBits;
    uint8_t i;
	uint8_t buff[18]; 

    buff[0] = PICC_WRITE;
    buff[1] = blockAddr;
    calculateCRC(buff, 2, &buff[2]);
    status = MFRC522ToCard(PCD_TRANSCEIVE, buff, 4, buff, &recvBits);

    if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A))
    {   
		status = MI_ERR;   
	}

    if (status == MI_OK)
    {
        for (i=0; i<16; i++)		//?FIFO?16Byte?? Datos a la FIFO 16Byte escribir
        {    
        	buff[i] = *(writeData+i);   
        }
        calculateCRC(buff, 16, &buff[16]);
        status = MFRC522ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits);

		if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A))
        {   
			status = MI_ERR;   
		}
    }

    return status;
}


/*
 * MFRC522Halt -> halt
 * Cartas de Mando para dormir
 * Los parámetros de entrada: Ninguno
 * Valor devuelto: Ninguno
 */
void RFID::halt()
{
    uint8_t status;
    uint16_t unLen;
    uint8_t buff[4];

    buff[0] = PICC_HALT;
    buff[1] = 0;
    calculateCRC(buff, 2, &buff[2]);

    clearBitMask(Status2Reg, 0x08); // turn off encryption

    status = MFRC522ToCard(PCD_TRANSCEIVE, buff, 4, buff,&unLen);
}

inline __attribute__((always_inline))
uint8_t RFID::softSPITranser(uint8_t data) {

  uint8_t b=0;

  for (uint8_t bit = 0; bit < 8; bit++) {
    if (data & (1 << (7-bit)))		// walks down mask from bit 7 to bit 0
      pinSetFast(_mosiPin); // Data High
    else
      pinResetFast(_mosiPin); // Data Low
		
    pinSetFast(_clockPin); // Clock High

    b <<= 1;
    if (pinReadFast(_misoPin))
      b |= 1;

    pinResetFast(_clockPin); // Clock Low
  }
  return b;

}

3/3 "RFID.h"

C/C++
/* RFID.h - Library to use ARDUINO RFID MODULE KIT 13.56 MHZ WITH TAGS SPI W AND R BY COOQROBOT.
 * Based on code Dr.Leong   ( WWW.B2CQSHOP.COM )
 * Created by Miguel Balboa (circuitito.com), Jan, 2012.
 * Modified by Paul Kourany to run on Spark Core with added support for Software SPI, Mar, 2014.
 */
#ifndef RFID_h
#define RFID_h

#include "application.h"

/* !!! Uncomment the following line if SOFT SPI is to be used !!! */
#define _USE_SOFT_SPI_


/******************************************************************************
 * Definitions
 ******************************************************************************/
#define MAX_LEN 16   // Largo máximo de la matriz

//MF522 comando palabra
#define PCD_IDLE              0x00               // NO action; Y cancelar el comando
#define PCD_AUTHENT           0x0E               // autenticación de clave
#define PCD_RECEIVE           0x08               // recepción de datos
#define PCD_TRANSMIT          0x04               // Enviar datos
#define PCD_TRANSCEIVE        0x0C               // Enviar y recibir datos
#define PCD_RESETPHASE        0x0F               // reajustar
#define PCD_CALCCRC           0x03               // CRC calcular

//Mifare_One  Tarjeta Mifare_One comando palabra
#define PICC_REQIDL           0x26               // Area de la antena no esta tratando de entrar en el estado de reposo
#define PICC_REQALL           0x52               // Todas las cartas para encontrar el área de la antena
#define PICC_ANTICOLL         0x93               // anti-colisión
#define PICC_SElECTTAG        0x93               // elección de tarjeta
#define PICC_AUTHENT1A        0x60               // verificación key A
#define PICC_AUTHENT1B        0x61               // verificación Key B
#define PICC_READ             0x30               // leer bloque
#define PICC_WRITE            0xA0               // Escribir en el bloque 
#define PICC_DECREMENT        0xC0               // cargo
#define PICC_INCREMENT        0xC1               // recargar
#define PICC_RESTORE          0xC2               // Transferencia de datos de bloque de buffer
#define PICC_TRANSFER         0xB0               // Guardar los datos en el búfer
#define PICC_HALT             0x50               // inactividad

//MF522 Código de error de comunicación cuando regresó
#define MI_OK                 0
#define MI_NOTAGERR           1
#define MI_ERR                2

//------------------ MFRC522 registro---------------
//Page 0:Command and Status
#define     Reserved00            0x00    
#define     CommandReg            0x01    
#define     CommIEnReg            0x02    
#define     DivlEnReg             0x03    
#define     CommIrqReg            0x04    
#define     DivIrqReg             0x05
#define     ErrorReg              0x06    
#define     Status1Reg            0x07    
#define     Status2Reg            0x08    
#define     FIFODataReg           0x09
#define     FIFOLevelReg          0x0A
#define     WaterLevelReg         0x0B
#define     ControlReg            0x0C
#define     BitFramingReg         0x0D
#define     CollReg               0x0E
#define     Reserved01            0x0F
//Page 1:Command     
#define     Reserved10            0x10
#define     ModeReg               0x11
#define     TxModeReg             0x12
#define     RxModeReg             0x13
#define     TxControlReg          0x14
#define     TxAutoReg             0x15
#define     TxSelReg              0x16
#define     RxSelReg              0x17
#define     RxThresholdReg        0x18
#define     DemodReg              0x19
#define     Reserved11            0x1A
#define     Reserved12            0x1B
#define     MifareReg             0x1C
#define     Reserved13            0x1D
#define     Reserved14            0x1E
#define     SerialSpeedReg        0x1F
//Page 2:CFG    
#define     Reserved20            0x20  
#define     CRCResultRegM         0x21
#define     CRCResultRegL         0x22
#define     Reserved21            0x23
#define     ModWidthReg           0x24
#define     Reserved22            0x25
#define     RFCfgReg              0x26
#define     GsNReg                0x27
#define     CWGsPReg	          0x28
#define     ModGsPReg             0x29
#define     TModeReg              0x2A
#define     TPrescalerReg         0x2B
#define     TReloadRegH           0x2C
#define     TReloadRegL           0x2D
#define     TCounterValueRegH     0x2E
#define     TCounterValueRegL     0x2F
//Page 3:TestRegister     
#define     Reserved30            0x30
#define     TestSel1Reg           0x31
#define     TestSel2Reg           0x32
#define     TestPinEnReg          0x33
#define     TestPinValueReg       0x34
#define     TestBusReg            0x35
#define     AutoTestReg           0x36
#define     VersionReg            0x37
#define     AnalogTestReg         0x38
#define     TestDAC1Reg           0x39  
#define     TestDAC2Reg           0x3A   
#define     TestADCReg            0x3B   
#define     Reserved31            0x3C   
#define     Reserved32            0x3D   
#define     Reserved33            0x3E   
#define     Reserved34			  0x3F
//-----------------------------------------------

class RFID
{
  public:
    RFID(uint8_t chipSelectPin, uint8_t NRSTPD);
    
    RFID(uint8_t chipSelectPin, uint8_t NRSTPD, uint8_t mosiPin, uint8_t misoPin, uint8_t clockPin);

	bool isCard();
	bool readCardSerial();

    void init();
	void reset();
	void writeMFRC522(uint8_t addr, uint8_t val);
	void antennaOn(void);
	uint8_t readMFRC522(uint8_t addr);
	void setBitMask(uint8_t reg, uint8_t mask);
	void clearBitMask(uint8_t reg, uint8_t mask);
	void calculateCRC(uint8_t *pIndata, uint8_t len, uint8_t *pOutData);
	uint8_t MFRC522Request(uint8_t reqMode, uint8_t *TagType);
	uint8_t MFRC522ToCard(uint8_t command, uint8_t *sendData, uint8_t sendLen, uint8_t *backData, uint16_t *backLen);
	uint8_t anticoll(uint8_t *serNum);
	uint8_t auth(uint8_t authMode, uint8_t BlockAddr, uint8_t *Sectorkey, uint8_t *serNum);
	uint8_t read(uint8_t blockAddr, uint8_t *recvData);
	uint8_t write(uint8_t blockAddr, uint8_t *writeData);
	void halt();

	uint8_t serNum[5];       // Constante para guardar el numero de serie leido.
	uint8_t AserNum[5];      // Constante para guardar el numero d serie de la secion actual.

  private:
    uint8_t softSPITranser(uint8_t data);      // SOFT SPI
  
    uint8_t _chipSelectPin;
	uint8_t _NRSTPD;
    uint8_t _mosiPin;
    uint8_t _misoPin;
    uint8_t _clockPin;
};

#endif

Credits

Ingo Lohs

Ingo Lohs

182 projects • 194 followers
I am well over 50 years and come from the middle of Germany.

Comments