#include "pn532.h" #define PN532_PACKBUFFSIZ 64 uint8_t pn532_packetbuffer[PN532_PACKBUFFSIZ]; uint8_t pn532ack[] = {0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00}; uint8_t pn532response_firmwarevers[] = {0x00, 0xFF, 0x06, 0xFA, 0xD5, 0x03}; uint8_t writeBuffer[60]; uint8_t _uid[7]; // ISO14443A uid uint8_t _uidLen; // uid len uint8_t _key[6]; // Mifare Classic key uint8_t _inListedTag; // Tg number of inlisted tag. uint8_t pn532_sendCommandCheckAck(uint8_t *cmd, uint8_t cmdlen, uint16_t timeout); uint8_t pn532_readack() ; uint8_t pn532_waitready(uint16_t timeout) ; void pn532_readdata(uint8_t* buff, uint8_t n); void pn532_writecommand(uint8_t* cmd, uint8_t cmdlen); uint8_t pn532_isready(); //=============================================================================================== void pn532_reset() { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 0); HAL_Delay(400); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 1); HAL_Delay(10); } //=============================================================================================== uint32_t pn532_getFirmwareVersion(void) { uint32_t response; pn532_packetbuffer[0] = PN532_COMMAND_GETFIRMWAREVERSION; if (pn532_sendCommandCheckAck(pn532_packetbuffer, 1,1000)==0) { return 0; } // read data packet pn532_readdata(pn532_packetbuffer, 12); // check some basic stuff if (0 != strncmp((char *)pn532_packetbuffer, (char *)pn532response_firmwarevers, 6)) { return 0; } int offset = 7; // Skip a response byte when using I2C to ignore extra data. response = pn532_packetbuffer[offset++]; response <<= 8; response |= pn532_packetbuffer[offset++]; response <<= 8; response |= pn532_packetbuffer[offset++]; response <<= 8; response |= pn532_packetbuffer[offset++]; return response; } //=============================================================================================== uint8_t 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 (pn532_sendCommandCheckAck(pn532_packetbuffer, 4, 1000) == 0) return 0; // read data packet pn532_readdata(pn532_packetbuffer, 8); int offset = 6; if (pn532_packetbuffer[offset] == 0x15) { return 1; } else {return 0;} } //=============================================================================================== uint8_t pn532_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 (pn532_sendCommandCheckAck(pn532_packetbuffer, 3, 1000)==0) { return 0x0; // no cards read } // wait for a card to enter the field (only possible with I2C) if (!pn532_waitready(timeout)) { return 0x0; } pn532_readdata(pn532_packetbuffer, 20); // 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 */ if (pn532_packetbuffer[7] != 1) return 0; uint16_t sens_res = pn532_packetbuffer[9]; sens_res <<= 8; sens_res |= pn532_packetbuffer[10]; /* Card appears to be Mifare Classic */ *uidLength = pn532_packetbuffer[12]; for (uint8_t i=0; i < pn532_packetbuffer[12]; i++) { uid[i] = pn532_packetbuffer[13+i]; } return 1; } /**************************************************************************/ /*! Tries to authenticate a block of memory on a MIFARE card using the INDATAEXCHANGE command. See section 7.3.8 of the PN532 User Manual for more information on sending MIFARE and other commands. @param uid Pointer to a byte array containing the card UID @param uidLen The length (in bytes) of the card's UID (Should be 4 for MIFARE Classic) @param blockNumber The block number to authenticate. (0..63 for 1KB cards, and 0..255 for 4KB cards). @param keyNumber Which key type to use during authentication (0 = MIFARE_CMD_AUTH_A, 1 = MIFARE_CMD_AUTH_B) @param keyData Pointer to a byte array containing the 6 bytes key value @returns 1 if everything executed properly, 0 for an error */ /**************************************************************************/ uint8_t pn532_mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) { uint8_t len; 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 byte card ID */ } if (pn532_sendCommandCheckAck(pn532_packetbuffer, 10+_uidLen,1000)==0) return 0; // Read the response packet pn532_readdata(pn532_packetbuffer, 12); // 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[7] != 0x00) { return 0; } return 1; } /**************************************************************************/ /*! Tries to read an entire 16-byte data block at the specified block address. @param blockNumber The block number to authenticate. (0..63 for 1KB cards, and 0..255 for 4KB cards). @param data Pointer to the byte array that will hold the retrieved data (if any) @returns 1 if everything executed properly, 0 for an error */ /**************************************************************************/ uint8_t pn532_mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t * data) { /* 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 (pn532_sendCommandCheckAck(pn532_packetbuffer, 4,1000)==0) { return 0; } /* Read the response packet */ pn532_readdata(pn532_packetbuffer, 26); /* If byte 8 isn't 0x00 we probably have an error */ if (pn532_packetbuffer[7] != 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+8, 16); return 1; } /**************************************************************************/ /*! Tries to write an entire 16-byte data block at the specified block address. @param blockNumber The block number to authenticate. (0..63 for 1KB cards, and 0..255 for 4KB cards). @param data The byte array that contains the data to write. @returns 1 if everything executed properly, 0 for an error */ /**************************************************************************/ 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 ( pn532_sendCommandCheckAck(pn532_packetbuffer, 20,10000)==0) { return 0; } HAL_Delay(50); /* Read the response packet */ pn532_readdata(pn532_packetbuffer, 26); return 1; } //=============================================================================================== uint8_t pn532_sendCommandCheckAck(uint8_t *cmd, uint8_t cmdlen, uint16_t timeout) { // write the command pn532_writecommand(cmd, cmdlen); // Wait for chip to say its ready! if (!pn532_waitready(timeout)) { return 0; } // read acknowledgement if (!pn532_readack()) { return 0; } return 1; // ack'd command } //=============================================================================================== uint8_t pn532_readack() { uint8_t ackbuff[6]; pn532_readdata(ackbuff, 6); return (0 == strncmp((char *)ackbuff, (char *)pn532ack, 6)); } //=============================================================================================== uint8_t pn532_waitready(uint16_t timeout) { uint16_t timer = 0; while(pn532_isready()==0) { if (timeout != 0) { timer += 10; if (timer > timeout) { //term_printf("TIME OUT \n\r"); return 0; } } HAL_Delay(10); } return 1; } //=============================================================================================== uint8_t pn532_isready() { uint8_t x; x = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_10); if (x==0) {return 1;} else {return 0;} } //=============================================================================================== void pn532_readdata(uint8_t* buff, uint8_t n) { // I2C write. uint8_t i; HAL_Delay(50); i2c1_ReadBuffer(PN532_I2C_ADDRESS, buff, n+2); // discard first byte for (i=0; i