Skip to content
This repository was archived by the owner on Jun 8, 2022. It is now read-only.
122 changes: 61 additions & 61 deletions PN5180.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,10 @@ bool PN5180::writeRegister(uint8_t reg, uint32_t value) {
For all 4 byte command parameter transfers (e.g. register values), the payload
parameters passed follow the little endian approach (Least Significant Byte first).
*/
uint8_t buf[6] = { PN5180_WRITE_REGISTER, reg, p[0], p[1], p[2], p[3] };
uint8_t cmd[] = { PN5180_WRITE_REGISTER, reg, p[0], p[1], p[2], p[3] };

SPI.beginTransaction(PN5180_SPI_SETTINGS);
transceiveCommand(buf, 6);
transceiveCommand(cmd, sizeof(cmd));
SPI.endTransaction();

return true;
Expand All @@ -129,10 +129,10 @@ bool PN5180::writeRegisterWithOrMask(uint8_t reg, uint32_t mask) {
PN5180DEBUG("\n");
#endif

uint8_t buf[6] = { PN5180_WRITE_REGISTER_OR_MASK, reg, p[0], p[1], p[2], p[3] };
uint8_t cmd[] = { PN5180_WRITE_REGISTER_OR_MASK, reg, p[0], p[1], p[2], p[3] };

SPI.beginTransaction(PN5180_SPI_SETTINGS);
transceiveCommand(buf, 6);
transceiveCommand(cmd, sizeof(cmd));
SPI.endTransaction();

return true;
Expand All @@ -159,10 +159,10 @@ bool PN5180::writeRegisterWithAndMask(uint8_t reg, uint32_t mask) {
PN5180DEBUG("\n");
#endif

uint8_t buf[6] = { PN5180_WRITE_REGISTER_AND_MASK, reg, p[0], p[1], p[2], p[3] };
uint8_t cmd[] = { PN5180_WRITE_REGISTER_AND_MASK, reg, p[0], p[1], p[2], p[3] };

SPI.beginTransaction(PN5180_SPI_SETTINGS);
transceiveCommand(buf, 6);
transceiveCommand(cmd, sizeof(cmd));
SPI.endTransaction();

return true;
Expand All @@ -180,10 +180,10 @@ bool PN5180::readRegister(uint8_t reg, uint32_t *value) {
PN5180DEBUG(formatHex(reg));
PN5180DEBUG(F("...\n"));

uint8_t cmd[2] = { PN5180_READ_REGISTER, reg };
uint8_t cmd[] = { PN5180_READ_REGISTER, reg };

SPI.beginTransaction(PN5180_SPI_SETTINGS);
transceiveCommand(cmd, 2, (uint8_t*)value, 4);
transceiveCommand(cmd, sizeof(cmd), (uint8_t*)value, 4);
SPI.endTransaction();

PN5180DEBUG(F("Register value=0x"));
Expand All @@ -196,31 +196,31 @@ bool PN5180::readRegister(uint8_t reg, uint32_t *value) {
/*
* WRITE_EEPROM - 0x06
*/
bool PN5180::writeEEPROM(uint8_t addr, uint8_t *data, int len) {
if ((addr > 254) || ((addr+len) > 254)) {
PN5180DEBUG(F("ERROR: Writing beyond addr 254!\n"));
return false;
}

PN5180DEBUG(F("Writing to EEPROM at 0x"));
PN5180DEBUG(formatHex(addr));
PN5180DEBUG(F(", size="));
PN5180DEBUG(len);
PN5180DEBUG(F("...\n"));

uint8_t buffer[len+2];
buffer[0] = PN5180_WRITE_EEPROM;
buffer[1] = addr;
for (int i=0; i<len; i++) {
buffer[2+i] = data[i];
}

SPI.beginTransaction(PN5180_SPI_SETTINGS);
transceiveCommand(buffer, len+2);
SPI.endTransaction();

return true;
}
bool PN5180::writeEEPROM(uint8_t addr, uint8_t *data, int len) {
if ((addr > 254) || ((addr+len) > 254)) {
PN5180DEBUG(F("ERROR: Writing beyond addr 254!\n"));
return false;
}

PN5180DEBUG(F("Writing to EEPROM at 0x"));
PN5180DEBUG(formatHex(addr));
PN5180DEBUG(F(", size="));
PN5180DEBUG(len);
PN5180DEBUG(F("...\n"));

uint8_t cmd[len+2];
cmd[0] = PN5180_WRITE_EEPROM;
cmd[1] = addr;
for (int i=0; i<len; i++) {
cmd[2+i] = data[i];
}

SPI.beginTransaction(PN5180_SPI_SETTINGS);
transceiveCommand(cmd, len+2);
SPI.endTransaction();

return true;
}

/*
* READ_EEPROM - 0x07
Expand All @@ -245,10 +245,10 @@ bool PN5180::readEEprom(uint8_t addr, uint8_t *buffer, int len) {
PN5180DEBUG(len);
PN5180DEBUG(F("...\n"));

uint8_t cmd[3] = { PN5180_READ_EEPROM, addr, len };
uint8_t cmd[] = { PN5180_READ_EEPROM, addr, (uint8_t)len };

SPI.beginTransaction(PN5180_SPI_SETTINGS);
transceiveCommand(cmd, 3, buffer, len);
transceiveCommand(cmd, sizeof(cmd), buffer, len);
SPI.endTransaction();

#ifdef DEBUG
Expand Down Expand Up @@ -295,11 +295,11 @@ bool PN5180::sendData(uint8_t *data, int len, uint8_t validBits) {
PN5180DEBUG("\n");
#endif

uint8_t buffer[len+2];
buffer[0] = PN5180_SEND_DATA;
buffer[1] = validBits; // number of valid bits of last byte are transmitted (0 = all bits are transmitted)
uint8_t cmd[len+2];
cmd[0] = PN5180_SEND_DATA;
cmd[1] = validBits; // number of valid bits of last byte are transmitted (0 = all bits are transmitted)
for (int i=0; i<len; i++) {
buffer[2+i] = data[i];
cmd[2+i] = data[i];
}

writeRegisterWithAndMask(SYSTEM_CONFIG, 0xfffffff8); // Idle/StopCom Command
Expand All @@ -314,13 +314,13 @@ bool PN5180::sendData(uint8_t *data, int len, uint8_t validBits) {
*/

PN5180TransceiveStat transceiveState = getTransceiveState();
if (PN5180_TS_WaitTransmit != transceiveState) {
if (transceiveState != PN5180_TS_WaitTransmit) {
PN5180DEBUG(F("*** ERROR: Transceiver not in state WaitTransmit!?\n"));
return false;
}

SPI.beginTransaction(PN5180_SPI_SETTINGS);
transceiveCommand(buffer, len+2);
transceiveCommand(cmd, len+2);
SPI.endTransaction();

return true;
Expand All @@ -337,22 +337,22 @@ bool PN5180::sendData(uint8_t *data, int len, uint8_t validBits) {
* reception buffer is invalid. If the condition is not fulfilled, an exception is raised.
*/
uint8_t * PN5180::readData(int len, uint8_t *buffer /* = NULL */) {
if (len > 508) {
if (len < 0 || (unsigned int)len > sizeof(readBuffer)) {
Serial.println(F("*** FATAL: Reading more than 508 bytes is not supported!"));
return 0L;
return 0;
}
if (NULL == buffer) {
if (buffer == NULL) {
buffer = readBuffer;
}

PN5180DEBUG(F("Reading Data (len="));
PN5180DEBUG(len);
PN5180DEBUG(F(")...\n"));

uint8_t cmd[2] = { PN5180_READ_DATA, 0x00 };
uint8_t cmd[] = { PN5180_READ_DATA, 0x00 };

SPI.beginTransaction(PN5180_SPI_SETTINGS);
transceiveCommand(cmd, 2, buffer, len);
transceiveCommand(cmd, sizeof(cmd), buffer, len);
SPI.endTransaction();

#ifdef DEBUG
Expand Down Expand Up @@ -392,10 +392,10 @@ bool PN5180::loadRFConfig(uint8_t txConf, uint8_t rxConf) {
PN5180DEBUG(formatHex(rxConf));
PN5180DEBUG("\n");

uint8_t cmd[3] = { PN5180_LOAD_RF_CONFIG, txConf, rxConf };
uint8_t cmd[] = { PN5180_LOAD_RF_CONFIG, txConf, rxConf };

SPI.beginTransaction(PN5180_SPI_SETTINGS);
transceiveCommand(cmd, 3);
transceiveCommand(cmd, sizeof(cmd));
SPI.endTransaction();

return true;
Expand All @@ -409,13 +409,13 @@ bool PN5180::loadRFConfig(uint8_t txConf, uint8_t rxConf) {
bool PN5180::setRF_on() {
PN5180DEBUG(F("Set RF ON\n"));

uint8_t cmd[2] = { PN5180_RF_ON, 0x00 };
uint8_t cmd[] = { PN5180_RF_ON, 0x00 };

SPI.beginTransaction(PN5180_SPI_SETTINGS);
transceiveCommand(cmd, 2);
transceiveCommand(cmd, sizeof(cmd));
SPI.endTransaction();

while (0 == (TX_RFON_IRQ_STAT & getIRQStatus())); // wait for RF field to set up
while (!(getIRQStatus() & TX_RFON_IRQ_STAT)); // wait for RF field to set up
clearIRQStatus(TX_RFON_IRQ_STAT);
return true;
}
Expand All @@ -428,13 +428,13 @@ bool PN5180::setRF_on() {
bool PN5180::setRF_off() {
PN5180DEBUG(F("Set RF OFF\n"));

uint8_t cmd[2] { PN5180_RF_OFF, 0x00 };
uint8_t cmd[] { PN5180_RF_OFF, 0x00 };

SPI.beginTransaction(PN5180_SPI_SETTINGS);
transceiveCommand(cmd, 2);
transceiveCommand(cmd, sizeof(cmd));
SPI.endTransaction();

while (0 == (TX_RFOFF_IRQ_STAT & getIRQStatus())); // wait for RF field to shut down
while (!(getIRQStatus() & TX_RFOFF_IRQ_STAT)); // wait for RF field to shut down
clearIRQStatus(TX_RFOFF_IRQ_STAT);
return true;
}
Expand Down Expand Up @@ -488,23 +488,23 @@ bool PN5180::transceiveCommand(uint8_t *sendBuffer, size_t sendBufferLen, uint8_
#endif

// 0.
while (LOW != digitalRead(PN5180_BUSY)); // wait until busy is low
while (digitalRead(PN5180_BUSY) != LOW); // wait until busy is low
// 1.
digitalWrite(PN5180_NSS, LOW); delay(2);
// 2.
for (uint8_t i=0; i<sendBufferLen; i++) {
SPI.transfer(sendBuffer[i]);
}
// 3.
while(HIGH != digitalRead(PN5180_BUSY)); // wait until BUSY is high
while(digitalRead(PN5180_BUSY) != HIGH); // wait until BUSY is high
// 4.
digitalWrite(PN5180_NSS, HIGH); delay(1);
// 5.
while (LOW != digitalRead(PN5180_BUSY)); // wait unitl BUSY is low
while (digitalRead(PN5180_BUSY) != LOW); // wait unitl BUSY is low

// check, if write-only
//
if ((0 == recvBuffer) || (0 == recvBufferLen)) return true;
if ((recvBuffer == NULL) || (recvBufferLen == 0)) return true;
PN5180DEBUG(F("Receiving SPI frame...\n"));

// 1.
Expand All @@ -514,11 +514,11 @@ bool PN5180::transceiveCommand(uint8_t *sendBuffer, size_t sendBufferLen, uint8_
recvBuffer[i] = SPI.transfer(0xff);
}
// 3.
while(HIGH != digitalRead(PN5180_BUSY)); // wait until BUSY is high
while(digitalRead(PN5180_BUSY) != HIGH); // wait until BUSY is high
// 4.
digitalWrite(PN5180_NSS, HIGH); delay(1);
// 5.
while(LOW != digitalRead(PN5180_BUSY)); // wait until BUSY is low
while(digitalRead(PN5180_BUSY) != LOW); // wait until BUSY is low

#ifdef DEBUG
PN5180DEBUG(F("Received: "));
Expand All @@ -541,7 +541,7 @@ void PN5180::reset() {
digitalWrite(PN5180_RST, HIGH); // 2ms to ramp up required
delay(10);

while (0 == (IDLE_IRQ_STAT & getIRQStatus())); // wait for system to start up
while (!(getIRQStatus() & IDLE_IRQ_STAT)); // wait for system to start up

clearIRQStatus(0xffffffff); // clear all flags
}
Expand Down
96 changes: 43 additions & 53 deletions PN5180FeliCa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,71 +51,61 @@ bool PN5180FeliCa::setupRF() {
* buffer[18..19] is POL_RES data
*
* return value: the uid length in bytes:
* - zero if no tag was recognized
* - 8 if a FeliCa tag was recognized
* - zero if no tag was recognized
* - 8 if a FeliCa tag was recognized
*/
uint8_t PN5180FeliCa::pol_req(uint8_t *buffer) {
uint8_t cmd[6];
uint8_t uidLength = 0;
// Load FeliCa 424 protocol
if (!loadRFConfig(0x09, 0x89))
return 0;
// OFF Crypto
if (!writeRegisterWithAndMask(SYSTEM_CONFIG, 0xFFFFFFBF))
return 0;

//send FeliCa request (every packet starts with length)
cmd[0] = 0x06; //total length
cmd[1] = 0x00; //POL_REQ command
cmd[2] = 0xFF; //
cmd[3] = 0xFF; // any target
cmd[4] = 0x01; // System Code request
cmd[5] = 0x00; // 1 timeslot only

if (!sendData(cmd, 6, 0x00))
return 0;
//wait a little to avoid bug with some cards
delay(50);

//response packet should be 0x14 (20 bytes total length), 0x01 Response Code, 8 IDm bytes, 8 PMm bytes, 2 Request Data bytes
//READ 20 bytes reply
uint8_t cmd[] = {
0x06, //total length
0x00, //POL_REQ command
0xFF, //
0xFF, // any target
0x01, // System Code request
0x00, // 1 timeslot only
};
// Load FeliCa 424 protocol
if (!loadRFConfig(0x09, 0x89))
return 0;
// OFF Crypto
if (!writeRegisterWithAndMask(SYSTEM_CONFIG, 0xFFFFFFBF))
return 0;

//send FeliCa request (every packet starts with length)
if (!sendData(cmd, sizeof(cmd)))
return 0;
//wait a little to avoid bug with some cards
delay(50);

//response packet should be 0x14 (20 bytes total length), 0x01 Response Code, 8 IDm bytes, 8 PMm bytes, 2 Request Data bytes
//READ 20 bytes reply
uint8_t *internalBuffer = readData(20);
if (!internalBuffer)
return 0;
for (int i=0; i<20; i++) {
if (!internalBuffer)
return 0;
for (int i=0; i<20; i++) {
buffer[i] = internalBuffer[i];
}

//check Response Code
if ( buffer[1] != 0x01 ){
uidLength = 0;
} else {
uidLength = 8;
}
return uidLength;
}

// Check response code and return corresponding UID length
return buffer[1] == 0x01 ? 8 : 0;
}

uint8_t PN5180FeliCa::readCardSerial(uint8_t *buffer) {
uint8_t response[20] = { 0 };
uint8_t uidLength;

uint8_t response[20];
uint8_t uidLength;

for (int i = 0; i < 20; i++)
response[i] = 0;

uidLength = pol_req(response);
uidLength = pol_req(response);

// no reply
if (uidLength == 0)
return 0;
// no reply
if (uidLength == 0)
return 0;

for (int i = 0; i < uidLength; i++)
buffer[i] = response[i+2];
for (int i=0; i<uidLength; i++)
buffer[i] = response[i+2];

return uidLength;
return uidLength;
}

bool PN5180FeliCa::isCardPresent() {
uint8_t buffer[8];
return (readCardSerial(buffer) != 0);
uint8_t buffer[8];
return (readCardSerial(buffer) != 0);
}
Loading