449 lines
8.0 KiB
C++
449 lines
8.0 KiB
C++
#include "CR95HF.h"
|
|
#include "SPI.h"
|
|
|
|
// Write command to the CR95HF
|
|
void CR95HF::writeCmd(unsigned short cmd, unsigned short dataLen)
|
|
{
|
|
unsigned short i = 0;
|
|
|
|
digitalWrite(CS, LOW);
|
|
SPI.beginTransaction(SETTINGS);
|
|
SPI.transfer(0x00); // Send cmd to CR95HF
|
|
SPI.transfer(cmd);
|
|
SPI.transfer(dataLen);
|
|
while (dataLen == 0)
|
|
{
|
|
digitalWrite(CS, HIGH);
|
|
break;
|
|
}
|
|
for (i = 0; i < dataLen; i++)
|
|
{
|
|
SPI.transfer(sdata[i]);
|
|
}
|
|
SPI.endTransaction();
|
|
digitalWrite(CS, HIGH);
|
|
}
|
|
|
|
// Poll the CR95HF
|
|
void CR95HF::readCmd()
|
|
{
|
|
unsigned short i = 0;
|
|
|
|
while (1)
|
|
{
|
|
digitalWrite(CS, LOW);
|
|
SPI.beginTransaction(SETTINGS);
|
|
SPI.transfer(0x03);
|
|
res = SPI.transfer(0);
|
|
SPI.endTransaction();
|
|
digitalWrite(CS, HIGH);
|
|
|
|
if ((res & 0x08) >> 3)
|
|
{
|
|
digitalWrite(CS, LOW);
|
|
SPI.beginTransaction(SETTINGS);
|
|
SPI.transfer(0x02);
|
|
res = SPI.transfer(0);
|
|
dataNum = SPI.transfer(0);
|
|
for (i = 0; i < dataNum; i++)
|
|
rdata[i] = SPI.transfer(0);
|
|
SPI.endTransaction();
|
|
digitalWrite(CS, HIGH);
|
|
break;
|
|
}
|
|
SPI.endTransaction();
|
|
digitalWrite(CS, HIGH);
|
|
delay(10);
|
|
}
|
|
}
|
|
|
|
// Initialize MCU and peripherals
|
|
void CR95HF::begin()
|
|
{
|
|
// Configure GPIO pins
|
|
// if (SSI_0 != -1)
|
|
// pinMode(SSI_0, OUTPUT);
|
|
// if (SSI_1 != -1)
|
|
// pinMode(SSI_1, OUTPUT);
|
|
if (IRQ_IN != -1)
|
|
pinMode(IRQ_IN, OUTPUT);
|
|
|
|
pinMode(CS, OUTPUT);
|
|
|
|
// Set in SPI mode
|
|
// if (SSI_0 != -1)
|
|
// digitalWrite(SSI_0, HIGH);
|
|
// if (SSI_1 != -1)
|
|
// digitalWrite(SSI_1, LOW);
|
|
if (IRQ_IN != -1)
|
|
digitalWrite(IRQ_IN, HIGH);
|
|
delay(1);
|
|
|
|
if (IRQ_IN != -1)
|
|
digitalWrite(IRQ_IN, LOW);
|
|
delay(1);
|
|
if (IRQ_IN != -1)
|
|
digitalWrite(IRQ_IN, HIGH);
|
|
delay(1);
|
|
|
|
Serial.println("RFID init: init SPI");
|
|
SPI.begin(SCK, MISO, MOSI);
|
|
|
|
Serial.print("RFID init: Wait for response");
|
|
while (!EchoResponse())
|
|
{ // Until CR95HF is detected
|
|
if (IRQ_IN != -1)
|
|
digitalWrite(IRQ_IN, HIGH);
|
|
delay(10);
|
|
if (IRQ_IN != -1)
|
|
digitalWrite(IRQ_IN, LOW);
|
|
delay(10);
|
|
Serial.print(".");
|
|
}
|
|
Serial.println("ok");
|
|
|
|
Serial.printf("RFID init: Serial=%s\n", readSerial());
|
|
Calibration();
|
|
IndexMod_Gain();
|
|
AutoFDet();
|
|
Select_ISO_IEC_18092_Protocol();
|
|
}
|
|
|
|
// Get Echo reponse from CR95HF
|
|
char CR95HF::EchoResponse()
|
|
{
|
|
|
|
digitalWrite(CS, LOW);
|
|
SPI.beginTransaction(SETTINGS);
|
|
SPI.transfer(0x00); // Send cmd to CR95HF
|
|
SPI.transfer(ECHO);
|
|
SPI.endTransaction();
|
|
digitalWrite(CS, HIGH);
|
|
Serial.println("send echo");
|
|
|
|
while (1)
|
|
{
|
|
digitalWrite(CS, LOW);
|
|
SPI.beginTransaction(SETTINGS);
|
|
SPI.transfer(0x03);
|
|
tmp = SPI.transfer(0);
|
|
SPI.endTransaction();
|
|
digitalWrite(CS, HIGH);
|
|
Serial.printf("rfid: received %x\n",tmp);
|
|
|
|
if ((tmp & 0x08) >> 3)
|
|
{
|
|
digitalWrite(CS, LOW);
|
|
SPI.beginTransaction(SETTINGS);
|
|
SPI.transfer(0x02);
|
|
tmp = SPI.transfer(0);
|
|
SPI.endTransaction();
|
|
digitalWrite(CS, HIGH);
|
|
if (tmp == ECHO)
|
|
{
|
|
Serial.println("receive echo");
|
|
return 1;
|
|
}
|
|
Serial.printf("no echo, received %x\n",tmp);
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Calibrate CR95HF device
|
|
void CR95HF::Calibration()
|
|
{
|
|
sdata[0] = 0x03;
|
|
sdata[1] = 0xA1;
|
|
sdata[2] = 0x00;
|
|
sdata[3] = 0xF8;
|
|
sdata[4] = 0x01;
|
|
sdata[5] = 0x18;
|
|
sdata[6] = 0x00;
|
|
sdata[7] = 0x20;
|
|
sdata[8] = 0x60;
|
|
sdata[9] = 0x60;
|
|
sdata[10] = 0x00;
|
|
sdata[11] = 0x00;
|
|
sdata[12] = 0x3F;
|
|
sdata[13] = 0x01;
|
|
writeCmd(Idle, 0x0E);
|
|
readCmd();
|
|
|
|
sdata[0] = 0x03;
|
|
sdata[1] = 0xA1;
|
|
sdata[2] = 0x00;
|
|
sdata[3] = 0xF8;
|
|
sdata[4] = 0x01;
|
|
sdata[5] = 0x18;
|
|
sdata[6] = 0x00;
|
|
sdata[7] = 0x20;
|
|
sdata[8] = 0x60;
|
|
sdata[9] = 0x60;
|
|
sdata[10] = 0x00;
|
|
sdata[11] = 0xFC;
|
|
sdata[12] = 0x3F;
|
|
sdata[13] = 0x01;
|
|
writeCmd(Idle, 0x0E);
|
|
readCmd();
|
|
|
|
sdata[0] = 0x03;
|
|
sdata[1] = 0xA1;
|
|
sdata[2] = 0x00;
|
|
sdata[3] = 0xF8;
|
|
sdata[4] = 0x01;
|
|
sdata[5] = 0x18;
|
|
sdata[6] = 0x00;
|
|
sdata[7] = 0x20;
|
|
sdata[8] = 0x60;
|
|
sdata[9] = 0x60;
|
|
sdata[10] = 0x00;
|
|
sdata[11] = 0x7C;
|
|
sdata[12] = 0x3F;
|
|
sdata[13] = 0x01;
|
|
writeCmd(Idle, 0x0E);
|
|
readCmd();
|
|
|
|
sdata[0] = 0x03;
|
|
sdata[1] = 0xA1;
|
|
sdata[2] = 0x00;
|
|
sdata[3] = 0xF8;
|
|
sdata[4] = 0x01;
|
|
sdata[5] = 0x18;
|
|
sdata[6] = 0x00;
|
|
sdata[7] = 0x20;
|
|
sdata[8] = 0x60;
|
|
sdata[9] = 0x60;
|
|
sdata[10] = 0x00;
|
|
sdata[11] = 0x3C;
|
|
sdata[12] = 0x3F;
|
|
sdata[13] = 0x01;
|
|
writeCmd(Idle, 0x0E);
|
|
readCmd();
|
|
|
|
sdata[0] = 0x03;
|
|
sdata[1] = 0xA1;
|
|
sdata[2] = 0x00;
|
|
sdata[3] = 0xF8;
|
|
sdata[4] = 0x01;
|
|
sdata[5] = 0x18;
|
|
sdata[6] = 0x00;
|
|
sdata[7] = 0x20;
|
|
sdata[8] = 0x60;
|
|
sdata[9] = 0x60;
|
|
sdata[10] = 0x00;
|
|
sdata[11] = 0x5C;
|
|
sdata[12] = 0x3F;
|
|
sdata[13] = 0x01;
|
|
writeCmd(Idle, 0x0E);
|
|
readCmd();
|
|
|
|
sdata[0] = 0x03;
|
|
sdata[1] = 0xA1;
|
|
sdata[2] = 0x00;
|
|
sdata[3] = 0xF8;
|
|
sdata[4] = 0x01;
|
|
sdata[5] = 0x18;
|
|
sdata[6] = 0x00;
|
|
sdata[7] = 0x20;
|
|
sdata[8] = 0x60;
|
|
sdata[9] = 0x60;
|
|
sdata[10] = 0x00;
|
|
sdata[11] = 0x6C;
|
|
sdata[12] = 0x3F;
|
|
sdata[13] = 0x01;
|
|
writeCmd(Idle, 0x0E);
|
|
readCmd();
|
|
|
|
sdata[0] = 0x03;
|
|
sdata[1] = 0xA1;
|
|
sdata[2] = 0x00;
|
|
sdata[3] = 0xF8;
|
|
sdata[4] = 0x01;
|
|
sdata[5] = 0x18;
|
|
sdata[6] = 0x00;
|
|
sdata[7] = 0x20;
|
|
sdata[8] = 0x60;
|
|
sdata[9] = 0x60;
|
|
sdata[10] = 0x00;
|
|
sdata[11] = 0x74;
|
|
sdata[12] = 0x3F;
|
|
sdata[13] = 0x01;
|
|
writeCmd(Idle, 0x0E);
|
|
readCmd();
|
|
|
|
sdata[0] = 0x03;
|
|
sdata[1] = 0xA1;
|
|
sdata[2] = 0x00;
|
|
sdata[3] = 0xF8;
|
|
sdata[4] = 0x01;
|
|
sdata[5] = 0x18;
|
|
sdata[6] = 0x00;
|
|
sdata[7] = 0x20;
|
|
sdata[8] = 0x60;
|
|
sdata[9] = 0x60;
|
|
sdata[10] = 0x00;
|
|
sdata[11] = 0x70;
|
|
sdata[12] = 0x3F;
|
|
sdata[13] = 0x01;
|
|
writeCmd(Idle, 0x0E);
|
|
readCmd();
|
|
}
|
|
|
|
// Get CR95HF chip ID
|
|
char *CR95HF::readSerial()
|
|
{
|
|
writeCmd(IDN, 0);
|
|
readCmd();
|
|
for (j = 0; j < dataNum; j++)
|
|
{
|
|
CR95HF_ID[j] = rdata[j];
|
|
}
|
|
return CR95HF_ID;
|
|
}
|
|
|
|
// Select the RF communication protocol (ISO/IEC 14443-A)
|
|
void CR95HF::Select_ISO_IEC_14443_A_Protocol()
|
|
{
|
|
sdata[0] = 0x02;
|
|
sdata[1] = 0x00;
|
|
writeCmd(ProtocolSelect, 2);
|
|
readCmd();
|
|
|
|
// Clear read and write buffers
|
|
for (j = 0; j < 18; j++)
|
|
{
|
|
rdata[j] = 0;
|
|
sdata[j] = 0;
|
|
}
|
|
}
|
|
|
|
// Select the RF communication protocol (ISO/IEC 18092)
|
|
void CR95HF::Select_ISO_IEC_18092_Protocol()
|
|
{
|
|
sdata[0] = 0x04;
|
|
sdata[1] = 0x51;
|
|
writeCmd(ProtocolSelect, 2);
|
|
readCmd();
|
|
|
|
// Clear read and write buffers
|
|
for (j = 0; j < 18; j++)
|
|
{
|
|
rdata[j] = 0;
|
|
sdata[j] = 0;
|
|
}
|
|
}
|
|
|
|
// Configure IndexMod & Gain
|
|
void CR95HF::IndexMod_Gain()
|
|
{
|
|
sdata[0] = 0x09;
|
|
sdata[1] = 0x04;
|
|
sdata[2] = 0x68;
|
|
sdata[3] = 0x01;
|
|
sdata[4] = 0x01;
|
|
sdata[5] = 0x50;
|
|
writeCmd(WrReg, 6);
|
|
readCmd();
|
|
}
|
|
|
|
// Configure Auto FDet
|
|
void CR95HF::AutoFDet()
|
|
{
|
|
sdata[0] = 0x09;
|
|
sdata[1] = 0x04;
|
|
sdata[2] = 0x0A;
|
|
sdata[3] = 0x01;
|
|
sdata[4] = 0x02;
|
|
sdata[5] = 0xA1;
|
|
writeCmd(WrReg, 6);
|
|
readCmd();
|
|
}
|
|
|
|
// Read the tag ID
|
|
void CR95HF::GetTagID()
|
|
{
|
|
sdata[0] = 0x26;
|
|
sdata[1] = 0x07;
|
|
writeCmd(SendRecv, 2);
|
|
readCmd();
|
|
|
|
sdata[0] = 0x93;
|
|
sdata[1] = 0x20;
|
|
sdata[2] = 0x08;
|
|
writeCmd(SendRecv, 3);
|
|
readCmd();
|
|
|
|
if (res == 0x80)
|
|
{
|
|
for (j = 1; j < dataNum - 3; j++)
|
|
{
|
|
ID += String(rdata[j], HEX);
|
|
}
|
|
TAG_flag = 1;
|
|
}
|
|
else
|
|
{
|
|
TAG_flag = 0;
|
|
Select_ISO_IEC_18092_Protocol();
|
|
}
|
|
}
|
|
|
|
// Read the NFC Forum tags
|
|
void CR95HF::GetNFCTag()
|
|
{
|
|
sdata[0] = 0x00;
|
|
sdata[1] = 0xFF;
|
|
sdata[2] = 0xFF;
|
|
sdata[3] = 0x00;
|
|
sdata[4] = 0x00;
|
|
writeCmd(SendRecv, 5);
|
|
readCmd();
|
|
|
|
if (res == 0x80)
|
|
{
|
|
for (j = 0; j < dataNum; j++)
|
|
{
|
|
ID += String(rdata[j], HEX);
|
|
}
|
|
NFC_flag = 1;
|
|
}
|
|
else
|
|
{
|
|
NFC_flag = 0;
|
|
Select_ISO_IEC_14443_A_Protocol();
|
|
}
|
|
}
|
|
|
|
String CR95HF::getID()
|
|
{
|
|
|
|
String id = "";
|
|
|
|
if (!TAG_flag)
|
|
GetNFCTag(); // Get NFC ID
|
|
|
|
if (!NFC_flag)
|
|
GetTagID(); // Get Tag ID
|
|
|
|
if (ID.c_str()[0] == 0)
|
|
{ // If there is no tag present
|
|
flag++; // Increment counter flag
|
|
}
|
|
else
|
|
{ // If tag is present
|
|
flag = 0; // Reset counter flag
|
|
id = ID; // Set current ID as previous ID
|
|
}
|
|
ID = ""; // Terminate the ID string
|
|
|
|
// Clear read and write buffers
|
|
for (j = 0; j < 18; j++)
|
|
{
|
|
rdata[j] = 0;
|
|
sdata[j] = 0;
|
|
}
|
|
|
|
return id;
|
|
}
|