1
0
mirror of https://github.com/whowechina/aic_pico.git synced 2024-11-12 00:40:47 +01:00

Add FeliCa read to nfc interface

This commit is contained in:
whowechina 2024-04-23 20:47:50 +08:00
parent 8c74095e42
commit dd817f089e
4 changed files with 533 additions and 524 deletions

View File

@ -58,4 +58,6 @@ const char *nfc_module_name();
bool nfc_mifare_auth(const uint8_t uid[4], uint8_t block_id, uint8_t key_id, const uint8_t *key); bool nfc_mifare_auth(const uint8_t uid[4], uint8_t block_id, uint8_t key_id, const uint8_t *key);
bool nfc_mifare_read(uint8_t block_id, uint8_t block_data[16]); bool nfc_mifare_read(uint8_t block_id, uint8_t block_data[16]);
bool nfc_felica_read(uint16_t svc_code, uint16_t block_id, uint8_t block_data[16]);
#endif #endif

View File

@ -55,18 +55,21 @@ struct {
void (*rf_field)(bool on); void (*rf_field)(bool on);
bool (*mifare_auth)(const uint8_t uid[4], uint8_t block_id, uint8_t key_id, const uint8_t key[6]); bool (*mifare_auth)(const uint8_t uid[4], uint8_t block_id, uint8_t key_id, const uint8_t key[6]);
bool (*mifare_read)(uint8_t block_id, uint8_t block_data[16]); bool (*mifare_read)(uint8_t block_id, uint8_t block_data[16]);
bool (*felica_read)(uint16_t svc_code, uint16_t block_id, uint8_t block_data[16]);
void (*set_wait_loop)(nfc_wait_loop_t loop); void (*set_wait_loop)(nfc_wait_loop_t loop);
} api[3] = { } api[3] = {
{ {
pn532_poll_mifare, pn532_poll_felica, func_null, pn532_poll_mifare, pn532_poll_felica, func_null,
pn532_rf_field, pn532_rf_field,
pn532_mifare_auth, pn532_mifare_read, pn532_mifare_auth, pn532_mifare_read,
pn532_felica_read,
pn532_set_wait_loop pn532_set_wait_loop
}, },
{ {
pn5180_poll_mifare, pn5180_poll_felica, pn5180_poll_vicinity, pn5180_poll_mifare, pn5180_poll_felica, pn5180_poll_vicinity,
pn5180_rf_field, pn5180_rf_field,
pn5180_mifare_auth, pn5180_mifare_read, pn5180_mifare_auth, pn5180_mifare_read,
NULL,
pn5180_set_wait_loop pn5180_set_wait_loop
}, },
{ 0 }, { 0 },
@ -248,3 +251,11 @@ bool nfc_mifare_read(uint8_t block_id, uint8_t block_data[16])
} }
return api[nfc_module].mifare_read(block_id, block_data); return api[nfc_module].mifare_read(block_id, block_data);
} }
bool nfc_felica_read(uint16_t svc_code, uint16_t block_id, uint8_t block_data[16])
{
if (!api[nfc_module].felica_read) {
return false;
}
return api[nfc_module].felica_read(svc_code, block_id, block_data);
}

View File

