Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: MicroNFCBoardAPI_P2P_Client MicroNFCBoardAPI_Blink MicroNFCBoardAPI_Tag_Emulator MicroNFCBoardAPI_Tag_Reader ... more
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 }
Generated on Tue Jul 12 2022 18:54:47 by
1.7.2