SONY製のNFCカードリーダ RC-S620/S をイニシエータとして使用し、NFC Type-A/Bと通信するライブラリです。FeliCaとは通信できません。(This library can't communicate with FeliCa! Only for NFC Type-A/B.)
RCS620S_AB.cpp@2:08ccf5062b69, 2020-06-13 (annotated)
- Committer:
- hmizuno
- Date:
- Sat Jun 13 01:57:30 2020 +0000
- Revision:
- 2:08ccf5062b69
- Parent:
- 1:98c4a45b646a
Add timeout retry when UART communication fails
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
hmizuno | 0:16a4197a4dfb | 1 | #include "mbed.h" |
hmizuno | 0:16a4197a4dfb | 2 | #include "RCS620S_AB.h" |
hmizuno | 0:16a4197a4dfb | 3 | |
hmizuno | 0:16a4197a4dfb | 4 | //public function |
hmizuno | 0:16a4197a4dfb | 5 | |
hmizuno | 0:16a4197a4dfb | 6 | //rc-s620 デフォルトボーレート;115200 |
hmizuno | 0:16a4197a4dfb | 7 | RCS620S_AB::RCS620S_AB(PinName tx, PinName rx): |
hmizuno | 0:16a4197a4dfb | 8 | _serial(tx, rx, 115200){ |
hmizuno | 0:16a4197a4dfb | 9 | initialize(); |
hmizuno | 0:16a4197a4dfb | 10 | }; |
hmizuno | 0:16a4197a4dfb | 11 | |
hmizuno | 0:16a4197a4dfb | 12 | /***************/ |
hmizuno | 0:16a4197a4dfb | 13 | /**** 制御系 ****/ |
hmizuno | 0:16a4197a4dfb | 14 | /***************/ |
hmizuno | 0:16a4197a4dfb | 15 | |
hmizuno | 0:16a4197a4dfb | 16 | void RCS620S_AB::powerDown(){ |
hmizuno | 0:16a4197a4dfb | 17 | sendCommand_and_RecieveRes(wired_data_RFConfiguration_PowerDown,(uint16_t)sizeof(wired_data_RFConfiguration_PowerDown)); |
hmizuno | 0:16a4197a4dfb | 18 | } |
hmizuno | 0:16a4197a4dfb | 19 | |
hmizuno | 0:16a4197a4dfb | 20 | void RCS620S_AB::wakeUp(){ |
hmizuno | 2:08ccf5062b69 | 21 | //powerdown直後に呼ばれた場合でも10ms以上確保 |
hmizuno | 2:08ccf5062b69 | 22 | wait_ms(11); |
hmizuno | 0:16a4197a4dfb | 23 | _serial.putc(0x55); |
hmizuno | 0:16a4197a4dfb | 24 | wait_ms(50); |
hmizuno | 0:16a4197a4dfb | 25 | } |
hmizuno | 0:16a4197a4dfb | 26 | |
hmizuno | 0:16a4197a4dfb | 27 | void RCS620S_AB::reset(){ |
hmizuno | 0:16a4197a4dfb | 28 | //”カードを”リセットするためにRFをOFF |
hmizuno | 0:16a4197a4dfb | 29 | sendCommand_and_RecieveRes(wired_data_RFConfiguration_RFoff,(uint16_t)sizeof(wired_data_RFConfiguration_RFoff)); |
hmizuno | 0:16a4197a4dfb | 30 | wait_ms(50); |
hmizuno | 0:16a4197a4dfb | 31 | sendCommand_and_RecieveRes(wired_data_Reset,(uint16_t)sizeof(wired_data_Reset)); |
hmizuno | 0:16a4197a4dfb | 32 | } |
hmizuno | 0:16a4197a4dfb | 33 | |
hmizuno | 0:16a4197a4dfb | 34 | /***************/ |
hmizuno | 0:16a4197a4dfb | 35 | /**** 受信系 ****/ |
hmizuno | 0:16a4197a4dfb | 36 | /***************/ |
hmizuno | 0:16a4197a4dfb | 37 | /*受信バッファ配列 要素番号カンペ (ATQB受信例) |
hmizuno | 0:16a4197a4dfb | 38 | |
hmizuno | 0:16a4197a4dfb | 39 | [11]D5 [12]4B [13]Tg [14~][CardRes] DCS |
hmizuno | 0:16a4197a4dfb | 40 | |
hmizuno | 0:16a4197a4dfb | 41 | [ 0] 00 [ 1] 00 [ 2] FF [ 3] 00 [ 4] FF [ 5] 00 ~ACK |
hmizuno | 0:16a4197a4dfb | 42 | [ 6] 00 [ 7] 00 [ 8] FF [ 9] 12 [10] EE ~LCS |
hmizuno | 0:16a4197a4dfb | 43 | [11] D5 [12] 4B [13] 01 [14] 01 [15] 50 ・・・ [LEN-2] DCS [LEN-1] 00 |
hmizuno | 0:16a4197a4dfb | 44 | ・全部ほしい場合:[0] ~ [LEN-1] |
hmizuno | 0:16a4197a4dfb | 45 | ・レスポンス部が欲しい場合:[11] ~ [LEN-3] |
hmizuno | 0:16a4197a4dfb | 46 | ・カードのデータ部が欲しい場合:[14] ~ [LEN-3] |
hmizuno | 0:16a4197a4dfb | 47 | */ |
hmizuno | 0:16a4197a4dfb | 48 | |
hmizuno | 0:16a4197a4dfb | 49 | //重要!配列要素集は0始まりのためLENと1ずれる! |
hmizuno | 0:16a4197a4dfb | 50 | |
hmizuno | 0:16a4197a4dfb | 51 | //※デバッグ用 受信バッファーのデータを全て取得(ACKやチェックサム含むすべてのデータ) |
hmizuno | 0:16a4197a4dfb | 52 | void RCS620S_AB::getAllRes(uint8_t ansArray[], int *ansLen){ |
hmizuno | 0:16a4197a4dfb | 53 | extractRes(0, recieveLEN-1 , ansArray, ansLen); |
hmizuno | 0:16a4197a4dfb | 54 | } |
hmizuno | 0:16a4197a4dfb | 55 | |
hmizuno | 0:16a4197a4dfb | 56 | //ACKやチェックサムを除いたレスポンスを取得 |
hmizuno | 0:16a4197a4dfb | 57 | void RCS620S_AB::getRes(uint8_t ansArray[], int *ansLen){ |
hmizuno | 0:16a4197a4dfb | 58 | uint8_t dataLen = checkRxData_and_getLEN(); |
hmizuno | 0:16a4197a4dfb | 59 | if(dataLen > 0){ |
hmizuno | 0:16a4197a4dfb | 60 | extractRes(11, 11+dataLen-3 , ansArray, ansLen); |
hmizuno | 0:16a4197a4dfb | 61 | }else{ |
hmizuno | 0:16a4197a4dfb | 62 | ansArray[0] = 0x00; |
hmizuno | 0:16a4197a4dfb | 63 | *ansLen = 0; |
hmizuno | 0:16a4197a4dfb | 64 | } |
hmizuno | 0:16a4197a4dfb | 65 | } |
hmizuno | 0:16a4197a4dfb | 66 | |
hmizuno | 0:16a4197a4dfb | 67 | //inListPasseveTarget 及び inDataExchangeからカード情報だけを取得 |
hmizuno | 0:16a4197a4dfb | 68 | void RCS620S_AB::getCardRes(uint8_t ansArray[], int *ansLen){ |
hmizuno | 0:16a4197a4dfb | 69 | |
hmizuno | 0:16a4197a4dfb | 70 | //inListPassiveTargetの場合 [11]D5 [12]4B [13]Tg [14~][CardRes] DCS |
hmizuno | 0:16a4197a4dfb | 71 | //inDataExchangeの場合 [11]D5 [12]41 [13]Status [14~][CardRes] DCS |
hmizuno | 0:16a4197a4dfb | 72 | //⇒共用可能 |
hmizuno | 0:16a4197a4dfb | 73 | |
hmizuno | 0:16a4197a4dfb | 74 | if(checkCardRes()){ |
hmizuno | 0:16a4197a4dfb | 75 | extractRes(14, recieveLEN-3 , ansArray, ansLen); |
hmizuno | 0:16a4197a4dfb | 76 | }else{ |
hmizuno | 0:16a4197a4dfb | 77 | ansArray[0] = 0x00; |
hmizuno | 0:16a4197a4dfb | 78 | *ansLen = 0; |
hmizuno | 0:16a4197a4dfb | 79 | } |
hmizuno | 0:16a4197a4dfb | 80 | } |
hmizuno | 0:16a4197a4dfb | 81 | |
hmizuno | 0:16a4197a4dfb | 82 | /***************/ |
hmizuno | 0:16a4197a4dfb | 83 | /**** 送信系 ****/ |
hmizuno | 0:16a4197a4dfb | 84 | /***************/ |
hmizuno | 0:16a4197a4dfb | 85 | |
hmizuno | 0:16a4197a4dfb | 86 | //ICカードのコマンドのデータパケット部を受け取り、チェックサムなどの付加情報を付与し送信 |
hmizuno | 0:16a4197a4dfb | 87 | void RCS620S_AB::sendCommand_and_RecieveRes(const uint8_t wired_packet_data[], uint16_t wired_packet_data_len){ |
hmizuno | 0:16a4197a4dfb | 88 | |
hmizuno | 0:16a4197a4dfb | 89 | //長すぎたらエラー |
hmizuno | 0:16a4197a4dfb | 90 | if(wired_packet_data_len > 252){ |
hmizuno | 0:16a4197a4dfb | 91 | exit(1); |
hmizuno | 0:16a4197a4dfb | 92 | } |
hmizuno | 0:16a4197a4dfb | 93 | |
hmizuno | 0:16a4197a4dfb | 94 | //0xD4で始まらなかったらエラー |
hmizuno | 0:16a4197a4dfb | 95 | if(wired_packet_data[0] != 0xD4){ |
hmizuno | 0:16a4197a4dfb | 96 | exit(1); |
hmizuno | 0:16a4197a4dfb | 97 | } |
hmizuno | 0:16a4197a4dfb | 98 | |
hmizuno | 0:16a4197a4dfb | 99 | //送信コマンド = 0x00 0x00 0xff LEN LCS [DATA PACKET] DCS 0x00 |
hmizuno | 0:16a4197a4dfb | 100 | |
hmizuno | 0:16a4197a4dfb | 101 | uint8_t *packet_data_command; |
hmizuno | 0:16a4197a4dfb | 102 | uint8_t LEN, LCS, DCS = 0x00; |
hmizuno | 0:16a4197a4dfb | 103 | uint32_t data_sum = 0x00000000; |
hmizuno | 0:16a4197a4dfb | 104 | |
hmizuno | 0:16a4197a4dfb | 105 | int i = 0; |
hmizuno | 0:16a4197a4dfb | 106 | |
hmizuno | 0:16a4197a4dfb | 107 | //LEN・LCSを計算 |
hmizuno | 0:16a4197a4dfb | 108 | LEN = (uint8_t)(wired_packet_data_len); //送信データの長さ |
hmizuno | 0:16a4197a4dfb | 109 | LCS = (uint8_t)(0x0100 - LEN); |
hmizuno | 0:16a4197a4dfb | 110 | |
hmizuno | 0:16a4197a4dfb | 111 | //card_command+リーダライタコマンド分のメモリを確保 |
hmizuno | 0:16a4197a4dfb | 112 | |
hmizuno | 0:16a4197a4dfb | 113 | packet_data_command = (uint8_t*)malloc(sizeof(uint8_t) * (LEN + 7)); |
hmizuno | 0:16a4197a4dfb | 114 | |
hmizuno | 0:16a4197a4dfb | 115 | |
hmizuno | 0:16a4197a4dfb | 116 | //カードリーダのコマンドを送信データに結合 |
hmizuno | 0:16a4197a4dfb | 117 | |
hmizuno | 0:16a4197a4dfb | 118 | packet_data_command[0] = 0x00; //Preamble |
hmizuno | 0:16a4197a4dfb | 119 | packet_data_command[1] = 0x00; //Start Of Packet_1 |
hmizuno | 0:16a4197a4dfb | 120 | packet_data_command[2] = 0xff; //Start Of Packet_2 |
hmizuno | 0:16a4197a4dfb | 121 | |
hmizuno | 0:16a4197a4dfb | 122 | packet_data_command[3] = LEN; //LEN |
hmizuno | 0:16a4197a4dfb | 123 | packet_data_command[4] = LCS; //LCS |
hmizuno | 0:16a4197a4dfb | 124 | |
hmizuno | 0:16a4197a4dfb | 125 | //パケットデータを流し込む |
hmizuno | 0:16a4197a4dfb | 126 | for(i = 0; i < LEN; i++){ |
hmizuno | 0:16a4197a4dfb | 127 | packet_data_command[i + 5] = wired_packet_data[i]; //DATA |
hmizuno | 0:16a4197a4dfb | 128 | data_sum = data_sum + wired_packet_data[i]; //DCS計算用 |
hmizuno | 0:16a4197a4dfb | 129 | } |
hmizuno | 0:16a4197a4dfb | 130 | |
hmizuno | 0:16a4197a4dfb | 131 | //DCSを計算 |
hmizuno | 0:16a4197a4dfb | 132 | DCS = (uint8_t)(0x100 - (data_sum % 0x100)); |
hmizuno | 0:16a4197a4dfb | 133 | |
hmizuno | 0:16a4197a4dfb | 134 | packet_data_command[5 + LEN] = DCS; //DCS |
hmizuno | 0:16a4197a4dfb | 135 | packet_data_command[5 + LEN + 1] = 0x00; //Postamble |
hmizuno | 0:16a4197a4dfb | 136 | |
hmizuno | 0:16a4197a4dfb | 137 | //レスポンスバッファをクリア |
hmizuno | 0:16a4197a4dfb | 138 | clearRecieveBuffer(); |
hmizuno | 0:16a4197a4dfb | 139 | |
hmizuno | 0:16a4197a4dfb | 140 | //コマンドを送信 |
hmizuno | 2:08ccf5062b69 | 141 | //busy中に送り付けてしまっても自動リトライするよう改良 20/6/11 |
hmizuno | 2:08ccf5062b69 | 142 | //ACK応答が返ってくるまでコマンドを送り付ける |
hmizuno | 2:08ccf5062b69 | 143 | //ただし配線が外れてたら無限ループ |
hmizuno | 2:08ccf5062b69 | 144 | do{ |
hmizuno | 2:08ccf5062b69 | 145 | for(i = 0; i <= (5 + LEN + 1); i++){ |
hmizuno | 2:08ccf5062b69 | 146 | _serial.putc(packet_data_command[i]); |
hmizuno | 2:08ccf5062b69 | 147 | } |
hmizuno | 2:08ccf5062b69 | 148 | }while(!isACKrecieved(UART_TRANSMIT_FAIL_TIMEOUT_MS)); |
hmizuno | 0:16a4197a4dfb | 149 | |
hmizuno | 0:16a4197a4dfb | 150 | //powerdownの時はレスポンスが返ってこないので受信待機が無限ループに入ってしまう |
hmizuno | 0:16a4197a4dfb | 151 | //powerdown時はACKのみチェックする |
hmizuno | 0:16a4197a4dfb | 152 | //コマンドリファレンス39ページ『ただしACKは返します』 |
hmizuno | 0:16a4197a4dfb | 153 | if(wired_packet_data[1] != wired_data_RFConfiguration_PowerDown[1]){ |
hmizuno | 0:16a4197a4dfb | 154 | //レスポンス受信完了まで待機 |
hmizuno | 0:16a4197a4dfb | 155 | waitWhileRead(5); |
hmizuno | 0:16a4197a4dfb | 156 | }else{ |
hmizuno | 0:16a4197a4dfb | 157 | do{ |
hmizuno | 0:16a4197a4dfb | 158 | wait_ms(1); |
hmizuno | 1:98c4a45b646a | 159 | }while(recieveLEN < sizeof(wired_complete_ACK)); |
hmizuno | 0:16a4197a4dfb | 160 | } |
hmizuno | 0:16a4197a4dfb | 161 | |
hmizuno | 0:16a4197a4dfb | 162 | //メモリをfree |
hmizuno | 0:16a4197a4dfb | 163 | free(packet_data_command); |
hmizuno | 0:16a4197a4dfb | 164 | } |
hmizuno | 0:16a4197a4dfb | 165 | |
hmizuno | 0:16a4197a4dfb | 166 | |
hmizuno | 0:16a4197a4dfb | 167 | //ICカードのコマンドを、リーダライタのInDataExchangeを使ってICカードへ送信する関数 |
hmizuno | 0:16a4197a4dfb | 168 | void RCS620S_AB::sendInDataExchange_and_RecieveRes(const uint8_t card_command[], uint16_t card_command_len){ |
hmizuno | 0:16a4197a4dfb | 169 | |
hmizuno | 0:16a4197a4dfb | 170 | //card_command+リーダライタコマンド分のメモリを確保 |
hmizuno | 0:16a4197a4dfb | 171 | uint8_t *packet_command; |
hmizuno | 0:16a4197a4dfb | 172 | packet_command = (uint8_t*)malloc(sizeof(uint8_t) * (card_command_len + 3)); |
hmizuno | 0:16a4197a4dfb | 173 | |
hmizuno | 0:16a4197a4dfb | 174 | //無線コマンドの前にInDataExchange有線コマンド結合 |
hmizuno | 0:16a4197a4dfb | 175 | packet_command[0] = 0xD4; //コマンドコード |
hmizuno | 0:16a4197a4dfb | 176 | packet_command[1] = 0x40; //サブコマンドコード |
hmizuno | 0:16a4197a4dfb | 177 | packet_command[2] = 0x01; //Tg(InListPassiveTargetであらかじめ1枚に指定) |
hmizuno | 0:16a4197a4dfb | 178 | |
hmizuno | 0:16a4197a4dfb | 179 | for(int i = 0; i < card_command_len ; i++){ |
hmizuno | 0:16a4197a4dfb | 180 | packet_command[i + 3] = card_command[i]; |
hmizuno | 0:16a4197a4dfb | 181 | } |
hmizuno | 0:16a4197a4dfb | 182 | |
hmizuno | 0:16a4197a4dfb | 183 | //カードリーダへ送信 |
hmizuno | 0:16a4197a4dfb | 184 | sendCommand_and_RecieveRes(packet_command, (card_command_len + 3)); |
hmizuno | 0:16a4197a4dfb | 185 | |
hmizuno | 0:16a4197a4dfb | 186 | //メモリをfree |
hmizuno | 0:16a4197a4dfb | 187 | free(packet_command); |
hmizuno | 0:16a4197a4dfb | 188 | } |
hmizuno | 0:16a4197a4dfb | 189 | |
hmizuno | 0:16a4197a4dfb | 190 | |
hmizuno | 0:16a4197a4dfb | 191 | void RCS620S_AB::sendInListPasseveTarget_typeA(){ |
hmizuno | 0:16a4197a4dfb | 192 | sendCommand_and_RecieveRes(wired_data_InListPassiveTarget_typeA,(uint16_t)sizeof(wired_data_InListPassiveTarget_typeA)); |
hmizuno | 0:16a4197a4dfb | 193 | } |
hmizuno | 0:16a4197a4dfb | 194 | |
hmizuno | 0:16a4197a4dfb | 195 | void RCS620S_AB::sendInListPassiveTarget_typeB(){ |
hmizuno | 0:16a4197a4dfb | 196 | sendCommand_and_RecieveRes(wired_data_InListPassiveTarget_typeB,(uint16_t)sizeof(wired_data_InListPassiveTarget_typeB)); |
hmizuno | 0:16a4197a4dfb | 197 | } |
hmizuno | 0:16a4197a4dfb | 198 | |
hmizuno | 0:16a4197a4dfb | 199 | //private functioin |
hmizuno | 0:16a4197a4dfb | 200 | |
hmizuno | 0:16a4197a4dfb | 201 | /***************/ |
hmizuno | 0:16a4197a4dfb | 202 | /**** 制御系 ****/ |
hmizuno | 0:16a4197a4dfb | 203 | /***************/ |
hmizuno | 0:16a4197a4dfb | 204 | |
hmizuno | 0:16a4197a4dfb | 205 | void RCS620S_AB::initialize(){ |
hmizuno | 0:16a4197a4dfb | 206 | //UART受信割り込み設定 |
hmizuno | 0:16a4197a4dfb | 207 | _serial.attach(callback(this,&RCS620S_AB::serialRxIrq), Serial::RxIrq); |
hmizuno | 0:16a4197a4dfb | 208 | sendCommand_and_RecieveRes(wired_data_AdditionalTime24ms,(uint16_t)sizeof(wired_data_AdditionalTime24ms)); |
hmizuno | 0:16a4197a4dfb | 209 | } |
hmizuno | 0:16a4197a4dfb | 210 | |
hmizuno | 0:16a4197a4dfb | 211 | /***************/ |
hmizuno | 0:16a4197a4dfb | 212 | /**** 受信系 ****/ |
hmizuno | 0:16a4197a4dfb | 213 | /***************/ |
hmizuno | 0:16a4197a4dfb | 214 | |
hmizuno | 0:16a4197a4dfb | 215 | //カードリーダ UART受信割込み |
hmizuno | 0:16a4197a4dfb | 216 | //※この関数のなかでデバッグ用printf使用不可(処理中に取りこぼす) |
hmizuno | 0:16a4197a4dfb | 217 | void RCS620S_AB::serialRxIrq(){ |
hmizuno | 0:16a4197a4dfb | 218 | recieveBuffer[recieveLEN] = (uint8_t)_serial.getc(); //0 |
hmizuno | 0:16a4197a4dfb | 219 | recieveLEN++; //1 LEN = 配列番号+1 になりOK |
hmizuno | 0:16a4197a4dfb | 220 | if(recieveLEN >= READ_BUF_SIZE){ |
hmizuno | 0:16a4197a4dfb | 221 | exit(1); |
hmizuno | 0:16a4197a4dfb | 222 | } |
hmizuno | 0:16a4197a4dfb | 223 | } |
hmizuno | 0:16a4197a4dfb | 224 | |
hmizuno | 0:16a4197a4dfb | 225 | void RCS620S_AB::clearRecieveBuffer(){ |
hmizuno | 0:16a4197a4dfb | 226 | //受信バッファカーソル位置を先頭に |
hmizuno | 0:16a4197a4dfb | 227 | recieveLEN = 0; |
hmizuno | 0:16a4197a4dfb | 228 | |
hmizuno | 0:16a4197a4dfb | 229 | //受信バッファをクリア |
hmizuno | 0:16a4197a4dfb | 230 | for(int i = 0; i < READ_BUF_SIZE; i++){ |
hmizuno | 0:16a4197a4dfb | 231 | recieveBuffer[i] = 0x00; |
hmizuno | 0:16a4197a4dfb | 232 | } |
hmizuno | 0:16a4197a4dfb | 233 | } |
hmizuno | 0:16a4197a4dfb | 234 | |
hmizuno | 2:08ccf5062b69 | 235 | //ACK受信待ち |
hmizuno | 2:08ccf5062b69 | 236 | bool RCS620S_AB::isACKrecieved(int timeout_ms){ |
hmizuno | 2:08ccf5062b69 | 237 | int elapsedTime = 0; |
hmizuno | 2:08ccf5062b69 | 238 | do{ |
hmizuno | 2:08ccf5062b69 | 239 | wait_ms(1); |
hmizuno | 2:08ccf5062b69 | 240 | elapsedTime++; |
hmizuno | 2:08ccf5062b69 | 241 | if(elapsedTime > timeout_ms){ |
hmizuno | 2:08ccf5062b69 | 242 | return false; |
hmizuno | 2:08ccf5062b69 | 243 | } |
hmizuno | 2:08ccf5062b69 | 244 | }while(recieveLEN < sizeof(wired_complete_ACK)); |
hmizuno | 2:08ccf5062b69 | 245 | return true; |
hmizuno | 2:08ccf5062b69 | 246 | } |
hmizuno | 2:08ccf5062b69 | 247 | |
hmizuno | 0:16a4197a4dfb | 248 | //読み取り完了まで待機 |
hmizuno | 0:16a4197a4dfb | 249 | //ACK受信後、一定時間経過しても受信文字数が増えなくなる(=RX割り込みがかからない=受信完了)まで待機 |
hmizuno | 0:16a4197a4dfb | 250 | void RCS620S_AB::waitWhileRead(int cycleTime_ms){ |
hmizuno | 0:16a4197a4dfb | 251 | |
hmizuno | 0:16a4197a4dfb | 252 | int cTime; |
hmizuno | 0:16a4197a4dfb | 253 | if(cycleTime_ms >= 1){ |
hmizuno | 0:16a4197a4dfb | 254 | cTime = cycleTime_ms; |
hmizuno | 0:16a4197a4dfb | 255 | }else{ |
hmizuno | 0:16a4197a4dfb | 256 | cTime = 1; |
hmizuno | 0:16a4197a4dfb | 257 | } |
hmizuno | 0:16a4197a4dfb | 258 | |
hmizuno | 0:16a4197a4dfb | 259 | //ackはmax3.5ms |
hmizuno | 0:16a4197a4dfb | 260 | int l; |
hmizuno | 0:16a4197a4dfb | 261 | do{ |
hmizuno | 0:16a4197a4dfb | 262 | l = recieveLEN; //現在の受信文字数 |
hmizuno | 0:16a4197a4dfb | 263 | wait_ms(cTime); |
hmizuno | 0:16a4197a4dfb | 264 | }while(recieveLEN <= sizeof(wired_complete_ACK) || l < recieveLEN);//一定時間後の受信文字数と比較 |
hmizuno | 0:16a4197a4dfb | 265 | } |
hmizuno | 0:16a4197a4dfb | 266 | |
hmizuno | 0:16a4197a4dfb | 267 | //受信バッファからrecieveBuffer[start] ~ recieveBuffer[end] を抜き出す |
hmizuno | 0:16a4197a4dfb | 268 | void RCS620S_AB::extractRes(int start, int end, uint8_t ansArray[], int *ansLen){ |
hmizuno | 0:16a4197a4dfb | 269 | if(end > recieveLEN || start > end){ |
hmizuno | 0:16a4197a4dfb | 270 | *ansLen = 0; |
hmizuno | 0:16a4197a4dfb | 271 | }else{ |
hmizuno | 0:16a4197a4dfb | 272 | int j = 0; |
hmizuno | 0:16a4197a4dfb | 273 | for(int i = start; i <= end; i++){ |
hmizuno | 0:16a4197a4dfb | 274 | ansArray[j] = recieveBuffer[i]; |
hmizuno | 0:16a4197a4dfb | 275 | j++; |
hmizuno | 0:16a4197a4dfb | 276 | } |
hmizuno | 0:16a4197a4dfb | 277 | *ansLen = end - start + 1; |
hmizuno | 0:16a4197a4dfb | 278 | } |
hmizuno | 0:16a4197a4dfb | 279 | } |
hmizuno | 0:16a4197a4dfb | 280 | |
hmizuno | 0:16a4197a4dfb | 281 | /***************/ |
hmizuno | 0:16a4197a4dfb | 282 | /**** 検査系 ****/ |
hmizuno | 0:16a4197a4dfb | 283 | /***************/ |
hmizuno | 0:16a4197a4dfb | 284 | |
hmizuno | 0:16a4197a4dfb | 285 | //頭についているACKが仕様書記載通りのデータになっているか確認 |
hmizuno | 0:16a4197a4dfb | 286 | bool RCS620S_AB::checkACK(){ |
hmizuno | 0:16a4197a4dfb | 287 | bool flag = true; |
hmizuno | 0:16a4197a4dfb | 288 | for(int i = 0; i<sizeof(wired_complete_ACK); i++){ |
hmizuno | 0:16a4197a4dfb | 289 | if(wired_complete_ACK[i] != recieveBuffer[i]){ |
hmizuno | 0:16a4197a4dfb | 290 | flag = false; |
hmizuno | 0:16a4197a4dfb | 291 | } |
hmizuno | 0:16a4197a4dfb | 292 | } |
hmizuno | 0:16a4197a4dfb | 293 | return flag; |
hmizuno | 0:16a4197a4dfb | 294 | } |
hmizuno | 0:16a4197a4dfb | 295 | |
hmizuno | 0:16a4197a4dfb | 296 | |
hmizuno | 0:16a4197a4dfb | 297 | bool RCS620S_AB::checkCardRes(){ |
hmizuno | 0:16a4197a4dfb | 298 | //inListPassiveTargetの場合 D5 4B Tg [CardRes] DCS |
hmizuno | 0:16a4197a4dfb | 299 | //inDataExchangeの場合 D5 41 Status [CardRes] DCS |
hmizuno | 0:16a4197a4dfb | 300 | |
hmizuno | 0:16a4197a4dfb | 301 | //そもそも受信できてなければエラー |
hmizuno | 0:16a4197a4dfb | 302 | if(checkRxData_and_getLEN() < 1){ |
hmizuno | 0:16a4197a4dfb | 303 | return false; |
hmizuno | 0:16a4197a4dfb | 304 | } |
hmizuno | 0:16a4197a4dfb | 305 | |
hmizuno | 0:16a4197a4dfb | 306 | //使う頻度が多いinDataExchangeを先に評価 |
hmizuno | 0:16a4197a4dfb | 307 | if(recieveBuffer[12] == 0x41 && recieveBuffer[13] == 0x00){ |
hmizuno | 0:16a4197a4dfb | 308 | //inListpassiveTargetレスポンス(0x41)ならばターゲットidが0x01かチェック |
hmizuno | 0:16a4197a4dfb | 309 | return true; |
hmizuno | 0:16a4197a4dfb | 310 | }else if(recieveBuffer[12] == 0x4B && recieveBuffer[13] == 0x01){ |
hmizuno | 0:16a4197a4dfb | 311 | //inListpassiveTargetレスポンス(0x4B)ならばターゲットidが0x01かチェック |
hmizuno | 0:16a4197a4dfb | 312 | return true; |
hmizuno | 0:16a4197a4dfb | 313 | }else{ |
hmizuno | 0:16a4197a4dfb | 314 | return false; |
hmizuno | 0:16a4197a4dfb | 315 | } |
hmizuno | 0:16a4197a4dfb | 316 | } |
hmizuno | 0:16a4197a4dfb | 317 | |
hmizuno | 0:16a4197a4dfb | 318 | |
hmizuno | 0:16a4197a4dfb | 319 | //受信データをチェックしてOKならLENを返す、異常なら0を返す |
hmizuno | 0:16a4197a4dfb | 320 | uint8_t RCS620S_AB::checkRxData_and_getLEN(){ |
hmizuno | 0:16a4197a4dfb | 321 | |
hmizuno | 0:16a4197a4dfb | 322 | //頭にACKが付いているかチェック |
hmizuno | 0:16a4197a4dfb | 323 | if(!checkACK()){ |
hmizuno | 0:16a4197a4dfb | 324 | return 0; |
hmizuno | 0:16a4197a4dfb | 325 | } |
hmizuno | 0:16a4197a4dfb | 326 | |
hmizuno | 0:16a4197a4dfb | 327 | //LEN+LCSをチェックしてLENを取得 |
hmizuno | 0:16a4197a4dfb | 328 | uint8_t data_len = 0; |
hmizuno | 0:16a4197a4dfb | 329 | |
hmizuno | 0:16a4197a4dfb | 330 | uint8_t recieved_LEN_check = (uint8_t)(0x00ff & (recieveBuffer[9]+recieveBuffer[10])); |
hmizuno | 0:16a4197a4dfb | 331 | if(recieved_LEN_check == 0x00 && recieveBuffer[9] > 0x00){ |
hmizuno | 0:16a4197a4dfb | 332 | data_len = recieveBuffer[9]; |
hmizuno | 0:16a4197a4dfb | 333 | }else{ |
hmizuno | 0:16a4197a4dfb | 334 | //LEN受信エラー |
hmizuno | 0:16a4197a4dfb | 335 | return 0; |
hmizuno | 0:16a4197a4dfb | 336 | } |
hmizuno | 0:16a4197a4dfb | 337 | |
hmizuno | 0:16a4197a4dfb | 338 | //レスポンスコードをチェック |
hmizuno | 0:16a4197a4dfb | 339 | if(recieveBuffer[11] != 0xD5){ |
hmizuno | 0:16a4197a4dfb | 340 | //レスポンスコードが 0xD5 でない |
hmizuno | 0:16a4197a4dfb | 341 | return 0; |
hmizuno | 0:16a4197a4dfb | 342 | } |
hmizuno | 0:16a4197a4dfb | 343 | |
hmizuno | 0:16a4197a4dfb | 344 | //DCSをチェック |
hmizuno | 0:16a4197a4dfb | 345 | uint32_t data_sum = 0x00000000; |
hmizuno | 0:16a4197a4dfb | 346 | for(int i = 11; i < 11 + data_len; i++){ |
hmizuno | 0:16a4197a4dfb | 347 | data_sum = data_sum + recieveBuffer[i]; |
hmizuno | 0:16a4197a4dfb | 348 | } |
hmizuno | 0:16a4197a4dfb | 349 | data_sum = 0x000000FF & data_sum; |
hmizuno | 0:16a4197a4dfb | 350 | //データ合計にDCSを足す |
hmizuno | 0:16a4197a4dfb | 351 | data_sum = data_sum + recieveBuffer[11 + data_len]; |
hmizuno | 0:16a4197a4dfb | 352 | |
hmizuno | 0:16a4197a4dfb | 353 | if(data_sum == 0x100){ |
hmizuno | 0:16a4197a4dfb | 354 | //LENを返す |
hmizuno | 0:16a4197a4dfb | 355 | return data_len; |
hmizuno | 0:16a4197a4dfb | 356 | }else{ |
hmizuno | 0:16a4197a4dfb | 357 | //データ受信エラー |
hmizuno | 0:16a4197a4dfb | 358 | return 0; |
hmizuno | 0:16a4197a4dfb | 359 | } |
hmizuno | 0:16a4197a4dfb | 360 | } |