AppNearMe / MicroNFCBoardAPI

Dependents:   MicroNFCBoardAPI_P2P_Client MicroNFCBoardAPI_Blink MicroNFCBoardAPI_Tag_Emulator MicroNFCBoardAPI_Tag_Reader ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers transport.cpp Source File

transport.cpp

00001 /*
00002 MicroNFCBoard mbed API
00003 
00004 Copyright (c) 2014-2015 AppNearMe Ltd
00005 
00006 Licensed under the Apache License, Version 2.0 (the "License");
00007 you may not use this file except in compliance with the License.
00008 You may obtain a copy of the License at
00009 
00010 http://www.apache.org/licenses/LICENSE-2.0
00011 
00012 Unless required by applicable law or agreed to in writing, software
00013 distributed under the License is distributed on an "AS IS" BASIS,
00014 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015 See the License for the specific language governing permissions and
00016 limitations under the License.
00017  */
00018 
00019 #include "transport.h"
00020 
00021 
00022 //MSB first
00023 #define WRITE_UINT32( addr, val ) do{ *(((uint8_t*)(addr)) + 0) = ((val) >> 24 ) & 0xFF; \
00024                                            *(((uint8_t*)(addr)) + 1) = ((val) >> 16 ) & 0xFF; \
00025                                            *(((uint8_t*)(addr)) + 2) = ((val) >> 8 ) & 0xFF; \
00026                                            *(((uint8_t*)(addr)) + 3) = ((val) >> 0 ) & 0xFF; } while(0)
00027 #define WRITE_UINT16( addr, val ) do{ *(((uint8_t*)(addr)) + 0) = ((val) >> 8 ) & 0xFF; \
00028                                            *(((uint8_t*)(addr)) + 1) = ((val) >> 0 ) & 0xFF; } while(0)
00029 
00030 //MSB first
00031 #define READ_UINT32( addr, val ) do{ val = (*(uint32_t*)(((uint8_t*)(addr)) + 0) << 24 ) \
00032                                               | (*(uint32_t*)(((uint8_t*)(addr)) + 1) << 16 ) \
00033                                               | (*(((uint8_t*)(addr)) + 2) << 8 ) \
00034                                               | (*(((uint8_t*)(addr)) + 3) << 0 ); } while(0)
00035 #define READ_UINT16( addr, val ) do{ val = (*(((uint8_t*)(addr)) + 0) << 8 ) \
00036                                               | (*(((uint8_t*)(addr)) + 1) << 0 ); } while(0)
00037 
00038 
00039 Transport::Transport(PinName mosi, PinName miso, PinName sck, PinName cs, PinName irq) : \
00040 _cs(cs), _spi(mosi, miso, sck), _int(irq)
00041 {
00042 }
00043 
00044 void Transport::init()
00045 {
00046   _spi.format(8, 1);
00047   _spi.frequency(100000);
00048   _cs = 1;
00049 
00050   for(int i = 0; i < 64; i++)
00051   {
00052     _cs = 0;
00053     _spi.write(0);
00054     _cs = 1;
00055   }
00056 }
00057 
00058 void Transport::reset()
00059 {
00060   uint8_t out[] = {0};
00061   command(Transport::RESET, out, sizeof(out), NULL, 0);
00062 }
00063 
00064 bool Transport::statusChanged()
00065 {
00066   return (_int.read() != 0);
00067 }
00068 
00069 uint32_t Transport::status()
00070 {
00071   uint8_t in[4];
00072   command(Transport::GET_STATUS, NULL, 0, in, sizeof(in));
00073 
00074   uint32_t status;
00075   READ_UINT32(&in[0], status);
00076   return status;
00077 }
00078 
00079 void Transport::nfcPoll(bool readerWriter, bool emulator, bool p2p)
00080 {
00081   uint8_t out[] = {(readerWriter?1:0) | (emulator?2:0) | (p2p?4:0)};
00082   command(Transport::NFC_POLL, out, sizeof(out), NULL, 0);
00083 }
00084 
00085 void Transport::nfcOperation(bool readOp, bool writeOp)
00086 {
00087   uint8_t out[1];
00088   if(readOp)
00089   {
00090     out[0] = 1;
00091   }
00092   else if(writeOp)
00093   {
00094     out[0] = 2;
00095   }
00096   else
00097   {
00098     out[0] = 0;
00099   }
00100   command(Transport::NFC_OPERATION, out, sizeof(out), NULL, 0);
00101 }
00102 
00103 void Transport::nfcGetInfoIsoA(uint8_t* atqa, uint8_t* sak, uint8_t* uid, size_t* pUidLength)
00104 {
00105   uint8_t in[2 + 1 + 1 + 10];
00106   command(Transport::NFC_GET_INFO, NULL, 0, in, sizeof(in));
00107   memcpy(atqa, &in[0], 2);
00108   *sak = in[2];
00109   *pUidLength = in[3];
00110   memcpy(uid, &in[4], *pUidLength);
00111 }
00112 
00113 void Transport::nfcGetMessageInfo(size_t* pRecordCount)
00114 {
00115   uint8_t in[2];
00116   command(Transport::NFC_GET_MESSAGE_INFO, NULL, 0, in, sizeof(in));
00117   READ_UINT16(&in[0], *pRecordCount);
00118 }
00119 
00120 void Transport::nfcSetMessageInfo(size_t recordCount)
00121 {
00122   uint8_t out[2];
00123   WRITE_UINT16(&out[0], recordCount);
00124   command(Transport::NFC_SET_MESSAGE_INFO, out, sizeof(out), NULL, 0);
00125 }
00126 
00127 void Transport::nfcGetRecordInfo(size_t recordNumber, uint16_t* pType, uint16_t* info, size_t infoCount)
00128 {
00129   uint8_t out[2];
00130   uint8_t in[2+2*infoCount];
00131   WRITE_UINT16(&out[0], recordNumber);
00132   command(Transport::NFC_GET_RECORD_INFO, out, sizeof(out), in, sizeof(in));
00133   READ_UINT16(&in[0], *pType);
00134   for(int i = 0; i < infoCount; i++)
00135   {
00136     READ_UINT16(&in[2+2*i], info[i]);
00137   }
00138 }
00139 
00140 void Transport::nfcSetRecordInfo(size_t recordNumber, uint16_t type, const uint16_t* info, size_t infoCount)
00141 {
00142   uint8_t out[2+2+2*infoCount];
00143   WRITE_UINT16(&out[0], recordNumber);
00144   WRITE_UINT16(&out[2], type);
00145   for(int i = 0; i < infoCount; i++)
00146   {
00147     WRITE_UINT16(&out[2+2+2*i], info[i]);
00148   }
00149   command(Transport::NFC_SET_RECORD_INFO, out, sizeof(out), NULL, 0);
00150 }
00151 
00152 void Transport::nfcGetRecordData(size_t recordNumber, size_t item, size_t offset, uint8_t* data, size_t length)
00153 {
00154   uint8_t out[7];
00155   WRITE_UINT16(&out[0], recordNumber);
00156   out[2] = item;
00157   WRITE_UINT16(&out[3], offset);
00158   WRITE_UINT16(&out[5], length);
00159   command(Transport::NFC_GET_RECORD_DATA, out, sizeof(out), data, length);
00160 }
00161 
00162 void Transport::nfcSetRecordData(size_t recordNumber, size_t item, size_t offset, const uint8_t* data, size_t length)
00163 {
00164   uint8_t out[7+length];
00165   WRITE_UINT16(&out[0], recordNumber);
00166   out[2] = item;
00167   WRITE_UINT16(&out[3], offset);
00168   WRITE_UINT16(&out[5], length);
00169   memcpy(&out[7], data, length);
00170   command(Transport::NFC_SET_RECORD_DATA, out, sizeof(out), NULL, 0);
00171 }
00172 
00173 void Transport::nfcPrepareMessage(bool lock, bool generate)
00174 {
00175   uint8_t out[1];
00176   if(lock)
00177   {
00178     out[0] = 1;
00179   }
00180   else if(generate)
00181   {
00182     out[0] = 2;
00183   }
00184   else
00185   {
00186     out[0] = 0;
00187   }
00188   command(Transport::NFC_PREPARE_MESSAGE, out, sizeof(out), NULL, 0);
00189 }
00190 
00191 void Transport::nfcDecodePrefix(uint8_t prefix, char* data, size_t* pDataLength)
00192 {
00193   uint8_t out[] = { prefix };
00194   uint8_t in[2 + 36]; //max prefix length is 36
00195   command(Transport::NFC_DECODE_PREFIX, out, sizeof(out), in, sizeof(in));
00196   size_t length;
00197   READ_UINT16(&in[0], length);
00198   if(length < *pDataLength)
00199   {
00200     *pDataLength = length;
00201   }
00202   memcpy(data, &in[2], *pDataLength);
00203 }
00204 
00205 void Transport::nfcEncodePrefix(uint8_t* pPrefix, const char* data, size_t* pDataLength)
00206 {
00207   uint8_t out[2 + *pDataLength];
00208   uint8_t in[3];
00209   WRITE_UINT16(&out[0], *pDataLength);
00210   memcpy(&out[2], data, *pDataLength);
00211   command(Transport::NFC_ENCODE_PREFIX, out, sizeof(out), in, sizeof(in));
00212   *pPrefix = in[0];
00213   READ_UINT16(&in[1], *pDataLength);
00214 }
00215 
00216 void Transport::leds(bool led1, bool led2)
00217 {
00218   uint8_t out[] = {led1?1:0, led2?1:0};
00219   command(Transport::LEDS, out, sizeof(out), NULL, 0);
00220 }
00221 
00222 Transport::CommandError Transport::command(Transport::CommandCode command, uint8_t* outBuf, size_t outLength, uint8_t* inBuf, size_t inLength)
00223 {
00224   _cs = 0;
00225   _spi.write((uint8_t)((outLength + 1) & 0xFF));
00226   _cs = 1;
00227   _cs = 0;
00228   _spi.write((uint8_t)(command & 0xFF));
00229   _cs = 1;
00230   for(int i = 0; i < outLength; i++)
00231   {
00232     _cs = 0;
00233     _spi.write(outBuf[i]);
00234     _cs = 1;
00235   }
00236 
00237   size_t length = 0;
00238   while(length == 0)
00239   {
00240     _cs = 0;
00241     length = _spi.write(0);
00242     _cs = 1;
00243   }
00244 
00245   _cs = 0;
00246   Transport::CommandCode retCmd = (Transport::CommandCode)_spi.write(0);
00247   length--;
00248   _cs = 1;
00249 
00250   _cs = 0;
00251   Transport::CommandError ret = (Transport::CommandError)_spi.write(0);
00252   length--;
00253   _cs = 1;
00254 
00255   for(int i = 0; i < length; i++)
00256   {
00257     _cs = 0;
00258     if(i < inLength)
00259     {
00260       inBuf[i] = _spi.write(0);
00261     }
00262     else
00263     {
00264       _spi.write(0);
00265     }
00266     _cs = 1;
00267   }
00268 
00269   return ret;
00270 }