Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ PN532正在尝试从Felica标签获取设备的型号_C++_Arduino_Nfc_Nxp Microcontroller - Fatal编程技术网

C++ PN532正在尝试从Felica标签获取设备的型号

C++ PN532正在尝试从Felica标签获取设备的型号,c++,arduino,nfc,nxp-microcontroller,C++,Arduino,Nfc,Nxp Microcontroller,我只是一个从Felica标签获取设备号的Arduino Uno,但内存只会输出0xff。我也使用I2C而不是SPI,我不确定这是否重要 #include <Wire.h> #include <SPI.h> #include <Adafruit_PN532.h> // If using the breakout with SPI, define the pins for SPI communication. #define PN532_SCK (2) #de

我只是一个从Felica标签获取设备号的Arduino Uno,但内存只会输出0xff。我也使用I2C而不是SPI,我不确定这是否重要

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_PN532.h>

// If using the breakout with SPI, define the pins for SPI communication.
#define PN532_SCK  (2)
#define PN532_MOSI (3)
#define PN532_SS   (4)
#define PN532_MISO (5)

// If using the breakout or shield with I2C, define just the pins connected
// to the IRQ and reset lines.  Use the values below (2, 3) for the shield!
#define PN532_IRQ   (2)
#define PN532_RESET (3)  // Not connected by default on the NFC Shield

// Uncomment just _one_ line below depending on how your breakout or shield
// is connected to the Arduino:

// Use this line for a breakout with a SPI connection:
//Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);

// Use this line for a breakout with a hardware SPI connection.  Note that
// the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's
// hardware SPI SCK, MOSI, and MISO pins.  On an Arduino Uno these are
// SCK = 13, MOSI = 11, MISO = 12.  The SS line can be any digital IO pin.
//Adafruit_PN532 nfc(PN532_SS);

// Or use this line for a breakout or shield with an I2C connection:
Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);

#if defined(ARDUINO_ARCH_SAMD)
// for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
// also change #define in Adafruit_PN532.cpp library file
   #define Serial SerialUSB
#endif

uint8_t _prevIDm[8]; //IDm of the card previously detected
unsigned long  _prevTime;

void setup(void) {
  #ifndef ESP8266
    while (!Serial); // for Leonardo/Micro/Zero
  #endif
  Serial.begin(115200);
  Serial.println("Hello!");

  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }

  // Got ok data, print it out!
  Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
  Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
  Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);

  // 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.
  nfc.setPassiveActivationRetries(0xFF);

  // configure board to read RFID tags
  nfc.SAMConfig();

  Serial.println("Waiting for an FeliCa card");
}

