NFC API for mbed using the MicroNFCBoard as a peripheral

Dependents:   MicroNFCBoardAPI_P2P_Client MicroNFCBoardAPI_Blink MicroNFCBoardAPI_Tag_Emulator MicroNFCBoardAPI_Tag_Reader ... more

Committer:
AppNearMe
Date:
Fri Apr 24 12:59:31 2015 +0000
Revision:
1:1d246e0872c6
Parent:
0:07fa9c0dd549
Child:
2:9b0733b8fa95
Set license to Apache 2

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AppNearMe 1:1d246e0872c6 1 /*
AppNearMe 1:1d246e0872c6 2 MicroNFCBoard mbed API
AppNearMe 1:1d246e0872c6 3
AppNearMe 1:1d246e0872c6 4 Copyright (c) 2014-2015 AppNearMe Ltd
AppNearMe 1:1d246e0872c6 5
AppNearMe 1:1d246e0872c6 6 Licensed under the Apache License, Version 2.0 (the "License");
AppNearMe 1:1d246e0872c6 7 you may not use this file except in compliance with the License.
AppNearMe 1:1d246e0872c6 8 You may obtain a copy of the License at
AppNearMe 1:1d246e0872c6 9
AppNearMe 1:1d246e0872c6 10 http://www.apache.org/licenses/LICENSE-2.0
AppNearMe 1:1d246e0872c6 11
AppNearMe 1:1d246e0872c6 12 Unless required by applicable law or agreed to in writing, software
AppNearMe 1:1d246e0872c6 13 distributed under the License is distributed on an "AS IS" BASIS,
AppNearMe 1:1d246e0872c6 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
AppNearMe 1:1d246e0872c6 15 See the License for the specific language governing permissions and
AppNearMe 1:1d246e0872c6 16 limitations under the License.
AppNearMe 0:07fa9c0dd549 17 */
AppNearMe 0:07fa9c0dd549 18
AppNearMe 0:07fa9c0dd549 19 #include "transport.h"
AppNearMe 0:07fa9c0dd549 20
AppNearMe 0:07fa9c0dd549 21
AppNearMe 0:07fa9c0dd549 22 //MSB first
AppNearMe 0:07fa9c0dd549 23 #define WRITE_UINT32( addr, val ) do{ *(((uint8_t*)(addr)) + 0) = ((val) >> 24 ) & 0xFF; \
AppNearMe 0:07fa9c0dd549 24 *(((uint8_t*)(addr)) + 1) = ((val) >> 16 ) & 0xFF; \
AppNearMe 0:07fa9c0dd549 25 *(((uint8_t*)(addr)) + 2) = ((val) >> 8 ) & 0xFF; \
AppNearMe 0:07fa9c0dd549 26 *(((uint8_t*)(addr)) + 3) = ((val) >> 0 ) & 0xFF; } while(0)
AppNearMe 0:07fa9c0dd549 27 #define WRITE_UINT16( addr, val ) do{ *(((uint8_t*)(addr)) + 0) = ((val) >> 8 ) & 0xFF; \
AppNearMe 0:07fa9c0dd549 28 *(((uint8_t*)(addr)) + 1) = ((val) >> 0 ) & 0xFF; } while(0)
AppNearMe 0:07fa9c0dd549 29
AppNearMe 0:07fa9c0dd549 30 //MSB first
AppNearMe 0:07fa9c0dd549 31 #define READ_UINT32( addr, val ) do{ val = (*(((uint8_t*)(addr)) + 0) << 24 ) \
AppNearMe 0:07fa9c0dd549 32 | (*(((uint8_t*)(addr)) + 1) << 16 ) \
AppNearMe 0:07fa9c0dd549 33 | (*(((uint8_t*)(addr)) + 2) << 8 ) \
AppNearMe 0:07fa9c0dd549 34 | (*(((uint8_t*)(addr)) + 3) << 0 ); } while(0)
AppNearMe 0:07fa9c0dd549 35 #define READ_UINT16( addr, val ) do{ val = (*(((uint8_t*)(addr)) + 0) << 8 ) \
AppNearMe 0:07fa9c0dd549 36 | (*(((uint8_t*)(addr)) + 1) << 0 ); } while(0)
AppNearMe 0:07fa9c0dd549 37
AppNearMe 0:07fa9c0dd549 38
AppNearMe 0:07fa9c0dd549 39 Transport::Transport(PinName mosi, PinName miso, PinName sck, PinName cs, PinName irq) : \
AppNearMe 0:07fa9c0dd549 40 _cs(cs), _spi(mosi, miso, sck), _int(irq)
AppNearMe 0:07fa9c0dd549 41 {
AppNearMe 0:07fa9c0dd549 42 }
AppNearMe 0:07fa9c0dd549 43
AppNearMe 0:07fa9c0dd549 44 void Transport::init()
AppNearMe 0:07fa9c0dd549 45 {
AppNearMe 0:07fa9c0dd549 46 _spi.format(8, 1);
AppNearMe 0:07fa9c0dd549 47 _spi.frequency(100000);
AppNearMe 0:07fa9c0dd549 48 _cs = 1;
AppNearMe 0:07fa9c0dd549 49
AppNearMe 0:07fa9c0dd549 50 for(int i = 0; i < 64; i++)
AppNearMe 0:07fa9c0dd549 51 {
AppNearMe 0:07fa9c0dd549 52 _cs = 0;
AppNearMe 0:07fa9c0dd549 53 _spi.write(0);
AppNearMe 0:07fa9c0dd549 54 _cs = 1;
AppNearMe 0:07fa9c0dd549 55 }
AppNearMe 0:07fa9c0dd549 56 }
AppNearMe 0:07fa9c0dd549 57
AppNearMe 0:07fa9c0dd549 58 void Transport::reset()
AppNearMe 0:07fa9c0dd549 59 {
AppNearMe 0:07fa9c0dd549 60 uint8_t out[] = {0};
AppNearMe 0:07fa9c0dd549 61 command(Transport::RESET, out, sizeof(out), NULL, 0);
AppNearMe 0:07fa9c0dd549 62 }
AppNearMe 0:07fa9c0dd549 63
AppNearMe 0:07fa9c0dd549 64 bool Transport::statusChanged()
AppNearMe 0:07fa9c0dd549 65 {
AppNearMe 0:07fa9c0dd549 66 return (_int.read() != 0);
AppNearMe 0:07fa9c0dd549 67 }
AppNearMe 0:07fa9c0dd549 68
AppNearMe 0:07fa9c0dd549 69 uint32_t Transport::status()
AppNearMe 0:07fa9c0dd549 70 {
AppNearMe 0:07fa9c0dd549 71 uint8_t in[4];
AppNearMe 0:07fa9c0dd549 72 command(Transport::GET_STATUS, NULL, 0, in, sizeof(in));
AppNearMe 0:07fa9c0dd549 73
AppNearMe 0:07fa9c0dd549 74 uint32_t status;
AppNearMe 0:07fa9c0dd549 75 READ_UINT32(&in[0], status);
AppNearMe 0:07fa9c0dd549 76 return status;
AppNearMe 0:07fa9c0dd549 77 }
AppNearMe 0:07fa9c0dd549 78
AppNearMe 0:07fa9c0dd549 79 void Transport::nfcPoll(bool enable)
AppNearMe 0:07fa9c0dd549 80 {
AppNearMe 0:07fa9c0dd549 81 uint8_t out[] = {enable?1:0};
AppNearMe 0:07fa9c0dd549 82 command(Transport::NFC_POLL, out, sizeof(out), NULL, 0);
AppNearMe 0:07fa9c0dd549 83 }
AppNearMe 0:07fa9c0dd549 84
AppNearMe 0:07fa9c0dd549 85 void Transport::nfcOperation(bool readOp, bool writeOp)
AppNearMe 0:07fa9c0dd549 86 {
AppNearMe 0:07fa9c0dd549 87 uint8_t out[1];
AppNearMe 0:07fa9c0dd549 88 if(readOp)
AppNearMe 0:07fa9c0dd549 89 {
AppNearMe 0:07fa9c0dd549 90 out[0] = 1;
AppNearMe 0:07fa9c0dd549 91 }
AppNearMe 0:07fa9c0dd549 92 else if(writeOp)
AppNearMe 0:07fa9c0dd549 93 {
AppNearMe 0:07fa9c0dd549 94 out[0] = 2;
AppNearMe 0:07fa9c0dd549 95 }
AppNearMe 0:07fa9c0dd549 96 else
AppNearMe 0:07fa9c0dd549 97 {
AppNearMe 0:07fa9c0dd549 98 out[0] = 0;
AppNearMe 0:07fa9c0dd549 99 }
AppNearMe 0:07fa9c0dd549 100 command(Transport::NFC_OPERATION, out, sizeof(out), NULL, 0);
AppNearMe 0:07fa9c0dd549 101 }
AppNearMe 0:07fa9c0dd549 102
AppNearMe 0:07fa9c0dd549 103 void Transport::nfcGetInfoIsoA(uint8_t* atqa, uint8_t* sak, uint8_t* uid, size_t* pUidLength)
AppNearMe 0:07fa9c0dd549 104 {
AppNearMe 0:07fa9c0dd549 105 uint8_t in[2 + 1 + 1 + 10];
AppNearMe 0:07fa9c0dd549 106 command(Transport::NFC_GET_INFO, NULL, 0, in, sizeof(in));
AppNearMe 0:07fa9c0dd549 107 memcpy(atqa, &in[0], 2);
AppNearMe 0:07fa9c0dd549 108 *sak = in[2];
AppNearMe 0:07fa9c0dd549 109 *pUidLength = in[3];
AppNearMe 0:07fa9c0dd549 110 memcpy(uid, &in[4], *pUidLength);
AppNearMe 0:07fa9c0dd549 111 }
AppNearMe 0:07fa9c0dd549 112
AppNearMe 0:07fa9c0dd549 113 void Transport::nfcGetMessageInfo(size_t* pRecordCount)
AppNearMe 0:07fa9c0dd549 114 {
AppNearMe 0:07fa9c0dd549 115 uint8_t in[2];
AppNearMe 0:07fa9c0dd549 116 command(Transport::NFC_GET_MESSAGE_INFO, NULL, 0, in, sizeof(in));
AppNearMe 0:07fa9c0dd549 117 READ_UINT16(&in[0], *pRecordCount);
AppNearMe 0:07fa9c0dd549 118 }
AppNearMe 0:07fa9c0dd549 119
AppNearMe 0:07fa9c0dd549 120 void Transport::nfcSetMessageInfo(size_t recordCount)
AppNearMe 0:07fa9c0dd549 121 {
AppNearMe 0:07fa9c0dd549 122 uint8_t out[2];
AppNearMe 0:07fa9c0dd549 123 WRITE_UINT16(&out[0], recordCount);
AppNearMe 0:07fa9c0dd549 124 command(Transport::NFC_SET_MESSAGE_INFO, out, sizeof(out), NULL, 0);
AppNearMe 0:07fa9c0dd549 125 }
AppNearMe 0:07fa9c0dd549 126
AppNearMe 0:07fa9c0dd549 127 void Transport::nfcGetRecordInfo(size_t recordNumber, uint16_t* pType, uint16_t* info, size_t infoCount)
AppNearMe 0:07fa9c0dd549 128 {
AppNearMe 0:07fa9c0dd549 129 uint8_t out[2];
AppNearMe 0:07fa9c0dd549 130 uint8_t in[2+2*infoCount];
AppNearMe 0:07fa9c0dd549 131 WRITE_UINT16(&out[0], recordNumber);
AppNearMe 0:07fa9c0dd549 132 command(Transport::NFC_GET_RECORD_INFO, out, sizeof(out), in, sizeof(in));
AppNearMe 0:07fa9c0dd549 133 READ_UINT16(&in[0], *pType);
AppNearMe 0:07fa9c0dd549 134 for(int i = 0; i < infoCount; i++)
AppNearMe 0:07fa9c0dd549 135 {
AppNearMe 0:07fa9c0dd549 136 READ_UINT16(&in[2+2*i], info[i]);
AppNearMe 0:07fa9c0dd549 137 }
AppNearMe 0:07fa9c0dd549 138 }
AppNearMe 0:07fa9c0dd549 139
AppNearMe 0:07fa9c0dd549 140 void Transport::nfcSetRecordInfo(size_t recordNumber, uint16_t type, uint16_t* info, size_t infoCount)
AppNearMe 0:07fa9c0dd549 141 {
AppNearMe 0:07fa9c0dd549 142 uint8_t out[2+2+2*infoCount];
AppNearMe 0:07fa9c0dd549 143 WRITE_UINT16(&out[0], recordNumber);
AppNearMe 0:07fa9c0dd549 144 WRITE_UINT16(&out[2], type);
AppNearMe 0:07fa9c0dd549 145 for(int i = 0; i < infoCount; i++)
AppNearMe 0:07fa9c0dd549 146 {
AppNearMe 0:07fa9c0dd549 147 WRITE_UINT16(&out[2+2+2*i], info[i]);
AppNearMe 0:07fa9c0dd549 148 }
AppNearMe 0:07fa9c0dd549 149 command(Transport::NFC_SET_RECORD_INFO, out, sizeof(out), NULL, 0);
AppNearMe 0:07fa9c0dd549 150 }
AppNearMe 0:07fa9c0dd549 151
AppNearMe 0:07fa9c0dd549 152 void Transport::nfcGetRecordData(size_t recordNumber, size_t item, size_t offset, uint8_t* data, size_t length)
AppNearMe 0:07fa9c0dd549 153 {
AppNearMe 0:07fa9c0dd549 154 uint8_t out[7];
AppNearMe 0:07fa9c0dd549 155 WRITE_UINT16(&out[0], recordNumber);
AppNearMe 0:07fa9c0dd549 156 out[2] = item;
AppNearMe 0:07fa9c0dd549 157 WRITE_UINT16(&out[3], offset);
AppNearMe 0:07fa9c0dd549 158 WRITE_UINT16(&out[5], length);
AppNearMe 0:07fa9c0dd549 159 command(Transport::NFC_GET_RECORD_DATA, out, sizeof(out), data, length);
AppNearMe 0:07fa9c0dd549 160 }
AppNearMe 0:07fa9c0dd549 161
AppNearMe 0:07fa9c0dd549 162 void Transport::nfcSetRecordData(size_t recordNumber, size_t item, size_t offset, uint8_t* data, size_t length)
AppNearMe 0:07fa9c0dd549 163 {
AppNearMe 0:07fa9c0dd549 164 uint8_t out[7+length];
AppNearMe 0:07fa9c0dd549 165 WRITE_UINT16(&out[0], recordNumber);
AppNearMe 0:07fa9c0dd549 166 out[2] = item;
AppNearMe 0:07fa9c0dd549 167 WRITE_UINT16(&out[3], offset);
AppNearMe 0:07fa9c0dd549 168 WRITE_UINT16(&out[5], length);
AppNearMe 0:07fa9c0dd549 169 memcpy(&out[7], data, length);
AppNearMe 0:07fa9c0dd549 170 command(Transport::NFC_SET_RECORD_DATA, out, sizeof(out), NULL, 0);
AppNearMe 0:07fa9c0dd549 171 }
AppNearMe 0:07fa9c0dd549 172
AppNearMe 0:07fa9c0dd549 173 void Transport::nfcPrepareMessage(bool lock, bool generate)
AppNearMe 0:07fa9c0dd549 174 {
AppNearMe 0:07fa9c0dd549 175 uint8_t out[1];
AppNearMe 0:07fa9c0dd549 176 if(lock)
AppNearMe 0:07fa9c0dd549 177 {
AppNearMe 0:07fa9c0dd549 178 out[0] = 1;
AppNearMe 0:07fa9c0dd549 179 }
AppNearMe 0:07fa9c0dd549 180 else if(generate)
AppNearMe 0:07fa9c0dd549 181 {
AppNearMe 0:07fa9c0dd549 182 out[0] = 2;
AppNearMe 0:07fa9c0dd549 183 }
AppNearMe 0:07fa9c0dd549 184 else
AppNearMe 0:07fa9c0dd549 185 {
AppNearMe 0:07fa9c0dd549 186 out[0] = 0;
AppNearMe 0:07fa9c0dd549 187 }
AppNearMe 0:07fa9c0dd549 188 command(Transport::NFC_POLL, out, sizeof(out), NULL, 0);
AppNearMe 0:07fa9c0dd549 189 }
AppNearMe 0:07fa9c0dd549 190
AppNearMe 0:07fa9c0dd549 191 void Transport::nfcDecodePrefix(uint8_t prefix, char* data, size_t* pDataLength)
AppNearMe 0:07fa9c0dd549 192 {
AppNearMe 0:07fa9c0dd549 193 uint8_t out[] = { prefix };
AppNearMe 0:07fa9c0dd549 194 uint8_t in[2 + 36]; //max prefix length is 36
AppNearMe 0:07fa9c0dd549 195 command(Transport::NFC_DECODE_PREFIX, out, sizeof(out), in, sizeof(in));
AppNearMe 0:07fa9c0dd549 196 size_t length;
AppNearMe 0:07fa9c0dd549 197 READ_UINT16(&in[0], length);
AppNearMe 0:07fa9c0dd549 198 if(length < *pDataLength)
AppNearMe 0:07fa9c0dd549 199 {
AppNearMe 0:07fa9c0dd549 200 *pDataLength = length;
AppNearMe 0:07fa9c0dd549 201 }
AppNearMe 0:07fa9c0dd549 202 memcpy(data, &in[2], *pDataLength);
AppNearMe 0:07fa9c0dd549 203 }
AppNearMe 0:07fa9c0dd549 204
AppNearMe 0:07fa9c0dd549 205 void Transport::nfcEncodePrefix(uint8_t* pPrefix, char* data, size_t dataLength)
AppNearMe 0:07fa9c0dd549 206 {
AppNearMe 0:07fa9c0dd549 207 uint8_t out[2 + dataLength];
AppNearMe 0:07fa9c0dd549 208 uint8_t in[1];
AppNearMe 0:07fa9c0dd549 209
AppNearMe 0:07fa9c0dd549 210 WRITE_UINT16(&out[0], dataLength);
AppNearMe 0:07fa9c0dd549 211 memcpy(data, &out[2], dataLength);
AppNearMe 0:07fa9c0dd549 212
AppNearMe 0:07fa9c0dd549 213 command(Transport::NFC_ENCODE_PREFIX, out, sizeof(out), in, sizeof(in));
AppNearMe 0:07fa9c0dd549 214
AppNearMe 0:07fa9c0dd549 215 *pPrefix = in[0];
AppNearMe 0:07fa9c0dd549 216 }
AppNearMe 0:07fa9c0dd549 217
AppNearMe 0:07fa9c0dd549 218 void Transport::leds(bool led1, bool led2)
AppNearMe 0:07fa9c0dd549 219 {
AppNearMe 0:07fa9c0dd549 220 uint8_t out[] = {led1?1:0, led2?1:0};
AppNearMe 0:07fa9c0dd549 221 command(Transport::LEDS, out, sizeof(out), NULL, 0);
AppNearMe 0:07fa9c0dd549 222 }
AppNearMe 0:07fa9c0dd549 223
AppNearMe 0:07fa9c0dd549 224 Transport::CommandError Transport::command(Transport::CommandCode command, uint8_t* outBuf, size_t outLength, uint8_t* inBuf, size_t inLength)
AppNearMe 0:07fa9c0dd549 225 {
AppNearMe 0:07fa9c0dd549 226 _cs = 0;
AppNearMe 0:07fa9c0dd549 227 _spi.write((uint8_t)((outLength + 1) & 0xFF));
AppNearMe 0:07fa9c0dd549 228 _cs = 1;
AppNearMe 0:07fa9c0dd549 229 _cs = 0;
AppNearMe 0:07fa9c0dd549 230 _spi.write((uint8_t)(command & 0xFF));
AppNearMe 0:07fa9c0dd549 231 _cs = 1;
AppNearMe 0:07fa9c0dd549 232 for(int i = 0; i < outLength; i++)
AppNearMe 0:07fa9c0dd549 233 {
AppNearMe 0:07fa9c0dd549 234 _cs = 0;
AppNearMe 0:07fa9c0dd549 235 _spi.write(outBuf[i]);
AppNearMe 0:07fa9c0dd549 236 _cs = 1;
AppNearMe 0:07fa9c0dd549 237 }
AppNearMe 0:07fa9c0dd549 238
AppNearMe 0:07fa9c0dd549 239 size_t length = 0;
AppNearMe 0:07fa9c0dd549 240 while(length == 0)
AppNearMe 0:07fa9c0dd549 241 {
AppNearMe 0:07fa9c0dd549 242 _cs = 0;
AppNearMe 0:07fa9c0dd549 243 length = _spi.write(0);
AppNearMe 0:07fa9c0dd549 244 _cs = 1;
AppNearMe 0:07fa9c0dd549 245 }
AppNearMe 0:07fa9c0dd549 246
AppNearMe 0:07fa9c0dd549 247 _cs = 0;
AppNearMe 0:07fa9c0dd549 248 Transport::CommandCode retCmd = (Transport::CommandCode)_spi.write(0);
AppNearMe 0:07fa9c0dd549 249 length--;
AppNearMe 0:07fa9c0dd549 250 _cs = 1;
AppNearMe 0:07fa9c0dd549 251
AppNearMe 0:07fa9c0dd549 252 _cs = 0;
AppNearMe 0:07fa9c0dd549 253 Transport::CommandError ret = (Transport::CommandError)_spi.write(0);
AppNearMe 0:07fa9c0dd549 254 length--;
AppNearMe 0:07fa9c0dd549 255 _cs = 1;
AppNearMe 0:07fa9c0dd549 256
AppNearMe 0:07fa9c0dd549 257 for(int i = 0; i < length; i++)
AppNearMe 0:07fa9c0dd549 258 {
AppNearMe 0:07fa9c0dd549 259 _cs = 0;
AppNearMe 0:07fa9c0dd549 260 if(i < inLength)
AppNearMe 0:07fa9c0dd549 261 {
AppNearMe 0:07fa9c0dd549 262 inBuf[i] = _spi.write(0);
AppNearMe 0:07fa9c0dd549 263 }
AppNearMe 0:07fa9c0dd549 264 else
AppNearMe 0:07fa9c0dd549 265 {
AppNearMe 0:07fa9c0dd549 266 _spi.write(0);
AppNearMe 0:07fa9c0dd549 267 }
AppNearMe 0:07fa9c0dd549 268 _cs = 1;
AppNearMe 0:07fa9c0dd549 269 }
AppNearMe 0:07fa9c0dd549 270
AppNearMe 0:07fa9c0dd549 271 return ret;
AppNearMe 0:07fa9c0dd549 272 }