PN532 Driver library This library provides an abstract API to drive the pn532 nfc chip, with I2C/HSU/SPI interface. Its based on the Seeed Studio's Arduino version.

Dependents:   PN532_ReadUid Nfctest2

Committer:
dotnfc
Date:
Tue Sep 13 06:17:35 2016 +0000
Revision:
1:b5922b3b3257
Parent:
0:db8030e71f55
Remove ununsed files.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dotnfc 0:db8030e71f55 1 ////////////////////////////////////////////////////////////////////////////////
dotnfc 0:db8030e71f55 2 // pn532 hsu interface for mbed platform
dotnfc 0:db8030e71f55 3 //
dotnfc 0:db8030e71f55 4 // by dotnfc@163.com
dotnfc 0:db8030e71f55 5 // 2016/09/10 18:16:00
dotnfc 0:db8030e71f55 6
dotnfc 0:db8030e71f55 7 #include "PN532_HSU.h"
dotnfc 0:db8030e71f55 8 #include "PN532_debug.h"
dotnfc 0:db8030e71f55 9
dotnfc 0:db8030e71f55 10
dotnfc 0:db8030e71f55 11 PN532_HSU::PN532_HSU(HardwareSerial &serial)
dotnfc 0:db8030e71f55 12 {
dotnfc 0:db8030e71f55 13 _serial = &serial;
dotnfc 0:db8030e71f55 14 command = 0;
dotnfc 0:db8030e71f55 15 }
dotnfc 0:db8030e71f55 16
dotnfc 0:db8030e71f55 17 void PN532_HSU::begin()
dotnfc 0:db8030e71f55 18 {
dotnfc 0:db8030e71f55 19 _serial->baud(115200);
dotnfc 0:db8030e71f55 20 }
dotnfc 0:db8030e71f55 21
dotnfc 0:db8030e71f55 22 void PN532_HSU::wakeup()
dotnfc 0:db8030e71f55 23 {
dotnfc 0:db8030e71f55 24 const uint8_t wakeup_cmd[] = { 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x05, 0xFB, 0xD4, 0x14, 0x01, 0x00, 0x01, 0x16, 0x00 };
dotnfc 0:db8030e71f55 25 _serial->write(wakeup_cmd, sizeof(wakeup_cmd));
dotnfc 0:db8030e71f55 26
dotnfc 0:db8030e71f55 27 delay (50);
dotnfc 0:db8030e71f55 28
dotnfc 0:db8030e71f55 29 /** dump serial buffer */
dotnfc 0:db8030e71f55 30 if(_serial->readable()){
dotnfc 0:db8030e71f55 31 DMSG("Dump sperial buffer: ");
dotnfc 0:db8030e71f55 32 }
dotnfc 0:db8030e71f55 33 while(_serial->readable()){
dotnfc 0:db8030e71f55 34 uint8_t ret = _serial->getc();
dotnfc 0:db8030e71f55 35 DMSG_HEX(ret);
dotnfc 0:db8030e71f55 36 }
dotnfc 0:db8030e71f55 37 DMSG("\n");
dotnfc 0:db8030e71f55 38 }
dotnfc 0:db8030e71f55 39
dotnfc 0:db8030e71f55 40 int8_t PN532_HSU::writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen)
dotnfc 0:db8030e71f55 41 {
dotnfc 0:db8030e71f55 42 /** dump serial buffer */
dotnfc 0:db8030e71f55 43 if(_serial->readable()){
dotnfc 0:db8030e71f55 44 DMSG("Dump sperial buffer: ");
dotnfc 0:db8030e71f55 45 }
dotnfc 0:db8030e71f55 46 while(_serial->readable()){
dotnfc 0:db8030e71f55 47 uint8_t ret = _serial->getc();
dotnfc 0:db8030e71f55 48 DMSG_HEX(ret);
dotnfc 0:db8030e71f55 49 }
dotnfc 0:db8030e71f55 50 DMSG("\n");
dotnfc 0:db8030e71f55 51
dotnfc 0:db8030e71f55 52 command = header[0];
dotnfc 0:db8030e71f55 53
dotnfc 0:db8030e71f55 54 _serial->write(PN532_PREAMBLE);
dotnfc 0:db8030e71f55 55 _serial->write(PN532_STARTCODE1);
dotnfc 0:db8030e71f55 56 _serial->write(PN532_STARTCODE2);
dotnfc 0:db8030e71f55 57
dotnfc 0:db8030e71f55 58 uint8_t length = hlen + blen + 1; // length of data field: TFI + DATA
dotnfc 0:db8030e71f55 59 _serial->write(length);
dotnfc 0:db8030e71f55 60 _serial->write(~length + 1); // checksum of length
dotnfc 0:db8030e71f55 61
dotnfc 0:db8030e71f55 62 _serial->write(PN532_HOSTTOPN532);
dotnfc 0:db8030e71f55 63 uint8_t sum = PN532_HOSTTOPN532; // sum of TFI + DATA
dotnfc 0:db8030e71f55 64
dotnfc 0:db8030e71f55 65 DMSG("\nWrite: ");
dotnfc 0:db8030e71f55 66
dotnfc 0:db8030e71f55 67 _serial->write(header, hlen);
dotnfc 0:db8030e71f55 68 for (uint8_t i = 0; i < hlen; i++) {
dotnfc 0:db8030e71f55 69 sum += header[i];
dotnfc 0:db8030e71f55 70
dotnfc 0:db8030e71f55 71 DMSG_HEX(header[i]);
dotnfc 0:db8030e71f55 72 }
dotnfc 0:db8030e71f55 73
dotnfc 0:db8030e71f55 74 _serial->write(body, blen);
dotnfc 0:db8030e71f55 75 for (uint8_t i = 0; i < blen; i++) {
dotnfc 0:db8030e71f55 76 sum += body[i];
dotnfc 0:db8030e71f55 77
dotnfc 0:db8030e71f55 78 DMSG_HEX(body[i]);
dotnfc 0:db8030e71f55 79 }
dotnfc 0:db8030e71f55 80
dotnfc 0:db8030e71f55 81 uint8_t checksum = ~sum + 1; // checksum of TFI + DATA
dotnfc 0:db8030e71f55 82 _serial->write(checksum);
dotnfc 0:db8030e71f55 83 _serial->write(PN532_POSTAMBLE);
dotnfc 0:db8030e71f55 84
dotnfc 0:db8030e71f55 85 delay (50);
dotnfc 0:db8030e71f55 86 return readAckFrame();
dotnfc 0:db8030e71f55 87 }
dotnfc 0:db8030e71f55 88
dotnfc 0:db8030e71f55 89 int16_t PN532_HSU::readResponse(uint8_t buf[], uint8_t len, uint16_t timeout)
dotnfc 0:db8030e71f55 90 {
dotnfc 0:db8030e71f55 91 uint8_t tmp[3];
dotnfc 0:db8030e71f55 92
dotnfc 0:db8030e71f55 93 delay(100);
dotnfc 0:db8030e71f55 94
dotnfc 0:db8030e71f55 95 DMSG("\nRead: ");
dotnfc 0:db8030e71f55 96
dotnfc 0:db8030e71f55 97 /** Frame Preamble and Start Code */
dotnfc 0:db8030e71f55 98 if(receive(tmp, 3, timeout)<=0){
dotnfc 0:db8030e71f55 99 return PN532_TIMEOUT;
dotnfc 0:db8030e71f55 100 }
dotnfc 0:db8030e71f55 101 if(0 != tmp[0] || 0!= tmp[1] || 0xFF != tmp[2]){
dotnfc 0:db8030e71f55 102 DMSG("Preamble error");
dotnfc 0:db8030e71f55 103 return PN532_INVALID_FRAME;
dotnfc 0:db8030e71f55 104 }
dotnfc 0:db8030e71f55 105
dotnfc 0:db8030e71f55 106 /** receive length and check */
dotnfc 0:db8030e71f55 107 uint8_t length[2];
dotnfc 0:db8030e71f55 108 if(receive(length, 2, timeout) <= 0){
dotnfc 0:db8030e71f55 109 return PN532_TIMEOUT;
dotnfc 0:db8030e71f55 110 }
dotnfc 0:db8030e71f55 111 if( 0 != (uint8_t)(length[0] + length[1]) ){
dotnfc 0:db8030e71f55 112 DMSG("Length error\n");
dotnfc 0:db8030e71f55 113 return PN532_INVALID_FRAME;
dotnfc 0:db8030e71f55 114 }
dotnfc 0:db8030e71f55 115 length[0] -= 2;
dotnfc 0:db8030e71f55 116 if( length[0] > len){
dotnfc 0:db8030e71f55 117 return PN532_NO_SPACE;
dotnfc 0:db8030e71f55 118 }
dotnfc 0:db8030e71f55 119
dotnfc 0:db8030e71f55 120 /** receive command byte */
dotnfc 0:db8030e71f55 121 uint8_t cmd = command + 1; // response command
dotnfc 0:db8030e71f55 122 if(receive(tmp, 2, timeout) <= 0){
dotnfc 0:db8030e71f55 123 return PN532_TIMEOUT;
dotnfc 0:db8030e71f55 124 }
dotnfc 0:db8030e71f55 125 if( PN532_PN532TOHOST != tmp[0] || cmd != tmp[1]){
dotnfc 0:db8030e71f55 126 DMSG("Command error\n");
dotnfc 0:db8030e71f55 127 return PN532_INVALID_FRAME;
dotnfc 0:db8030e71f55 128 }
dotnfc 0:db8030e71f55 129
dotnfc 0:db8030e71f55 130 if(receive(buf, length[0], timeout) != length[0]){
dotnfc 0:db8030e71f55 131 return PN532_TIMEOUT;
dotnfc 0:db8030e71f55 132 }
dotnfc 0:db8030e71f55 133 uint8_t sum = PN532_PN532TOHOST + cmd;
dotnfc 0:db8030e71f55 134 for(uint8_t i=0; i<length[0]; i++){
dotnfc 0:db8030e71f55 135 sum += buf[i];
dotnfc 0:db8030e71f55 136 }
dotnfc 0:db8030e71f55 137
dotnfc 0:db8030e71f55 138 /** checksum and postamble */
dotnfc 0:db8030e71f55 139 if(receive(tmp, 2, timeout) <= 0){
dotnfc 0:db8030e71f55 140 return PN532_TIMEOUT;
dotnfc 0:db8030e71f55 141 }
dotnfc 0:db8030e71f55 142 if( 0 != (uint8_t)(sum + tmp[0]) || 0 != tmp[1] ){
dotnfc 0:db8030e71f55 143 DMSG("Checksum error\n");
dotnfc 0:db8030e71f55 144 return PN532_INVALID_FRAME;
dotnfc 0:db8030e71f55 145 }
dotnfc 0:db8030e71f55 146
dotnfc 0:db8030e71f55 147 DMSG ("\n");
dotnfc 0:db8030e71f55 148 return length[0];
dotnfc 0:db8030e71f55 149 }
dotnfc 0:db8030e71f55 150
dotnfc 0:db8030e71f55 151 int8_t PN532_HSU::readAckFrame()
dotnfc 0:db8030e71f55 152 {
dotnfc 0:db8030e71f55 153 const uint8_t PN532_ACK[] = {0, 0, 0xFF, 0, 0xFF, 0};
dotnfc 0:db8030e71f55 154 uint8_t ackBuf[sizeof(PN532_ACK)];
dotnfc 0:db8030e71f55 155
dotnfc 0:db8030e71f55 156 delay(100);
dotnfc 0:db8030e71f55 157
dotnfc 0:db8030e71f55 158 DMSG("\nAck: ");
dotnfc 0:db8030e71f55 159
dotnfc 0:db8030e71f55 160 if( receive(ackBuf, sizeof(PN532_ACK), PN532_ACK_WAIT_TIME) <= 0 ){
dotnfc 0:db8030e71f55 161 DMSG("Timeout\n");
dotnfc 0:db8030e71f55 162 return PN532_TIMEOUT;
dotnfc 0:db8030e71f55 163 }
dotnfc 0:db8030e71f55 164
dotnfc 0:db8030e71f55 165 if( memcmp(ackBuf, PN532_ACK, sizeof(PN532_ACK)) ){
dotnfc 0:db8030e71f55 166 DMSG("Invalid\n");
dotnfc 0:db8030e71f55 167 return PN532_INVALID_ACK;
dotnfc 0:db8030e71f55 168 }
dotnfc 0:db8030e71f55 169 return 0;
dotnfc 0:db8030e71f55 170 }
dotnfc 0:db8030e71f55 171
dotnfc 0:db8030e71f55 172 /**
dotnfc 0:db8030e71f55 173 @brief receive data .
dotnfc 0:db8030e71f55 174 @param buf --> return value buffer.
dotnfc 0:db8030e71f55 175 len --> length expect to receive.
dotnfc 0:db8030e71f55 176 timeout --> time of reveiving
dotnfc 0:db8030e71f55 177 @retval number of received bytes, 0 means no data received.
dotnfc 0:db8030e71f55 178 */
dotnfc 0:db8030e71f55 179 int8_t PN532_HSU::receive(uint8_t *buf, int len, uint16_t timeout)
dotnfc 0:db8030e71f55 180 {
dotnfc 0:db8030e71f55 181 int read_bytes = 0;
dotnfc 0:db8030e71f55 182 int ret;
dotnfc 0:db8030e71f55 183 Timer tmr_hsu;
dotnfc 0:db8030e71f55 184 unsigned long start_millis;
dotnfc 0:db8030e71f55 185
dotnfc 0:db8030e71f55 186 tmr_hsu.start();
dotnfc 0:db8030e71f55 187 while (read_bytes < len) {
dotnfc 0:db8030e71f55 188 start_millis = tmr_hsu.read_ms(); // millis();
dotnfc 0:db8030e71f55 189 do {
dotnfc 0:db8030e71f55 190 ret = _serial->getc();
dotnfc 0:db8030e71f55 191 if (ret >= 0) {
dotnfc 0:db8030e71f55 192 break;
dotnfc 0:db8030e71f55 193 }
dotnfc 0:db8030e71f55 194 delay(10);
dotnfc 0:db8030e71f55 195 } while((timeout == 0) || ((tmr_hsu.read_ms() /* millis() */ - start_millis ) < timeout));
dotnfc 0:db8030e71f55 196
dotnfc 0:db8030e71f55 197 if (ret < 0) {
dotnfc 0:db8030e71f55 198 if(read_bytes){
dotnfc 0:db8030e71f55 199 tmr_hsu.stop ();
dotnfc 0:db8030e71f55 200 return read_bytes;
dotnfc 0:db8030e71f55 201 }else{
dotnfc 0:db8030e71f55 202 tmr_hsu.stop ();
dotnfc 0:db8030e71f55 203 return PN532_TIMEOUT;
dotnfc 0:db8030e71f55 204 }
dotnfc 0:db8030e71f55 205 }
dotnfc 0:db8030e71f55 206 buf[read_bytes] = (uint8_t)ret;
dotnfc 0:db8030e71f55 207 DMSG_HEX(ret);
dotnfc 0:db8030e71f55 208 read_bytes++;
dotnfc 0:db8030e71f55 209 }
dotnfc 0:db8030e71f55 210
dotnfc 0:db8030e71f55 211 tmr_hsu.stop ();
dotnfc 0:db8030e71f55 212 return read_bytes;
dotnfc 0:db8030e71f55 213 }