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.
pn512_poll.c
00001 /* 00002 * Copyright (c) 2014-2018, ARM Limited, All Rights Reserved 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00006 * not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 /** 00018 * \file pn512_poll.c 00019 * \copyright Copyright (c) ARM Ltd 2014 00020 * \author Donatien Garnier 00021 */ 00022 00023 #define __DEBUG__ 0 00024 #ifndef __MODULE__ 00025 #define __MODULE__ "pn512_poll.c" 00026 #endif 00027 00028 #include "stack/nfc_errors.h" 00029 00030 #include "pn512.h" 00031 #include "pn512_poll.h" 00032 #include "pn512_transceive.h" 00033 #include "pn512_registers.h" 00034 #include "pn512_rf.h" 00035 #include "pn512_cmd.h" 00036 #include "pn512_internal.h" 00037 00038 #define TIMEOUT 1000 00039 00040 static void pn512_target_anticollision(pn512_t *pPN512, pn512_cb_t cb); 00041 static void pn512_initiator_isoa_anticollision(pn512_t *pPN512, pn512_cb_t cb); 00042 00043 static inline bool pn512_config_initiator(pn512_t *pPN512) 00044 { 00045 return (pPN512->config.initiators.nfc_iso_dep_a | pPN512->config.initiators.nfc_iso_dep_b | 00046 pPN512->config.initiators.nfc_nfc_dep_a | pPN512->config.initiators.nfc_nfc_dep_f_212 | pPN512->config.initiators.nfc_nfc_dep_f_424 | 00047 pPN512->config.initiators.nfc_type1 | pPN512->config.initiators.nfc_type2 | pPN512->config.initiators.nfc_type3) != 0; 00048 } 00049 00050 static inline bool pn512_config_target(pn512_t *pPN512) 00051 { 00052 return (pPN512->config.targets.nfc_iso_dep_a | pPN512->config.targets.nfc_iso_dep_b | 00053 pPN512->config.targets.nfc_nfc_dep_a | pPN512->config.targets.nfc_nfc_dep_f_212 | pPN512->config.initiators.nfc_nfc_dep_f_424 | 00054 pPN512->config.targets.nfc_type1 | pPN512->config.targets.nfc_type2 | pPN512->config.targets.nfc_type3) != 0; 00055 } 00056 00057 void pn512_target_anticollision_complete(pn512_t *pPN512, nfc_err_t ret) 00058 { 00059 00060 bool iso14443a = pPN512->config.targets.nfc_type2 || pPN512->config.targets.nfc_iso_dep_a || pPN512->config.targets.nfc_nfc_dep_a; //We do not support type 1 card emulation so irrelevant 00061 bool felica = pPN512->config.targets.nfc_type3 || pPN512->config.targets.nfc_nfc_dep_f_212 || pPN512->config.targets.nfc_nfc_dep_f_424; 00062 00063 nfc_transceiver_t *pTransceiver = &pPN512->transceiver; 00064 if (ret) { 00065 NFC_WARN("Returned %d", ret); 00066 pn512_anticollision_callback(pPN512, ret); 00067 return; 00068 } 00069 00070 //Data available in FIFO 00071 if (pPN512->readLastByteLength != 8) { //We should receive a full byte 00072 NFC_WARN("Not enough data in FIFO"); 00073 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00074 return; 00075 } 00076 00077 //If successful, update state machine 00078 if (iso14443a && felica) { 00079 //Update current protocol accordingly 00080 uint8_t txmode = pn512_register_read(pPN512, PN512_REG_TXMODE); 00081 if ((txmode & 0x03) == 0x00) { 00082 pn512_framing_set(pPN512, nfc_framing_target_a_106); 00083 00084 NFC_DBG("A 106"); 00085 felica = false; 00086 } else if ((txmode & 0x03) == 0x02) { 00087 if ((txmode & 0x70) == 0x20) { 00088 //424kbps 00089 NFC_DBG("F 424"); 00090 pn512_framing_set(pPN512, nfc_framing_target_f_424); 00091 } else { 00092 //212kbps 00093 NFC_DBG("F 212"); 00094 pn512_framing_set(pPN512, nfc_framing_target_f_212); 00095 } 00096 iso14443a = false; 00097 } else { 00098 //Unsupported mode, exit 00099 pn512_anticollision_callback(pPN512, NFC_ERR_UNSUPPORTED); 00100 return; 00101 } 00102 } 00103 00104 if (iso14443a) { 00105 if (ac_buffer_reader_readable(ac_buffer_builder_buffer(&pPN512->readBufBldr)) == 0) { 00106 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00107 return; 00108 } 00109 00110 //Halt device, so that if anticollision is restarted it's in the correct state (cleared automatically by RF reset) 00111 pn512_register_write(pPN512, PN512_REG_MIFNFC, 0x62 | 0x04); 00112 00113 //Copy buffer to peek 00114 ac_buffer_t readBufDup; 00115 ac_buffer_dup(&readBufDup, ac_buffer_builder_buffer(&pPN512->readBufBldr)); 00116 00117 uint8_t b0 = ac_buffer_read_nu8(&readBufDup); 00118 00119 //Get first byte 00120 //Read FIFO to see if the target was selected as NFC-DEP, ISO-DEP or proprietary (NFC Type 2) 00121 //F0 --> NFC-DEP 00122 //E0 --> ISO-DEP 00123 //Anything else --> NFC Type 2 00124 00125 //First check if this could be NFC-DEP 00126 if (pPN512->config.targets.nfc_nfc_dep_a && (b0 == 0xF0)) { 00127 pTransceiver->active_tech.nfc_nfc_dep_a = true; 00128 } else if (pPN512->config.targets.nfc_iso_dep_a && (b0 == 0xE0)) { 00129 pTransceiver->active_tech.nfc_iso_dep_a = true; 00130 } else if (pPN512->config.targets.nfc_type2) { 00131 pTransceiver->active_tech.nfc_type2 = true; 00132 } else { 00133 //Unknown tech, return error 00134 pn512_anticollision_callback(pPN512, NFC_ERR_UNSUPPORTED); 00135 return; 00136 } 00137 00138 //Give control to higher layer 00139 pn512_anticollision_callback(pPN512, NFC_OK); 00140 return; 00141 } else if (felica) { 00142 //First check if this could be NFC-DEP 00143 if ((pPN512->config.targets.nfc_nfc_dep_f_212 || pPN512->config.targets.nfc_nfc_dep_f_424)) { 00144 if (pPN512->framing == nfc_framing_target_f_424) { 00145 pTransceiver->active_tech.nfc_nfc_dep_f_424 = true; 00146 } else { 00147 pTransceiver->active_tech.nfc_nfc_dep_f_212 = true; 00148 } 00149 } else { 00150 pn512_anticollision_callback(pPN512, NFC_ERR_UNSUPPORTED); 00151 return; 00152 } 00153 } 00154 00155 //NFC-IP 1 active mode is not supported by other devices so ignore it for now 00156 pn512_anticollision_callback(pPN512, NFC_OK); 00157 } 00158 00159 00160 void pn512_target_anticollision(pn512_t *pPN512, pn512_cb_t cb) 00161 { 00162 pPN512->anticollision.cb = cb; 00163 00164 //Reset active states 00165 pPN512->transceiver.initiator_ntarget = false; 00166 pPN512->transceiver.active_tech.nfc_type1 = pPN512->transceiver.active_tech.nfc_type2 = pPN512->transceiver.active_tech.nfc_type3 00167 = pPN512->transceiver.active_tech.nfc_iso_dep_a = pPN512->transceiver.active_tech.nfc_nfc_dep_a = 00168 pPN512->transceiver.active_tech.nfc_nfc_dep_f_212 = pPN512->transceiver.active_tech.nfc_nfc_dep_f_424 = 0; 00169 00170 pn512_set_timeout((nfc_transceiver_t *)pPN512, -1); //Should only fail on RF drop 00171 00172 pn512_transceive_hw(pPN512, pn512_transceive_mode_target_autocoll, pn512_target_anticollision_complete); 00173 } 00174 00175 // ISO A 00176 00177 #define ISO14443A_BUF_SIZE 8 00178 00179 #define REQA 0x26 00180 #define SEL(n) (0x93 + (n)*2) 00181 #define NVB(bits) ( (((2*8 + (bits))>>3)<<4) | ((bits) & 0x7) ) 00182 #define HALTA1 0x50 00183 #define HALTA2 0x00 00184 #define CT 0x88 00185 00186 static void pn512_initiator_isoa_anticollision_reqa(pn512_t *pPN512); 00187 static void pn512_initiator_isoa_anticollision_atqa(pn512_t *pPN512, nfc_err_t ret); 00188 static void pn512_initiator_isoa_anticollision_cascade_1(pn512_t *pPN512); 00189 static void pn512_initiator_isoa_anticollision_cascade_2(pn512_t *pPN512, nfc_err_t ret); 00190 static void pn512_initiator_isoa_anticollision_cascade_3(pn512_t *pPN512, nfc_err_t ret); 00191 static void pn512_initiator_isoa_anticollision_cascade_4(pn512_t *pPN512, nfc_err_t ret); 00192 static void pn512_initiator_isoa_anticollision_complete(pn512_t *pPN512); 00193 00194 void pn512_initiator_isoa_anticollision(pn512_t *pPN512, pn512_cb_t cb) 00195 { 00196 pPN512->anticollision.cb = cb; 00197 00198 // Reset transceive mode 00199 pPN512->transceive.mode = pn512_transceive_mode_idle; 00200 00201 pn512_initiator_isoa_anticollision_reqa(pPN512); 00202 } 00203 00204 void pn512_initiator_isoa_anticollision_reqa(pn512_t *pPN512) 00205 { 00206 ac_buffer_builder_t *pDataOutBldr = &pPN512->readBufBldr; 00207 ac_buffer_builder_reset(pDataOutBldr); 00208 00209 pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcA.uidLength = 0; 00210 00211 ac_buffer_builder_write_nu8(pDataOutBldr, REQA); 00212 pn512_set_last_byte_length((nfc_transceiver_t *)pPN512, 7); //Only 7 bits in this first command 00213 // FIXME PN512 Anomaly: pn512_register_write(pPN512, PN512_REG_COLL, 0x00); // Set MSB to 0, to accept collisions 00214 pn512_set_crc((nfc_transceiver_t *)pPN512, false, false); 00215 pn512_set_timeout((nfc_transceiver_t *)pPN512, 4); 00216 pn512_set_write((nfc_transceiver_t *)pPN512, ac_buffer_builder_buffer(pDataOutBldr)); 00217 00218 pn512_transceive_hw(pPN512, pn512_transceive_mode_transceive, pn512_initiator_isoa_anticollision_atqa); 00219 } 00220 00221 void pn512_initiator_isoa_anticollision_atqa(pn512_t *pPN512, nfc_err_t ret) 00222 { 00223 // Clear collisions register 00224 // FIXME PN512 Anomaly: pn512_register_write(pPN512, PN512_REG_COLL, 0x80); // Set MSB to 1, to treat collisions as errors 00225 00226 if (ret && (ret != NFC_ERR_COLLISION)) { // There might be collisions here 00227 NFC_WARN("Did not receive ATQA: error %d", ret); 00228 pn512_anticollision_callback(pPN512, NFC_ERR_NOPEER); 00229 return; 00230 } 00231 00232 ac_buffer_t *pResp = pn512_get_read((nfc_transceiver_t *)pPN512); 00233 00234 if (ac_buffer_reader_readable(pResp) != 2) { 00235 NFC_WARN("Wrong length (%u bytes)", ac_buffer_reader_readable(pResp)); 00236 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00237 return; 00238 } 00239 00240 NFC_DBG("Got ATQA:"); 00241 NFC_DBG_BLOCK(ac_buffer_dump(pResp);) 00242 00243 // Ignore ATQA as there can be collisions 00244 ac_buffer_read_n_bytes(pResp, pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcA.atqa, 2); 00245 00246 //Start cascading 00247 pPN512->anticollision.iso_a.cascade_level = 1; 00248 pPN512->anticollision.iso_a.valid_bits = 0; 00249 pPN512->anticollision.iso_a.more_targets = false; 00250 memset(pPN512->anticollision.iso_a.cln, 0, 5); 00251 00252 pn512_initiator_isoa_anticollision_cascade_1(pPN512); 00253 } 00254 00255 void pn512_initiator_isoa_anticollision_cascade_1(pn512_t *pPN512) 00256 { 00257 ac_buffer_builder_t *pDataOutBldr = &pPN512->readBufBldr; 00258 ac_buffer_builder_reset(pDataOutBldr); 00259 00260 //SEL 00261 ac_buffer_builder_write_nu8(pDataOutBldr, SEL(pPN512->anticollision.iso_a.cascade_level - 1)); //SEL: Cascade level 00262 ac_buffer_builder_write_nu8(pDataOutBldr, NVB(pPN512->anticollision.iso_a.valid_bits)); //First NVB: Bytecount = 2, Bitcount = 0, then adapt if collision detected 00263 00264 NFC_DBG("SEL - cascade level %u, %u valid bits - NVB %u", pPN512->anticollision.iso_a.cascade_level, pPN512->anticollision.iso_a.valid_bits, NVB(pPN512->anticollision.iso_a.valid_bits)); 00265 00266 if (pPN512->anticollision.iso_a.valid_bits > 0) { 00267 // Transmit first part of uid 00268 ac_buffer_builder_write_n_bytes(pDataOutBldr, pPN512->anticollision.iso_a.cln, (pPN512->anticollision.iso_a.valid_bits >> 3) + ((pPN512->anticollision.iso_a.valid_bits & 0x7) ? 1 : 0)); 00269 pn512_set_last_byte_length((nfc_transceiver_t *)pPN512, pPN512->anticollision.iso_a.valid_bits & 0x7); 00270 pn512_set_first_byte_align((nfc_transceiver_t *)pPN512, pPN512->anticollision.iso_a.valid_bits & 0x7); 00271 } 00272 00273 // FIXME PN512 Anomaly: pn512_register_write(pPN512, PN512_REG_COLL, 0x00); // Set MSB to 0, to accept collisions 00274 pn512_set_crc((nfc_transceiver_t *)pPN512, false, false); 00275 pn512_set_timeout((nfc_transceiver_t *)pPN512, 30); 00276 pn512_set_write((nfc_transceiver_t *)pPN512, ac_buffer_builder_buffer(pDataOutBldr)); 00277 00278 00279 pn512_register_write(pPN512, PN512_REG_COMIRQ, 2); 00280 NFC_DBG("IRQ status %04X", ((pn512_register_read(pPN512, PN512_REG_COMIRQ)) 00281 | ((pn512_register_read(pPN512, PN512_REG_DIVIRQ)) << 8))); 00282 00283 pn512_transceive_hw(pPN512, pn512_transceive_mode_transceive, pn512_initiator_isoa_anticollision_cascade_2); 00284 } 00285 00286 void pn512_initiator_isoa_anticollision_cascade_2(pn512_t *pPN512, nfc_err_t ret) 00287 { 00288 ac_buffer_t *pResp = pn512_get_read((nfc_transceiver_t *)pPN512); 00289 00290 // Load & clear collisions register 00291 // FIXME PN512 Anomaly: pn512_register_write(pPN512, PN512_REG_COLL, 0x80); // Set MSB to 1, to treat collisions as errors 00292 00293 if (ret && (ret != NFC_ERR_COLLISION)) { // There might be collisions here 00294 NFC_WARN("Did not receive response: error %d", ret); 00295 pn512_anticollision_callback(pPN512, ret); 00296 return; 00297 } 00298 00299 // We should receive 5 bytes back minus all the CLn bits that we have transmitted; we ignore all bits from the first collision 00300 size_t expected_resp_bits = (5 << 3) - pPN512->anticollision.iso_a.valid_bits; 00301 00302 // Check for collision 00303 uint8_t valid_bits = expected_resp_bits; 00304 if (ret == NFC_ERR_COLLISION) { 00305 uint8_t coll_reg = pn512_register_read(pPN512, PN512_REG_COLL); 00306 00307 // FIXME - PN512 error 00308 //if( !(coll_reg & 0x20) ) // bit 5 is CollPosNotValidSet 00309 { 00310 valid_bits = (coll_reg & 0x1f); 00311 00312 if (valid_bits == 0) { 00313 valid_bits = 32; 00314 } 00315 00316 valid_bits--; 00317 00318 NFC_DBG("Collision detected, %u valid bits", valid_bits); 00319 if (valid_bits < expected_resp_bits) { 00320 // Collision detected 00321 pPN512->anticollision.iso_a.more_targets = true; 00322 } else { 00323 valid_bits = expected_resp_bits; 00324 } 00325 } 00326 } 00327 00328 size_t resp_sz = (valid_bits >> 3) + ((valid_bits & 0x7) ? 1 : 0); 00329 if (ac_buffer_reader_readable(pResp) < resp_sz) { 00330 (void) pn512_register_read(pPN512, PN512_REG_COLL); 00331 00332 NFC_WARN("Wrong length (%u instead of %u - valid bits %u)", ac_buffer_reader_readable(pResp), resp_sz, valid_bits); 00333 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00334 return; 00335 } 00336 00337 // Read bytes 00338 uint8_t bufIn[5] = {0}; 00339 ac_buffer_read_n_bytes(pResp, bufIn + (pPN512->anticollision.iso_a.valid_bits >> 3), resp_sz); 00340 00341 // Mask out valid bits that are already known 00342 bufIn[pPN512->anticollision.iso_a.valid_bits >> 3] &= 0xff << (pPN512->anticollision.iso_a.valid_bits & 0x7); 00343 00344 // Update number of valid bits 00345 pPN512->anticollision.iso_a.valid_bits += valid_bits; 00346 00347 // Mask out bits past valid bits in last byte 00348 bufIn[pPN512->anticollision.iso_a.valid_bits >> 3] &= 0xff >> ((8 - pPN512->anticollision.iso_a.valid_bits) & 0x7); 00349 00350 // Now remember bits before collision 00351 for (size_t p = 0; p < 5; p++) { 00352 pPN512->anticollision.iso_a.cln[p] |= bufIn[p]; 00353 } 00354 00355 // If we have all bits, then check BCC, go to next step 00356 if (pPN512->anticollision.iso_a.valid_bits < 5 * 8) { // Collision, add a 1 at the end of known bits to resolve collision 00357 pPN512->anticollision.iso_a.cln[pPN512->anticollision.iso_a.valid_bits >> 3] |= (1 << (pPN512->anticollision.iso_a.valid_bits & 0x7)); 00358 pPN512->anticollision.iso_a.valid_bits++; 00359 00360 // Restart first step with more valid bits 00361 pn512_initiator_isoa_anticollision_cascade_1(pPN512); 00362 return; 00363 } 00364 00365 //Check BCC if all bits are valid 00366 if (pPN512->anticollision.iso_a.cln[4] != (pPN512->anticollision.iso_a.cln[0] ^ pPN512->anticollision.iso_a.cln[1] ^ pPN512->anticollision.iso_a.cln[2] ^ pPN512->anticollision.iso_a.cln[3])) { 00367 NFC_WARN("Wrong BCC %02X != %02X", bufIn[4], bufIn[0] ^ bufIn[1] ^ bufIn[2] ^ bufIn[3]); 00368 pn512_anticollision_callback(pPN512, NFC_ERR_COLLISION); 00369 return; //TODO handle this properly 00370 } 00371 00372 if (pPN512->anticollision.iso_a.cln[0] == CT) { 00373 //Not the last cascade level 00374 if (pPN512->anticollision.iso_a.cascade_level == 3) { // not allowed 00375 NFC_WARN("Cascade tag present in cascade level 3"); 00376 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00377 return; 00378 } 00379 memcpy(&pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcA.uid[(pPN512->anticollision.iso_a.cascade_level - 1) * 3], &pPN512->anticollision.iso_a.cln[1], 3); 00380 pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcA.uidLength += 3; 00381 } else { 00382 //Last cascade level 00383 memcpy(&pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcA.uid[(pPN512->anticollision.iso_a.cascade_level - 1) * 3], &pPN512->anticollision.iso_a.cln[0], 4); 00384 pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcA.uidLength += 4; 00385 } 00386 00387 ac_buffer_builder_t *pDataOutBldr = &pPN512->readBufBldr; 00388 ac_buffer_builder_reset(pDataOutBldr); 00389 00390 //Select and get SAK 00391 ac_buffer_builder_write_nu8(pDataOutBldr, SEL(pPN512->anticollision.iso_a.cascade_level - 1)); //SEL: Cascade level 00392 ac_buffer_builder_write_nu8(pDataOutBldr, NVB(40)); //NVB: 40 valid bits = 5 bytes 00393 00394 //Transmit last 4 transmitted UID bytes + BCC (including cascade byte if relevant) 00395 ac_buffer_builder_write_n_bytes(pDataOutBldr, pPN512->anticollision.iso_a.cln, 5); 00396 00397 NFC_DBG("Selecting target"); 00398 00399 //This time compute & check CRC 00400 pn512_set_crc((nfc_transceiver_t *)pPN512, true, true); 00401 pn512_set_write((nfc_transceiver_t *)pPN512, ac_buffer_builder_buffer(pDataOutBldr)); 00402 pn512_transceive_hw(pPN512, pn512_transceive_mode_transceive, pn512_initiator_isoa_anticollision_cascade_3); 00403 } 00404 00405 static void pn512_initiator_isoa_anticollision_cascade_3(pn512_t *pPN512, nfc_err_t ret) 00406 { 00407 ac_buffer_t *pResp = pn512_get_read((nfc_transceiver_t *)pPN512); 00408 00409 if (ret) { 00410 NFC_WARN("Did not receive response: error %d", ret); 00411 pn512_anticollision_callback(pPN512, ret); 00412 return; 00413 } 00414 00415 if (ac_buffer_reader_readable(pResp) != 1) { 00416 NFC_WARN("Wrong length"); 00417 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00418 return; 00419 } 00420 00421 pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcA.sak = ac_buffer_read_nu8(pResp); 00422 NFC_DBG("Got SAK %02X", pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcA.sak); 00423 00424 //Check SAK 00425 if (pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcA.sak & 0x04) { 00426 //Continue anticollision 00427 pPN512->anticollision.iso_a.cascade_level++; 00428 pPN512->anticollision.iso_a.valid_bits = 0; 00429 memset(pPN512->anticollision.iso_a.cln, 0, 5); 00430 pn512_initiator_isoa_anticollision_cascade_1(pPN512); 00431 } else { 00432 //Anticollision complete 00433 00434 NFC_DBG("Found one target- SAK = %02X", pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcA.sak); 00435 00436 //Analyze SAK 00437 memset(&pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type, 0, sizeof(nfc_tech_t)); 00438 00439 if (pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcA.sak & 0x40) { //NFC-IP1 compliant 00440 pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type.nfc_nfc_dep_a = true; 00441 } 00442 if ((pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcA.sak & 0x20) 00443 && pPN512->config.initiators.nfc_iso_dep_a) { //ISO-14443A-4 compliant 00444 pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type.nfc_iso_dep_a = true; 00445 } 00446 if (!(pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcA.sak & 0x60) 00447 && pPN512->config.initiators.nfc_type2) { //Potentially NFC Type 2 (or Mifare, etc) 00448 pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type.nfc_type2 = true; 00449 } 00450 00451 // Unknown target 00452 if (!pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type.nfc_iso_dep_a 00453 && !pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type.nfc_nfc_dep_a 00454 && !pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type.nfc_type2 00455 ) { 00456 pn512_anticollision_callback(pPN512, NFC_ERR_NOPEER); 00457 return; 00458 } 00459 00460 // Valid target detected 00461 pPN512->transceiver.active_tech = pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type; 00462 pPN512->transceiver.remote_targets_count++; 00463 00464 if (!pPN512->config.options.bail_at_first_target 00465 && pPN512->anticollision.iso_a.more_targets 00466 && (pPN512->transceiver.remote_targets_count < MUNFC_MAX_REMOTE_TARGETS)) { 00467 // Halt target and continue with others 00468 ac_buffer_builder_t *pDataOutBldr = &pPN512->readBufBldr; 00469 ac_buffer_builder_reset(pDataOutBldr); 00470 00471 //HALTA 00472 ac_buffer_builder_write_nu8(pDataOutBldr, HALTA1); 00473 ac_buffer_builder_write_nu8(pDataOutBldr, HALTA2); 00474 00475 pn512_set_crc((nfc_transceiver_t *)pPN512, true, false); 00476 pn512_set_timeout((nfc_transceiver_t *)pPN512, 30); 00477 pn512_set_write((nfc_transceiver_t *)pPN512, ac_buffer_builder_buffer(pDataOutBldr)); 00478 pn512_transceive_hw(pPN512, pn512_transceive_mode_transmit, pn512_initiator_isoa_anticollision_cascade_4); 00479 return; 00480 } 00481 00482 // Leave it activated and finish! 00483 pn512_initiator_isoa_anticollision_complete(pPN512); 00484 } 00485 } 00486 00487 static void pn512_initiator_isoa_anticollision_cascade_4(pn512_t *pPN512, nfc_err_t ret) 00488 { 00489 if (ret) { 00490 NFC_WARN("Could not halt device: error %d", ret); 00491 pn512_anticollision_callback(pPN512, ret); 00492 return; 00493 } 00494 00495 // Start again 00496 pn512_initiator_isoa_anticollision_reqa(pPN512); 00497 } 00498 00499 void pn512_initiator_isoa_anticollision_complete(pn512_t *pPN512) 00500 { 00501 pn512_anticollision_callback(pPN512, NFC_OK); 00502 } 00503 00504 // ISO B 00505 static void pn512_initiator_isob_anticollision(pn512_t *pPN512, pn512_cb_t cb); 00506 static void pn512_initiator_isob_anticollision_reqb(pn512_t *pPN512); 00507 static void pn512_initiator_isob_anticollision_atqb(pn512_t *pPN512, nfc_err_t ret); 00508 static void pn512_initiator_isob_anticollision_next_slot(pn512_t *pPN512); 00509 static void pn512_initiator_isob_anticollision_haltb_resp(pn512_t *pPN512, nfc_err_t ret); 00510 static void pn512_initiator_isob_anticollision_complete(pn512_t *pPN512); 00511 00512 #define REQB 0x05 00513 #define HALTB 0x50 00514 00515 void pn512_initiator_isob_anticollision(pn512_t *pPN512, pn512_cb_t cb) 00516 { 00517 pPN512->anticollision.cb = cb; 00518 pPN512->anticollision.iso_b.slots_num_exponent = 0; // Start with one slot 00519 pPN512->anticollision.iso_b.slot_number = 0; 00520 pPN512->anticollision.iso_b.found_one = false; 00521 00522 // Reset transceive mode 00523 pPN512->transceive.mode = pn512_transceive_mode_idle; 00524 00525 pn512_initiator_isob_anticollision_reqb(pPN512); 00526 } 00527 00528 void pn512_initiator_isob_anticollision_reqb(pn512_t *pPN512) 00529 { 00530 ac_buffer_builder_t *pDataOutBldr = &pPN512->readBufBldr; 00531 ac_buffer_builder_reset(pDataOutBldr); 00532 00533 if (pPN512->anticollision.iso_b.slot_number == 0) { 00534 // Send REQB/WUPB 00535 pPN512->anticollision.iso_b.more_targets = false; 00536 00537 ac_buffer_builder_write_nu8(pDataOutBldr, REQB); 00538 ac_buffer_builder_write_nu8(pDataOutBldr, 0x00); // AFI: All card types should respond 00539 uint8_t wup = 0; 00540 if ((pPN512->anticollision.iso_b.slots_num_exponent == 0)) { //&& (pPN512->anticollision.iso_b.slot_number == 0)) 00541 wup |= 0x8; // Send Wake-Up command on first iteration 00542 } 00543 ac_buffer_builder_write_nu8(pDataOutBldr, wup | (pPN512->anticollision.iso_b.slots_num_exponent & 0x7)); // Param: number of slots 00544 } else { 00545 // Just send slot marker 00546 ac_buffer_builder_write_nu8(pDataOutBldr, REQB | ((pPN512->anticollision.iso_b.slot_number & 0xf) << 4)); 00547 } 00548 00549 pn512_set_crc((nfc_transceiver_t *)pPN512, true, true); 00550 pn512_set_timeout((nfc_transceiver_t *)pPN512, 18); 00551 pn512_set_write((nfc_transceiver_t *)pPN512, ac_buffer_builder_buffer(pDataOutBldr)); 00552 pn512_transceive_hw(pPN512, pn512_transceive_mode_transceive, pn512_initiator_isob_anticollision_atqb); 00553 } 00554 00555 void pn512_initiator_isob_anticollision_atqb(pn512_t *pPN512, nfc_err_t ret) 00556 { 00557 // Three cases: 00558 // - 1 response --> store response, halt PICC and check next slot number 00559 // - No response --> check next slot number 00560 // - Collision --> check next slot number but we will have to increment number of slots 00561 ac_buffer_t *pResp = pn512_get_read((nfc_transceiver_t *)pPN512); 00562 00563 if (ret && (ret != NFC_ERR_COLLISION) && (ret != NFC_ERR_WRONG_COMM) && (ret != NFC_ERR_TIMEOUT)) { 00564 NFC_WARN("Did not receive ATQB: error %u", ret); 00565 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00566 return; 00567 } 00568 00569 // Increment slot number 00570 pPN512->anticollision.iso_b.slot_number++; 00571 00572 if ((ret == NFC_ERR_COLLISION) || (ret == NFC_ERR_WRONG_COMM)) { 00573 pPN512->anticollision.iso_b.more_targets = true; 00574 } else if (!ret) { 00575 pPN512->anticollision.iso_b.found_one = true; 00576 00577 // Decode ATQB 00578 if (ac_buffer_reader_readable(pResp) != 12) { 00579 NFC_WARN("Wrong length (%u bytes)", ac_buffer_reader_readable(pResp)); 00580 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00581 return; 00582 } 00583 00584 NFC_DBG("Got ATQB:"); 00585 NFC_DBG_BLOCK(ac_buffer_dump(pResp);) 00586 00587 // Check first byte 00588 uint8_t atqb0 = ac_buffer_read_nu8(pResp); 00589 if (atqb0 != 0x50) { 00590 NFC_WARN("Wrong first byte for ATQB: %02X", atqb0); 00591 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00592 return; 00593 } 00594 00595 memset(&pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type, 0, sizeof(nfc_tech_t)); 00596 pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type.nfc_iso_dep_b = true; 00597 00598 // Save PUPI, application data & protocol info 00599 ac_buffer_read_n_bytes(pResp, pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcB.pupi, 4); 00600 ac_buffer_read_n_bytes(pResp, pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcB.application_data, 4); 00601 ac_buffer_read_n_bytes(pResp, pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcB.protocol_info, 3); 00602 00603 // Valid target detected 00604 pPN512->transceiver.active_tech = pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type; 00605 pPN512->transceiver.remote_targets_count++; 00606 00607 if (!pPN512->config.options.bail_at_first_target 00608 && (pPN512->anticollision.iso_b.more_targets || (pPN512->anticollision.iso_b.slot_number < (1 << pPN512->anticollision.iso_b.slots_num_exponent))) 00609 && (pPN512->transceiver.remote_targets_count < MUNFC_MAX_REMOTE_TARGETS)) { 00610 // Halt target and continue with others 00611 ac_buffer_builder_t *pDataOutBldr = &pPN512->readBufBldr; 00612 ac_buffer_builder_reset(pDataOutBldr); 00613 00614 // Halt PICC and move on to the next slot 00615 00616 //HALTB 00617 ac_buffer_builder_write_nu8(pDataOutBldr, HALTB); 00618 ac_buffer_builder_write_n_bytes(pDataOutBldr, pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count - 1].nfcB.pupi, 4); 00619 00620 pn512_set_crc((nfc_transceiver_t *)pPN512, true, true); 00621 pn512_set_timeout((nfc_transceiver_t *)pPN512, 30); 00622 pn512_set_write((nfc_transceiver_t *)pPN512, ac_buffer_builder_buffer(pDataOutBldr)); 00623 pn512_transceive_hw(pPN512, pn512_transceive_mode_transceive, pn512_initiator_isob_anticollision_haltb_resp); 00624 return; 00625 } else { 00626 pn512_initiator_isob_anticollision_complete(pPN512); 00627 return; 00628 } 00629 } 00630 00631 // Move on to the next slot 00632 pn512_initiator_isob_anticollision_next_slot(pPN512); 00633 } 00634 00635 void pn512_initiator_isob_anticollision_next_slot(pn512_t *pPN512) 00636 { 00637 if (pPN512->anticollision.iso_b.slot_number >= (1 << pPN512->anticollision.iso_b.slots_num_exponent)) { 00638 if (!pPN512->anticollision.iso_b.more_targets) { 00639 // No further collisions to resolve 00640 pn512_initiator_isob_anticollision_complete(pPN512); 00641 return; 00642 } 00643 if (pPN512->anticollision.iso_b.slots_num_exponent >= 4) { 00644 // Cannot handle more than 16 slots 00645 pn512_initiator_isob_anticollision_complete(pPN512); 00646 return; 00647 } 00648 pPN512->anticollision.iso_b.slots_num_exponent++; 00649 pPN512->anticollision.iso_b.slot_number = 0; 00650 } 00651 pn512_initiator_isob_anticollision_reqb(pPN512); 00652 } 00653 00654 void pn512_initiator_isob_anticollision_haltb_resp(pn512_t *pPN512, nfc_err_t ret) 00655 { 00656 // Check for response 00657 if (ret) { 00658 NFC_WARN("Did not receive HALTB response: error %u", ret); 00659 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00660 return; 00661 } 00662 00663 ac_buffer_t *pResp = pn512_get_read((nfc_transceiver_t *)pPN512); 00664 00665 if (ac_buffer_reader_readable(pResp) != 1) { 00666 NFC_WARN("Wrong length (%u bytes)", ac_buffer_reader_readable(pResp)); 00667 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00668 return; 00669 } 00670 00671 NFC_DBG("Got HALTB response:"); 00672 NFC_DBG_BLOCK(ac_buffer_dump(pResp);) 00673 00674 // Check byte 00675 uint8_t haltbr = ac_buffer_read_nu8(pResp); 00676 if (haltbr != 0x00) { 00677 NFC_WARN("Wrong byte for HALTB response: %02X", haltbr); 00678 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00679 return; 00680 } 00681 00682 // PICC halted, move to next slot 00683 pn512_initiator_isob_anticollision_next_slot(pPN512); 00684 } 00685 00686 void pn512_initiator_isob_anticollision_complete(pn512_t *pPN512) 00687 { 00688 if (pPN512->anticollision.iso_b.found_one) { 00689 pn512_anticollision_callback(pPN512, NFC_OK); 00690 } else { 00691 pn512_anticollision_callback(pPN512, NFC_ERR_NOPEER); 00692 } 00693 } 00694 00695 // Felica 00696 static void pn512_initiator_felica_anticollision(pn512_t *pPN512, pn512_cb_t cb); 00697 static void pn512_initiator_felica_anticollision_reqc(pn512_t *pPN512); 00698 static void pn512_initiator_felica_anticollision_atqc(pn512_t *pPN512, nfc_err_t ret); 00699 static void pn512_initiator_felica_anticollision_complete(pn512_t *pPN512); 00700 00701 #define REQC 0x00 00702 00703 void pn512_initiator_felica_anticollision(pn512_t *pPN512, pn512_cb_t cb) 00704 { 00705 pPN512->anticollision.cb = cb; 00706 00707 // Reset transceive mode 00708 pPN512->transceive.mode = pn512_transceive_mode_idle; 00709 00710 pn512_initiator_felica_anticollision_reqc(pPN512); 00711 } 00712 00713 void pn512_initiator_felica_anticollision_reqc(pn512_t *pPN512) 00714 { 00715 ac_buffer_builder_t *pDataOutBldr = &pPN512->readBufBldr; 00716 ac_buffer_builder_reset(pDataOutBldr); 00717 00718 ac_buffer_builder_write_nu8(pDataOutBldr, 6); //Length 00719 ac_buffer_builder_write_nu8(pDataOutBldr, REQC); 00720 ac_buffer_builder_write_nu16(pDataOutBldr, 0xFFFF); //Any system code 00721 ac_buffer_builder_write_nu8(pDataOutBldr, 0x00); // Padding 00722 ac_buffer_builder_write_nu8(pDataOutBldr, 0x07); // 8 time slots, more would overflow the rx buffer if many cards responded 00723 00724 pn512_set_crc((nfc_transceiver_t *)pPN512, true, true); 00725 pn512_set_timeout((nfc_transceiver_t *)pPN512, 13); //8 timeslots at 212kbps 00726 pn512_set_write((nfc_transceiver_t *)pPN512, ac_buffer_builder_buffer(pDataOutBldr)); 00727 00728 pn512_framing_rx_multiple_enable(pPN512); // Set RxMultiple bit 00729 00730 pn512_transceive_hw(pPN512, pn512_transceive_mode_transceive, pn512_initiator_felica_anticollision_atqc); 00731 } 00732 00733 void pn512_initiator_felica_anticollision_atqc(pn512_t *pPN512, nfc_err_t ret) 00734 { 00735 ac_buffer_t *pResp = pn512_get_read((nfc_transceiver_t *)pPN512); 00736 00737 if (ret || (ac_buffer_reader_readable(pResp) == 0)) { 00738 NFC_WARN("Did not receive ATQC: error %d", ret); 00739 pn512_anticollision_callback(pPN512, NFC_ERR_NOPEER); 00740 return; 00741 } 00742 00743 // We might have multiple responses 00744 NFC_DBG("Got ATQC:"); 00745 NFC_DBG_BLOCK(ac_buffer_dump(pResp);) 00746 00747 while (ac_buffer_reader_readable(pResp) > 0) { 00748 if (ac_buffer_reader_readable(pResp) != 18 + 1) { // ATQC is 18 bytes, 1 byte for errors added by PN512 00749 NFC_WARN("Wrong length (%d bytes)", ac_buffer_reader_readable(pResp)); 00750 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00751 return; 00752 } 00753 00754 // First byte is length, check that it's correct 00755 uint8_t frame_length = ac_buffer_read_nu8(pResp); 00756 uint8_t atqc0 = ac_buffer_read_nu8(pResp); 00757 if ((frame_length != 18) || (atqc0 != 0x01)) { 00758 NFC_WARN("Wrong ATQC frame"); 00759 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00760 return; 00761 } 00762 00763 // Read NFCID2 00764 ac_buffer_read_n_bytes(pResp, pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcF.nfcid2, 8); 00765 00766 // Discard padding bytes 00767 ac_buffer_read_n_skip(pResp, 8); 00768 00769 // Read error register 00770 uint8_t err_reg = ac_buffer_read_nu8(pResp); 00771 if (err_reg & 0x1f) { 00772 // Error within this time slot, skip 00773 continue; 00774 } 00775 00776 //Populate tech accordingly 00777 memset(&pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type, 0, sizeof(nfc_tech_t)); 00778 if ( 00779 (pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcF.nfcid2[0] == 0x01) 00780 && (pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcF.nfcid2[1] == 0xFE) 00781 ) { 00782 // NFC-DEP supported 00783 pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type.nfc_nfc_dep_f_212 = 1; 00784 } else { 00785 // Type 3 supported 00786 pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type.nfc_type3 = 1; 00787 } 00788 pPN512->transceiver.active_tech = pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type; 00789 pPN512->transceiver.remote_targets_count++; 00790 00791 // Only continue if we can have more targets 00792 if (!pPN512->config.options.bail_at_first_target 00793 && (pPN512->transceiver.remote_targets_count < MUNFC_MAX_REMOTE_TARGETS)) { 00794 continue; 00795 } 00796 break; 00797 } 00798 00799 pn512_initiator_felica_anticollision_complete(pPN512); 00800 } 00801 00802 void pn512_initiator_felica_anticollision_complete(pn512_t *pPN512) 00803 { 00804 pn512_anticollision_callback(pPN512, NFC_OK); 00805 } 00806 00807 void pn512_poll_setup(pn512_t *pPN512) 00808 { 00809 bool target = pPN512->config.targets.nfc_type2 00810 || pPN512->config.targets.nfc_type3 00811 || pPN512->config.targets.nfc_iso_dep_a 00812 || pPN512->config.targets.nfc_nfc_dep_a 00813 || pPN512->config.targets.nfc_nfc_dep_f_212 00814 || pPN512->config.targets.nfc_nfc_dep_f_424; 00815 00816 // No need for initiator-specific configuration at this stage, but keep this just in case 00817 // bool initiator = pPN512->config.initiators.nfc_type1 00818 // || pPN512->config.initiators.nfc_type2 00819 // || pPN512->config.initiators.nfc_type3 00820 // || pPN512->config.initiators.nfc_iso_dep_a 00821 // || pPN512->config.initiators.nfc_nfc_dep_a 00822 // || pPN512->config.initiators.nfc_nfc_dep_f_212 00823 // || pPN512->config.initiators.nfc_nfc_dep_f_424; 00824 00825 if (target) { 00826 NFC_DBG("Configure anticoll/polling response"); 00827 //Setup ATQA, SAK and Felica polling response 00828 pn512_fifo_clear(pPN512); 00829 00830 ac_buffer_builder_t *pDataCfgBldr = &pPN512->readBufBldr; 00831 ac_buffer_builder_reset(pDataCfgBldr); 00832 00833 //Write ATQA 00834 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x04); 00835 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00836 00837 //Write NFCID1 (0s as it will be randomly generated) - first byte will be set to 0x08 by HW according to NFC-IP1 00838 for (int i = 0; i < 3; i++) { 00839 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00840 } 00841 00842 //Write SAK 00843 uint8_t sak = 0x00; //Default SAK (UID complete) 00844 if (pPN512->config.targets.nfc_iso_dep_a) { 00845 sak |= 0x20; //This target is ISO-14443A-4 compliant 00846 } 00847 if (pPN512->config.targets.nfc_nfc_dep_a) { 00848 sak |= 0x40; //This target is NFC-IP1 compliant 00849 } 00850 ac_buffer_builder_write_nu8(pDataCfgBldr, sak); 00851 00852 //Write NFCID2 (xx 0xfe according to NFC-IP1 and 0s as 6 bytes will be randomly generated) 00853 if (pPN512->config.targets.nfc_nfc_dep_f_212 || pPN512->config.targets.nfc_nfc_dep_f_424) { 00854 //Byte 1 is 0x01 if supporting NFC-IP1 00855 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x01); 00856 } else if (pPN512->config.targets.nfc_type3) { //NFC-IP will have priority over type 3 tag emulation 00857 //Byte 1 is 0x02 if supporting Type 3 tag platform 00858 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x02); 00859 } else { 00860 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00861 } 00862 ac_buffer_builder_write_nu8(pDataCfgBldr, 0xFE); 00863 00864 for (int i = 0; i < 6; i++) { 00865 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00866 } 00867 00868 //2 PAD0 bytes (Felica spec) - this would code the manufacturer + IC code (0xFFFF for NFC-IP1 tags) 00869 ac_buffer_builder_write_nu8(pDataCfgBldr, 0xFF); 00870 ac_buffer_builder_write_nu8(pDataCfgBldr, 0xFF); 00871 00872 //3 PAD1 bytes 00873 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00874 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00875 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00876 00877 if (!(pPN512->config.targets.nfc_nfc_dep_f_212 || pPN512->config.targets.nfc_nfc_dep_f_424) 00878 && pPN512->config.targets.nfc_type3) { 00879 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x01); //MRTI Check 00880 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x01); //MRTI Update 00881 } else { 00882 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00883 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00884 } 00885 00886 //1 PAD2 byte 00887 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00888 00889 //2 system code bytes 00890 if (!(pPN512->config.targets.nfc_nfc_dep_f_212 || pPN512->config.targets.nfc_nfc_dep_f_424) 00891 && pPN512->config.targets.nfc_type3) { 00892 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x12); 00893 ac_buffer_builder_write_nu8(pDataCfgBldr, 0xFC); 00894 } else { 00895 ac_buffer_builder_write_nu8(pDataCfgBldr, 0xFF); //Wildcard system code 00896 ac_buffer_builder_write_nu8(pDataCfgBldr, 0xFF); 00897 } 00898 00899 //Write NFCID3 00900 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00901 00902 pn512_fifo_write(pPN512, ac_buffer_builder_buffer(pDataCfgBldr)); 00903 00904 pn512_cmd_exec(pPN512, PN512_CMD_CONFIG); 00905 pn512_cmd_wait_idle(pPN512, -1); 00906 00907 NFC_DBG("Overwrite NFCIDs with random numbers"); 00908 00909 //Overwrite NFCIDs with random numbers 00910 pn512_cmd_exec(pPN512, PN512_CMD_RNDIDG); 00911 pn512_cmd_wait_idle(pPN512, -1); 00912 } 00913 } 00914 00915 static void pn512_poll_iteration(pn512_t *pPN512, nfc_err_t ret); 00916 static void pn512_poll_delay_complete(uint32_t events, void *pUserData) 00917 { 00918 pn512_t *pPN512 = (pn512_t *) pUserData; 00919 00920 if (events & EVENT_ABORTED) { 00921 pn512_poll_callback(pPN512, NFC_ERR_ABORTED); 00922 return; 00923 } 00924 00925 pn512_poll_iteration(pPN512, NFC_OK); 00926 } 00927 00928 static void pn512_poll_delay(pn512_t *pPN512, uint32_t timeout) 00929 { 00930 task_init(&pPN512->transceiver.task, EVENT_TIMEOUT, timeout, pn512_poll_delay_complete, pPN512); 00931 nfc_scheduler_queue_task(&pPN512->transceiver.scheduler, &pPN512->transceiver.task); 00932 } 00933 00934 void pn512_poll_iteration(pn512_t *pPN512, nfc_err_t ret) 00935 { 00936 do { 00937 if (pPN512->poll.state == pn512_polling_state_start_listening) { 00938 NFC_DBG("pn512_polling_state_start_listening"); 00939 // Start with listening 00940 if (!pn512_config_target(pPN512)) { 00941 // Otherwise switch to next step 00942 pPN512->poll.state = pn512_polling_state_start_polling; 00943 continue; 00944 } 00945 00946 pPN512->poll.state = pn512_polling_state_listen_wait_for_remote_field; 00947 00948 // Shortcut if target is halted (means RF field is still here) 00949 if (pn512_register_read(pPN512, PN512_REG_MIFNFC) & 0x04) { 00950 continue; 00951 } 00952 00953 // Fix for PN512 bug that sometimes detects its own RF field 00954 // if(pPN512->rf_on) 00955 { 00956 //Switch RF field off 00957 pn512_rf_field_switch_off(pPN512); 00958 NFC_DBG("RF field switched off"); 00959 } 00960 00961 NFC_DBG("Target anticollision"); 00962 00963 bool iso14443a = pPN512->config.targets.nfc_type2 || pPN512->config.targets.nfc_iso_dep_a || pPN512->config.targets.nfc_nfc_dep_a; 00964 bool felica = pPN512->config.targets.nfc_type3 || pPN512->config.targets.nfc_nfc_dep_f_212 || pPN512->config.targets.nfc_nfc_dep_f_424; 00965 00966 NFC_DBG("Switch in target mode and set framing: ISO A: %s; Felica: %s", iso14443a ? "Yes" : "No", felica ? "Yes" : "No"); 00967 00968 //Switch in target mode 00969 if (iso14443a && felica) { 00970 pn512_framing_set(pPN512, nfc_framing_target_mode_detector); 00971 } else if (iso14443a) { 00972 pn512_framing_set(pPN512, nfc_framing_target_a_106); 00973 } else if (felica) { 00974 pn512_framing_set(pPN512, nfc_framing_target_f_212); 00975 } 00976 00977 pn512_rf_field_wait_for_external(pPN512, pPN512->config.options.listen_for, pn512_poll_iteration); 00978 return; 00979 } 00980 00981 if (pPN512->poll.state == pn512_polling_state_listen_wait_for_remote_field) { 00982 NFC_DBG("pn512_polling_state_listen_wait_for_remote_field"); 00983 00984 if (!pn512_config_target(pPN512)) { 00985 // Otherwise switch to next step 00986 pPN512->poll.state = pn512_polling_state_start_listening; 00987 continue; 00988 } 00989 00990 if (ret == NFC_ERR_TIMEOUT) { 00991 // Continue polling 00992 pPN512->poll.state = pn512_polling_state_start_polling; 00993 continue; 00994 } 00995 00996 if (ret) { 00997 pn512_poll_callback(pPN512, ret); 00998 return; 00999 } 01000 01001 pPN512->poll.state = pn512_polling_state_listen_anticollision; 01002 01003 pn512_target_anticollision(pPN512, pn512_poll_iteration); 01004 return; 01005 } 01006 01007 if (pPN512->poll.state == pn512_polling_state_listen_anticollision) { 01008 NFC_DBG("pn512_polling_state_listen_anticollision"); 01009 01010 if (ret == NFC_ERR_FIELD) { 01011 // This means that a remote field was dropped - give it another chance 01012 pPN512->poll.state = pn512_polling_state_listen_wait_for_remote_field; 01013 pn512_rf_field_switch_off(pPN512); 01014 pn512_rf_field_wait_for_external(pPN512, pPN512->config.options.listen_for, pn512_poll_iteration); 01015 return; 01016 } 01017 01018 if (ret) { 01019 pn512_poll_callback(pPN512, ret); 01020 return; 01021 } 01022 01023 // Be safe, not sure what the framing is 01024 pPN512->framing = nfc_framing_unknown; 01025 01026 pn512_poll_callback(pPN512, NFC_OK); 01027 return; 01028 } 01029 01030 if (pPN512->poll.state == pn512_polling_state_start_polling) { 01031 NFC_DBG("pn512_polling_state_start_polling"); 01032 01033 if (!pn512_config_initiator(pPN512)) { 01034 // Otherwise switch to next step 01035 pPN512->poll.state = pn512_polling_state_start_listening; 01036 continue; 01037 } 01038 01039 // Try to activate RF field 01040 pPN512->poll.state = pn512_polling_state_rf_collision_avoidance; 01041 01042 pn512_rf_field_nfcip1_rf_collision_avoidance(pPN512, pn512_poll_iteration); 01043 return; 01044 } 01045 01046 if (pPN512->poll.state == pn512_polling_state_rf_collision_avoidance) { 01047 NFC_DBG("pn512_polling_state_rf_collision_avoidance"); 01048 01049 if (ret) { 01050 pn512_poll_callback(pPN512, ret); 01051 return; 01052 } 01053 01054 NFC_DBG("Own RF field is %s", pPN512->rf_on ? "on" : "off"); 01055 01056 if (!pPN512->rf_on) { 01057 // Go back to listening, target framing is still valid so no need to reset it 01058 pPN512->poll.state = pn512_polling_state_listen_wait_for_remote_field; 01059 continue; 01060 } 01061 01062 pPN512->poll.state = pn512_polling_state_polling_nfc_a_start; 01063 } 01064 01065 if (pPN512->poll.state == pn512_polling_state_polling_nfc_a_start) { 01066 NFC_DBG("pn512_polling_state_polling_nfc_a_start"); 01067 01068 //Check if ISO A is needed 01069 bool nfc_a = pPN512->config.initiators.nfc_type2 || pPN512->config.initiators.nfc_iso_dep_a || pPN512->config.initiators.nfc_nfc_dep_a; //We do not support type 1 card emulation so irrelevant 01070 if (!nfc_a) { 01071 // Continue with NFC B 01072 pPN512->poll.state = pn512_polling_state_polling_nfc_b_start; 01073 continue; 01074 } 01075 01076 pPN512->transceiver.initiator_ntarget = true; 01077 pn512_framing_set(pPN512, nfc_framing_initiator_a_106); 01078 01079 pPN512->poll.state = pn512_polling_state_polling_nfc_a_gt; 01080 pn512_poll_delay(pPN512, 10 + 5); // Guard time for ISO A is 5 ms 01081 return; 01082 } 01083 01084 if (pPN512->poll.state == pn512_polling_state_polling_nfc_a_gt) { 01085 NFC_DBG("pn512_polling_state_polling_nfc_a_gt"); 01086 01087 // Start anticollision 01088 pPN512->poll.state = pn512_polling_state_polling_nfc_a_anticollision; 01089 pn512_initiator_isoa_anticollision(pPN512, pn512_poll_iteration); 01090 return; 01091 } 01092 01093 if (pPN512->poll.state == pn512_polling_state_polling_nfc_a_anticollision) { 01094 NFC_DBG("pn512_polling_state_polling_nfc_a_anticollision"); 01095 01096 if (ret == NFC_ERR_NOPEER) { 01097 NFC_DBG("Not found"); 01098 // Continue with NFC B 01099 pPN512->poll.state = pn512_polling_state_polling_nfc_b_start; 01100 continue; 01101 } 01102 01103 if ((ret == NFC_OK) && (pPN512->config.options.bail_at_first_tech || (pPN512->transceiver.remote_targets_count == MUNFC_MAX_REMOTE_TARGETS))) { 01104 // At least one target found, exit polling loop 01105 pn512_poll_callback(pPN512, NFC_OK); 01106 return; 01107 } 01108 01109 if (ret == NFC_ERR_ABORTED) { 01110 pn512_poll_callback(pPN512, ret); 01111 return; 01112 } 01113 01114 // Continue with NFC B 01115 pPN512->poll.state = pn512_polling_state_polling_nfc_b_start; 01116 continue; 01117 } 01118 01119 if (pPN512->poll.state == pn512_polling_state_polling_nfc_b_start) { 01120 NFC_DBG("pn512_polling_state_polling_nfc_b_start"); 01121 01122 //Check if ISO B is needed 01123 bool nfc_b = pPN512->config.initiators.nfc_iso_dep_b; 01124 if (!nfc_b) { 01125 // Continue with NFC F 01126 pPN512->poll.state = pn512_polling_state_polling_nfc_f_start; 01127 continue; 01128 } 01129 01130 pPN512->transceiver.initiator_ntarget = true; 01131 pn512_framing_set(pPN512, nfc_framing_initiator_b_106); 01132 01133 pPN512->poll.state = pn512_polling_state_polling_nfc_b_gt; 01134 pn512_poll_delay(pPN512, 10 + 5); // Guard time for ISO B is 5 ms 01135 return; 01136 } 01137 01138 if (pPN512->poll.state == pn512_polling_state_polling_nfc_b_gt) { 01139 NFC_DBG("pn512_polling_state_polling_nfc_b_gt"); 01140 01141 // Start anticollision 01142 pPN512->poll.state = pn512_polling_state_polling_nfc_b_anticollision; 01143 pn512_initiator_isob_anticollision(pPN512, pn512_poll_iteration); 01144 return; 01145 } 01146 01147 if (pPN512->poll.state == pn512_polling_state_polling_nfc_b_anticollision) { 01148 NFC_DBG("pn512_polling_state_polling_nfc_b_anticollision"); 01149 01150 if (ret == NFC_ERR_NOPEER) { 01151 NFC_DBG("Not found"); 01152 // Continue with NFC F 01153 pPN512->poll.state = pn512_polling_state_polling_nfc_f_start; 01154 continue; 01155 } 01156 01157 if ((ret == NFC_OK) 01158 && (pPN512->config.options.bail_at_first_tech 01159 || (pPN512->transceiver.remote_targets_count 01160 == MUNFC_MAX_REMOTE_TARGETS))) { 01161 // At least one target found, exit polling loop 01162 pn512_poll_callback(pPN512, NFC_OK); 01163 return; 01164 } 01165 01166 if (ret == NFC_ERR_ABORTED) { 01167 pn512_poll_callback(pPN512, ret); 01168 return; 01169 } 01170 01171 // Continue with NFC F 01172 pPN512->poll.state = pn512_polling_state_polling_nfc_f_start; 01173 continue; 01174 } 01175 01176 if (pPN512->poll.state == pn512_polling_state_polling_nfc_f_start) { 01177 NFC_DBG("pn512_polling_state_polling_nfc_f_start"); 01178 01179 //Check if Felica is needed 01180 bool nfc_f = pPN512->config.initiators.nfc_type3 || pPN512->config.initiators.nfc_nfc_dep_f_212; 01181 if (!nfc_f) { 01182 // Wrap up 01183 pPN512->poll.state = pn512_polling_state_finish_polling; 01184 continue; 01185 } 01186 01187 pPN512->transceiver.initiator_ntarget = true; 01188 pn512_framing_set(pPN512, nfc_framing_initiator_f_212); 01189 01190 pPN512->poll.state = pn512_polling_state_polling_nfc_f_gt; 01191 pn512_poll_delay(pPN512, 20); // Guard time for Felica is 20 ms 01192 return; 01193 } 01194 01195 if (pPN512->poll.state == pn512_polling_state_polling_nfc_f_gt) { 01196 NFC_DBG("pn512_polling_state_polling_nfc_f_gt"); 01197 01198 // Start anticollision 01199 pPN512->poll.state = pn512_polling_state_polling_nfc_f_anticollision; 01200 pn512_initiator_felica_anticollision(pPN512, pn512_poll_iteration); 01201 return; 01202 } 01203 01204 if (pPN512->poll.state == pn512_polling_state_polling_nfc_f_anticollision) { 01205 NFC_DBG("pn512_polling_state_polling_nfc_f_anticollision"); 01206 01207 if (ret == NFC_ERR_NOPEER) { 01208 NFC_DBG("Not found"); 01209 // Resolve polling 01210 pPN512->poll.state = pn512_polling_state_finish_polling; 01211 continue; 01212 } 01213 01214 if ((ret == NFC_OK) && (pPN512->config.options.bail_at_first_tech || (pPN512->transceiver.remote_targets_count == MUNFC_MAX_REMOTE_TARGETS))) { 01215 // At least one target found, exit polling loop 01216 pn512_poll_callback(pPN512, NFC_OK); 01217 return; 01218 } 01219 01220 if (ret == NFC_ERR_ABORTED) { 01221 pn512_poll_callback(pPN512, ret); 01222 return; 01223 } 01224 01225 // Resolve polling 01226 pPN512->poll.state = pn512_polling_state_finish_polling; 01227 continue; 01228 } 01229 01230 if (pPN512->poll.state == pn512_polling_state_finish_polling) { 01231 if (pPN512->transceiver.remote_targets_count > 0) { 01232 pn512_poll_callback(pPN512, NFC_OK); 01233 } else { 01234 pn512_poll_callback(pPN512, NFC_ERR_NOPEER); 01235 } 01236 return; 01237 } 01238 01239 } while (true); 01240 } 01241 01242 // Main polling loop function 01243 void pn512_poll_hw(pn512_t *pPN512, pn512_cb_t cb) 01244 { 01245 nfc_transceiver_t *pTransceiver = (nfc_transceiver_t *)pPN512; 01246 pPN512->poll.cb = cb; 01247 01248 //Reset active state 01249 pTransceiver->initiator_ntarget = false; 01250 memset(&pTransceiver->active_tech, 0, sizeof(nfc_tech_t)); 01251 01252 //Reset discovered targets 01253 pTransceiver->remote_targets_count = 0; 01254 01255 //Initialize state machine 01256 pPN512->poll.state = pn512_polling_state_start_listening; 01257 01258 if (!pn512_config_target(pPN512) && !pn512_config_initiator(pPN512)) { 01259 pn512_poll_callback(pPN512, NFC_ERR_PARAMS); 01260 return; 01261 } 01262 01263 //First iteration 01264 pn512_poll_iteration(pPN512, NFC_OK); 01265 }
Generated on Tue Aug 9 2022 00:37:17 by
1.7.2