to colorize a colorful pixel with a simple touch using nfc technology

Dependencies:   Chainable_RGB_LED mbed

use Arch, NFC Shield and Grove - Chainable RGB LED to DIY a touch pixel. Then use an Android with NFC support to colorize it.

The project is on https://github.com/Seeed-Studio/TouchPixel

Committer:
yihui
Date:
Fri Dec 27 01:46:32 2013 +0000
Revision:
0:88960f3eeb2c
initial

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yihui 0:88960f3eeb2c 1
yihui 0:88960f3eeb2c 2 #include "PN532_SPI.h"
yihui 0:88960f3eeb2c 3 #include "PN532_debug.h"
yihui 0:88960f3eeb2c 4
yihui 0:88960f3eeb2c 5 #define STATUS_READ 2
yihui 0:88960f3eeb2c 6 #define DATA_WRITE 1
yihui 0:88960f3eeb2c 7 #define DATA_READ 3
yihui 0:88960f3eeb2c 8
yihui 0:88960f3eeb2c 9 PN532_SPI::PN532_SPI(SPI &spi, PinName ss) : _ss(ss)
yihui 0:88960f3eeb2c 10 {
yihui 0:88960f3eeb2c 11 command = 0;
yihui 0:88960f3eeb2c 12 _spi = &spi;
yihui 0:88960f3eeb2c 13 _spi->format(8, 0);
yihui 0:88960f3eeb2c 14 _spi->frequency(2000000);
yihui 0:88960f3eeb2c 15
yihui 0:88960f3eeb2c 16 _ss = 1;
yihui 0:88960f3eeb2c 17 }
yihui 0:88960f3eeb2c 18
yihui 0:88960f3eeb2c 19 PN532_SPI::PN532_SPI(SPI *spi, PinName ss) : _ss(ss)
yihui 0:88960f3eeb2c 20 {
yihui 0:88960f3eeb2c 21 command = 0;
yihui 0:88960f3eeb2c 22 _spi = spi;
yihui 0:88960f3eeb2c 23 _spi->format(8, 0);
yihui 0:88960f3eeb2c 24 _spi->frequency(2000000);
yihui 0:88960f3eeb2c 25
yihui 0:88960f3eeb2c 26 _ss = 1;
yihui 0:88960f3eeb2c 27 }
yihui 0:88960f3eeb2c 28
yihui 0:88960f3eeb2c 29 void PN532_SPI::begin()
yihui 0:88960f3eeb2c 30 {
yihui 0:88960f3eeb2c 31
yihui 0:88960f3eeb2c 32 }
yihui 0:88960f3eeb2c 33
yihui 0:88960f3eeb2c 34 void PN532_SPI::wakeup()
yihui 0:88960f3eeb2c 35 {
yihui 0:88960f3eeb2c 36 _ss = 0;
yihui 0:88960f3eeb2c 37 wait_ms(2);
yihui 0:88960f3eeb2c 38 _ss = 1;
yihui 0:88960f3eeb2c 39 }
yihui 0:88960f3eeb2c 40
yihui 0:88960f3eeb2c 41 int8_t PN532_SPI::writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen)
yihui 0:88960f3eeb2c 42 {
yihui 0:88960f3eeb2c 43 command = header[0];
yihui 0:88960f3eeb2c 44 writeFrame(header, hlen, body, blen);
yihui 0:88960f3eeb2c 45
yihui 0:88960f3eeb2c 46 uint8_t timeout = PN532_ACK_WAIT_TIME;
yihui 0:88960f3eeb2c 47 while (!isReady()) {
yihui 0:88960f3eeb2c 48 wait_ms(1);
yihui 0:88960f3eeb2c 49 timeout--;
yihui 0:88960f3eeb2c 50 if (0 == timeout) {
yihui 0:88960f3eeb2c 51 DMSG("Time out when waiting for ACK\n");
yihui 0:88960f3eeb2c 52 return -2;
yihui 0:88960f3eeb2c 53 }
yihui 0:88960f3eeb2c 54 }
yihui 0:88960f3eeb2c 55 if (readAckFrame()) {
yihui 0:88960f3eeb2c 56 DMSG("Invalid ACK\n");
yihui 0:88960f3eeb2c 57 return PN532_INVALID_ACK;
yihui 0:88960f3eeb2c 58 }
yihui 0:88960f3eeb2c 59 return 0;
yihui 0:88960f3eeb2c 60 }
yihui 0:88960f3eeb2c 61
yihui 0:88960f3eeb2c 62 int16_t PN532_SPI::readResponse(uint8_t buf[], uint8_t len, uint16_t timeout)
yihui 0:88960f3eeb2c 63 {
yihui 0:88960f3eeb2c 64 uint16_t time = 0;
yihui 0:88960f3eeb2c 65 while (!isReady()) {
yihui 0:88960f3eeb2c 66 wait_ms(1);
yihui 0:88960f3eeb2c 67 time++;
yihui 0:88960f3eeb2c 68 if (timeout > 0 && time > timeout) {
yihui 0:88960f3eeb2c 69 return PN532_TIMEOUT;
yihui 0:88960f3eeb2c 70 }
yihui 0:88960f3eeb2c 71 }
yihui 0:88960f3eeb2c 72
yihui 0:88960f3eeb2c 73 _ss = 0;
yihui 0:88960f3eeb2c 74 wait_ms(1);
yihui 0:88960f3eeb2c 75
yihui 0:88960f3eeb2c 76 int16_t result;
yihui 0:88960f3eeb2c 77 do {
yihui 0:88960f3eeb2c 78 write(DATA_READ);
yihui 0:88960f3eeb2c 79
yihui 0:88960f3eeb2c 80 if (0x00 != read() || // PREAMBLE
yihui 0:88960f3eeb2c 81 0x00 != read() || // STARTCODE1
yihui 0:88960f3eeb2c 82 0xFF != read() // STARTCODE2
yihui 0:88960f3eeb2c 83 ) {
yihui 0:88960f3eeb2c 84
yihui 0:88960f3eeb2c 85 result = PN532_INVALID_FRAME;
yihui 0:88960f3eeb2c 86 break;
yihui 0:88960f3eeb2c 87 }
yihui 0:88960f3eeb2c 88
yihui 0:88960f3eeb2c 89 uint8_t length = read();
yihui 0:88960f3eeb2c 90 if (0 != (uint8_t)(length + read())) { // checksum of length
yihui 0:88960f3eeb2c 91 result = PN532_INVALID_FRAME;
yihui 0:88960f3eeb2c 92 break;
yihui 0:88960f3eeb2c 93 }
yihui 0:88960f3eeb2c 94
yihui 0:88960f3eeb2c 95 uint8_t cmd = command + 1; // response command
yihui 0:88960f3eeb2c 96 if (PN532_PN532TOHOST != read() || (cmd) != read()) {
yihui 0:88960f3eeb2c 97 result = PN532_INVALID_FRAME;
yihui 0:88960f3eeb2c 98 break;
yihui 0:88960f3eeb2c 99 }
yihui 0:88960f3eeb2c 100
yihui 0:88960f3eeb2c 101 DMSG("read: ");
yihui 0:88960f3eeb2c 102 DMSG_HEX(cmd);
yihui 0:88960f3eeb2c 103
yihui 0:88960f3eeb2c 104 length -= 2;
yihui 0:88960f3eeb2c 105 if (length > len) {
yihui 0:88960f3eeb2c 106 for (uint8_t i = 0; i < length; i++) {
yihui 0:88960f3eeb2c 107 DMSG_HEX(read()); // dump message
yihui 0:88960f3eeb2c 108 }
yihui 0:88960f3eeb2c 109 DMSG("\nNot enough space\n");
yihui 0:88960f3eeb2c 110 read();
yihui 0:88960f3eeb2c 111 read();
yihui 0:88960f3eeb2c 112 result = PN532_NO_SPACE; // not enough space
yihui 0:88960f3eeb2c 113 break;
yihui 0:88960f3eeb2c 114 }
yihui 0:88960f3eeb2c 115
yihui 0:88960f3eeb2c 116 uint8_t sum = PN532_PN532TOHOST + cmd;
yihui 0:88960f3eeb2c 117 for (uint8_t i = 0; i < length; i++) {
yihui 0:88960f3eeb2c 118 buf[i] = read();
yihui 0:88960f3eeb2c 119 sum += buf[i];
yihui 0:88960f3eeb2c 120
yihui 0:88960f3eeb2c 121 DMSG_HEX(buf[i]);
yihui 0:88960f3eeb2c 122 }
yihui 0:88960f3eeb2c 123 DMSG("\n");
yihui 0:88960f3eeb2c 124
yihui 0:88960f3eeb2c 125 uint8_t checksum = read();
yihui 0:88960f3eeb2c 126 if (0 != (uint8_t)(sum + checksum)) {
yihui 0:88960f3eeb2c 127 DMSG("checksum is not ok\n");
yihui 0:88960f3eeb2c 128 result = PN532_INVALID_FRAME;
yihui 0:88960f3eeb2c 129 break;
yihui 0:88960f3eeb2c 130 }
yihui 0:88960f3eeb2c 131 read(); // POSTAMBLE
yihui 0:88960f3eeb2c 132
yihui 0:88960f3eeb2c 133 result = length;
yihui 0:88960f3eeb2c 134 } while (0);
yihui 0:88960f3eeb2c 135
yihui 0:88960f3eeb2c 136 _ss = 1;
yihui 0:88960f3eeb2c 137
yihui 0:88960f3eeb2c 138 return result;
yihui 0:88960f3eeb2c 139 }
yihui 0:88960f3eeb2c 140
yihui 0:88960f3eeb2c 141 bool PN532_SPI::isReady()
yihui 0:88960f3eeb2c 142 {
yihui 0:88960f3eeb2c 143 _ss = 0;
yihui 0:88960f3eeb2c 144
yihui 0:88960f3eeb2c 145 write(STATUS_READ);
yihui 0:88960f3eeb2c 146 uint8_t status = read() & 1;
yihui 0:88960f3eeb2c 147 _ss = 1;
yihui 0:88960f3eeb2c 148 return status;
yihui 0:88960f3eeb2c 149 }
yihui 0:88960f3eeb2c 150
yihui 0:88960f3eeb2c 151 void PN532_SPI::writeFrame(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen)
yihui 0:88960f3eeb2c 152 {
yihui 0:88960f3eeb2c 153 _ss = 0;
yihui 0:88960f3eeb2c 154 wait_ms(2); // wake up PN532
yihui 0:88960f3eeb2c 155
yihui 0:88960f3eeb2c 156 write(DATA_WRITE);
yihui 0:88960f3eeb2c 157 write(PN532_PREAMBLE);
yihui 0:88960f3eeb2c 158 write(PN532_STARTCODE1);
yihui 0:88960f3eeb2c 159 write(PN532_STARTCODE2);
yihui 0:88960f3eeb2c 160
yihui 0:88960f3eeb2c 161 uint8_t length = hlen + blen + 1; // length of data field: TFI + DATA
yihui 0:88960f3eeb2c 162 write(length);
yihui 0:88960f3eeb2c 163 write(~length + 1); // checksum of length
yihui 0:88960f3eeb2c 164
yihui 0:88960f3eeb2c 165 write(PN532_HOSTTOPN532);
yihui 0:88960f3eeb2c 166 uint8_t sum = PN532_HOSTTOPN532; // sum of TFI + DATA
yihui 0:88960f3eeb2c 167
yihui 0:88960f3eeb2c 168 DMSG("write: ");
yihui 0:88960f3eeb2c 169
yihui 0:88960f3eeb2c 170 for (uint8_t i = 0; i < hlen; i++) {
yihui 0:88960f3eeb2c 171 write(header[i]);
yihui 0:88960f3eeb2c 172 sum += header[i];
yihui 0:88960f3eeb2c 173
yihui 0:88960f3eeb2c 174 DMSG_HEX(header[i]);
yihui 0:88960f3eeb2c 175 }
yihui 0:88960f3eeb2c 176 for (uint8_t i = 0; i < blen; i++) {
yihui 0:88960f3eeb2c 177 write(body[i]);
yihui 0:88960f3eeb2c 178 sum += body[i];
yihui 0:88960f3eeb2c 179
yihui 0:88960f3eeb2c 180 DMSG_HEX(header[i]);
yihui 0:88960f3eeb2c 181 }
yihui 0:88960f3eeb2c 182
yihui 0:88960f3eeb2c 183 uint8_t checksum = ~sum + 1; // checksum of TFI + DATA
yihui 0:88960f3eeb2c 184 write(checksum);
yihui 0:88960f3eeb2c 185 write(PN532_POSTAMBLE);
yihui 0:88960f3eeb2c 186
yihui 0:88960f3eeb2c 187 _ss = 1;
yihui 0:88960f3eeb2c 188
yihui 0:88960f3eeb2c 189 DMSG("\n");
yihui 0:88960f3eeb2c 190 }
yihui 0:88960f3eeb2c 191
yihui 0:88960f3eeb2c 192 int8_t PN532_SPI::readAckFrame()
yihui 0:88960f3eeb2c 193 {
yihui 0:88960f3eeb2c 194 const uint8_t PN532_ACK[] = {0, 0, 0xFF, 0, 0xFF, 0};
yihui 0:88960f3eeb2c 195
yihui 0:88960f3eeb2c 196 uint8_t ackBuf[sizeof(PN532_ACK)];
yihui 0:88960f3eeb2c 197
yihui 0:88960f3eeb2c 198 _ss = 0;
yihui 0:88960f3eeb2c 199 wait_ms(1);
yihui 0:88960f3eeb2c 200 write(DATA_READ);
yihui 0:88960f3eeb2c 201
yihui 0:88960f3eeb2c 202 for (uint8_t i = 0; i < sizeof(PN532_ACK); i++) {
yihui 0:88960f3eeb2c 203 ackBuf[i] = read();
yihui 0:88960f3eeb2c 204 }
yihui 0:88960f3eeb2c 205
yihui 0:88960f3eeb2c 206 _ss = 1;
yihui 0:88960f3eeb2c 207
yihui 0:88960f3eeb2c 208 return memcmp(ackBuf, PN532_ACK, sizeof(PN532_ACK));
yihui 0:88960f3eeb2c 209 }