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