It is a door opener with mbed and Felica(RFID).

Dependencies:   mbed Servo SDFileSystem

Committer:
ryought
Date:
Tue May 15 07:47:19 2012 +0000
Revision:
6:9fe8caff6142
FINAL

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ryought 6:9fe8caff6142 1 /*
ryought 6:9fe8caff6142 2 * RC-S620/S sample library for Arduino
ryought 6:9fe8caff6142 3 *
ryought 6:9fe8caff6142 4 * Copyright 2010 Sony Corporation
ryought 6:9fe8caff6142 5 *
ryought 6:9fe8caff6142 6 * Rewrite for mbed
ryought 6:9fe8caff6142 7 *
ryought 6:9fe8caff6142 8 * modified by SWITCHSCIENCE
ryought 6:9fe8caff6142 9 *
ryought 6:9fe8caff6142 10 */
ryought 6:9fe8caff6142 11
ryought 6:9fe8caff6142 12 #include <stdio.h>
ryought 6:9fe8caff6142 13 #include <string.h>
ryought 6:9fe8caff6142 14 #include <stdint.h>
ryought 6:9fe8caff6142 15 #include "RCS620S.h"
ryought 6:9fe8caff6142 16 #include "mbed.h"
ryought 6:9fe8caff6142 17
ryought 6:9fe8caff6142 18 extern Serial serial;
ryought 6:9fe8caff6142 19
ryought 6:9fe8caff6142 20 /* --------------------------------
ryought 6:9fe8caff6142 21 * Constant
ryought 6:9fe8caff6142 22 * -------------------------------- */
ryought 6:9fe8caff6142 23
ryought 6:9fe8caff6142 24 #define RCS620S_DEFAULT_TIMEOUT 1000
ryought 6:9fe8caff6142 25
ryought 6:9fe8caff6142 26 /* --------------------------------
ryought 6:9fe8caff6142 27 * Variable
ryought 6:9fe8caff6142 28 * -------------------------------- */
ryought 6:9fe8caff6142 29
ryought 6:9fe8caff6142 30 /* --------------------------------
ryought 6:9fe8caff6142 31 * Prototype Declaration
ryought 6:9fe8caff6142 32 * -------------------------------- */
ryought 6:9fe8caff6142 33
ryought 6:9fe8caff6142 34 /* --------------------------------
ryought 6:9fe8caff6142 35 * Macro
ryought 6:9fe8caff6142 36 * -------------------------------- */
ryought 6:9fe8caff6142 37
ryought 6:9fe8caff6142 38 /* --------------------------------
ryought 6:9fe8caff6142 39 * Function
ryought 6:9fe8caff6142 40 * -------------------------------- */
ryought 6:9fe8caff6142 41
ryought 6:9fe8caff6142 42 /* ------------------------
ryought 6:9fe8caff6142 43 * public
ryought 6:9fe8caff6142 44 * ------------------------ */
ryought 6:9fe8caff6142 45
ryought 6:9fe8caff6142 46 RCS620S::RCS620S()
ryought 6:9fe8caff6142 47 {
ryought 6:9fe8caff6142 48 this->timeout = RCS620S_DEFAULT_TIMEOUT;
ryought 6:9fe8caff6142 49
ryought 6:9fe8caff6142 50 }
ryought 6:9fe8caff6142 51
ryought 6:9fe8caff6142 52 int RCS620S::initDevice(void)
ryought 6:9fe8caff6142 53 {
ryought 6:9fe8caff6142 54 int ret;
ryought 6:9fe8caff6142 55 uint8_t response[RCS620S_MAX_RW_RESPONSE_LEN];
ryought 6:9fe8caff6142 56 uint16_t responseLen;
ryought 6:9fe8caff6142 57
ryought 6:9fe8caff6142 58 /* RFConfiguration (various timings) */
ryought 6:9fe8caff6142 59 ret = rwCommand((const uint8_t*)"\xd4\x32\x02\x00\x00\x00", 6,
ryought 6:9fe8caff6142 60 response, &responseLen);
ryought 6:9fe8caff6142 61 if (!ret || (responseLen != 2) ||
ryought 6:9fe8caff6142 62 (memcmp(response, "\xd5\x33", 2) != 0)) {
ryought 6:9fe8caff6142 63 return 0;
ryought 6:9fe8caff6142 64 }
ryought 6:9fe8caff6142 65
ryought 6:9fe8caff6142 66 /* RFConfiguration (max retries) */
ryought 6:9fe8caff6142 67 ret = rwCommand((const uint8_t*)"\xd4\x32\x05\x00\x00\x00", 6,
ryought 6:9fe8caff6142 68 response, &responseLen);
ryought 6:9fe8caff6142 69 if (!ret || (responseLen != 2) ||
ryought 6:9fe8caff6142 70 (memcmp(response, "\xd5\x33", 2) != 0)) {
ryought 6:9fe8caff6142 71 return 0;
ryought 6:9fe8caff6142 72 }
ryought 6:9fe8caff6142 73
ryought 6:9fe8caff6142 74 /* RFConfiguration (additional wait time = 24ms) */
ryought 6:9fe8caff6142 75 ret = rwCommand((const uint8_t*)"\xd4\x32\x81\xb7", 4,
ryought 6:9fe8caff6142 76 response, &responseLen);
ryought 6:9fe8caff6142 77 if (!ret || (responseLen != 2) ||
ryought 6:9fe8caff6142 78 (memcmp(response, "\xd5\x33", 2) != 0)) {
ryought 6:9fe8caff6142 79 return 0;
ryought 6:9fe8caff6142 80 }
ryought 6:9fe8caff6142 81
ryought 6:9fe8caff6142 82 return 1;
ryought 6:9fe8caff6142 83 }
ryought 6:9fe8caff6142 84
ryought 6:9fe8caff6142 85 int RCS620S::polling(uint16_t systemCode)
ryought 6:9fe8caff6142 86 {
ryought 6:9fe8caff6142 87 int ret;
ryought 6:9fe8caff6142 88 uint8_t buf[9];
ryought 6:9fe8caff6142 89 uint8_t response[RCS620S_MAX_RW_RESPONSE_LEN];
ryought 6:9fe8caff6142 90 uint16_t responseLen;
ryought 6:9fe8caff6142 91
ryought 6:9fe8caff6142 92 /* InListPassiveTarget */
ryought 6:9fe8caff6142 93 memcpy(buf, "\xd4\x4a\x01\x01\x00\xff\xff\x00\x00", 9);
ryought 6:9fe8caff6142 94 buf[5] = (uint8_t)((systemCode >> 8) & 0xff);
ryought 6:9fe8caff6142 95 buf[6] = (uint8_t)((systemCode >> 0) & 0xff);
ryought 6:9fe8caff6142 96
ryought 6:9fe8caff6142 97 ret = rwCommand(buf, 9, response, &responseLen);
ryought 6:9fe8caff6142 98 if (!ret || (responseLen != 22) ||
ryought 6:9fe8caff6142 99 (memcmp(response, "\xd5\x4b\x01\x01\x12\x01", 6) != 0)) {
ryought 6:9fe8caff6142 100 return 0;
ryought 6:9fe8caff6142 101 }
ryought 6:9fe8caff6142 102
ryought 6:9fe8caff6142 103 memcpy(this->idm, response + 6, 8);
ryought 6:9fe8caff6142 104 memcpy(this->pmm, response + 14, 8);
ryought 6:9fe8caff6142 105
ryought 6:9fe8caff6142 106 return 1;
ryought 6:9fe8caff6142 107 }
ryought 6:9fe8caff6142 108
ryought 6:9fe8caff6142 109 int RCS620S::cardCommand(
ryought 6:9fe8caff6142 110 const uint8_t* command,
ryought 6:9fe8caff6142 111 uint8_t commandLen,
ryought 6:9fe8caff6142 112 uint8_t response[RCS620S_MAX_CARD_RESPONSE_LEN],
ryought 6:9fe8caff6142 113 uint8_t* responseLen)
ryought 6:9fe8caff6142 114 {
ryought 6:9fe8caff6142 115 int ret;
ryought 6:9fe8caff6142 116 uint16_t commandTimeout;
ryought 6:9fe8caff6142 117 uint8_t buf[RCS620S_MAX_RW_RESPONSE_LEN];
ryought 6:9fe8caff6142 118 uint16_t len;
ryought 6:9fe8caff6142 119
ryought 6:9fe8caff6142 120 if (this->timeout >= (0x10000 / 2)) {
ryought 6:9fe8caff6142 121 commandTimeout = 0xffff;
ryought 6:9fe8caff6142 122 } else {
ryought 6:9fe8caff6142 123 commandTimeout = (uint16_t)(this->timeout * 2);
ryought 6:9fe8caff6142 124 }
ryought 6:9fe8caff6142 125
ryought 6:9fe8caff6142 126 /* CommunicateThruEX */
ryought 6:9fe8caff6142 127 buf[0] = 0xd4;
ryought 6:9fe8caff6142 128 buf[1] = 0xa0;
ryought 6:9fe8caff6142 129 buf[2] = (uint8_t)((commandTimeout >> 0) & 0xff);
ryought 6:9fe8caff6142 130 buf[3] = (uint8_t)((commandTimeout >> 8) & 0xff);
ryought 6:9fe8caff6142 131 buf[4] = (uint8_t)(commandLen + 1);
ryought 6:9fe8caff6142 132 memcpy(buf + 5, command, commandLen);
ryought 6:9fe8caff6142 133
ryought 6:9fe8caff6142 134 ret = rwCommand(buf, 5 + commandLen, buf, &len);
ryought 6:9fe8caff6142 135 if (!ret || (len < 4) ||
ryought 6:9fe8caff6142 136 (buf[0] != 0xd5) || (buf[1] != 0xa1) || (buf[2] != 0x00) ||
ryought 6:9fe8caff6142 137 (len != (3 + buf[3]))) {
ryought 6:9fe8caff6142 138 return 0;
ryought 6:9fe8caff6142 139 }
ryought 6:9fe8caff6142 140
ryought 6:9fe8caff6142 141 *responseLen = (uint8_t)(buf[3] - 1);
ryought 6:9fe8caff6142 142 memcpy(response, buf + 4, *responseLen);
ryought 6:9fe8caff6142 143
ryought 6:9fe8caff6142 144 return 1;
ryought 6:9fe8caff6142 145 }
ryought 6:9fe8caff6142 146
ryought 6:9fe8caff6142 147 int RCS620S::rfOff(void)
ryought 6:9fe8caff6142 148 {
ryought 6:9fe8caff6142 149 int ret;
ryought 6:9fe8caff6142 150 uint8_t response[RCS620S_MAX_RW_RESPONSE_LEN];
ryought 6:9fe8caff6142 151 uint16_t responseLen;
ryought 6:9fe8caff6142 152
ryought 6:9fe8caff6142 153 /* RFConfiguration (RF field) */
ryought 6:9fe8caff6142 154 ret = rwCommand((const uint8_t*)"\xd4\x32\x01\x00", 4,
ryought 6:9fe8caff6142 155 response, &responseLen);
ryought 6:9fe8caff6142 156 if (!ret || (responseLen != 2) ||
ryought 6:9fe8caff6142 157 (memcmp(response, "\xd5\x33", 2) != 0)) {
ryought 6:9fe8caff6142 158 return 0;
ryought 6:9fe8caff6142 159 }
ryought 6:9fe8caff6142 160
ryought 6:9fe8caff6142 161 return 1;
ryought 6:9fe8caff6142 162 }
ryought 6:9fe8caff6142 163
ryought 6:9fe8caff6142 164 int RCS620S::push(
ryought 6:9fe8caff6142 165 const uint8_t* data,
ryought 6:9fe8caff6142 166 uint8_t dataLen)
ryought 6:9fe8caff6142 167 {
ryought 6:9fe8caff6142 168 int ret;
ryought 6:9fe8caff6142 169 uint8_t buf[RCS620S_MAX_CARD_RESPONSE_LEN];
ryought 6:9fe8caff6142 170 uint8_t responseLen;
ryought 6:9fe8caff6142 171
ryought 6:9fe8caff6142 172 if (dataLen > 224) {
ryought 6:9fe8caff6142 173 return 0;
ryought 6:9fe8caff6142 174 }
ryought 6:9fe8caff6142 175
ryought 6:9fe8caff6142 176 /* Push */
ryought 6:9fe8caff6142 177 buf[0] = 0xb0;
ryought 6:9fe8caff6142 178 memcpy(buf + 1, this->idm, 8);
ryought 6:9fe8caff6142 179 buf[9] = dataLen;
ryought 6:9fe8caff6142 180 memcpy(buf + 10, data, dataLen);
ryought 6:9fe8caff6142 181
ryought 6:9fe8caff6142 182 ret = cardCommand(buf, 10 + dataLen, buf, &responseLen);
ryought 6:9fe8caff6142 183 if (!ret || (responseLen != 10) || (buf[0] != 0xb1) ||
ryought 6:9fe8caff6142 184 (memcmp(buf + 1, this->idm, 8) != 0) || (buf[9] != dataLen)) {
ryought 6:9fe8caff6142 185 return 0;
ryought 6:9fe8caff6142 186 }
ryought 6:9fe8caff6142 187
ryought 6:9fe8caff6142 188 buf[0] = 0xa4;
ryought 6:9fe8caff6142 189 memcpy(buf + 1, this->idm, 8);
ryought 6:9fe8caff6142 190 buf[9] = 0x00;
ryought 6:9fe8caff6142 191
ryought 6:9fe8caff6142 192 ret = cardCommand(buf, 10, buf, &responseLen);
ryought 6:9fe8caff6142 193 if (!ret || (responseLen != 10) || (buf[0] != 0xa5) ||
ryought 6:9fe8caff6142 194 (memcmp(buf + 1, this->idm, 8) != 0) || (buf[9] != 0x00)) {
ryought 6:9fe8caff6142 195 return 0;
ryought 6:9fe8caff6142 196 }
ryought 6:9fe8caff6142 197
ryought 6:9fe8caff6142 198 wait(1);
ryought 6:9fe8caff6142 199 return 1;
ryought 6:9fe8caff6142 200 }
ryought 6:9fe8caff6142 201
ryought 6:9fe8caff6142 202 /* ------------------------
ryought 6:9fe8caff6142 203 * private
ryought 6:9fe8caff6142 204 * ------------------------ */
ryought 6:9fe8caff6142 205
ryought 6:9fe8caff6142 206 int RCS620S::rwCommand(
ryought 6:9fe8caff6142 207 const uint8_t* command,
ryought 6:9fe8caff6142 208 uint16_t commandLen,
ryought 6:9fe8caff6142 209 uint8_t response[RCS620S_MAX_RW_RESPONSE_LEN],
ryought 6:9fe8caff6142 210 uint16_t* responseLen)
ryought 6:9fe8caff6142 211 {
ryought 6:9fe8caff6142 212 int ret;
ryought 6:9fe8caff6142 213 uint8_t buf[9];
ryought 6:9fe8caff6142 214
ryought 6:9fe8caff6142 215 flushSerial();
ryought 6:9fe8caff6142 216
ryought 6:9fe8caff6142 217 uint8_t dcs = calcDCS(command, commandLen);
ryought 6:9fe8caff6142 218
ryought 6:9fe8caff6142 219 /* transmit the command */
ryought 6:9fe8caff6142 220 buf[0] = 0x00;
ryought 6:9fe8caff6142 221 buf[1] = 0x00;
ryought 6:9fe8caff6142 222 buf[2] = 0xff;
ryought 6:9fe8caff6142 223 if (commandLen <= 255) {
ryought 6:9fe8caff6142 224 /* normal frame */
ryought 6:9fe8caff6142 225 buf[3] = commandLen;
ryought 6:9fe8caff6142 226 buf[4] = (uint8_t)-buf[3];
ryought 6:9fe8caff6142 227 writeSerial(buf, 5);
ryought 6:9fe8caff6142 228 } else {
ryought 6:9fe8caff6142 229 /* extended frame */
ryought 6:9fe8caff6142 230 buf[3] = 0xff;
ryought 6:9fe8caff6142 231 buf[4] = 0xff;
ryought 6:9fe8caff6142 232 buf[5] = (uint8_t)((commandLen >> 8) & 0xff);
ryought 6:9fe8caff6142 233 buf[6] = (uint8_t)((commandLen >> 0) & 0xff);
ryought 6:9fe8caff6142 234 buf[7] = (uint8_t)-(buf[5] + buf[6]);
ryought 6:9fe8caff6142 235 writeSerial(buf, 8);
ryought 6:9fe8caff6142 236 }
ryought 6:9fe8caff6142 237 writeSerial(command, commandLen);
ryought 6:9fe8caff6142 238 buf[0] = dcs;
ryought 6:9fe8caff6142 239 buf[1] = 0x00;
ryought 6:9fe8caff6142 240 writeSerial(buf, 2);
ryought 6:9fe8caff6142 241
ryought 6:9fe8caff6142 242 /* receive an ACK */
ryought 6:9fe8caff6142 243 ret = readSerial(buf, 6);
ryought 6:9fe8caff6142 244 if (!ret || (memcmp(buf, "\x00\x00\xff\x00\xff\x00", 6) != 0)) {
ryought 6:9fe8caff6142 245 cancel();
ryought 6:9fe8caff6142 246 return 0;
ryought 6:9fe8caff6142 247 }
ryought 6:9fe8caff6142 248
ryought 6:9fe8caff6142 249 /* receive a response */
ryought 6:9fe8caff6142 250 ret = readSerial(buf, 5);
ryought 6:9fe8caff6142 251 if (!ret) {
ryought 6:9fe8caff6142 252 cancel();
ryought 6:9fe8caff6142 253 return 0;
ryought 6:9fe8caff6142 254 } else if (memcmp(buf, "\x00\x00\xff", 3) != 0) {
ryought 6:9fe8caff6142 255 return 0;
ryought 6:9fe8caff6142 256 }
ryought 6:9fe8caff6142 257 if ((buf[3] == 0xff) && (buf[4] == 0xff)) {
ryought 6:9fe8caff6142 258 ret = readSerial(buf + 5, 3);
ryought 6:9fe8caff6142 259 if (!ret || (((buf[5] + buf[6] + buf[7]) & 0xff) != 0)) {
ryought 6:9fe8caff6142 260 return 0;
ryought 6:9fe8caff6142 261 }
ryought 6:9fe8caff6142 262 *responseLen = (((uint16_t)buf[5] << 8) |
ryought 6:9fe8caff6142 263 ((uint16_t)buf[6] << 0));
ryought 6:9fe8caff6142 264 } else {
ryought 6:9fe8caff6142 265 if (((buf[3] + buf[4]) & 0xff) != 0) {
ryought 6:9fe8caff6142 266 return 0;
ryought 6:9fe8caff6142 267 }
ryought 6:9fe8caff6142 268 *responseLen = buf[3];
ryought 6:9fe8caff6142 269 }
ryought 6:9fe8caff6142 270 if (*responseLen > RCS620S_MAX_RW_RESPONSE_LEN) {
ryought 6:9fe8caff6142 271 return 0;
ryought 6:9fe8caff6142 272 }
ryought 6:9fe8caff6142 273
ryought 6:9fe8caff6142 274 ret = readSerial(response, *responseLen);
ryought 6:9fe8caff6142 275 if (!ret) {
ryought 6:9fe8caff6142 276 cancel();
ryought 6:9fe8caff6142 277 return 0;
ryought 6:9fe8caff6142 278 }
ryought 6:9fe8caff6142 279
ryought 6:9fe8caff6142 280 dcs = calcDCS(response, *responseLen);
ryought 6:9fe8caff6142 281
ryought 6:9fe8caff6142 282 ret = readSerial(buf, 2);
ryought 6:9fe8caff6142 283 if (!ret || (buf[0] != dcs) || (buf[1] != 0x00)) {
ryought 6:9fe8caff6142 284 cancel();
ryought 6:9fe8caff6142 285 return 0;
ryought 6:9fe8caff6142 286 }
ryought 6:9fe8caff6142 287
ryought 6:9fe8caff6142 288 return 1;
ryought 6:9fe8caff6142 289 }
ryought 6:9fe8caff6142 290
ryought 6:9fe8caff6142 291 void RCS620S::cancel(void)
ryought 6:9fe8caff6142 292 {
ryought 6:9fe8caff6142 293 /* transmit an ACK */
ryought 6:9fe8caff6142 294 writeSerial((const uint8_t*)"\x00\x00\xff\x00\xff\x00", 6);
ryought 6:9fe8caff6142 295 wait(1);
ryought 6:9fe8caff6142 296 flushSerial();
ryought 6:9fe8caff6142 297 }
ryought 6:9fe8caff6142 298
ryought 6:9fe8caff6142 299 uint8_t RCS620S::calcDCS(
ryought 6:9fe8caff6142 300 const uint8_t* data,
ryought 6:9fe8caff6142 301 uint16_t len)
ryought 6:9fe8caff6142 302 {
ryought 6:9fe8caff6142 303 uint8_t sum = 0;
ryought 6:9fe8caff6142 304
ryought 6:9fe8caff6142 305 for (uint16_t i = 0; i < len; i++) {
ryought 6:9fe8caff6142 306 sum += data[i];
ryought 6:9fe8caff6142 307 }
ryought 6:9fe8caff6142 308
ryought 6:9fe8caff6142 309 return (uint8_t)-(sum & 0xff);
ryought 6:9fe8caff6142 310 }
ryought 6:9fe8caff6142 311
ryought 6:9fe8caff6142 312 void RCS620S::writeSerial(
ryought 6:9fe8caff6142 313 const uint8_t* data,
ryought 6:9fe8caff6142 314 uint16_t len)
ryought 6:9fe8caff6142 315 {
ryought 6:9fe8caff6142 316 // Serial.write(data, len);
ryought 6:9fe8caff6142 317 uint16_t nwrite = 0;
ryought 6:9fe8caff6142 318
ryought 6:9fe8caff6142 319 while (nwrite < len) {
ryought 6:9fe8caff6142 320 serial.putc( *(data + nwrite) );
ryought 6:9fe8caff6142 321 nwrite++;
ryought 6:9fe8caff6142 322 }
ryought 6:9fe8caff6142 323 }
ryought 6:9fe8caff6142 324
ryought 6:9fe8caff6142 325
ryought 6:9fe8caff6142 326 int RCS620S::readSerial(
ryought 6:9fe8caff6142 327 uint8_t* data,
ryought 6:9fe8caff6142 328 uint16_t len)
ryought 6:9fe8caff6142 329 {
ryought 6:9fe8caff6142 330 uint16_t nread = 0;
ryought 6:9fe8caff6142 331 time_t t0 = time(NULL);
ryought 6:9fe8caff6142 332
ryought 6:9fe8caff6142 333 while (nread < len) {
ryought 6:9fe8caff6142 334 if ((checkTimeout(t0))) {
ryought 6:9fe8caff6142 335 return 0;
ryought 6:9fe8caff6142 336 }
ryought 6:9fe8caff6142 337
ryought 6:9fe8caff6142 338 if (serial.readable() > 0) {
ryought 6:9fe8caff6142 339 data[nread] = serial.getc();
ryought 6:9fe8caff6142 340 nread++;
ryought 6:9fe8caff6142 341 }
ryought 6:9fe8caff6142 342 }
ryought 6:9fe8caff6142 343
ryought 6:9fe8caff6142 344 return 1;
ryought 6:9fe8caff6142 345 }
ryought 6:9fe8caff6142 346
ryought 6:9fe8caff6142 347
ryought 6:9fe8caff6142 348 void RCS620S::flushSerial(void)
ryought 6:9fe8caff6142 349 {
ryought 6:9fe8caff6142 350 while( serial.readable() );
ryought 6:9fe8caff6142 351 }
ryought 6:9fe8caff6142 352
ryought 6:9fe8caff6142 353
ryought 6:9fe8caff6142 354 int RCS620S::checkTimeout(time_t t0)
ryought 6:9fe8caff6142 355 {
ryought 6:9fe8caff6142 356 time_t t = time(NULL);
ryought 6:9fe8caff6142 357
ryought 6:9fe8caff6142 358 if ((t - t0) >= this->timeout) {
ryought 6:9fe8caff6142 359 return 1;
ryought 6:9fe8caff6142 360 }
ryought 6:9fe8caff6142 361
ryought 6:9fe8caff6142 362 return 0;
ryought 6:9fe8caff6142 363 }