void loop(void) {
  uint8_t ret;
  uint16_t systemCode = 0xFFFF;
  uint8_t requestCode = 0x01;       // System Code request
  uint8_t idm[8];
  uint8_t pmm[8];
  uint16_t systemCodeResponse;

  // Wait for an FeliCa type cards.
  // When one is found, some basic information such as IDm, PMm, and System Code are retrieved.
  Serial.print("Waiting for an FeliCa card...  ");
  ret = nfc.felica_Polling(systemCode, requestCode, idm, pmm, &systemCodeResponse, 5000);

  if (ret != 1)
  {
    Serial.println("Could not find a card");
    delay(500);
    return;
  }

  if ( memcmp(idm, _prevIDm, 8) == 0 ) {
    if ( (millis() - _prevTime) < 3000 ) {
      Serial.println("Same card");
      delay(500);
      return;
    }
  }

  Serial.println("Found a card!");
  Serial.print("  IDm: ");
  nfc.PrintHex(idm, 8);
  Serial.print("  PMm: ");
  nfc.PrintHex(pmm, 8);
  Serial.print("  System Code: ");
  nfc.PrintHex16(systemCodeResponse);
  Serial.print("\n");

  memcpy(_prevIDm, idm, 8);
  _prevTime = millis();


  Serial.print("Request Service command -> ");
  //Code to indicate System FFFFh
  uint16_t nodeCodeList[3] = {0x0000, 0x1000, 0xFFFF};
  uint16_t keyVersions[3];
  ret = nfc.felica_RequestService(3, nodeCodeList, keyVersions);

  if (ret != 1)
  {
    Serial.println("error");
  } else {
    Serial.println("OK!");
    for(int i=0; i<3; i++ ) {
      Serial.print("  Node Code: "); nfc.PrintHex16(nodeCodeList[i]);
      Serial.print(" -> Key Version: "); nfc.PrintHex16(keyVersions[i]);
      Serial.println("");
    }
  }

  Serial.print("Read Without Encryption command -> ");
  uint8_t blockData[3][16];
  uint16_t serviceCodeList[1] = {0x000B};
  uint16_t blockList[3] = {0x8000, 0x8001, 0x8002};
  ret = nfc.felica_ReadWithoutEncryption(1, serviceCodeList, 3, blockList, blockData);

  if (ret != 1)
  {
    Serial.println("error");
  } else {
    Serial.println("OK!");
    for(int i=0; i<3; i++ ) {
      Serial.print("  Block no. "); Serial.print(i, DEC); Serial.print(": ");
      nfc.PrintHex(blockData[i], 16);
    }
  }


  Serial.print("Request Response command -> ");
  uint8_t mode;
  ret = nfc.felica_RequestResponse(&mode);
  if (ret != 1)
  {
    Serial.println("error");
  } else {
    Serial.println("OK!");
    Serial.print("  mode: "); Serial.println(mode, DEC);
  }


  Serial.print("Request System Code command -> ");
  uint8_t numSystemCode;
  uint16_t systemCodeList[16];
  ret = nfc.felica_RequestSystemCode(&numSystemCode, systemCodeList);
  if (ret != 1)
  {
    Serial.println("error");
  } else {
    Serial.println("OK!");
    for(int i=0; i< numSystemCode; i++) {
      Serial.print("  System code: ");  nfc.PrintHex16(systemCodeList[i]); Serial.println("");
    }
  }

  // Wait 1 second before continuing
  Serial.println("Card access completed!\n");
  //delay(1000);
}
#包括
#包括
#包括
//如果与SPI一起使用分线,请定义SPI通信的引脚。
#定义PN532_SCK(2)
#定义PN532_MOSI(3)
#定义PN532_SS(4)
#定义PN532_味噌(5)
//如果使用带I2C的叉接线或屏蔽,请仅定义连接的引脚
//到IRQ和重置行。使用以下(2,3)值作为屏蔽!
#定义PN532_IRQ(2)
#定义PN532_重置(3)//在NFC屏蔽上默认未连接
//根据你的突破或防御方式,只需在下面一行取消注释
//已连接到Arduino:
//将此线路用于带有SPI连接的分接头:
//Adafruit_PN532 nfc(PN532_SCK、PN532_MISO、PN532_MOSI、PN532_SS);
//使用此线路进行带硬件SPI连接的分接。注意
//PN532 SCK、MOSI和MISO引脚需要连接到Arduino的
//硬件SPI-SCK、MOSI和MISO引脚。在Arduino Uno上,这些是
//SCK=13,MOSI=11,MISO=12。SS线可以是任何数字IO引脚。
//Adafruit_PN532 nfc(PN532_SS);
//或将此线路用于带I2C连接的分接或屏蔽:
Adafruit_PN532 nfc(PN532_IRQ,PN532_重置);
#如有定义(ARDUINO_ARCH_SAMD)
//对于零,在USB串行控制台上输出,如果使用编程端口编程零,请删除下面的行!
//同时更改Adafru PN532.cpp库文件中的#定义
#定义串行USB
#恩迪夫
uint8_t_prevIDm[8]//以前检测到的卡的IDm
未签名长时间;
作废设置(作废){
#ifndef ESP8266
while(!Serial);//用于Leonardo/Micro/Zero
#恩迪夫
序列号开始(115200);
Serial.println(“你好!”);
begin();
uint32_t versiondata=nfc.getFirmwareVersion();
如果(!versiondata){
Serial.print(“未找到PN53x板”);
while(1);//停止
}
//得到了正确的数据,打印出来!
Serial.print(“找到的芯片PN5”);Serial.println((versiondata>>24)和0xFF,十六进制);
Serial.print(“固件版本”);Serial.print((versiondata>>16)和0xFF,DEC);
Serial.print('.');Serial.println((versiondata>>8)和0xFF,DEC);
//设置从卡读取的最大重试次数
//这可以防止我们永远等待一张卡片,这是
//PN532的默认行为。
nfc.setPassiveActivationRetries(0xFF);
//配置电路板以读取RFID标签
SAMConfig();
Serial.println(“等待FeliCa卡”);
}
无效循环(无效){
uint8_t ret;
uint16\u t系统代码=0xFFFF;
uint8\u t requestCode=0x01;//系统代码请求
uint8_t idm[8];
uint8_t pmm[8];
uint16_t systemCodeResponse;
//等待FeliCa类型的卡片。
//找到一个后,将检索一些基本信息,如IDm、PMm和系统代码。
Serial.print(“等待FeliCa卡…”);
ret=nfc.felica_轮询(systemCode、requestCode、idm、pmm和systemCodeResponse,5000);
如果(ret!=1)
{
Serial.println(“找不到卡”);
延迟(500);
返回;
}
if(memcmp(idm,8)==0){
如果((毫秒()-_时间)<3000){
Serial.println(“同一张卡”);
延迟(500);
返回;
}
}
Serial.println(“找到一张卡片!”);
串行打印(“IDm:”);
nfc.PrintHex(idm,8);
序列号。打印(“PMm:”);
nfc.PrintHex(pmm,8);
串行打印(“系统代码:”);
nfc.PrintHex16(系统代码响应);
串行打印(“\n”);
memcpy(_prevIDm,idm,8);
_prevTime=millis();
串行打印(“请求服务命令->”;
//指示系统FFFFh的代码
uint16_t nodecolist[3]={0x0000,0x1000,0xFFFF};
uint16_t键版本[3];
ret=nfc.felica_请求服务(3,节点删除列表,关键版本);
如果(ret!=1)
{
Serial.println(“错误”);
}否则{
Serial.println(“OK!”);
对于(int i=0;i>8)&0xff;
pn532_packetbuffer[5]=系统代码&0xFF;
pn532_packetbuffer[6]=请求代码;
pn532_packetbuffer[7]=0;
如果(!sendCommandCheckAck(pn532_packetbuffer,8,超时)){
#ifdef PN532DEBUG
PN532DEBUGPRINT.println(F(“无法发送轮询命令”);
#恩迪夫
返回-1;
}
//等待卡响应
如果(!waitready(超时)){
返回-2;
}
读取数据(pn532_数据包缓冲区,9+20+2);
如果(!felica_checkResponse(PN532_RESPONSE_INLISTPASSIVETARGET)){
返回-2;
}
//检查NbTg(pn532_包装缓冲区[7])
如果(pn532_packetbuffer[7]==0){
//没有找到卡片
返回0;
}否则如果(pn532_packetbuffer[7]!=1){
#ifdef PN532DEBUG
PN532DEBUGPRINT.print(F(“未处理的目标数inlisted.NbTg=”);
PN532DEBUGPRINT.println(pn532_packetbuffer[7],十六进制);
#恩迪夫
返回-3;
}
_inListedTag=pn532_packetbuffer[8];
#ifdef PN532DEBUG
PN532DEBUGPRINT.print(F(“标签号”);
PN532DEBUGPRINT.println(_inListedTag);
#恩迪夫
//长度检查
uint8_t responseLength=pn532_packetbuffer[9];
if(响应长度!=18&&responseLength!=20){
#ifdef PN532DEBUG
PN532DEBUGPRINT.println(F(“错误响应长度”);
#恩迪夫
返回-4;
}
uint8_t i;
对于(i=0;i FELICA\u请求\u服务\u最大\u节点\u数量){
#ifdef PN532DEBUG
PN532DEBUGPRINT.println(F(“numNode太大”);
#恩迪夫
返回-1;
}
uint8_t i,j=0;
uint8_t cmdLen=1+8+1+2*个节点;
uint8_t cmd[cmdLen];
cmd[j++]=FELICA_cmd_REQUEST_SERVICE;
对于(i=0;i8)&0xff;
}
uint8_t responseBuf[10+2*个节点];
uint8_t响应长度;
if(!felica_SendCommand(cmd、cmdLen、responseBuf、8+11+2*numNode+2和responseLength)){
#ifdef PN532DEBUG
PN532DEBUGPRINT.println(F(“请求服务命令失败”);
#恩迪夫
返回-2;
}
//长度检查
if(响应长度!=10+2*numNode){
#ifdef PN532DEBUG
PN532DEBUGPRINT.println(F(“请求服务命令失败(响应长度错误)”);
#恩迪夫
返回-3;
}
对于(i=0;i FELICA\u READ\u MAX\u BLOCK\u NUM

/***** FeliCa Functions ******/
/**************************************************************************/
/*!
    @brief  Poll FeliCa card. PN532 acting as reader/initiator,
            peer acting as card/responder.
    @param[in]  systemCode             Designation of System Code. When sending FFFFh as System Code,
                                       all the FeliCa cards can return response.
    @param[in]  requestCode            Designation of Request Data as follows:
                                         00h: No Request
                                         01h: System Code request (to acquire System Code of the card)
                                         02h: Communication perfomance request
    @param[out] idm                    IDm of the card (8 bytes)
    @param[out] pmm                    PMm of the card (8 bytes)
    @param[out] systemCodeResponse     System Code of the card (2bytes)
    @return                            1: A FeliCa card has detected,  0: No card has detected,   -1: error

*/
/**************************************************************************/
int8_t Adafruit_PN532::felica_Polling(uint16_t systemCode, uint8_t requestCode,
        uint8_t *idm, uint8_t *pmm, uint16_t *systemCodeResponse, uint16_t timeout)
{
  pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
  pn532_packetbuffer[1] = 1;
  pn532_packetbuffer[2] = 1;
  pn532_packetbuffer[3] = FELICA_CMD_POLLING;
  pn532_packetbuffer[4] = (systemCode >> 8) & 0xff;
  pn532_packetbuffer[5] = systemCode & 0xFF;
  pn532_packetbuffer[6] = requestCode;
  pn532_packetbuffer[7] = 0;

  if (!sendCommandCheckAck(pn532_packetbuffer,8,timeout)) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("Could not send Polling command"));
    #endif
    return -1;
  }

  // Wait card response
  if (!waitready(timeout)) {
    return -2;
  }

  readdata(pn532_packetbuffer, 9+20+2);
  if ( !felica_checkResponse(PN532_RESPONSE_INLISTPASSIVETARGET) ) {
    return -2;
  }

  // Check NbTg (pn532_packetbuffer[7])
  if (pn532_packetbuffer[7] == 0) {
    // No card have found
    return 0;
  } else if (pn532_packetbuffer[7] != 1) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.print (F("Unhandled number of targets inlisted. NbTg = "));
      PN532DEBUGPRINT.println(pn532_packetbuffer[7], HEX);
    #endif
    return -3;
  }

  _inListedTag = pn532_packetbuffer[8];
  #ifdef PN532DEBUG
    PN532DEBUGPRINT.print(F("Tag number: "));
    PN532DEBUGPRINT.println(_inListedTag);
  #endif

  // length check
  uint8_t responseLength = pn532_packetbuffer[9];
  if (responseLength != 18 && responseLength != 20) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("Wrong response length"));
    #endif
    return -4;
  }

  uint8_t i;
  for (i=0; i<8; ++i) {
    idm[i] = pn532_packetbuffer[11+i];
    _felicaIDm[i] = pn532_packetbuffer[11+i];
    pmm[i] = pn532_packetbuffer[19+i];
    _felicaPMm[i] = pn532_packetbuffer[19+i];
  }

  if ( responseLength == 20 ) {
    *systemCodeResponse = (uint16_t)((pn532_packetbuffer[26] << 8) + pn532_packetbuffer[27]);
  }

  return 1;
}


/**************************************************************************/
/*!
    @brief  Sends an FeliCa command with the currently inlisted peer

    @param[in]  commandBuf      FeliCa command packet. (e.g. 00 FF FF 00 00  for Polling command)
    @param[in]  commandlength   Length of the FeliCa command packet. (e.g. 0x05 for above Polling command )
    @param[out] responseBuf     FeliCa response packet. (e.g. 01 NFCID2(8 bytes) PAD  for Polling response)
    @param[out] responselength  Length of the FeliCa response packet. (e.g. 0x12 for above Polling command )
*/
/**************************************************************************/
int8_t Adafruit_PN532::felica_SendCommand (const uint8_t *commandBuf, uint8_t commandlength,
  uint8_t *responseBuf, uint8_t expectedResLen, uint8_t *responseLength)
{
  if (commandlength > PN532_PACKBUFFSIZ-3) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("Command length too long for packet buffer"));
    #endif
    return -1;
  }

  pn532_packetbuffer[0] = 0x40; // PN532_COMMAND_INDATAEXCHANGE;
  pn532_packetbuffer[1] = _inListedTag;
  pn532_packetbuffer[2] = commandlength + 1;
  memcpy(&pn532_packetbuffer[3], commandBuf, commandlength);

  if (!sendCommandCheckAck(pn532_packetbuffer,commandlength+3,200)) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("Could not send Command"));
    #endif
    return -2;
  }

  // Wait card response ( longer than 102.4ms )
  if (!waitready(110)) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("Could not receive response"));
    #endif
    return -3;
  }

  readdata(pn532_packetbuffer,expectedResLen);
  if ( !felica_checkResponse(PN532_RESPONSE_INDATAEXCHANGE) ) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("Could not receive response"));
    #endif
    return -3;
  }

  // Check status (pn532_packetbuffer[7])
  if ((pn532_packetbuffer[7] & 0x3F)!=0) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.print(F("Status code indicates an error: "));
      PN532DEBUGPRINT.println(pn532_packetbuffer[7], HEX);
    #endif
    return -4;
  }

  // length check
  *responseLength = pn532_packetbuffer[8] - 1;
  if (pn532_packetbuffer[3] - 4 != *responseLength) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("Wrong response length"));
    #endif
    return -5;
  }

  memcpy(responseBuf, &pn532_packetbuffer[9], *responseLength);

  return 1;
}


