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.
RCS620S.cpp
00001 /* 00002 * RC-S620/S sample library for Arduino 00003 * 00004 * Copyright 2010 Sony Corporation 00005 * 00006 * Rewrite for mbed 00007 * 00008 * modified by SWITCHSCIENCE 00009 * 00010 */ 00011 00012 #include <stdio.h> 00013 #include <string.h> 00014 #include <stdint.h> 00015 #include "RCS620S.h" 00016 #include "mbed.h" 00017 00018 extern Serial serial; 00019 00020 /* -------------------------------- 00021 * Constant 00022 * -------------------------------- */ 00023 00024 #define RCS620S_DEFAULT_TIMEOUT 1000 00025 00026 /* -------------------------------- 00027 * Variable 00028 * -------------------------------- */ 00029 00030 /* -------------------------------- 00031 * Prototype Declaration 00032 * -------------------------------- */ 00033 00034 /* -------------------------------- 00035 * Macro 00036 * -------------------------------- */ 00037 00038 /* -------------------------------- 00039 * Function 00040 * -------------------------------- */ 00041 00042 /* ------------------------ 00043 * public 00044 * ------------------------ */ 00045 00046 RCS620S::RCS620S() 00047 { 00048 this->timeout = RCS620S_DEFAULT_TIMEOUT; 00049 00050 } 00051 00052 int RCS620S::initDevice(void) 00053 { 00054 int ret; 00055 uint8_t response[RCS620S_MAX_RW_RESPONSE_LEN]; 00056 uint16_t responseLen; 00057 00058 /* RFConfiguration (various timings) */ 00059 ret = rwCommand((const uint8_t*)"\xd4\x32\x02\x00\x00\x00", 6, 00060 response, &responseLen); 00061 if (!ret || (responseLen != 2) || 00062 (memcmp(response, "\xd5\x33", 2) != 0)) { 00063 return 0; 00064 } 00065 00066 /* RFConfiguration (max retries) */ 00067 ret = rwCommand((const uint8_t*)"\xd4\x32\x05\x00\x00\x00", 6, 00068 response, &responseLen); 00069 if (!ret || (responseLen != 2) || 00070 (memcmp(response, "\xd5\x33", 2) != 0)) { 00071 return 0; 00072 } 00073 00074 /* RFConfiguration (additional wait time = 24ms) */ 00075 ret = rwCommand((const uint8_t*)"\xd4\x32\x81\xb7", 4, 00076 response, &responseLen); 00077 if (!ret || (responseLen != 2) || 00078 (memcmp(response, "\xd5\x33", 2) != 0)) { 00079 return 0; 00080 } 00081 00082 return 1; 00083 } 00084 00085 int RCS620S::polling(uint16_t systemCode) 00086 { 00087 int ret; 00088 uint8_t buf[9]; 00089 uint8_t response[RCS620S_MAX_RW_RESPONSE_LEN]; 00090 uint16_t responseLen; 00091 00092 /* InListPassiveTarget */ 00093 memcpy(buf, "\xd4\x4a\x01\x01\x00\xff\xff\x00\x00", 9); 00094 buf[5] = (uint8_t)((systemCode >> 8) & 0xff); 00095 buf[6] = (uint8_t)((systemCode >> 0) & 0xff); 00096 00097 ret = rwCommand(buf, 9, response, &responseLen); 00098 if (!ret || (responseLen != 22) || 00099 (memcmp(response, "\xd5\x4b\x01\x01\x12\x01", 6) != 0)) { 00100 return 0; 00101 } 00102 00103 memcpy(this->idm, response + 6, 8); 00104 memcpy(this->pmm, response + 14, 8); 00105 00106 return 1; 00107 } 00108 00109 int RCS620S::cardCommand( 00110 const uint8_t* command, 00111 uint8_t commandLen, 00112 uint8_t response[RCS620S_MAX_CARD_RESPONSE_LEN], 00113 uint8_t* responseLen) 00114 { 00115 int ret; 00116 uint16_t commandTimeout; 00117 uint8_t buf[RCS620S_MAX_RW_RESPONSE_LEN]; 00118 uint16_t len; 00119 00120 if (this->timeout >= (0x10000 / 2)) { 00121 commandTimeout = 0xffff; 00122 } else { 00123 commandTimeout = (uint16_t)(this->timeout * 2); 00124 } 00125 00126 /* CommunicateThruEX */ 00127 buf[0] = 0xd4; 00128 buf[1] = 0xa0; 00129 buf[2] = (uint8_t)((commandTimeout >> 0) & 0xff); 00130 buf[3] = (uint8_t)((commandTimeout >> 8) & 0xff); 00131 buf[4] = (uint8_t)(commandLen + 1); 00132 memcpy(buf + 5, command, commandLen); 00133 00134 ret = rwCommand(buf, 5 + commandLen, buf, &len); 00135 if (!ret || (len < 4) || 00136 (buf[0] != 0xd5) || (buf[1] != 0xa1) || (buf[2] != 0x00) || 00137 (len != (3 + buf[3]))) { 00138 return 0; 00139 } 00140 00141 *responseLen = (uint8_t)(buf[3] - 1); 00142 memcpy(response, buf + 4, *responseLen); 00143 00144 return 1; 00145 } 00146 00147 int RCS620S::rfOff(void) 00148 { 00149 int ret; 00150 uint8_t response[RCS620S_MAX_RW_RESPONSE_LEN]; 00151 uint16_t responseLen; 00152 00153 /* RFConfiguration (RF field) */ 00154 ret = rwCommand((const uint8_t*)"\xd4\x32\x01\x00", 4, 00155 response, &responseLen); 00156 if (!ret || (responseLen != 2) || 00157 (memcmp(response, "\xd5\x33", 2) != 0)) { 00158 return 0; 00159 } 00160 00161 return 1; 00162 } 00163 00164 int RCS620S::push( 00165 const uint8_t* data, 00166 uint8_t dataLen) 00167 { 00168 int ret; 00169 uint8_t buf[RCS620S_MAX_CARD_RESPONSE_LEN]; 00170 uint8_t responseLen; 00171 00172 if (dataLen > 224) { 00173 return 0; 00174 } 00175 00176 /* Push */ 00177 buf[0] = 0xb0; 00178 memcpy(buf + 1, this->idm, 8); 00179 buf[9] = dataLen; 00180 memcpy(buf + 10, data, dataLen); 00181 00182 ret = cardCommand(buf, 10 + dataLen, buf, &responseLen); 00183 if (!ret || (responseLen != 10) || (buf[0] != 0xb1) || 00184 (memcmp(buf + 1, this->idm, 8) != 0) || (buf[9] != dataLen)) { 00185 return 0; 00186 } 00187 00188 buf[0] = 0xa4; 00189 memcpy(buf + 1, this->idm, 8); 00190 buf[9] = 0x00; 00191 00192 ret = cardCommand(buf, 10, buf, &responseLen); 00193 if (!ret || (responseLen != 10) || (buf[0] != 0xa5) || 00194 (memcmp(buf + 1, this->idm, 8) != 0) || (buf[9] != 0x00)) { 00195 return 0; 00196 } 00197 00198 wait(1); 00199 return 1; 00200 } 00201 00202 /* ------------------------ 00203 * private 00204 * ------------------------ */ 00205 00206 int RCS620S::rwCommand( 00207 const uint8_t* command, 00208 uint16_t commandLen, 00209 uint8_t response[RCS620S_MAX_RW_RESPONSE_LEN], 00210 uint16_t* responseLen) 00211 { 00212 int ret; 00213 uint8_t buf[9]; 00214 00215 flushSerial(); 00216 00217 uint8_t dcs = calcDCS(command, commandLen); 00218 00219 /* transmit the command */ 00220 buf[0] = 0x00; 00221 buf[1] = 0x00; 00222 buf[2] = 0xff; 00223 if (commandLen <= 255) { 00224 /* normal frame */ 00225 buf[3] = commandLen; 00226 buf[4] = (uint8_t)-buf[3]; 00227 writeSerial(buf, 5); 00228 } else { 00229 /* extended frame */ 00230 buf[3] = 0xff; 00231 buf[4] = 0xff; 00232 buf[5] = (uint8_t)((commandLen >> 8) & 0xff); 00233 buf[6] = (uint8_t)((commandLen >> 0) & 0xff); 00234 buf[7] = (uint8_t)-(buf[5] + buf[6]); 00235 writeSerial(buf, 8); 00236 } 00237 writeSerial(command, commandLen); 00238 buf[0] = dcs; 00239 buf[1] = 0x00; 00240 writeSerial(buf, 2); 00241 00242 /* receive an ACK */ 00243 ret = readSerial(buf, 6); 00244 if (!ret || (memcmp(buf, "\x00\x00\xff\x00\xff\x00", 6) != 0)) { 00245 cancel(); 00246 return 0; 00247 } 00248 00249 /* receive a response */ 00250 ret = readSerial(buf, 5); 00251 if (!ret) { 00252 cancel(); 00253 return 0; 00254 } else if (memcmp(buf, "\x00\x00\xff", 3) != 0) { 00255 return 0; 00256 } 00257 if ((buf[3] == 0xff) && (buf[4] == 0xff)) { 00258 ret = readSerial(buf + 5, 3); 00259 if (!ret || (((buf[5] + buf[6] + buf[7]) & 0xff) != 0)) { 00260 return 0; 00261 } 00262 *responseLen = (((uint16_t)buf[5] << 8) | 00263 ((uint16_t)buf[6] << 0)); 00264 } else { 00265 if (((buf[3] + buf[4]) & 0xff) != 0) { 00266 return 0; 00267 } 00268 *responseLen = buf[3]; 00269 } 00270 if (*responseLen > RCS620S_MAX_RW_RESPONSE_LEN) { 00271 return 0; 00272 } 00273 00274 ret = readSerial(response, *responseLen); 00275 if (!ret) { 00276 cancel(); 00277 return 0; 00278 } 00279 00280 dcs = calcDCS(response, *responseLen); 00281 00282 ret = readSerial(buf, 2); 00283 if (!ret || (buf[0] != dcs) || (buf[1] != 0x00)) { 00284 cancel(); 00285 return 0; 00286 } 00287 00288 return 1; 00289 } 00290 00291 void RCS620S::cancel(void) 00292 { 00293 /* transmit an ACK */ 00294 writeSerial((const uint8_t*)"\x00\x00\xff\x00\xff\x00", 6); 00295 wait(1); 00296 flushSerial(); 00297 } 00298 00299 uint8_t RCS620S::calcDCS( 00300 const uint8_t* data, 00301 uint16_t len) 00302 { 00303 uint8_t sum = 0; 00304 00305 for (uint16_t i = 0; i < len; i++) { 00306 sum += data[i]; 00307 } 00308 00309 return (uint8_t)-(sum & 0xff); 00310 } 00311 00312 void RCS620S::writeSerial( 00313 const uint8_t* data, 00314 uint16_t len) 00315 { 00316 // Serial.write(data, len); 00317 uint16_t nwrite = 0; 00318 00319 while (nwrite < len) { 00320 serial.putc( *(data + nwrite) ); 00321 nwrite++; 00322 } 00323 } 00324 00325 00326 int RCS620S::readSerial( 00327 uint8_t* data, 00328 uint16_t len) 00329 { 00330 uint16_t nread = 0; 00331 time_t t0 = time(NULL); 00332 00333 while (nread < len) { 00334 if ((checkTimeout(t0))) { 00335 return 0; 00336 } 00337 00338 if (serial.readable() > 0) { 00339 data[nread] = serial.getc(); 00340 nread++; 00341 } 00342 } 00343 00344 return 1; 00345 } 00346 00347 00348 void RCS620S::flushSerial(void) 00349 { 00350 while( serial.readable() ); 00351 } 00352 00353 00354 int RCS620S::checkTimeout(time_t t0) 00355 { 00356 time_t t = time(NULL); 00357 00358 if ((t - t0) >= this->timeout) { 00359 return 1; 00360 } 00361 00362 return 0; 00363 }
Generated on Thu Jul 14 2022 23:56:03 by
1.7.2