123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498 |
- #include <stdio.h>
- #include "pn532.h"
- const uint8_t PN532_ACK[] = {0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00};
- const uint8_t PN532_FRAME_START[] = {0x00, 0x00, 0xFF};
- #define PN532_FRAME_MAX_LENGTH 255
- #define PN532_DEFAULT_TIMEOUT 1000
- int PN532_WriteFrame(PN532* pn532, uint8_t* data, uint16_t length) {
- if (length > PN532_FRAME_MAX_LENGTH || length < 1) {
- return PN532_STATUS_ERROR;
- }
-
-
-
-
-
-
-
-
- uint8_t frame[PN532_FRAME_MAX_LENGTH + 7];
- uint8_t checksum = 0;
- frame[0] = PN532_PREAMBLE;
- frame[1] = PN532_STARTCODE1;
- frame[2] = PN532_STARTCODE2;
- for (uint8_t i = 0; i < 3; i++) {
- checksum += frame[i];
- }
- frame[3] = length & 0xFF;
- frame[4] = (~length + 1) & 0xFF;
- for (uint8_t i = 0; i < length; i++) {
- frame[5 + i] = data[i];
- checksum += data[i];
- }
- frame[length + 5] = ~checksum & 0xFF;
- frame[length + 6] = PN532_POSTAMBLE;
- if (pn532->write_data(frame, length + 7) != PN532_STATUS_OK) {
- return PN532_STATUS_ERROR;
- }
- return PN532_STATUS_OK;
- }
- int PN532_ReadFrame(PN532* pn532, uint8_t* response, uint16_t length) {
- uint8_t buff[PN532_FRAME_MAX_LENGTH + 7];
- uint8_t checksum = 0;
-
- pn532->read_data(buff, length + 7);
-
- uint8_t offset = 0;
- while (buff[offset] == 0x00) {
- offset += 1;
- if (offset >= length + 8){
- pn532->log("Response frame preamble does not contain 0x00FF!");
- return PN532_STATUS_ERROR;
- }
- }
- if (buff[offset] != 0xFF) {
- pn532->log("Response frame preamble does not contain 0x00FF!");
- return PN532_STATUS_ERROR;
- }
- offset += 1;
- if (offset >= length + 8) {
- pn532->log("Response contains no data!");
- return PN532_STATUS_ERROR;
- }
-
- uint8_t frame_len = buff[offset];
- if (((frame_len + buff[offset+1]) & 0xFF) != 0) {
- pn532->log("Response length checksum did not match length!");
- return PN532_STATUS_ERROR;
- }
-
- for (uint8_t i = 0; i < frame_len + 1; i++) {
- checksum += buff[offset + 2 + i];
- }
- checksum &= 0xFF;
- if (checksum != 0) {
- pn532->log("Response checksum did not match expected checksum");
- return PN532_STATUS_ERROR;
- }
-
- for (uint8_t i = 0; i < frame_len; i++) {
- response[i] = buff[offset + 2 + i];
- }
- return frame_len;
- }
- int PN532_CallFunction(
- PN532* pn532,
- uint8_t command,
- uint8_t* response,
- uint16_t response_length,
- uint8_t* params,
- uint16_t params_length,
- uint32_t timeout
- ) {
-
- uint8_t buff[PN532_FRAME_MAX_LENGTH];
- buff[0] = PN532_HOSTTOPN532;
- buff[1] = command & 0xFF;
- for (uint8_t i = 0; i < params_length; i++) {
- buff[2 + i] = params[i];
- }
-
- if (PN532_WriteFrame(pn532, buff, params_length + 2) != PN532_STATUS_OK) {
- pn532->wakeup();
- pn532->log("Trying to wakeup");
- return PN532_STATUS_ERROR;
- }
- if (!pn532->wait_ready(timeout)) {
- return PN532_STATUS_ERROR;
- }
-
- pn532->read_data(buff, sizeof(PN532_ACK));
- for (uint8_t i = 0; i < sizeof(PN532_ACK); i++) {
- if (PN532_ACK[i] != buff[i]) {
- pn532->log("Did not receive expected ACK from PN532!");
- return PN532_STATUS_ERROR;
- }
- }
- if (!pn532->wait_ready(timeout)) {
- return PN532_STATUS_ERROR;
- }
-
- int frame_len = PN532_ReadFrame(pn532, buff, response_length + 2);
-
- if (! ((buff[0] == PN532_PN532TOHOST) && (buff[1] == (command+1)))) {
- pn532->log("Received unexpected command response!");
- return PN532_STATUS_ERROR;
- }
-
- for (uint8_t i = 0; i < response_length; i++) {
- response[i] = buff[i + 2];
- }
-
- return frame_len - 2;
- }
- int PN532_GetFirmwareVersion(PN532* pn532, uint8_t* version) {
-
- if (PN532_CallFunction(pn532, PN532_COMMAND_GETFIRMWAREVERSION,
- version, 4, NULL, 0, 500) == PN532_STATUS_ERROR) {
- pn532->log("Failed to detect the PN532");
- return PN532_STATUS_ERROR;
- }
- return PN532_STATUS_OK;
- }
- int PN532_SamConfiguration(PN532* pn532) {
-
-
-
-
-
-
- uint8_t params[] = {0x01, 0x14, 0x01};
- PN532_CallFunction(pn532, PN532_COMMAND_SAMCONFIGURATION,
- NULL, 0, params, sizeof(params), PN532_DEFAULT_TIMEOUT);
- return PN532_STATUS_OK;
- }
- int PN532_ReadPassiveTarget(
- PN532* pn532,
- uint8_t* response,
- uint8_t card_baud,
- uint32_t timeout
- ) {
-
- uint8_t params[] = {0x01, card_baud};
- uint8_t buff[19];
- int length = PN532_CallFunction(pn532, PN532_COMMAND_INLISTPASSIVETARGET,
- buff, sizeof(buff), params, sizeof(params), timeout);
- if (length < 0) {
- return PN532_STATUS_ERROR;
- }
-
- if (buff[0] != 0x01) {
- pn532->log("More than one card detected!");
- return PN532_STATUS_ERROR;
- }
- if (buff[5] > 7) {
- pn532->log("Found card with unexpectedly long UID!");
- return PN532_STATUS_ERROR;
- }
- for (uint8_t i = 0; i < buff[5]; i++) {
- response[i] = buff[6 + i];
- }
- return buff[5];
- }
- int PN532_MifareClassicAuthenticateBlock(
- PN532* pn532,
- uint8_t* uid,
- uint8_t uid_length,
- uint16_t block_number,
- uint16_t key_number,
- uint8_t* key
- ) {
-
- uint8_t response[1] = {0xFF};
- uint8_t params[3 + MIFARE_UID_MAX_LENGTH + MIFARE_KEY_LENGTH];
- params[0] = 0x01;
- params[1] = key_number & 0xFF;
- params[2] = block_number & 0xFF;
-
- for (uint8_t i = 0; i < MIFARE_KEY_LENGTH; i++) {
- params[3 + i] = key[i];
- }
-
- for (uint8_t i = 0; i < uid_length; i++) {
- params[3 + MIFARE_KEY_LENGTH + i] = uid[i];
- }
-
- PN532_CallFunction(pn532, PN532_COMMAND_INDATAEXCHANGE, response, sizeof(response),
- params, 3 + MIFARE_KEY_LENGTH + uid_length, PN532_DEFAULT_TIMEOUT);
- return response[0];
- }
- int PN532_MifareClassicReadBlock(PN532* pn532, uint8_t* response, uint16_t block_number) {
- uint8_t params[] = {0x01, MIFARE_CMD_READ, block_number & 0xFF};
- uint8_t buff[MIFARE_BLOCK_LENGTH + 1];
-
- PN532_CallFunction(pn532, PN532_COMMAND_INDATAEXCHANGE, buff, sizeof(buff),
- params, sizeof(params), PN532_DEFAULT_TIMEOUT);
-
- if (buff[0] != PN532_ERROR_NONE) {
- return buff[0];
- }
- for (uint8_t i = 0; i < MIFARE_BLOCK_LENGTH; i++) {
- response[i] = buff[i + 1];
- }
- return buff[0];
- }
- int PN532_MifareClassicWriteBlock(PN532* pn532, uint8_t* data, uint16_t block_number) {
- uint8_t params[MIFARE_BLOCK_LENGTH + 3];
- uint8_t response[1];
- params[0] = 0x01;
- params[1] = MIFARE_CMD_WRITE;
- params[2] = block_number & 0xFF;
- for (uint8_t i = 0; i < MIFARE_BLOCK_LENGTH; i++) {
- params[3 + i] = data[i];
- }
- PN532_CallFunction(pn532, PN532_COMMAND_INDATAEXCHANGE, response,
- sizeof(response), params, sizeof(params), PN532_DEFAULT_TIMEOUT);
- return response[0];
- }
- int PN532_Ntag2xxReadBlock(PN532* pn532, uint8_t* response, uint16_t block_number) {
- uint8_t params[] = {0x01, MIFARE_CMD_READ, block_number & 0xFF};
-
- uint8_t buff[MIFARE_BLOCK_LENGTH + 1];
-
- PN532_CallFunction(pn532, PN532_COMMAND_INDATAEXCHANGE, buff, sizeof(buff),
- params, sizeof(params), PN532_DEFAULT_TIMEOUT);
-
- if (buff[0] != PN532_ERROR_NONE) {
- return buff[0];
- }
-
-
- for (uint8_t i = 0; i < NTAG2XX_BLOCK_LENGTH; i++) {
- response[i] = buff[i + 1];
- }
- return buff[0];
- }
- int PN532_Ntag2xxWriteBlock(PN532* pn532, uint8_t* data, uint16_t block_number) {
- uint8_t params[NTAG2XX_BLOCK_LENGTH + 3];
- uint8_t response[1];
- params[0] = 0x01;
- params[1] = MIFARE_ULTRALIGHT_CMD_WRITE;
- params[2] = block_number & 0xFF;
- for (uint8_t i = 0; i < NTAG2XX_BLOCK_LENGTH; i++) {
- params[3 + i] = data[i];
- }
- PN532_CallFunction(pn532, PN532_COMMAND_INDATAEXCHANGE, response,
- sizeof(response), params, sizeof(params), PN532_DEFAULT_TIMEOUT);
- return response[0];
- }
- int PN532_ReadGpio(PN532* pn532, uint8_t* pins_state) {
- return PN532_CallFunction(pn532, PN532_COMMAND_READGPIO, pins_state, 3,
- NULL, 0, PN532_DEFAULT_TIMEOUT);
- }
- bool PN532_ReadGpioP(PN532* pn532, uint8_t pin_number) {
- uint8_t pins_state[3];
- PN532_CallFunction(pn532, PN532_COMMAND_READGPIO, pins_state,
- sizeof(pins_state), NULL, 0, PN532_DEFAULT_TIMEOUT);
- if ((pin_number >= 30) && (pin_number <= 37)) {
- return (pins_state[0] >> (pin_number - 30)) & 1 ? true : false;
- }
- if ((pin_number >= 70) && (pin_number <= 77)) {
- return (pins_state[1] >> (pin_number - 70)) & 1 ? true : false;
- }
- return false;
- }
- bool PN532_ReadGpioI(PN532* pn532, uint8_t pin_number) {
- uint8_t pins_state[3];
- PN532_CallFunction(pn532, PN532_COMMAND_READGPIO, pins_state,
- sizeof(pins_state), NULL, 0, PN532_DEFAULT_TIMEOUT);
- if (pin_number <= 7) {
- return (pins_state[2] >> pin_number) & 1 ? true : false;
- }
- return false;
- }
- int PN532_WriteGpio(PN532* pn532, uint8_t* pins_state) {
- uint8_t params[2];
-
- params[0] = 0x80 | pins_state[0];
- params[1] = 0x80 | pins_state[1];
- return PN532_CallFunction(pn532, PN532_COMMAND_WRITEGPIO, NULL, 0,
- params, sizeof(params), PN532_DEFAULT_TIMEOUT);
- }
- int PN532_WriteGpioP(PN532* pn532, uint8_t pin_number, bool pin_state) {
- uint8_t pins_state[2];
- uint8_t params[2];
- if (PN532_ReadGpio(pn532, pins_state) == PN532_STATUS_ERROR) {
- return PN532_STATUS_ERROR;
- }
- if ((pin_number >= 30) && (pin_number <= 37)) {
- if (pin_state) {
- params[0] = 0x80 | pins_state[0] | 1 << (pin_number - 30);
- } else {
- params[0] = (0x80 | pins_state[0]) & ~(1 << (pin_number - 30));
- }
- params[1] = 0x00;
- }
- if ((pin_number >= 70) && (pin_number <= 77)) {
- if (pin_state) {
- params[1] = 0x80 | pins_state[1] | 1 << (pin_number - 70);
- } else {
- params[1] = (0x80 | pins_state[1]) & ~(1 << (pin_number - 70));
- }
- params[0] = 0x00;
- }
- return PN532_CallFunction(pn532, PN532_COMMAND_WRITEGPIO, NULL, 0,
- params, sizeof(params), PN532_DEFAULT_TIMEOUT);
- }
|