/**************************************************************************/
/*!
    @brief  Sends FeliCa Request Service command

    @param[in]  numNode         Number of Node
    @param[in]  nodeCodeList    Node Code List (Big Endian)
    @param[out] keyVersions     Key Version of each Node (Big Endian)
*/
/**************************************************************************/
int8_t Adafruit_PN532::felica_RequestService(uint8_t numNode, uint16_t *nodeCodeList, uint16_t *keyVersions)
{
  if (numNode > FELICA_REQ_SERVICE_MAX_NODE_NUM) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("numNode is too large"));
    #endif
    return -1;
  }

  uint8_t i, j=0;
  uint8_t cmdLen = 1 + 8 + 1 + 2*numNode;
  uint8_t cmd[cmdLen];
  cmd[j++] = FELICA_CMD_REQUEST_SERVICE;
  for (i=0; i<8; ++i) {
    cmd[j++] = _felicaIDm[i];
  }
  cmd[j++] = numNode;
  for (i=0; i<numNode; ++i) {
    cmd[j++] = nodeCodeList[i] & 0xFF;
    cmd[j++] = (nodeCodeList[i] >> 8) & 0xff;
  }

  uint8_t responseBuf[10+2*numNode];
  uint8_t responseLength;

  if (!felica_SendCommand(cmd, cmdLen, responseBuf, 8 + 11 + 2*numNode + 2, &responseLength)) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("Request Service command failed"));
    #endif
    return -2;
  }

  // length check
  if ( responseLength != 10+2*numNode ) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("Request Service command failed (wrong response length)"));
    #endif
    return -3;
  }

  for(i=0; i<numNode; i++) {
    keyVersions[i] = (uint16_t)(responseBuf[10+i*2] + (responseBuf[10+i*2+1] << 8));
  }

  return 1;
}