@ -1,486 +1,482 @@
/* /*
* PN532 NFC Reader * PN532 NFC Reader
* WHowe <github.com/whowechina> * WHowe <github.com/whowechina>
* *
*/ */
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "hardware/gpio.h" #include "hardware/gpio.h"
#include "hardware/i2c.h" #include "hardware/i2c.h"
#include "pn532.h" #include "pn532.h"
#define IO_TIMEOUT_US 1000 #define IO_TIMEOUT_US 1000
#define PN532_I2C_ADDRESS 0x24 #define PN532_I2C_ADDRESS 0x24
#define PN532_PREAMBLE 0 #define PN532_PREAMBLE 0
#define PN532_STARTCODE1 0 #define PN532_STARTCODE1 0
#define PN532_STARTCODE2 0xff #define PN532_STARTCODE2 0xff
#define PN532_POSTAMBLE 0 #define PN532_POSTAMBLE 0
#define PN532_HOSTTOPN532 0xd4 #define PN532_HOSTTOPN532 0xd4
#define PN532_PN532TOHOST 0xd5 #define PN532_PN532TOHOST 0xd5
static i2c_inst_t *i2c_port = i2c0; static i2c_inst_t *i2c_port = i2c0;
bool pn532_init(i2c_inst_t *i2c) bool pn532_init(i2c_inst_t *i2c)
{ {
i2c_port = i2c; i2c_port = i2c;
uint32_t ver = pn532_firmware_ver(); uint32_t ver = pn532_firmware_ver();
return (ver > 0) && (ver < 0x7fffffff); return (ver > 0) && (ver < 0x7fffffff);
} }
static pn532_wait_loop_t wait_loop = NULL; static pn532_wait_loop_t wait_loop = NULL;
void pn532_set_wait_loop(pn532_wait_loop_t loop) void pn532_set_wait_loop(pn532_wait_loop_t loop)
{ {
wait_loop = loop; wait_loop = loop;
} }
static int pn532_write(const uint8_t *data, uint8_t len) static int pn532_write(const uint8_t *data, uint8_t len)
{ {
return i2c_write_blocking_until(i2c_port, PN532_I2C_ADDRESS, data, len, false, return i2c_write_blocking_until(i2c_port, PN532_I2C_ADDRESS, data, len, false,
time_us_64() + IO_TIMEOUT_US * len); time_us_64() + IO_TIMEOUT_US * len);
} }
static int pn532_read(uint8_t *data, uint8_t len) static int pn532_read(uint8_t *data, uint8_t len)
{ {
return i2c_read_blocking_until(i2c_port, PN532_I2C_ADDRESS, data, len, false, return i2c_read_blocking_until(i2c_port, PN532_I2C_ADDRESS, data, len, false,
time_us_64() + IO_TIMEOUT_US * len); time_us_64() + IO_TIMEOUT_US * len);
} }
static bool pn532_wait_ready() static bool pn532_wait_ready()
{ {
uint8_t status = 0; uint8_t status = 0;
for (int retry = 0; retry < 30; retry++) { for (int retry = 0; retry < 30; retry++) {
if (pn532_read(&status, 1) == 1 && status == 0x01) { if (pn532_read(&status, 1) == 1 && status == 0x01) {
return true; return true;
} }
if (wait_loop) { if (wait_loop) {
wait_loop(); wait_loop();
} }
sleep_us(1000); sleep_us(1000);
} }
return false; return false;
} }
static int read_frame(uint8_t *frame, uint8_t len) static int read_frame(uint8_t *frame, uint8_t len)
{ {
uint8_t buf[len + 1]; uint8_t buf[len + 1];
int ret = pn532_read(buf, len + 1); int ret = pn532_read(buf, len + 1);
#ifdef DEBUG #ifdef DEBUG
printf("I2C data read: %d -", ret); printf("I2C data read: %d -", ret);
for (int i = 0; i < len + 1; i++) { for (int i = 0; i < len + 1; i++) {
printf(" %02x", buf[i]); printf(" %02x", buf[i]);
} }
printf("\n"); printf("\n");
#endif #endif
if (ret == len + 1) { if (ret == len + 1) {
memcpy(frame, buf + 1, len); memcpy(frame, buf + 1, len);
return len; return len;
} }
return ret; return ret;
} }
static int write_frame(const uint8_t *frame, uint8_t len) static int write_frame(const uint8_t *frame, uint8_t len)
{ {
#ifdef DEBUG #ifdef DEBUG
printf("I2C frame write: %d -", len); printf("I2C frame write: %d -", len);
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
printf(" %02x", frame[i]); printf(" %02x", frame[i]);
} }
printf("\n"); printf("\n");
#endif #endif
return pn532_write(frame, len); return pn532_write(frame, len);
} }
static bool read_ack() static bool read_ack()
{ {
uint8_t resp[6]; uint8_t resp[6];
if (!pn532_wait_ready()) { if (!pn532_wait_ready()) {
return false; return false;
} }
read_frame(resp, 6); read_frame(resp, 6);
const uint8_t expect_ack[] = {0, 0, 0xff, 0, 0xff, 0}; const uint8_t expect_ack[] = {0, 0, 0xff, 0, 0xff, 0};
if (memcmp(resp, expect_ack, 6) != 0) { if (memcmp(resp, expect_ack, 6) != 0) {
return false; return false;
} }
return true; return true;
} }
int pn532_write_data(const uint8_t *data, uint8_t len) int pn532_write_data(const uint8_t *data, uint8_t len)
{ {
uint8_t frame[7 + len]; uint8_t frame[7 + len];
frame[0] = PN532_PREAMBLE; frame[0] = PN532_PREAMBLE;
frame[1] = PN532_STARTCODE1; frame[1] = PN532_STARTCODE1;
frame[2] = PN532_STARTCODE2; frame[2] = PN532_STARTCODE2;
uint8_t checksum = 0xff; uint8_t checksum = 0xff;
frame[3] = len; frame[3] = len;
frame[4] = (~len + 1); frame[4] = (~len + 1);
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
frame[5 + i] = data[i]; frame[5 + i] = data[i];
checksum += data[i]; checksum += data[i];
} }
frame[5 + len] = ~checksum; frame[5 + len] = ~checksum;
frame[6 + len] = PN532_POSTAMBLE; frame[6 + len] = PN532_POSTAMBLE;
write_frame(frame, 7 + len); write_frame(frame, 7 + len);
return read_ack(); return read_ack();
} }
int pn532_read_data(uint8_t *data, uint8_t len) int pn532_read_data(uint8_t *data, uint8_t len)
{ {
uint8_t resp[len + 7]; uint8_t resp[len + 7];
read_frame(resp, len + 7); read_frame(resp, len + 7);
if (resp[0] != PN532_PREAMBLE || if (resp[0] != PN532_PREAMBLE ||
resp[1] != PN532_STARTCODE1 || resp[1] != PN532_STARTCODE1 ||
resp[2] != PN532_STARTCODE2) { resp[2] != PN532_STARTCODE2) {
return -1; return -1;
} }
uint8_t length = resp[3]; uint8_t length = resp[3];
uint8_t length_check = length + resp[4]; uint8_t length_check = length + resp[4];
if (length > len || if (length > len ||
length_check != 0 || length_check != 0 ||
resp[length + 6] != PN532_POSTAMBLE) { resp[length + 6] != PN532_POSTAMBLE) {
return -1; return -1;
} }
uint8_t checksum = 0; uint8_t checksum = 0;
for (int i = 0; i <= length; i++) { for (int i = 0; i <= length; i++) {
data[i] = resp[5 + i]; data[i] = resp[5 + i];
checksum += resp[5 + i]; checksum += resp[5 + i];
} }
if (checksum != 0) { if (checksum != 0) {
return -1; return -1;
} }
return length; return length;
} }
int pn532_write_command(uint8_t cmd, const uint8_t *param, uint8_t len) int pn532_write_command(uint8_t cmd, const uint8_t *param, uint8_t len)
{ {
uint8_t data[len + 2]; uint8_t data[len + 2];
data[0] = PN532_HOSTTOPN532; data[0] = PN532_HOSTTOPN532;
data[1] = cmd; data[1] = cmd;
memcpy(data + 2, param, len); memcpy(data + 2, param, len);
return pn532_write_data(data, len + 2); return pn532_write_data(data, len + 2);
} }
static void write_nack() static void write_nack()
{ {
const uint8_t nack[] = {0, 0, 0xff, 0xff, 0, 0}; const uint8_t nack[] = {0, 0, 0xff, 0xff, 0, 0};
pn532_write(nack, 6); pn532_write(nack, 6);
} }
int pn532_peak_response_len() int pn532_peak_response_len()
{ {
uint8_t buf[6]; uint8_t buf[6];
if (!pn532_wait_ready()) { if (!pn532_wait_ready()) {
return -1; return -1;
} }
pn532_read(buf, 6); pn532_read(buf, 6);
if (buf[0] != 0x01 || if (buf[0] != 0x01 ||
buf[1] != PN532_PREAMBLE || buf[1] != PN532_PREAMBLE ||
buf[2] != PN532_STARTCODE1 || buf[2] != PN532_STARTCODE1 ||
buf[3] != PN532_STARTCODE2) { buf[3] != PN532_STARTCODE2) {
return -1; return -1;
} }
write_nack(); write_nack();
return buf[4]; return buf[4];
} }
int pn532_read_response(uint8_t cmd, uint8_t *resp, uint8_t len) int pn532_read_response(uint8_t cmd, uint8_t *resp, uint8_t len)
{ {
int real_len = pn532_peak_response_len(); int real_len = pn532_peak_response_len();
if (real_len < 0) { if (real_len < 0) {
return -1; return -1;
} }
if (!pn532_wait_ready()) { if (!pn532_wait_ready()) {
return -1; return -1;
} }
if (real_len < 2) { if (real_len < 2) {
return -1; return -1;
} }
uint8_t data[real_len]; uint8_t data[real_len];
int ret = pn532_read_data(data, real_len); int ret = pn532_read_data(data, real_len);
if (ret != real_len || if (ret != real_len ||
data[0] != PN532_PN532TOHOST || data[0] != PN532_PN532TOHOST ||
data[1] != cmd + 1) { data[1] != cmd + 1) {
return -1; return -1;
} }
int data_len = real_len - 2; int data_len = real_len - 2;
if (data_len > len) { if (data_len > len) {
return -1; return -1;
} }
if (data_len <= 0) { if (data_len <= 0) {
return -1; return -1;
} }
memcpy(resp, data + 2, data_len); memcpy(resp, data + 2, data_len);
return data_len; return data_len;
} }
uint32_t pn532_firmware_ver() uint32_t pn532_firmware_ver()
{ {
int ret = pn532_write_command(0x02, NULL, 0); int ret = pn532_write_command(0x02, NULL, 0);
if (ret < 0) { if (ret < 0) {
return 0; return 0;
} }
uint8_t ver[4]; uint8_t ver[4];
int result = pn532_read_response(0x02, ver, sizeof(ver)); int result = pn532_read_response(0x02, ver, sizeof(ver));
if (result < 4) { if (result < 4) {
return 0; return 0;
} }
uint32_t version = 0; uint32_t version = 0;
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
version <<= 8; version <<= 8;
version |= ver[i]; version |= ver[i];
} }
return version; return version;
} }
bool pn532_config_rf() bool pn532_config_rf()
{ {
uint8_t param[] = {0x05, 0xff, 0x01, 0x50}; uint8_t param[] = {0x05, 0xff, 0x01, 0x50};
pn532_write_command(0x32, param, sizeof(param)); pn532_write_command(0x32, param, sizeof(param));
return pn532_read_response(0x32, param, sizeof(param)) == 0; return pn532_read_response(0x32, param, sizeof(param)) == 0;
} }
bool pn532_config_sam() bool pn532_config_sam()
{ {
uint8_t param[] = {0x01, 0x14, 0x01}; uint8_t param[] = {0x01, 0x14, 0x01};
pn532_write_command(0x14, param, sizeof(param)); pn532_write_command(0x14, param, sizeof(param));
uint8_t resp; uint8_t resp;
return pn532_read_response(0x14, &resp, 1) == 0; return pn532_read_response(0x14, &resp, 1) == 0;
} }
static bool pn532_set_rf_field(bool auto_rf, bool on_off) static bool pn532_set_rf_field(bool auto_rf, bool on_off)
{ {
uint8_t param[] = { 1, (auto_rf ? 2 : 0) | (on_off ? 1 : 0) }; uint8_t param[] = { 1, (auto_rf ? 2 : 0) | (on_off ? 1 : 0) };
pn532_write_command(0x32, param, 2); pn532_write_command(0x32, param, 2);
uint8_t resp; uint8_t resp;
return pn532_read_response(0x32, &resp, 1) >= 0; return pn532_read_response(0x32, &resp, 1) >= 0;
} }
void pn532_rf_field(bool on) void pn532_rf_field(bool on)
{ {
pn532_set_rf_field(true, on); pn532_set_rf_field(true, on);
if (on) { if (on) {
pn532_config_sam(); pn532_config_sam();
} }
} }
static uint8_t readbuf[255]; static uint8_t readbuf[255];
bool pn532_poll_mifare(uint8_t uid[7], int *len) bool pn532_poll_mifare(uint8_t uid[7], int *len)
{ {
uint8_t param[] = {0x01, 0x00}; uint8_t param[] = {0x01, 0x00};
int ret = pn532_write_command(0x4a, param, sizeof(param)); int ret = pn532_write_command(0x4a, param, sizeof(param));
if (ret < 0) { if (ret < 0) {
return false; return false;
} }
int result = pn532_read_response(0x4a, readbuf, sizeof(readbuf)); int result = pn532_read_response(0x4a, readbuf, sizeof(readbuf));
if (result < 1 || readbuf[0] != 1) { if (result < 1 || readbuf[0] != 1) {
return false; return false;
} }
int idlen = readbuf[5]; int idlen = readbuf[5];
if ((idlen > 8) || (result != idlen + 6)) { if ((idlen > 8) || (result != idlen + 6)) {
return false; return false;
} }
memcpy(uid, readbuf + 6, idlen); memcpy(uid, readbuf + 6, idlen);
*len = idlen; *len = idlen;
return true; return true;
} }
static struct __attribute__((packed)) { static struct __attribute__((packed)) {
uint8_t idm[8]; uint8_t idm[8];
uint8_t pmm[8]; uint8_t pmm[8];
uint8_t syscode[2]; uint8_t syscode[2];
uint8_t inlist_tag; uint8_t inlist_tag;
} felica_poll_cache; } felica_poll_cache;
bool pn532_poll_felica(uint8_t uid[8], uint8_t pmm[8], uint8_t syscode[2], bool from_cache) bool pn532_poll_felica(uint8_t uid[8], uint8_t pmm[8], uint8_t syscode[2], bool from_cache)
{ {
if (from_cache) { if (from_cache) {
memcpy(uid, felica_poll_cache.idm, 8); memcpy(uid, felica_poll_cache.idm, 8);
memcpy(pmm, felica_poll_cache.pmm, 8); memcpy(pmm, felica_poll_cache.pmm, 8);
memcpy(syscode, felica_poll_cache.syscode, 2); memcpy(syscode, felica_poll_cache.syscode, 2);
return true; return true;
} }
uint8_t param[] = { 1, 1, 0, 0xff, 0xff, 1, 0}; uint8_t param[] = { 1, 1, 0, 0xff, 0xff, 1, 0};
int ret = pn532_write_command(0x4a, param, sizeof(param)); int ret = pn532_write_command(0x4a, param, sizeof(param));
if (ret < 0) { if (ret < 0) {
printf("%d\n", __LINE__); printf("%d\n", __LINE__);
return false; return false;
} }
int result = pn532_read_response(0x4a, readbuf, sizeof(readbuf)); int result = pn532_read_response(0x4a, readbuf, sizeof(readbuf));
if ((result != 22) || (readbuf[0] != 1) || (readbuf[2] != 20)) { if ((result != 22) || (readbuf[0] != 1) || (readbuf[2] != 20)) {
return false; return false;
} }
memcpy(&felica_poll_cache, readbuf + 4, 18); memcpy(&felica_poll_cache, readbuf + 4, 18);
felica_poll_cache.inlist_tag = readbuf[1]; felica_poll_cache.inlist_tag = readbuf[1];
memcpy(uid, readbuf + 4, 8); memcpy(uid, readbuf + 4, 8);
memcpy(pmm, readbuf + 12, 8); memcpy(pmm, readbuf + 12, 8);
memcpy(syscode, readbuf + 20, 2); memcpy(syscode, readbuf + 20, 2);
return true; return true;
} }
bool pn532_mifare_auth(const uint8_t uid[4], uint8_t block_id, uint8_t key_id, const uint8_t key[6]) bool pn532_mifare_auth(const uint8_t uid[4], uint8_t block_id, uint8_t key_id, const uint8_t key[6])
{ {
uint8_t param[] = { uint8_t param[] = {
1, key_id ? 0x61 : 0x60, block_id, 1, key_id ? 0x61 : 0x60, block_id,
key[0], key[1], key[2], key[3], key[4], key[5], key[0], key[1], key[2], key[3], key[4], key[5],
uid[0], uid[1], uid[2], uid[3] uid[0], uid[1], uid[2], uid[3]
}; };
int ret = pn532_write_command(0x40, param, sizeof(param)); int ret = pn532_write_command(0x40, param, sizeof(param));
if (ret < 0) { if (ret < 0) {
printf("\nPN532 failed mifare auth command"); printf("\nPN532 failed mifare auth command");
return false; return false;
} }
int result = pn532_read_response(0x40, readbuf, sizeof(readbuf)); int result = pn532_read_response(0x40, readbuf, sizeof(readbuf));
if (readbuf[0] != 0) { if (readbuf[0] != 0) {
printf("\nPN532 Mifare AUTH failed %d %02x", result, readbuf[0]); printf("\nPN532 Mifare AUTH failed %d %02x", result, readbuf[0]);
return false; return false;
} }
return true; return true;
} }
bool pn532_mifare_read(uint8_t block_id, uint8_t block_data[16]) bool pn532_mifare_read(uint8_t block_id, uint8_t block_data[16])
{ {
uint8_t param[] = { 1, 0x30, block_id }; uint8_t param[] = { 1, 0x30, block_id };
int ret = pn532_write_command(0x40, param, sizeof(param)); int ret = pn532_write_command(0x40, param, sizeof(param));
if (ret < 0) { if (ret < 0) {
printf("\nPN532 failed mifare read command"); printf("\nPN532 failed mifare read command");
return false; return false;
} }
int result = pn532_read_response(0x40, readbuf, sizeof(readbuf)); int result = pn532_read_response(0x40, readbuf, sizeof(readbuf));
if (readbuf[0] != 0 || result != 17) { if (readbuf[0] != 0 || result != 17) {
printf("\nPN532 Mifare READ failed %d %02x", result, readbuf[0]); printf("\nPN532 Mifare READ failed %d %02x", result, readbuf[0]);
return false; return false;
} }
memmove(block_data, readbuf + 1, 16); memmove(block_data, readbuf + 1, 16);
return true; return true;
} }
int pn532_felica_command(uint8_t cmd, const uint8_t *param, uint8_t param_len, uint8_t *outbuf) int pn532_felica_command(uint8_t cmd, const uint8_t *param, uint8_t param_len, uint8_t *outbuf)
{ {
int cmd_len = param_len + 11; int cmd_len = param_len + 11;
uint8_t cmd_buf[cmd_len + 1]; uint8_t cmd_buf[cmd_len + 1];
cmd_buf[0] = felica_poll_cache.inlist_tag; cmd_buf[0] = felica_poll_cache.inlist_tag;
cmd_buf[1] = cmd_len; cmd_buf[1] = cmd_len;
cmd_buf[2] = cmd; cmd_buf[2] = cmd;
memcpy(cmd_buf + 3, felica_poll_cache.idm, 8); memcpy(cmd_buf + 3, felica_poll_cache.idm, 8);
memcpy(cmd_buf + 11, param, param_len); memcpy(cmd_buf + 11, param, param_len);
int ret = pn532_write_command(0x40, cmd_buf, sizeof(cmd_buf)); int ret = pn532_write_command(0x40, cmd_buf, sizeof(cmd_buf));
if (ret < 0) { if (ret < 0) {
printf("\nFailed send felica command"); printf("\nFailed send felica command");
return -1; return -1;
} }
int result = pn532_read_response(0x40, readbuf, sizeof(readbuf)); int result = pn532_read_response(0x40, readbuf, sizeof(readbuf));
int outlen = readbuf[1] - 1; int outlen = readbuf[1] - 1;
if ((readbuf[0] & 0x3f) != 0 || result - 2 != outlen) { if ((readbuf[0] & 0x3f) != 0 || result - 2 != outlen) {
return -1; return -1;
} }
memmove(outbuf, readbuf + 2, outlen); memmove(outbuf, readbuf + 2, outlen);
return outlen; return outlen;
} }
bool pn532_felica_read_wo_encrypt(uint16_t svc_code, uint16_t block_id, uint8_t block_data[16]) bool pn532_felica_read(uint16_t svc_code, uint16_t block_id, uint8_t block_data[16])
{ {
uint8_t param[] = { 1, svc_code & 0xff, svc_code >> 8, uint8_t param[] = { 1, svc_code & 0xff, svc_code >> 8,
1, block_id >> 8, block_id & 0xff }; 1, block_id >> 8, block_id & 0xff };
int result = pn532_felica_command(0x06, param, sizeof(param), readbuf); int result = pn532_felica_command(0x06, param, sizeof(param), readbuf);
if (result != 12 + 16 || readbuf[9] != 0 || readbuf[10] != 0) { if (result != 12 + 16 || readbuf[9] != 0 || readbuf[10] != 0) {
//printf("\nPN532 Felica READ read failed %d %02x %02x", printf("\nPN532 Felica read failed [%04x:%04x]", svc_code, block_id);
// result, readbuf[9], readbuf[10]); memset(block_data, 0, 16);
for (int i = 0; i < result; i++) { return true; // we fake the result when it fails
printf(" %02x", readbuf[i]); }
}
memset(block_data, 0, 16); const uint8_t *result_data = readbuf + 12;
return true; // we fake the result when it fails memcpy(block_data, result_data, 16);
}
return true;
const uint8_t *result_data = readbuf + 12; }
memcpy(block_data, result_data, 16);
bool pn532_felica_write(uint16_t svc_code, uint16_t block_id, const uint8_t block_data[16])
return true; {
} uint8_t param[22] = { 1, svc_code & 0xff, svc_code >> 8,
1, block_id >> 8, block_id & 0xff };
bool pn532_felica_write_wo_encrypt(uint16_t svc_code, uint16_t block_id, const uint8_t block_data[16]) memcpy(param + 6, block_data, 16);
{ int result = pn532_felica_command(0x08, param, sizeof(param), readbuf);
uint8_t param[22] = { 1, svc_code & 0xff, svc_code >> 8,
1, block_id >> 8, block_id & 0xff }; if (result < 0) {
memcpy(param + 6, block_data, 16); printf("\nPN532 Felica WRITE failed %d", result);
int result = pn532_felica_command(0x08, param, sizeof(param), readbuf); return false;
}
if (result < 0) {
printf("\nPN532 Felica WRITE failed %d", result); printf("\nPN532 Felica WRITE success ");
return false; for (int i = 0; i < result; i++) {
} printf(" %02x", readbuf[i]);
}
printf("\nPN532 Felica WRITE success "); return false;
for (int i = 0; i < result; i++) { }
printf(" %02x", readbuf[i]);
}
return false;
}

