Merge branch 'main' of https://github.com/hykilpikonna/OpenHardware
This commit is contained in:
@@ -0,0 +1,29 @@
|
|||||||
|
diff PN532/PN532_SPI/PN532_SPI.cpp lib/PN532_SPI/PN532_SPI.cpp
|
||||||
|
10c10
|
||||||
|
< PN532_SPI::PN532_SPI(SPIClass &spi, uint8_t ss)
|
||||||
|
---
|
||||||
|
> PN532_SPI::PN532_SPI(SPIClass &spi, uint8_t sck, uint8_t miso, uint8_t mosi, uint8_t ss)
|
||||||
|
14c14,17
|
||||||
|
< _ss = ss;
|
||||||
|
---
|
||||||
|
> _sck = sck;
|
||||||
|
> _miso = miso;
|
||||||
|
> _mosi = mosi;
|
||||||
|
> _ss = ss;
|
||||||
|
21c24
|
||||||
|
< _spi->begin();
|
||||||
|
---
|
||||||
|
> _spi->begin(_sck, _miso, _mosi, _ss);
|
||||||
|
diff PN532/PN532_SPI/PN532_SPI.h lib/PN532_SPI/PN532_SPI.h
|
||||||
|
10c10
|
||||||
|
< PN532_SPI(SPIClass &spi, uint8_t ss);
|
||||||
|
---
|
||||||
|
> PN532_SPI(SPIClass &spi, uint8_t sck, uint8_t miso, uint8_t mosi, uint8_t ss);
|
||||||
|
19a20,22
|
||||||
|
> uint8_t _sck;
|
||||||
|
> uint8_t _miso;
|
||||||
|
> uint8_t _mosi;
|
||||||
|
23c26
|
||||||
|
< boolean isReady();
|
||||||
|
---
|
||||||
|
> bool isReady();
|
||||||
@@ -0,0 +1,213 @@
|
|||||||
|
|
||||||
|
#include "PN532_SPI.h"
|
||||||
|
#include "PN532_debug.h"
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
#define STATUS_READ 2
|
||||||
|
#define DATA_WRITE 1
|
||||||
|
#define DATA_READ 3
|
||||||
|
|
||||||
|
PN532_SPI::PN532_SPI(SPIClass &spi, uint8_t sck, uint8_t miso, uint8_t mosi, uint8_t ss)
|
||||||
|
{
|
||||||
|
command = 0;
|
||||||
|
_spi = &spi;
|
||||||
|
_sck = sck;
|
||||||
|
_miso = miso;
|
||||||
|
_mosi = mosi;
|
||||||
|
_ss = ss;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PN532_SPI::begin()
|
||||||
|
{
|
||||||
|
pinMode(_ss, OUTPUT);
|
||||||
|
|
||||||
|
_spi->begin(_sck, _miso, _mosi, _ss);
|
||||||
|
_spi->setDataMode(SPI_MODE0); // PN532 only supports mode0
|
||||||
|
_spi->setBitOrder(LSBFIRST);
|
||||||
|
#ifndef __SAM3X8E__
|
||||||
|
_spi->setClockDivider(SPI_CLOCK_DIV8); // set clock 2MHz(max: 5MHz)
|
||||||
|
#else
|
||||||
|
/** DUE spi library does not support SPI_CLOCK_DIV8 macro */
|
||||||
|
_spi->setClockDivider(42); // set clock 2MHz(max: 5MHz)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PN532_SPI::wakeup()
|
||||||
|
{
|
||||||
|
digitalWrite(_ss, LOW);
|
||||||
|
delay(2);
|
||||||
|
digitalWrite(_ss, HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int8_t PN532_SPI::writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen)
|
||||||
|
{
|
||||||
|
command = header[0];
|
||||||
|
writeFrame(header, hlen, body, blen);
|
||||||
|
|
||||||
|
uint8_t timeout = PN532_ACK_WAIT_TIME;
|
||||||
|
while (!isReady()) {
|
||||||
|
delay(1);
|
||||||
|
timeout--;
|
||||||
|
if (0 == timeout) {
|
||||||
|
DMSG("Time out when waiting for ACK\n");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (readAckFrame()) {
|
||||||
|
DMSG("Invalid ACK\n");
|
||||||
|
return PN532_INVALID_ACK;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t PN532_SPI::readResponse(uint8_t buf[], uint8_t len, uint16_t timeout)
|
||||||
|
{
|
||||||
|
uint16_t time = 0;
|
||||||
|
while (!isReady()) {
|
||||||
|
delay(1);
|
||||||
|
time++;
|
||||||
|
if (timeout > 0 && time > timeout) {
|
||||||
|
return PN532_TIMEOUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
digitalWrite(_ss, LOW);
|
||||||
|
delay(1);
|
||||||
|
|
||||||
|
int16_t result;
|
||||||
|
do {
|
||||||
|
write(DATA_READ);
|
||||||
|
|
||||||
|
if (0x00 != read() || // PREAMBLE
|
||||||
|
0x00 != read() || // STARTCODE1
|
||||||
|
0xFF != read() // STARTCODE2
|
||||||
|
) {
|
||||||
|
|
||||||
|
result = PN532_INVALID_FRAME;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t length = read();
|
||||||
|
if (0 != (uint8_t)(length + read())) { // checksum of length
|
||||||
|
result = PN532_INVALID_FRAME;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t cmd = command + 1; // response command
|
||||||
|
if (PN532_PN532TOHOST != read() || (cmd) != read()) {
|
||||||
|
result = PN532_INVALID_FRAME;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DMSG("read: ");
|
||||||
|
DMSG_HEX(cmd);
|
||||||
|
|
||||||
|
length -= 2;
|
||||||
|
if (length > len) {
|
||||||
|
for (uint8_t i = 0; i < length; i++) {
|
||||||
|
DMSG_HEX(read()); // dump message
|
||||||
|
}
|
||||||
|
DMSG("\nNot enough space\n");
|
||||||
|
read();
|
||||||
|
read();
|
||||||
|
result = PN532_NO_SPACE; // not enough space
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t sum = PN532_PN532TOHOST + cmd;
|
||||||
|
for (uint8_t i = 0; i < length; i++) {
|
||||||
|
buf[i] = read();
|
||||||
|
sum += buf[i];
|
||||||
|
|
||||||
|
DMSG_HEX(buf[i]);
|
||||||
|
}
|
||||||
|
DMSG('\n');
|
||||||
|
|
||||||
|
uint8_t checksum = read();
|
||||||
|
if (0 != (uint8_t)(sum + checksum)) {
|
||||||
|
DMSG("checksum is not ok\n");
|
||||||
|
result = PN532_INVALID_FRAME;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
read(); // POSTAMBLE
|
||||||
|
|
||||||
|
result = length;
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
digitalWrite(_ss, HIGH);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean PN532_SPI::isReady()
|
||||||
|
{
|
||||||
|
digitalWrite(_ss, LOW);
|
||||||
|
|
||||||
|
write(STATUS_READ);
|
||||||
|
uint8_t status = read() & 1;
|
||||||
|
digitalWrite(_ss, HIGH);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PN532_SPI::writeFrame(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen)
|
||||||
|
{
|
||||||
|
digitalWrite(_ss, LOW);
|
||||||
|
delay(2); // wake up PN532
|
||||||
|
|
||||||
|
write(DATA_WRITE);
|
||||||
|
write(PN532_PREAMBLE);
|
||||||
|
write(PN532_STARTCODE1);
|
||||||
|
write(PN532_STARTCODE2);
|
||||||
|
|
||||||
|
uint8_t length = hlen + blen + 1; // length of data field: TFI + DATA
|
||||||
|
write(length);
|
||||||
|
write(~length + 1); // checksum of length
|
||||||
|
|
||||||
|
write(PN532_HOSTTOPN532);
|
||||||
|
uint8_t sum = PN532_HOSTTOPN532; // sum of TFI + DATA
|
||||||
|
|
||||||
|
DMSG("write: ");
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < hlen; i++) {
|
||||||
|
write(header[i]);
|
||||||
|
sum += header[i];
|
||||||
|
|
||||||
|
DMSG_HEX(header[i]);
|
||||||
|
}
|
||||||
|
for (uint8_t i = 0; i < blen; i++) {
|
||||||
|
write(body[i]);
|
||||||
|
sum += body[i];
|
||||||
|
|
||||||
|
DMSG_HEX(body[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t checksum = ~sum + 1; // checksum of TFI + DATA
|
||||||
|
write(checksum);
|
||||||
|
write(PN532_POSTAMBLE);
|
||||||
|
|
||||||
|
digitalWrite(_ss, HIGH);
|
||||||
|
|
||||||
|
DMSG('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t PN532_SPI::readAckFrame()
|
||||||
|
{
|
||||||
|
const uint8_t PN532_ACK[] = {0, 0, 0xFF, 0, 0xFF, 0};
|
||||||
|
|
||||||
|
uint8_t ackBuf[sizeof(PN532_ACK)];
|
||||||
|
|
||||||
|
digitalWrite(_ss, LOW);
|
||||||
|
delay(1);
|
||||||
|
write(DATA_READ);
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < sizeof(PN532_ACK); i++) {
|
||||||
|
ackBuf[i] = read();
|
||||||
|
}
|
||||||
|
|
||||||
|
digitalWrite(_ss, HIGH);
|
||||||
|
|
||||||
|
return memcmp(ackBuf, PN532_ACK, sizeof(PN532_ACK));
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
#ifndef __PN532_SPI_H__
|
||||||
|
#define __PN532_SPI_H__
|
||||||
|
|
||||||
|
#include <SPI.h>
|
||||||
|
#include "PN532Interface.h"
|
||||||
|
|
||||||
|
class PN532_SPI : public PN532Interface {
|
||||||
|
public:
|
||||||
|
PN532_SPI(SPIClass &spi, uint8_t sck, uint8_t miso, uint8_t mosi, uint8_t ss);
|
||||||
|
|
||||||
|
void begin();
|
||||||
|
void wakeup();
|
||||||
|
int8_t writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body = 0, uint8_t blen = 0);
|
||||||
|
|
||||||
|
int16_t readResponse(uint8_t buf[], uint8_t len, uint16_t timeout);
|
||||||
|
|
||||||
|
private:
|
||||||
|
SPIClass* _spi;
|
||||||
|
uint8_t _sck;
|
||||||
|
uint8_t _miso;
|
||||||
|
uint8_t _mosi;
|
||||||
|
uint8_t _ss;
|
||||||
|
uint8_t command;
|
||||||
|
|
||||||
|
bool isReady();
|
||||||
|
void writeFrame(const uint8_t *header, uint8_t hlen, const uint8_t *body = 0, uint8_t blen = 0);
|
||||||
|
int8_t readAckFrame();
|
||||||
|
|
||||||
|
inline void write(uint8_t data) {
|
||||||
|
_spi->transfer(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
inline uint8_t read() {
|
||||||
|
return _spi->transfer(0);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
+18
-5
@@ -2,17 +2,28 @@
|
|||||||
|
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
#include <PN532_I2C.h>
|
#include <PN532_I2C.h>
|
||||||
|
#include <PN532_SPI.h>
|
||||||
#include <PN532.h>
|
#include <PN532.h>
|
||||||
#include <FastLED.h>
|
#include <FastLED.h>
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
|
#define PN532_MODE_I2C 1
|
||||||
|
#define PN532_MODE_SPI 2
|
||||||
|
#define PN532_MODE PN532_MODE_I2C
|
||||||
|
|
||||||
constexpr u8 NUM_LEDS = 7;
|
constexpr u8 NUM_LEDS = 7;
|
||||||
constexpr u8 BR_DIM = 8;
|
constexpr u8 BR_DIM = 8;
|
||||||
constexpr u8 BR_BRIGHT = 14;
|
constexpr u8 BR_BRIGHT = 14;
|
||||||
CRGB leds[NUM_LEDS];
|
CRGB leds[NUM_LEDS];
|
||||||
|
|
||||||
PN532_I2C pn532i2c(Wire);
|
#if PN532_MODE == PN532_MODE_SPI
|
||||||
PN532 nfc(pn532i2c);
|
PN532_SPI pn532(SPI, GPIO_NUM_36, GPIO_NUM_37, GPIO_NUM_35, GPIO_NUM_34);
|
||||||
|
#elif PN532_MODE == PN532_MODE_I2C
|
||||||
|
PN532_I2C pn532(Wire);
|
||||||
|
#else
|
||||||
|
#error Invalid PN532 mode
|
||||||
|
#endif
|
||||||
|
PN532 nfc(pn532);
|
||||||
|
|
||||||
constexpr u8 UID_LENGTH = 8;
|
constexpr u8 UID_LENGTH = 8;
|
||||||
u8 prevIDm[UID_LENGTH];
|
u8 prevIDm[UID_LENGTH];
|
||||||
@@ -27,8 +38,10 @@ void setup()
|
|||||||
USBSerial.begin(115200);
|
USBSerial.begin(115200);
|
||||||
USBSerial.println("Hello!");
|
USBSerial.println("Hello!");
|
||||||
|
|
||||||
|
#if PN532_MODE == PN532_MODE_I2C
|
||||||
// Initialize I2C communication
|
// Initialize I2C communication
|
||||||
Wire.setPins(GPIO_NUM_4, GPIO_NUM_5);
|
Wire.setPins(GPIO_NUM_4, GPIO_NUM_5);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Initialize the LED
|
// Initialize the LED
|
||||||
CFastLED::addLeds<NEOPIXEL, GPIO_NUM_6>(leds, NUM_LEDS);
|
CFastLED::addLeds<NEOPIXEL, GPIO_NUM_6>(leds, NUM_LEDS);
|
||||||
@@ -53,7 +66,7 @@ void setup()
|
|||||||
|
|
||||||
// Set the max number of retry attempts to read from a card
|
// Set the max number of retry attempts to read from a card
|
||||||
// This prevents us from waiting forever for a card, which is the default behaviour of the PN532.
|
// This prevents us from waiting forever for a card, which is the default behaviour of the PN532.
|
||||||
nfc.setPassiveActivationRetries(0xFF);
|
nfc.setPassiveActivationRetries(1);
|
||||||
nfc.SAMConfig();
|
nfc.SAMConfig();
|
||||||
|
|
||||||
// Clear the IDm buffer
|
// Clear the IDm buffer
|
||||||
@@ -111,13 +124,13 @@ void loop()
|
|||||||
// When one is found, some basic information such as IDm, PMm, and System Code are retrieved.
|
// When one is found, some basic information such as IDm, PMm, and System Code are retrieved.
|
||||||
leds[0] = CRGB::BlueViolet;
|
leds[0] = CRGB::BlueViolet;
|
||||||
FastLED.show();
|
FastLED.show();
|
||||||
if (nfc.felica_Polling(0xFFFF, 0x00, idm, pmm, &systemCode, 5) == 1)
|
if (nfc.felica_Polling(0xFFFF, 0x00, idm, pmm, &systemCode) == 1)
|
||||||
foundCard(idm, UID_LENGTH, "FeliCa");
|
foundCard(idm, UID_LENGTH, "FeliCa");
|
||||||
|
|
||||||
// Wait for an ISO14443A type cards (MIFARE, etc.). When one is found
|
// Wait for an ISO14443A type cards (MIFARE, etc.). When one is found
|
||||||
u8 uidLength;
|
u8 uidLength;
|
||||||
leds[0] = CRGB::OrangeRed;
|
leds[0] = CRGB::OrangeRed;
|
||||||
FastLED.show();
|
FastLED.show();
|
||||||
if (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, idm, &uidLength, 5) == 1)
|
if (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, idm, &uidLength) == 1)
|
||||||
foundCard(idm, uidLength, "ISO14443A");
|
foundCard(idm, uidLength, "ISO14443A");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user