/**************************************************************************/
/*!
    @brief  Sends FeliCa Request Service command

    @param[out]  mode         Current Mode of the card
*/
/**************************************************************************/
int8_t Adafruit_PN532::felica_RequestResponse(uint8_t *mode)
{
  uint8_t cmd[9];
  cmd[0] = FELICA_CMD_REQUEST_RESPONSE;
  memcpy(&cmd[1], _felicaIDm, 8);

  uint8_t responseBuf[10];
  uint8_t responseLength;
  if (!felica_SendCommand(cmd, 9, responseBuf, 8 + 11 + 2, &responseLength)) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("Request Response command failed"));
    #endif
    return -1;
  }

  // length check
  if ( responseLength != 10) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("Request Response command failed (wrong response length)"));
    #endif
    return -2;
  }

  *mode = responseBuf[9];

  return 1;
}

/**************************************************************************/
/*!
    @brief  Sends FeliCa Read Without Encryption command

    @param[in]  numService         Number of Service
    @param[in]  serviceCodeList    Service Code List (Big Endian)
    @param[in]  numBlock           Number of Block (This API only accepts 2-byte block list element)
    @param[in]  blockList          Block List
    @param[out] blockData          Block Data
*/
/**************************************************************************/
int8_t Adafruit_PN532::felica_ReadWithoutEncryption (uint8_t numService, const uint16_t *serviceCodeList,
  uint8_t numBlock, const uint16_t *blockList, uint8_t blockData[][16])
{
  if (numService > FELICA_READ_MAX_SERVICE_NUM) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("numService is too large"));
    #endif
    return -1;
  }
  if (numBlock > FELICA_READ_MAX_BLOCK_NUM) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("numBlock is too large"));
    #endif
    return -2;
  }

  uint8_t i, j=0;
  uint8_t cmdLen = 1 + 8 + 1 + 2*numService + 1 + 2*numBlock;
  uint8_t cmd[cmdLen];
  cmd[j++] = FELICA_CMD_READ_WITHOUT_ENCRYPTION;
  for (i=0; i<8; ++i) {
    cmd[j++] = _felicaIDm[i];
  }
  cmd[j++] = numService;
  for (i=0; i<numService; ++i) {
    cmd[j++] = serviceCodeList[i] & 0xFF;
    cmd[j++] = (serviceCodeList[i] >> 8) & 0xff;
  }
  cmd[j++] = numBlock;
  for (i=0; i<numBlock; ++i) {
    cmd[j++] = (blockList[i] >> 8) & 0xFF;
    cmd[j++] = blockList[i] & 0xff;
  }

  uint8_t responseBuf[12+16*numBlock];
  uint8_t responseLength;
  if (!felica_SendCommand(cmd, cmdLen, responseBuf, 8+13+16*numBlock + 2, &responseLength)) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("Read Without Encryption command failed"));
    #endif
    return -3;
  }

  // length check
  if ( responseLength != 12+16*numBlock ) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("Read Without Encryption command failed (wrong response length)"));
    #endif
    return -4;
  }

  // status flag check
  if ( responseBuf[9] != 0 || responseBuf[10] != 0 ) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.print(F("Read Without Encryption command failed (Status Flag: "));
      PrintHex8(pn532_packetbuffer[9]);
      PrintHex8(pn532_packetbuffer[10]);
      PN532DEBUGPRINT.println(F(")"));
    #endif
    return -5;
  }

  int k = 12;
  for(i=0; i<numBlock; i++ ) {
    for(j=0; j<16; j++ ) {
      blockData[i][j] = responseBuf[k++];
    }
  }

  return 1;
}