View File

@ -1,38 +1,38 @@
/* /*
* PN532 NFC Reader * PN532 NFC Reader
* WHowe <github.com/whowechina> * WHowe <github.com/whowechina>
* *
*/ */
#ifndef PN532_H #ifndef PN532_H
#define PN532_H #define PN532_H
#include <stdint.h> #include <stdint.h>
#include "hardware/i2c.h" #include "hardware/i2c.h"
typedef void (*pn532_wait_loop_t)(); typedef void (*pn532_wait_loop_t)();
void pn532_set_wait_loop(pn532_wait_loop_t loop); void pn532_set_wait_loop(pn532_wait_loop_t loop);
bool pn532_init(i2c_inst_t *i2c); bool pn532_init(i2c_inst_t *i2c);
int pn532_write_command(uint8_t cmd, const uint8_t *param, uint8_t len); int pn532_write_command(uint8_t cmd, const uint8_t *param, uint8_t len);
int pn532_read_response(uint8_t cmd, uint8_t *resp, uint8_t len); int pn532_read_response(uint8_t cmd, uint8_t *resp, uint8_t len);
uint32_t pn532_firmware_ver(); uint32_t pn532_firmware_ver();
bool pn532_config_sam(); bool pn532_config_sam();
bool pn532_config_rf(); bool pn532_config_rf();
void pn532_rf_field(bool on); void pn532_rf_field(bool on);
bool pn532_poll_mifare(uint8_t uid[7], int *len); bool pn532_poll_mifare(uint8_t uid[7], int *len);
bool pn532_poll_felica(uint8_t uid[8], uint8_t pmm[8], uint8_t syscode[2], bool from_cache); bool pn532_poll_felica(uint8_t uid[8], uint8_t pmm[8], uint8_t syscode[2], bool from_cache);
bool pn532_mifare_auth(const uint8_t uid[4], uint8_t block_id, uint8_t key_id, const uint8_t key[6]); bool pn532_mifare_auth(const uint8_t uid[4], uint8_t block_id, uint8_t key_id, const uint8_t key[6]);
bool pn532_mifare_read(uint8_t block_id, uint8_t block_data[16]); bool pn532_mifare_read(uint8_t block_id, uint8_t block_data[16]);
bool pn532_felica_read_wo_encrypt(uint16_t svc_code, uint16_t block_id, uint8_t block_data[16]); bool pn532_felica_read(uint16_t svc_code, uint16_t block_id, uint8_t block_data[16]);
bool pn532_felica_write_wo_encrypt(uint16_t svc_code, uint16_t block_id, const uint8_t block_data[16]); bool pn532_felica_write(uint16_t svc_code, uint16_t block_id, const uint8_t block_data[16]);
#endif #endif