int16_t PN532::tgGetData(uint8_t *buf, uint16_t len) { pn532_packetbuffer[0] = PN532_COMMAND_TGGETDATA; if (HAL(writeCommand)(pn532_packetbuffer, 1)) { DMSG("TgGetData: no ACK\n"); return -1; } int16_t status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), 3000); if (0 > status) { DMSG("TgGetData: failed to read response, error code - "); DMSG(status); DMSG('\n'); return status; } uint16_t length = status; if (length > len) { return -4; } if (pn532_packetbuffer[0] != 0) { DMSG("status is not ok\n"); return -5; } memcpy(buf, pn532_packetbuffer + 1, length - 1); return length - 1; }
boolean PN532::inListPassiveTarget() { pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET; pn532_packetbuffer[1] = 1; pn532_packetbuffer[2] = 0; DMSG("About to inList passive target"); if (HAL(writeCommand)(pn532_packetbuffer, 3)) { DMSG("Could not send inlist message\n"); return false; } int16_t status = HAL(readResponse)(pn532_packetbuffer,sizeof(pn532_packetbuffer), 30000); if (status < 0) { return false; } if (pn532_packetbuffer[0] != 1) { return false; } inListedTag = pn532_packetbuffer[1]; DMSG("Tag number: "); DMSG(inListedTag); DMSG('\n'); return true; }
/** * Peer to Peer */ int8_t PN532::tgInitAsTarget() { static const uint8_t command[] = { PN532_COMMAND_TGINITASTARGET, 0, 0x00, 0x00, //SENS_RES 0x00, 0x00, 0x00, //NFCID1 0x40, //SEL_RES 0x01, 0xFE, 0x0F, 0xBB, 0xBA, 0xA6, 0xC9, 0x89, // POL_RES 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x01, 0xFE, 0x0F, 0xBB, 0xBA, 0xA6, 0xC9, 0x89, 0x00, 0x00, //NFCID3t: Change this to desired value 0x06, 0x46, 0x66, 0x6D, 0x01, 0x01, 0x10, 0x00// LLCP magic number and version parameter }; int8_t status = HAL(writeCommand)(command, sizeof(command)); if (status < 0) { return status; } return HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), 0); }
uint8_t PN532::mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) { uint8_t i; // Hang on to the key and uid data memcpy (_key, keyData, 6); memcpy (_uid, uid, uidLen); _uidLen = uidLen; // Prepare the authentication command // pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; /* Data Exchange Header */ pn532_packetbuffer[1] = 1; /* Max card numbers */ pn532_packetbuffer[2] = (keyNumber) ? MIFARE_CMD_AUTH_B : MIFARE_CMD_AUTH_A; pn532_packetbuffer[3] = blockNumber; /* Block Number (1K = 0..63, 4K = 0..255 */ memcpy (pn532_packetbuffer + 4, _key, 6); for (i = 0; i < _uidLen; i++) { pn532_packetbuffer[10 + i] = _uid[i]; /* 4 bytes card ID */ } if (HAL(writeCommand)(pn532_packetbuffer, 10 + _uidLen)) return 0; // Read the response packet HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)); // Check if the response is valid and we are authenticated??? // for an auth success it should be bytes 5-7: 0xD5 0x41 0x00 // Mifare auth error is technically byte 7: 0x14 but anything other and 0x00 is not good if (pn532_packetbuffer[0] != 0x00) { DMSG("Authentification failed\n"); return 0; } return 1; }
uint8_t PN532::readGPIO(void) { pn532_packetbuffer[0] = PN532_COMMAND_READGPIO; // Send the READGPIO command (0x0C) if (HAL(writeCommand)(pn532_packetbuffer, 1)) return 0x0; HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)); /* READGPIO response without prefix and suffix should be in the following format: byte Description ------------- ------------------------------------------ b0 P3 GPIO Pins b1 P7 GPIO Pins (not used ... taken by I2C) b2 Interface Mode Pins (not used ... bus select pins) */ DMSG("P3 GPIO: "); DMSG_HEX(pn532_packetbuffer[7]); DMSG("P7 GPIO: "); DMSG_HEX(pn532_packetbuffer[8]); DMSG("I0I1 GPIO: "); DMSG_HEX(pn532_packetbuffer[9]); DMSG("\n"); return pn532_packetbuffer[0]; }
bool PN532::inDataExchange(uint8_t *send, uint8_t sendLength, uint8_t *response, uint8_t *responseLength) { uint8_t i; pn532_packetbuffer[0] = 0x40; // PN532_COMMAND_INDATAEXCHANGE; pn532_packetbuffer[1] = inListedTag; if (HAL(writeCommand)(pn532_packetbuffer, 2, send, sendLength)) { return false; } int16_t status = HAL(readResponse)(response, *responseLength, 1000); if (status < 0) { return false; } if ((response[0] & 0x3f) != 0) { DMSG("Status code indicates an error\n"); return false; } uint8_t length = status; length -= 1; if (length > *responseLength) { length = *responseLength; // silent truncation... } for (uint8_t i = 0; i < length; i++) { response[i] = response[i + 1]; } *responseLength = length; return true; }
uint8_t PN532::mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) { DMSG("Trying to read 16 bytes from block "); DMSG_INT(blockNumber); /* Prepare the command */ pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; pn532_packetbuffer[1] = 1; /* Card number */ pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */ pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */ /* Send the command */ if (HAL(writeCommand)(pn532_packetbuffer, 4)) { return 0; } /* Read the response packet */ HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)); /* If byte 8 isn't 0x00 we probably have an error */ if (pn532_packetbuffer[0] != 0x00) { return 0; } /* Copy the 16 data bytes to the output buffer */ /* Block content starts at byte 9 of a valid response */ memcpy (data, pn532_packetbuffer + 1, 16); return 1; }
int16_t PN532::tgGetData(uint8_t *buf, uint8_t len) { buf[0] = PN532_COMMAND_TGGETDATA; if (HAL(writeCommand)(buf, 1)) { return -1; } int16_t status = HAL(readResponse)(buf, len, 3000); if (0 >= status) { return status; } uint16_t length = status - 1; if (buf[0] != 0) { DMSG("status is not ok\n"); return -5; } for (uint8_t i = 0; i < length; i++) { buf[i] = buf[i + 1]; } return length; }
bool PN532::inListPassiveTarget() { pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET; pn532_packetbuffer[1] = 1; pn532_packetbuffer[2] = 0; DMSG("inList passive target\n"); if (HAL(writeCommand)(pn532_packetbuffer, 3)) { return false; } int16_t status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), 30000); if (status < 0) { return false; } if (pn532_packetbuffer[0] != 1) { return false; } inListedTag = pn532_packetbuffer[1]; return true; }
bool KeyDuino::inListPassiveTarget(uint8_t cardbaudrate, uint16_t timeout) { pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET; pn532_packetbuffer[1] = 1; pn532_packetbuffer[2] = cardbaudrate; DMSG_STR("\ninList passive target"); if(cardbaudrate == PN532_ISO14443B){ pn532_packetbuffer[3] = 0x00; if (HAL(writeCommand)(pn532_packetbuffer, 4)) return false; } else { if (HAL(writeCommand)(pn532_packetbuffer, 3)) return false; } int16_t status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), timeout); if (status < 0) { return false; } if (pn532_packetbuffer[0] != 1) { return false; } inListedTag = pn532_packetbuffer[1]; return true; }
bool PN532::tgSetData(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen) { if (hlen > (sizeof(pn532_packetbuffer) - 1)) { return false; } for (int8_t i = hlen - 1; i >= 0; i--){ pn532_packetbuffer[i + 1] = header[i]; } pn532_packetbuffer[0] = PN532_COMMAND_TGSETDATA; if (HAL(writeCommand)(pn532_packetbuffer, hlen + 1, body, blen)) { return false; } if (0 > HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), 3000)) { return false; } if (0 != pn532_packetbuffer[0]) { return false; } return true; }
uint32_t PN532::getFirmwareVersion(void) { uint32_t response; pn532_packetbuffer[0] = PN532_COMMAND_GETFIRMWAREVERSION; if (HAL(writeCommand)(pn532_packetbuffer, 1)) { return 0; } // read data packet int16_t status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)); if (0 > status) { return 0; } response = pn532_packetbuffer[0]; response <<= 8; response |= pn532_packetbuffer[1]; response <<= 8; response |= pn532_packetbuffer[2]; response <<= 8; response |= pn532_packetbuffer[3]; return response; }
bool KeyDuino::tgSetData(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen) { if (hlen > (sizeof(pn532_packetbuffer) - 1)) { if ((body != 0) || (header == pn532_packetbuffer)) { DMSG("tgSetData:buffer too small\n"); return false; } pn532_packetbuffer[0] = PN532_COMMAND_TGSETDATA; if (HAL(writeCommand)(pn532_packetbuffer, 1, header, hlen)) { return false; } } else { for (int8_t i = hlen - 1; i >= 0; i--){ pn532_packetbuffer[i + 1] = header[i]; } pn532_packetbuffer[0] = PN532_COMMAND_TGSETDATA; if (HAL(writeCommand)(pn532_packetbuffer, hlen + 1, body, blen)) { return false; } } if (0 > HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), 3000)) { return false; } if (0 != pn532_packetbuffer[0]) { return false; } return true; }
TdmManager::~TdmManager() { HAL().UnregisterEventsHandler(this); HAL().StopDevices(); // here - ? m_conference.reset(); m_streams.Clear(); }
void PN532::powerDown(uint8_t wakeUpEnable){ pn532_packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION; pn532_packetbuffer[1] = wakeUpEnable; if (HAL(writeCommand)(pn532_packetbuffer, 2)){ return; } HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)); }
void PN532::setParameters(uint8_t flags){ pn532_packetbuffer[0] = PN532_COMMAND_SETPARAMETERS; pn532_packetbuffer[1] = flags; if (HAL(writeCommand)(pn532_packetbuffer, 2)) { return; } HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)); }
boolean PN532::readPassiveTargetID(uint8_t cardbaudrate, uint8_t * uid, uint8_t * uidLength) { pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET; pn532_packetbuffer[1] = 1; // max 1 cards at once (we can set this to 2 later) pn532_packetbuffer[2] = cardbaudrate; if (HAL(writeCommand)(pn532_packetbuffer, 3)) { DMSG("No card(s) read"); return 0x0; // no cards read } // Wait for a card to enter the field uint8_t status = PN532_I2C_BUSY; // read data packet HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)); // check some basic stuff /* ISO14443A card response should be in the following format: byte Description ------------- ------------------------------------------ b0..6 Frame header and preamble b7 Tags Found b8 Tag Number (only one used in this example) b9..10 SENS_RES b11 SEL_RES b12 NFCID Length b13..NFCIDLen NFCID */ DMSG("Found "); DMSG(pn532_packetbuffer[0]); DMSG(" tags\n"); if (pn532_packetbuffer[0] != 1) return 0; uint16_t sens_res = pn532_packetbuffer[2]; sens_res <<= 8; sens_res |= pn532_packetbuffer[3]; DMSG("ATQA: 0x"); DMSG_HEX(sens_res); DMSG("SAK: 0x"); DMSG_HEX(pn532_packetbuffer[4]); /* Card appears to be Mifare Classic */ *uidLength = pn532_packetbuffer[5]; DMSG("UID:"); for (uint8_t i=0; i < pn532_packetbuffer[5]; i++) { uid[i] = pn532_packetbuffer[6+i]; DMSG(uid[i]); } DMSG('\n'); return 1; }
void PN532::rfConfiguration(uint8_t cfgItem, uint8_t* configurationData, uint8_t configurationDataLength){ pn532_packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION; pn532_packetbuffer[1] = cfgItem; memcpy (pn532_packetbuffer+2, configurationData, configurationDataLength); if (HAL(writeCommand)(pn532_packetbuffer, 2 + configurationDataLength)) { return; } HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)); }
int16_t PN532::inRelease(const uint8_t relevantTarget){ pn532_packetbuffer[0] = PN532_COMMAND_INRELEASE; pn532_packetbuffer[1] = relevantTarget; if (HAL(writeCommand)(pn532_packetbuffer, 2)) { return 0; } return HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)); }
boolean PN532::SAMConfig(void) { pn532_packetbuffer[0] = PN532_COMMAND_SAMCONFIGURATION; pn532_packetbuffer[1] = 0x01; // normal mode; pn532_packetbuffer[2] = 0x14; // timeout 50ms * 20 = 1 second pn532_packetbuffer[3] = 0x01; // use IRQ pin! if (HAL(writeCommand)(pn532_packetbuffer, 4)) return false; return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer))); }
bool KeyDuino::readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t timeout) { pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET; pn532_packetbuffer[1] = 1; // max 1 cards at once (we can set this to 2 later) pn532_packetbuffer[2] = cardbaudrate; if (HAL(writeCommand)(pn532_packetbuffer, 3)) { DMSG_STR("\nFailed writing"); return 0x0; // command failed } // read data packet if (HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), timeout) < 0) { DMSG_STR("\nFailed reading response"); return 0x0; } // check some basic stuff /* ISO14443A card response should be in the following format: byte Description ------------- ------------------------------------------ b0 Tags Found b1 Tag Number (only one used in this example) b2..3 SENS_RES b4 SEL_RES b5 NFCID Length b6..NFCIDLen NFCID */ if (pn532_packetbuffer[0] != 1) return 0; inListedTag = pn532_packetbuffer[1]; uint16_t sens_res = pn532_packetbuffer[2]; sens_res <<= 8; sens_res |= pn532_packetbuffer[3]; DMSG("\nATQA: 0x"); DMSG_HEX(sens_res); DMSG("\nSAK: 0x"); DMSG_HEX(pn532_packetbuffer[4]); DMSG("\n"); /* Card appears to be Mifare Classic */ *uidLength = pn532_packetbuffer[5]; this->_uidLen = pn532_packetbuffer[5]; for (uint8_t i = 0; i < pn532_packetbuffer[5]; i++) { uid[i] = pn532_packetbuffer[6 + i]; this->_uid[i] = pn532_packetbuffer[6 + i]; } return 1; }
bool PN532::setPassiveActivationRetries(uint8_t maxRetries) { pn532_packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION; pn532_packetbuffer[1] = 5; // Config item 5 (MaxRetries) pn532_packetbuffer[2] = 0xFF; // MxRtyATR (default = 0xFF) pn532_packetbuffer[3] = 0x01; // MxRtyPSL (default = 0x01) pn532_packetbuffer[4] = maxRetries; if (HAL(writeCommand)(pn532_packetbuffer, 5)) return 0x0; // no ACK return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer))); }
TdmManager::TdmManager( const TdmManagerProfile &profile ) : MsgObject(profile.Thread), m_profileVerify(profile), m_prof(profile), m_log(profile.LogCreator->CreateSession("TdmMng", true)), m_tagUserCmd(m_log->RegisterRecordKindStr("UserCmd")), m_tagError(m_log->RegisterRecordKindStr("Error")), m_buffCreator(profile.BidirBuffSize, profile.BidirBuffCount, profile.BidirBuffOffset), m_rtpInfra(profile.Thread, profile.RtpInfraPar, m_buffCreator), m_localIp(profile.LocalIp), m_eventQueue(iCmp::BfTdmEvent::SrcQueueTdm()) { HAL().RegisterEventsHandler(this); // conference m_conference.reset( new SndMix::ConferenceMng(*m_log, m_eventQueue, m_generalRtpParams, m_rtpInfra, *this) ); // log if(m_log->LogActive()) { *m_log << m_tagUserCmd << "TdmManager created. " << profile.getAsString() << EndRecord; } }
int8_t PN532::tgInitAsTarget(const uint8_t* command, const uint8_t len, const uint16_t timeout){ int8_t status = HAL(writeCommand)(command, len); if (status < 0) { return -1; } status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), timeout); if (status > 0) { return 1; } else if (PN532_TIMEOUT == status) { return 0; } else { return -2; } }
uint8_t KeyDuino::mifareultralight_WritePage (uint8_t page, uint8_t *buffer) { /* Prepare the first command */ pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; pn532_packetbuffer[1] = 1; /* Card number */ pn532_packetbuffer[2] = MIFARE_CMD_WRITE_ULTRALIGHT; /* Mifare UL Write cmd = 0xA2 */ pn532_packetbuffer[3] = page; /* page Number (0..63) */ memcpy (pn532_packetbuffer + 4, buffer, 4); /* Data Payload */ /* Send the command */ if (HAL(writeCommand)(pn532_packetbuffer, 8)) { return 0; } /* Read the response packet */ return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer))); }
uint8_t PN532::mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) { /* Prepare the first command */ pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; pn532_packetbuffer[1] = 1; /* Card number */ pn532_packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */ pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */ memcpy (pn532_packetbuffer + 4, data, 16); /* Data Payload */ /* Send the command */ if (HAL(writeCommand)(pn532_packetbuffer, 20)) { return 0; } /* Read the response packet */ return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer))); }
uint8_t PN532::mifareultralight_ReadPage (uint8_t page, uint8_t * buffer) { if (page >= 64) { DMSG("Page value out of range\n"); return 0; } DMSG("Reading page "); DMSG(page); DMSG('\n'); /* Prepare the command */ pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; pn532_packetbuffer[1] = 1; /* Card number */ pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */ pn532_packetbuffer[3] = page; /* Page Number (0..63 in most cases) */ /* Send the command */ if (HAL(writeCommand)(pn532_packetbuffer, 4)) { DMSG("Failed to receive ACK for write command\n"); return 0; } /* Read the response packet */ HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)); /* If byte 8 isn't 0x00 we probably have an error */ if (pn532_packetbuffer[0] == 0x00) { /* Copy the 4 data bytes to the output buffer */ /* Block content starts at byte 9 of a valid response */ /* Note that the command actually reads 16 byte or 4 */ /* pages at a time ... we simply discard the last 12 */ /* bytes */ memcpy (buffer, pn532_packetbuffer+1, 4); } else { return 0; } // Return OK signal return 1; }
boolean PN532::inDataExchange(uint8_t * send, uint8_t sendLength, uint8_t * response, uint8_t * responseLength) { if (sendLength > PN532_PACKBUFFSIZ -2) { #ifdef PN532DEBUG Serial.println("APDU length too long for packet buffer"); #endif return false; } uint8_t i; pn532_packetbuffer[0] = 0x40; // PN532_COMMAND_INDATAEXCHANGE; pn532_packetbuffer[1] = inListedTag; for (i=0; i<sendLength; ++i) { pn532_packetbuffer[i+2] = send[i]; } if (HAL(writeCommand)(pn532_packetbuffer,sendLength+2)) { DMSG("Could not send ADPU\n"); return false; } int16_t status = HAL(readResponse)(pn532_packetbuffer,sizeof(pn532_packetbuffer), 1000); if (status < 0) { return false; } uint8_t length = status; if ((pn532_packetbuffer[0] & 0x3f)!=0) { DMSG("Status code indicates an error\n"); return false; } length -= 1; if (length > *responseLength) { length = *responseLength; // silent truncation... } for (i=0; i<length; ++i) { response[i] = pn532_packetbuffer[1+i]; } *responseLength = length; return true; }
bool PN532::writeGPIO(uint8_t pinstate) { // Make sure pinstate does not try to toggle P32 or P34 pinstate |= (1 << PN532_GPIO_P32) | (1 << PN532_GPIO_P34); // Fill command buffer pn532_packetbuffer[0] = PN532_COMMAND_WRITEGPIO; pn532_packetbuffer[1] = PN532_GPIO_VALIDATIONBIT | pinstate; // P3 Pins pn532_packetbuffer[2] = 0x00; // P7 GPIO Pins (not used ... taken by I2C) DMSG("Writing P3 GPIO: "); DMSG_HEX(pn532_packetbuffer[1]); DMSG("\n"); // Send the WRITEGPIO command (0x0E) if (HAL(writeCommand)(pn532_packetbuffer, 3)) return 0; return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer))); }
uint8_t PN532::readGPIO(void) { pn532_packetbuffer[0] = PN532_COMMAND_READGPIO; // Send the READGPIO command (0x0C) if (HAL(writeCommand)(pn532_packetbuffer, 1)) return 0x0; HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)); /* READGPIO response without prefix and suffix should be in the following format: byte Description ------------- ------------------------------------------ b0 P3 GPIO Pins b1 P7 GPIO Pins (not used ... taken by I2C) b2 Interface Mode Pins (not used ... bus select pins) */ DMSG("P3 GPIO: "); DMSG_HEX(pn532_packetbuffer[7]); DMSG("P7 GPIO: "); DMSG_HEX(pn532_packetbuffer[8]); DMSG("I0I1 GPIO: "); DMSG_HEX(pn532_packetbuffer[9]); #ifdef DEBUG // Note: You can use the IO GPIO value to detect the serial bus being used switch(pn532_packetbuffer[3]) { case 0x00: // Using UART Serial.println("Using UART (IO = 0x00)"); break; case 0x01: // Using I2C Serial.println("Using I2C (IO = 0x01)"); break; case 0x02: // Using I2C Serial.println("Using I2C (IO = 0x02)"); break; } #endif return pn532_packetbuffer[0]; }