/**************************************************************************/
/*!
    @brief  Sends FeliCa Write Without Encryption command

    @param[in]  numService         Number of Service.
    @param[in]  serviceCodeList    Service Code List.
    @param[in]  numBlock           Number of Block. (This API only accepts 2-byte block list element)
    @param[in]  blockList          Block List.
    @param[out] blockData          Block Data.
    @return                          = 1: Success
                                     < 0: error
*/
/**************************************************************************/
int8_t Adafruit_PN532::felica_WriteWithoutEncryption (uint8_t numService, const uint16_t *serviceCodeList,
  uint8_t numBlock, const uint16_t *blockList, uint8_t blockData[][16])
{
  if (numService > FELICA_WRITE_MAX_SERVICE_NUM) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("numService is too large"));
    #endif
  }
  if (numBlock > FELICA_WRITE_MAX_BLOCK_NUM) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("numBlock is too large"));
    #endif
    return -2;
  }

  uint8_t i, j=0, k;
  uint8_t cmdLen = 1 + 8 + 1 + 2*numService + 1 + 2*numBlock + 16 * numBlock;
  uint8_t cmd[cmdLen];
  cmd[j++] = FELICA_CMD_WRITE_WITHOUT_ENCRYPTION;
  for (i=0; i<8; ++i) {
    cmd[j++] = _felicaIDm[i];
  }
  cmd[j++] = numService;
  for (i=0; i<numService; ++i) {
    cmd[j++] = serviceCodeList[i] & 0xFF;
    cmd[j++] = (serviceCodeList[i] >> 8) & 0xff;
  }
  cmd[j++] = numBlock;
  for (i=0; i<numBlock; ++i) {
    cmd[j++] = (blockList[i] >> 8) & 0xFF;
    cmd[j++] = blockList[i] & 0xff;
  }
  for (i=0; i<numBlock; ++i) {
    for(k=0; k<16; k++) {
      cmd[j++] = blockData[i][k];
    }
  }

  uint8_t response[11];
  uint8_t responseLength;
  if (felica_SendCommand(cmd, cmdLen, response, 8+12+2, &responseLength) != 1) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("Write Without Encryption command failed"));
    #endif
    return -3;
  }

  // length check
  if ( responseLength != 11 ) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("Write Without Encryption command failed (wrong response length)"));
    #endif
    return -4;
  }

  // status flag check
  if ( response[9] != 0 || response[10] != 0 ) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.print(F("Write Without Encryption command failed (Status Flag: "));
      PrintHex8(pn532_packetbuffer[9]);
      PrintHex8(pn532_packetbuffer[10]);
      PN532DEBUGPRINT.println(F(")"));
  #endif
    return -5;
  }

  return 1;
}



/**************************************************************************/
/*!
    @brief  Sends FeliCa Request System Code command

    @param[out] numSystemCode       Number of System Code (1 byte)
    @param[out] systemCodeList      System Code list
*/
/**************************************************************************/
int8_t Adafruit_PN532::felica_RequestSystemCode(uint8_t *numSystemCode, uint16_t *systemCodeList)
{
  uint8_t cmd[9];
  cmd[0] = FELICA_CMD_REQUEST_SYSTEM_CODE;
  memcpy(&cmd[1], _felicaIDm, 8);

  uint8_t responseBuf[10 + 2 * 16];
  uint8_t responseLength;
  if (!felica_SendCommand(cmd, 9, responseBuf, 8+11+32+2, &responseLength)) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("Request System Code command failed"));
    #endif
    return -1;
  }
  *numSystemCode = responseBuf[9];
  // length check
  if ( responseLength < 10 + 2 * *numSystemCode ) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("Request System Code command failed (wrong response length)"));
    #endif
    return -2;
  }

  uint8_t i;
  for(i=0; i<*numSystemCode; i++) {
    systemCodeList[i] = (uint16_t)((responseBuf[10+i*2]<< 8) + responseBuf[10+i*2+1]);
  }

  return 1;
}


/**************************************************************************/
/*!
    @brief  Release FeliCa card
*/
/**************************************************************************/
int8_t Adafruit_PN532::felica_Release()
{
  // InRelease
  pn532_packetbuffer[0] = PN532_COMMAND_INRELEASE;
  pn532_packetbuffer[1] = 0x00;   // All target
  #ifdef PN532DEBUG
    PN532DEBUGPRINT.println(F("Release all FeliCa target"));
  #endif

  if (! sendCommandCheckAck(pn532_packetbuffer, 2))
    return -1;  // no ACK

  readdata(pn532_packetbuffer,sizeof(pn532_packetbuffer));

  if ( !felica_checkResponse(PN532_RESPONSE_INRELEASE) ) {
    return -2;
  }

  if ((pn532_packetbuffer[7] & 0x3F)!=0) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.print(F("Status code indicates an error: "));
      PN532DEBUGPRINT.println(pn532_packetbuffer[7], HEX);
    #endif
    return -3;
  }

  /*
  // Power off RF
  pn532_packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION;
  pn532_packetbuffer[1] = 1;    // Config item 1 (RF field )
  pn532_packetbuffer[2] = 0x00; // AutoRFCA is off, RF is off
  #ifdef PN532DEBUG
    PN532DEBUGPRINT.println(F("Turning RF off"));
  #endif

  if (! sendCommandCheckAck(pn532_packetbuffer, 3))
    return false;  // no ACK

  // Wait more than 20 ms
  delay(20);

  // Power on RF
  pn532_packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION;
  pn532_packetbuffer[1] = 1;    // Config item 1 (RF field )
  pn532_packetbuffer[2] = 0x01; // AutoRFCA is off, RF is off
  #ifdef PN532DEBUG
    PN532DEBUGPRINT.println(F("Turning RF on"));
  #endif

  if (! sendCommandCheckAck(pn532_packetbuffer, 3))
    return false;  // no ACK

  */

  return 1;
}



bool Adafruit_PN532::felica_checkResponse(uint8_t PN532_command)
{
    if (pn532_packetbuffer[0] != 0 || pn532_packetbuffer[1] != 0 || pn532_packetbuffer[2] != 0xff) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("Preamble missing"));
    #endif
    return false;
  }

  uint8_t length = pn532_packetbuffer[3];
  if (pn532_packetbuffer[4]!=(uint8_t)(~length+1)) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println(F("Length check invalid"));
      PN532DEBUGPRINT.println(length,HEX);
      PN532DEBUGPRINT.println((~length)+1,HEX);
    #endif
    return false;
  }

  if (pn532_packetbuffer[5]!=PN532_PN532TOHOST || pn532_packetbuffer[6]!=PN532_command) {
    #ifdef PN532DEBUG
      PN532DEBUGPRINT.print(F("Wrong TFI in response: "));
      PN532DEBUGPRINT.println(pn532_packetbuffer[6],HEX);
    #endif
    return false;
  }

  return true;
}



/************** high level communication functions (handles both I2C and SPI) */


/**************************************************************************/
/*!
    @brief  Tries to read the SPI or I2C ACK signal
*/
/**************************************************************************/
bool Adafruit_PN532::readack() {
  uint8_t ackbuff[6];

  readdata(ackbuff, 6);

  return (0 == strncmp((char *)ackbuff, (char *)pn532ack, 6));
}


/**************************************************************************/
/*!
    @brief  Return true if the PN532 is ready with a response.
*/
/**************************************************************************/
bool Adafruit_PN532::isready() {
  if (_usingSPI) {
    // SPI read status and check if ready.
    #ifdef SPI_HAS_TRANSACTION
      if (_hardwareSPI) SPI.beginTransaction(PN532_SPI_SETTING);
    #endif
    digitalWrite(_ss, LOW);
    delay(2);
    spi_write(PN532_SPI_STATREAD);
    // read byte
    uint8_t x = spi_read();

    digitalWrite(_ss, HIGH);
    #ifdef SPI_HAS_TRANSACTION
      if (_hardwareSPI) SPI.endTransaction();
    #endif

    // Check if status is ready.
    return x == PN532_SPI_READY;
  }
  else {
    // I2C check if status is ready by IRQ line being pulled low.
    uint8_t x = digitalRead(_irq);
    return x == 0;
  }
}

/**************************************************************************/
/*!
    @brief  Waits until the PN532 is ready.

    @param  timeout   Timeout before giving up
*/
/**************************************************************************/
bool Adafruit_PN532::waitready(uint16_t timeout) {
  uint16_t timer = 0;
  while(!isready()) {
    if (timeout != 0) {
      timer += 10;
      if (timer > timeout) {
        PN532DEBUGPRINT.println("TIMEOUT!");
        return false;
      }
    }
    delay(10);
  }
  return true;
}

/**************************************************************************/
/*!
    @brief  Reads n bytes of data from the PN532 via SPI or I2C.

    @param  buff      Pointer to the buffer where data will be written
    @param  n         Number of bytes to be read
*/
/**************************************************************************/
void Adafruit_PN532::readdata(uint8_t* buff, uint8_t n) {
  if (_usingSPI) {
    // SPI write.
    #ifdef SPI_HAS_TRANSACTION
      if (_hardwareSPI) SPI.beginTransaction(PN532_SPI_SETTING);
    #endif
    digitalWrite(_ss, LOW);
    delay(2);
    spi_write(PN532_SPI_DATAREAD);

    #ifdef PN532DEBUG
      PN532DEBUGPRINT.print(F("Reading: "));
    #endif
    for (uint8_t i=0; i<n; i++) {
      delay(1);
      buff[i] = spi_read();
      #ifdef PN532DEBUG
        PN532DEBUGPRINT.print(F(" 0x"));
        PN532DEBUGPRINT.print(buff[i], HEX);
      #endif
    }

    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println();
    #endif

    digitalWrite(_ss, HIGH);
    #ifdef SPI_HAS_TRANSACTION
      if (_hardwareSPI) SPI.endTransaction();
    #endif
  }
  else {
    // I2C write.
    uint16_t timer = 0;

    delay(2);

    #ifdef PN532DEBUG
      PN532DEBUGPRINT.print(F("Reading: "));
    #endif
    // Start read (n+1 to take into account leading 0x01 with I2C)
    WIRE.requestFrom((uint8_t)PN532_I2C_ADDRESS, (uint8_t)(n+2));
    // Discard the leading 0x01
    i2c_recv();
    for (uint8_t i=0; i<n; i++) {
      delay(1);
      buff[i] = i2c_recv();
      #ifdef PN532DEBUG
        PN532DEBUGPRINT.print(F(" 0x"));
        PN532DEBUGPRINT.print(buff[i], HEX);
      #endif
    }
    // Discard trailing 0x00 0x00
    // i2c_recv();

    #ifdef PN532DEBUG
      PN532DEBUGPRINT.println();
    #endif
  }
}
}
Waiting for an FeliCa card... Found a card! IDm: 0x01 0x27 0x04 0x7E 0x49 0x5F 0x4E 0xB3 PMm: 0x00 0xF2 0x00 0x00 0x00 0x01 0x12 0x00 System Code: 0x0088 Request Service command -> error Read Without Encryption command -> OK! Block no. 0: 0x10 0x04 0x01 0x00 0x0D 0x00 0x00 0x00 0x00 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF Block no. 1: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF Block no. 2: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF Request Response command -> error Request System Code command -> OK! System code: 0x0B00 Card access completed!