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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
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 ( 00541 pPN512->anticollision.iso_b.slots_num_exponent == 0 00542 //&& (pPN512->anticollision.iso_b.slot_number == 0) 00543 ) { 00544 wup |= 0x8; // Send Wake-Up command on first iteration 00545 } 00546 ac_buffer_builder_write_nu8(pDataOutBldr, wup | (pPN512->anticollision.iso_b.slots_num_exponent & 0x7)); // Param: number of slots 00547 } else { 00548 // Just send slot marker 00549 ac_buffer_builder_write_nu8(pDataOutBldr, REQB | ((pPN512->anticollision.iso_b.slot_number & 0xf) << 4)); 00550 } 00551 00552 pn512_set_crc((nfc_transceiver_t *)pPN512, true, true); 00553 pn512_set_timeout((nfc_transceiver_t *)pPN512, 18); 00554 pn512_set_write((nfc_transceiver_t *)pPN512, ac_buffer_builder_buffer(pDataOutBldr)); 00555 pn512_transceive_hw(pPN512, pn512_transceive_mode_transceive, pn512_initiator_isob_anticollision_atqb); 00556 } 00557 00558 void pn512_initiator_isob_anticollision_atqb(pn512_t *pPN512, nfc_err_t ret) 00559 { 00560 // Three cases: 00561 // - 1 response --> store response, halt PICC and check next slot number 00562 // - No response --> check next slot number 00563 // - Collision --> check next slot number but we will have to increment number of slots 00564 ac_buffer_t *pResp = pn512_get_read((nfc_transceiver_t *)pPN512); 00565 00566 if (ret && (ret != NFC_ERR_COLLISION) && (ret != NFC_ERR_WRONG_COMM) && (ret != NFC_ERR_TIMEOUT)) { 00567 NFC_WARN("Did not receive ATQB: error %u", ret); 00568 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00569 return; 00570 } 00571 00572 // Increment slot number 00573 pPN512->anticollision.iso_b.slot_number++; 00574 00575 if ((ret == NFC_ERR_COLLISION) || (ret == NFC_ERR_WRONG_COMM)) { 00576 pPN512->anticollision.iso_b.more_targets = true; 00577 } else if (!ret) { 00578 pPN512->anticollision.iso_b.found_one = true; 00579 00580 // Decode ATQB 00581 if (ac_buffer_reader_readable(pResp) != 12) { 00582 NFC_WARN("Wrong length (%u bytes)", ac_buffer_reader_readable(pResp)); 00583 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00584 return; 00585 } 00586 00587 NFC_DBG("Got ATQB:"); 00588 NFC_DBG_BLOCK(ac_buffer_dump(pResp);) 00589 00590 // Check first byte 00591 uint8_t atqb0 = ac_buffer_read_nu8(pResp); 00592 if (atqb0 != 0x50) { 00593 NFC_WARN("Wrong first byte for ATQB: %02X", atqb0); 00594 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00595 return; 00596 } 00597 00598 memset(&pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type, 0, sizeof(nfc_tech_t)); 00599 pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type.nfc_iso_dep_b = true; 00600 00601 // Save PUPI, application data & protocol info 00602 ac_buffer_read_n_bytes(pResp, pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcB.pupi, 4); 00603 ac_buffer_read_n_bytes(pResp, pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcB.application_data, 4); 00604 ac_buffer_read_n_bytes(pResp, pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcB.protocol_info, 3); 00605 00606 // Valid target detected 00607 pPN512->transceiver.active_tech = pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type; 00608 pPN512->transceiver.remote_targets_count++; 00609 00610 if (!pPN512->config.options.bail_at_first_target 00611 && (pPN512->anticollision.iso_b.more_targets || (pPN512->anticollision.iso_b.slot_number < (1 << pPN512->anticollision.iso_b.slots_num_exponent))) 00612 && (pPN512->transceiver.remote_targets_count < MUNFC_MAX_REMOTE_TARGETS)) { 00613 // Halt target and continue with others 00614 ac_buffer_builder_t *pDataOutBldr = &pPN512->readBufBldr; 00615 ac_buffer_builder_reset(pDataOutBldr); 00616 00617 // Halt PICC and move on to the next slot 00618 00619 //HALTB 00620 ac_buffer_builder_write_nu8(pDataOutBldr, HALTB); 00621 ac_buffer_builder_write_n_bytes(pDataOutBldr, pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count - 1].nfcB.pupi, 4); 00622 00623 pn512_set_crc((nfc_transceiver_t *)pPN512, true, true); 00624 pn512_set_timeout((nfc_transceiver_t *)pPN512, 30); 00625 pn512_set_write((nfc_transceiver_t *)pPN512, ac_buffer_builder_buffer(pDataOutBldr)); 00626 pn512_transceive_hw(pPN512, pn512_transceive_mode_transceive, pn512_initiator_isob_anticollision_haltb_resp); 00627 return; 00628 } else { 00629 pn512_initiator_isob_anticollision_complete(pPN512); 00630 return; 00631 } 00632 } 00633 00634 // Move on to the next slot 00635 pn512_initiator_isob_anticollision_next_slot(pPN512); 00636 } 00637 00638 void pn512_initiator_isob_anticollision_next_slot(pn512_t *pPN512) 00639 { 00640 if (pPN512->anticollision.iso_b.slot_number >= (1 << pPN512->anticollision.iso_b.slots_num_exponent)) { 00641 if (!pPN512->anticollision.iso_b.more_targets) { 00642 // No further collisions to resolve 00643 pn512_initiator_isob_anticollision_complete(pPN512); 00644 return; 00645 } 00646 if (pPN512->anticollision.iso_b.slots_num_exponent >= 4) { 00647 // Cannot handle more than 16 slots 00648 pn512_initiator_isob_anticollision_complete(pPN512); 00649 return; 00650 } 00651 pPN512->anticollision.iso_b.slots_num_exponent++; 00652 pPN512->anticollision.iso_b.slot_number = 0; 00653 } 00654 pn512_initiator_isob_anticollision_reqb(pPN512); 00655 } 00656 00657 void pn512_initiator_isob_anticollision_haltb_resp(pn512_t *pPN512, nfc_err_t ret) 00658 { 00659 // Check for response 00660 if (ret) { 00661 NFC_WARN("Did not receive HALTB response: error %u", ret); 00662 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00663 return; 00664 } 00665 00666 ac_buffer_t *pResp = pn512_get_read((nfc_transceiver_t *)pPN512); 00667 00668 if (ac_buffer_reader_readable(pResp) != 1) { 00669 NFC_WARN("Wrong length (%u bytes)", ac_buffer_reader_readable(pResp)); 00670 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00671 return; 00672 } 00673 00674 NFC_DBG("Got HALTB response:"); 00675 NFC_DBG_BLOCK(ac_buffer_dump(pResp);) 00676 00677 // Check byte 00678 uint8_t haltbr = ac_buffer_read_nu8(pResp); 00679 if (haltbr != 0x00) { 00680 NFC_WARN("Wrong byte for HALTB response: %02X", haltbr); 00681 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00682 return; 00683 } 00684 00685 // PICC halted, move to next slot 00686 pn512_initiator_isob_anticollision_next_slot(pPN512); 00687 } 00688 00689 void pn512_initiator_isob_anticollision_complete(pn512_t *pPN512) 00690 { 00691 if (pPN512->anticollision.iso_b.found_one) { 00692 pn512_anticollision_callback(pPN512, NFC_OK); 00693 } else { 00694 pn512_anticollision_callback(pPN512, NFC_ERR_NOPEER); 00695 } 00696 } 00697 00698 // Felica 00699 static void pn512_initiator_felica_anticollision(pn512_t *pPN512, pn512_cb_t cb); 00700 static void pn512_initiator_felica_anticollision_reqc(pn512_t *pPN512); 00701 static void pn512_initiator_felica_anticollision_atqc(pn512_t *pPN512, nfc_err_t ret); 00702 static void pn512_initiator_felica_anticollision_complete(pn512_t *pPN512); 00703 00704 #define REQC 0x00 00705 00706 void pn512_initiator_felica_anticollision(pn512_t *pPN512, pn512_cb_t cb) 00707 { 00708 pPN512->anticollision.cb = cb; 00709 00710 // Reset transceive mode 00711 pPN512->transceive.mode = pn512_transceive_mode_idle; 00712 00713 pn512_initiator_felica_anticollision_reqc(pPN512); 00714 } 00715 00716 void pn512_initiator_felica_anticollision_reqc(pn512_t *pPN512) 00717 { 00718 ac_buffer_builder_t *pDataOutBldr = &pPN512->readBufBldr; 00719 ac_buffer_builder_reset(pDataOutBldr); 00720 00721 ac_buffer_builder_write_nu8(pDataOutBldr, 6); //Length 00722 ac_buffer_builder_write_nu8(pDataOutBldr, REQC); 00723 ac_buffer_builder_write_nu16(pDataOutBldr, 0xFFFF); //Any system code 00724 ac_buffer_builder_write_nu8(pDataOutBldr, 0x00); // Padding 00725 ac_buffer_builder_write_nu8(pDataOutBldr, 0x07); // 8 time slots, more would overflow the rx buffer if many cards responded 00726 00727 pn512_set_crc((nfc_transceiver_t *)pPN512, true, true); 00728 pn512_set_timeout((nfc_transceiver_t *)pPN512, 13); //8 timeslots at 212kbps 00729 pn512_set_write((nfc_transceiver_t *)pPN512, ac_buffer_builder_buffer(pDataOutBldr)); 00730 00731 pn512_framing_rx_multiple_enable(pPN512); // Set RxMultiple bit 00732 00733 pn512_transceive_hw(pPN512, pn512_transceive_mode_transceive, pn512_initiator_felica_anticollision_atqc); 00734 } 00735 00736 void pn512_initiator_felica_anticollision_atqc(pn512_t *pPN512, nfc_err_t ret) 00737 { 00738 ac_buffer_t *pResp = pn512_get_read((nfc_transceiver_t *)pPN512); 00739 00740 if (ret || (ac_buffer_reader_readable(pResp) == 0)) { 00741 NFC_WARN("Did not receive ATQC: error %d", ret); 00742 pn512_anticollision_callback(pPN512, NFC_ERR_NOPEER); 00743 return; 00744 } 00745 00746 // We might have multiple responses 00747 NFC_DBG("Got ATQC:"); 00748 NFC_DBG_BLOCK(ac_buffer_dump(pResp);) 00749 00750 while (ac_buffer_reader_readable(pResp) > 0) { 00751 if (ac_buffer_reader_readable(pResp) != 18 + 1) { // ATQC is 18 bytes, 1 byte for errors added by PN512 00752 NFC_WARN("Wrong length (%d bytes)", ac_buffer_reader_readable(pResp)); 00753 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00754 return; 00755 } 00756 00757 // First byte is length, check that it's correct 00758 uint8_t frame_length = ac_buffer_read_nu8(pResp); 00759 uint8_t atqc0 = ac_buffer_read_nu8(pResp); 00760 if ((frame_length != 18) || (atqc0 != 0x01)) { 00761 NFC_WARN("Wrong ATQC frame"); 00762 pn512_anticollision_callback(pPN512, NFC_ERR_PROTOCOL); 00763 return; 00764 } 00765 00766 // Read NFCID2 00767 ac_buffer_read_n_bytes(pResp, pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcF.nfcid2, 8); 00768 00769 // Discard padding bytes 00770 ac_buffer_read_n_skip(pResp, 8); 00771 00772 // Read error register 00773 uint8_t err_reg = ac_buffer_read_nu8(pResp); 00774 if (err_reg & 0x1f) { 00775 // Error within this time slot, skip 00776 continue; 00777 } 00778 00779 //Populate tech accordingly 00780 memset(&pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type, 0, sizeof(nfc_tech_t)); 00781 if ( 00782 (pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcF.nfcid2[0] == 0x01) 00783 && (pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].nfcF.nfcid2[1] == 0xFE) 00784 ) { 00785 // NFC-DEP supported 00786 pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type.nfc_nfc_dep_f_212 = 1; 00787 } else { 00788 // Type 3 supported 00789 pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type.nfc_type3 = 1; 00790 } 00791 pPN512->transceiver.active_tech = pPN512->transceiver.remote_targets[pPN512->transceiver.remote_targets_count].type; 00792 pPN512->transceiver.remote_targets_count++; 00793 00794 // Only continue if we can have more targets 00795 if (!pPN512->config.options.bail_at_first_target 00796 && (pPN512->transceiver.remote_targets_count < MUNFC_MAX_REMOTE_TARGETS)) { 00797 continue; 00798 } 00799 break; 00800 } 00801 00802 pn512_initiator_felica_anticollision_complete(pPN512); 00803 } 00804 00805 void pn512_initiator_felica_anticollision_complete(pn512_t *pPN512) 00806 { 00807 pn512_anticollision_callback(pPN512, NFC_OK); 00808 } 00809 00810 void pn512_poll_setup(pn512_t *pPN512) 00811 { 00812 bool target = pPN512->config.targets.nfc_type2 00813 || pPN512->config.targets.nfc_type3 00814 || pPN512->config.targets.nfc_iso_dep_a 00815 || pPN512->config.targets.nfc_nfc_dep_a 00816 || pPN512->config.targets.nfc_nfc_dep_f_212 00817 || pPN512->config.targets.nfc_nfc_dep_f_424; 00818 00819 // No need for initiator-specific configuration at this stage, but keep this just in case 00820 // bool initiator = pPN512->config.initiators.nfc_type1 00821 // || pPN512->config.initiators.nfc_type2 00822 // || pPN512->config.initiators.nfc_type3 00823 // || pPN512->config.initiators.nfc_iso_dep_a 00824 // || pPN512->config.initiators.nfc_nfc_dep_a 00825 // || pPN512->config.initiators.nfc_nfc_dep_f_212 00826 // || pPN512->config.initiators.nfc_nfc_dep_f_424; 00827 00828 if (target) { 00829 NFC_DBG("Configure anticoll/polling response"); 00830 //Setup ATQA, SAK and Felica polling response 00831 pn512_fifo_clear(pPN512); 00832 00833 ac_buffer_builder_t *pDataCfgBldr = &pPN512->readBufBldr; 00834 ac_buffer_builder_reset(pDataCfgBldr); 00835 00836 //Write ATQA 00837 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x04); 00838 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00839 00840 //Write NFCID1 (0s as it will be randomly generated) - first byte will be set to 0x08 by HW according to NFC-IP1 00841 for (int i = 0; i < 3; i++) { 00842 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00843 } 00844 00845 //Write SAK 00846 uint8_t sak = 0x00; //Default SAK (UID complete) 00847 if (pPN512->config.targets.nfc_iso_dep_a) { 00848 sak |= 0x20; //This target is ISO-14443A-4 compliant 00849 } 00850 if (pPN512->config.targets.nfc_nfc_dep_a) { 00851 sak |= 0x40; //This target is NFC-IP1 compliant 00852 } 00853 ac_buffer_builder_write_nu8(pDataCfgBldr, sak); 00854 00855 //Write NFCID2 (xx 0xfe according to NFC-IP1 and 0s as 6 bytes will be randomly generated) 00856 if (pPN512->config.targets.nfc_nfc_dep_f_212 || pPN512->config.targets.nfc_nfc_dep_f_424) { 00857 //Byte 1 is 0x01 if supporting NFC-IP1 00858 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x01); 00859 } else if (pPN512->config.targets.nfc_type3) { //NFC-IP will have priority over type 3 tag emulation 00860 //Byte 1 is 0x02 if supporting Type 3 tag platform 00861 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x02); 00862 } else { 00863 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00864 } 00865 ac_buffer_builder_write_nu8(pDataCfgBldr, 0xFE); 00866 00867 for (int i = 0; i < 6; i++) { 00868 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00869 } 00870 00871 //2 PAD0 bytes (Felica spec) - this would code the manufacturer + IC code (0xFFFF for NFC-IP1 tags) 00872 ac_buffer_builder_write_nu8(pDataCfgBldr, 0xFF); 00873 ac_buffer_builder_write_nu8(pDataCfgBldr, 0xFF); 00874 00875 //3 PAD1 bytes 00876 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00877 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00878 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00879 00880 if (!(pPN512->config.targets.nfc_nfc_dep_f_212 || pPN512->config.targets.nfc_nfc_dep_f_424) 00881 && pPN512->config.targets.nfc_type3) { 00882 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x01); //MRTI Check 00883 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x01); //MRTI Update 00884 } else { 00885 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00886 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00887 } 00888 00889 //1 PAD2 byte 00890 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00891 00892 //2 system code bytes 00893 if (!(pPN512->config.targets.nfc_nfc_dep_f_212 || pPN512->config.targets.nfc_nfc_dep_f_424) 00894 && pPN512->config.targets.nfc_type3) { 00895 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x12); 00896 ac_buffer_builder_write_nu8(pDataCfgBldr, 0xFC); 00897 } else { 00898 ac_buffer_builder_write_nu8(pDataCfgBldr, 0xFF); //Wildcard system code 00899 ac_buffer_builder_write_nu8(pDataCfgBldr, 0xFF); 00900 } 00901 00902 //Write NFCID3 00903 ac_buffer_builder_write_nu8(pDataCfgBldr, 0x00); 00904 00905 pn512_fifo_write(pPN512, ac_buffer_builder_buffer(pDataCfgBldr)); 00906 00907 pn512_cmd_exec(pPN512, PN512_CMD_CONFIG); 00908 pn512_cmd_wait_idle(pPN512, -1); 00909 00910 NFC_DBG("Overwrite NFCIDs with random numbers"); 00911 00912 //Overwrite NFCIDs with random numbers 00913 pn512_cmd_exec(pPN512, PN512_CMD_RNDIDG); 00914 pn512_cmd_wait_idle(pPN512, -1); 00915 } 00916 } 00917 00918 static void pn512_poll_iteration(pn512_t *pPN512, nfc_err_t ret); 00919 static void pn512_poll_delay_complete(uint32_t events, void *pUserData) 00920 { 00921 pn512_t *pPN512 = (pn512_t *) pUserData; 00922 00923 if (events & EVENT_ABORTED) { 00924 pn512_poll_callback(pPN512, NFC_ERR_ABORTED); 00925 return; 00926 } 00927 00928 pn512_poll_iteration(pPN512, NFC_OK); 00929 } 00930 00931 static void pn512_poll_delay(pn512_t *pPN512, uint32_t timeout) 00932 { 00933 task_init(&pPN512->transceiver.task, EVENT_TIMEOUT, timeout, pn512_poll_delay_complete, pPN512); 00934 nfc_scheduler_queue_task(&pPN512->transceiver.scheduler, &pPN512->transceiver.task); 00935 } 00936 00937 void pn512_poll_iteration(pn512_t *pPN512, nfc_err_t ret) 00938 { 00939 do { 00940 if (pPN512->poll.state == pn512_polling_state_start_listening) { 00941 NFC_DBG("pn512_polling_state_start_listening"); 00942 // Start with listening 00943 if (!pn512_config_target(pPN512)) { 00944 // Otherwise switch to next step 00945 pPN512->poll.state = pn512_polling_state_start_polling; 00946 continue; 00947 } 00948 00949 pPN512->poll.state = pn512_polling_state_listen_wait_for_remote_field; 00950 00951 // Shortcut if target is halted (means RF field is still here) 00952 if (pn512_register_read(pPN512, PN512_REG_MIFNFC) & 0x04) { 00953 continue; 00954 } 00955 00956 // Fix for PN512 bug that sometimes detects its own RF field 00957 // if(pPN512->rf_on) 00958 { 00959 //Switch RF field off 00960 pn512_rf_field_switch_off(pPN512); 00961 NFC_DBG("RF field switched off"); 00962 } 00963 00964 NFC_DBG("Target anticollision"); 00965 00966 bool iso14443a = pPN512->config.targets.nfc_type2 || pPN512->config.targets.nfc_iso_dep_a || pPN512->config.targets.nfc_nfc_dep_a; 00967 bool felica = pPN512->config.targets.nfc_type3 || pPN512->config.targets.nfc_nfc_dep_f_212 || pPN512->config.targets.nfc_nfc_dep_f_424; 00968 00969 NFC_DBG("Switch in target mode and set framing: ISO A: %s; Felica: %s", iso14443a ? "Yes" : "No", felica ? "Yes" : "No"); 00970 00971 //Switch in target mode 00972 if (iso14443a && felica) { 00973 pn512_framing_set(pPN512, nfc_framing_target_mode_detector); 00974 } else if (iso14443a) { 00975 pn512_framing_set(pPN512, nfc_framing_target_a_106); 00976 } else if (felica) { 00977 pn512_framing_set(pPN512, nfc_framing_target_f_212); 00978 } 00979 00980 pn512_rf_field_wait_for_external(pPN512, pPN512->config.options.listen_for, pn512_poll_iteration); 00981 return; 00982 } 00983 00984 if (pPN512->poll.state == pn512_polling_state_listen_wait_for_remote_field) { 00985 NFC_DBG("pn512_polling_state_listen_wait_for_remote_field"); 00986 00987 if (!pn512_config_target(pPN512)) { 00988 // Otherwise switch to next step 00989 pPN512->poll.state = pn512_polling_state_start_listening; 00990 continue; 00991 } 00992 00993 if (ret == NFC_ERR_TIMEOUT) { 00994 // Continue polling 00995 pPN512->poll.state = pn512_polling_state_start_polling; 00996 continue; 00997 } 00998 00999 if (ret) { 01000 pn512_poll_callback(pPN512, ret); 01001 return; 01002 } 01003 01004 pPN512->poll.state = pn512_polling_state_listen_anticollision; 01005 01006 pn512_target_anticollision(pPN512, pn512_poll_iteration); 01007 return; 01008 } 01009 01010 if (pPN512->poll.state == pn512_polling_state_listen_anticollision) { 01011 NFC_DBG("pn512_polling_state_listen_anticollision"); 01012 01013 if (ret == NFC_ERR_FIELD) { 01014 // This means that a remote field was dropped - give it another chance 01015 pPN512->poll.state = pn512_polling_state_listen_wait_for_remote_field; 01016 pn512_rf_field_switch_off(pPN512); 01017 pn512_rf_field_wait_for_external(pPN512, pPN512->config.options.listen_for, pn512_poll_iteration); 01018 return; 01019 } 01020 01021 if (ret) { 01022 pn512_poll_callback(pPN512, ret); 01023 return; 01024 } 01025 01026 // Be safe, not sure what the framing is 01027 pPN512->framing = nfc_framing_unknown; 01028 01029 pn512_poll_callback(pPN512, NFC_OK); 01030 return; 01031 } 01032 01033 if (pPN512->poll.state == pn512_polling_state_start_polling) { 01034 NFC_DBG("pn512_polling_state_start_polling"); 01035 01036 if (!pn512_config_initiator(pPN512)) { 01037 // Otherwise switch to next step 01038 pPN512->poll.state = pn512_polling_state_start_listening; 01039 continue; 01040 } 01041 01042 // Try to activate RF field 01043 pPN512->poll.state = pn512_polling_state_rf_collision_avoidance; 01044 01045 pn512_rf_field_nfcip1_rf_collision_avoidance(pPN512, pn512_poll_iteration); 01046 return; 01047 } 01048 01049 if (pPN512->poll.state == pn512_polling_state_rf_collision_avoidance) { 01050 NFC_DBG("pn512_polling_state_rf_collision_avoidance"); 01051 01052 if (ret) { 01053 pn512_poll_callback(pPN512, ret); 01054 return; 01055 } 01056 01057 NFC_DBG("Own RF field is %s", pPN512->rf_on ? "on" : "off"); 01058 01059 if (!pPN512->rf_on) { 01060 // Go back to listening, target framing is still valid so no need to reset it 01061 pPN512->poll.state = pn512_polling_state_listen_wait_for_remote_field; 01062 continue; 01063 } 01064 01065 pPN512->poll.state = pn512_polling_state_polling_nfc_a_start; 01066 } 01067 01068 if (pPN512->poll.state == pn512_polling_state_polling_nfc_a_start) { 01069 NFC_DBG("pn512_polling_state_polling_nfc_a_start"); 01070 01071 //Check if ISO A is needed 01072 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 01073 if (!nfc_a) { 01074 // Continue with NFC B 01075 pPN512->poll.state = pn512_polling_state_polling_nfc_b_start; 01076 continue; 01077 } 01078 01079 pPN512->transceiver.initiator_ntarget = true; 01080 pn512_framing_set(pPN512, nfc_framing_initiator_a_106); 01081 01082 pPN512->poll.state = pn512_polling_state_polling_nfc_a_gt; 01083 pn512_poll_delay(pPN512, 10 + 5); // Guard time for ISO A is 5 ms 01084 return; 01085 } 01086 01087 if (pPN512->poll.state == pn512_polling_state_polling_nfc_a_gt) { 01088 NFC_DBG("pn512_polling_state_polling_nfc_a_gt"); 01089 01090 // Start anticollision 01091 pPN512->poll.state = pn512_polling_state_polling_nfc_a_anticollision; 01092 pn512_initiator_isoa_anticollision(pPN512, pn512_poll_iteration); 01093 return; 01094 } 01095 01096 if (pPN512->poll.state == pn512_polling_state_polling_nfc_a_anticollision) { 01097 NFC_DBG("pn512_polling_state_polling_nfc_a_anticollision"); 01098 01099 if (ret == NFC_ERR_NOPEER) { 01100 NFC_DBG("Not found"); 01101 // Continue with NFC B 01102 pPN512->poll.state = pn512_polling_state_polling_nfc_b_start; 01103 continue; 01104 } 01105 01106 if ((ret == NFC_OK) && (pPN512->config.options.bail_at_first_tech || (pPN512->transceiver.remote_targets_count == MUNFC_MAX_REMOTE_TARGETS))) { 01107 // At least one target found, exit polling loop 01108 pn512_poll_callback(pPN512, NFC_OK); 01109 return; 01110 } 01111 01112 if (ret == NFC_ERR_ABORTED) { 01113 pn512_poll_callback(pPN512, ret); 01114 return; 01115 } 01116 01117 // Continue with NFC B 01118 pPN512->poll.state = pn512_polling_state_polling_nfc_b_start; 01119 continue; 01120 } 01121 01122 if (pPN512->poll.state == pn512_polling_state_polling_nfc_b_start) { 01123 NFC_DBG("pn512_polling_state_polling_nfc_b_start"); 01124 01125 //Check if ISO B is needed 01126 bool nfc_b = pPN512->config.initiators.nfc_iso_dep_b; 01127 if (!nfc_b) { 01128 // Continue with NFC F 01129 pPN512->poll.state = pn512_polling_state_polling_nfc_f_start; 01130 continue; 01131 } 01132 01133 pPN512->transceiver.initiator_ntarget = true; 01134 pn512_framing_set(pPN512, nfc_framing_initiator_b_106); 01135 01136 pPN512->poll.state = pn512_polling_state_polling_nfc_b_gt; 01137 pn512_poll_delay(pPN512, 10 + 5); // Guard time for ISO B is 5 ms 01138 return; 01139 } 01140 01141 if (pPN512->poll.state == pn512_polling_state_polling_nfc_b_gt) { 01142 NFC_DBG("pn512_polling_state_polling_nfc_b_gt"); 01143 01144 // Start anticollision 01145 pPN512->poll.state = pn512_polling_state_polling_nfc_b_anticollision; 01146 pn512_initiator_isob_anticollision(pPN512, pn512_poll_iteration); 01147 return; 01148 } 01149 01150 if (pPN512->poll.state == pn512_polling_state_polling_nfc_b_anticollision) { 01151 NFC_DBG("pn512_polling_state_polling_nfc_b_anticollision"); 01152 01153 if (ret == NFC_ERR_NOPEER) { 01154 NFC_DBG("Not found"); 01155 // Continue with NFC F 01156 pPN512->poll.state = pn512_polling_state_polling_nfc_f_start; 01157 continue; 01158 } 01159 01160 if ((ret == NFC_OK) 01161 && (pPN512->config.options.bail_at_first_tech 01162 || (pPN512->transceiver.remote_targets_count 01163 == MUNFC_MAX_REMOTE_TARGETS))) { 01164 // At least one target found, exit polling loop 01165 pn512_poll_callback(pPN512, NFC_OK); 01166 return; 01167 } 01168 01169 if (ret == NFC_ERR_ABORTED) { 01170 pn512_poll_callback(pPN512, ret); 01171 return; 01172 } 01173 01174 // Continue with NFC F 01175 pPN512->poll.state = pn512_polling_state_polling_nfc_f_start; 01176 continue; 01177 } 01178 01179 if (pPN512->poll.state == pn512_polling_state_polling_nfc_f_start) { 01180 NFC_DBG("pn512_polling_state_polling_nfc_f_start"); 01181 01182 //Check if Felica is needed 01183 bool nfc_f = pPN512->config.initiators.nfc_type3 || pPN512->config.initiators.nfc_nfc_dep_f_212; 01184 if (!nfc_f) { 01185 // Wrap up 01186 pPN512->poll.state = pn512_polling_state_finish_polling; 01187 continue; 01188 } 01189 01190 pPN512->transceiver.initiator_ntarget = true; 01191 pn512_framing_set(pPN512, nfc_framing_initiator_f_212); 01192 01193 pPN512->poll.state = pn512_polling_state_polling_nfc_f_gt; 01194 pn512_poll_delay(pPN512, 20); // Guard time for Felica is 20 ms 01195 return; 01196 } 01197 01198 if (pPN512->poll.state == pn512_polling_state_polling_nfc_f_gt) { 01199 NFC_DBG("pn512_polling_state_polling_nfc_f_gt"); 01200 01201 // Start anticollision 01202 pPN512->poll.state = pn512_polling_state_polling_nfc_f_anticollision; 01203 pn512_initiator_felica_anticollision(pPN512, pn512_poll_iteration); 01204 return; 01205 } 01206 01207 if (pPN512->poll.state == pn512_polling_state_polling_nfc_f_anticollision) { 01208 NFC_DBG("pn512_polling_state_polling_nfc_f_anticollision"); 01209 01210 if (ret == NFC_ERR_NOPEER) { 01211 NFC_DBG("Not found"); 01212 // Resolve polling 01213 pPN512->poll.state = pn512_polling_state_finish_polling; 01214 continue; 01215 } 01216 01217 if ((ret == NFC_OK) && (pPN512->config.options.bail_at_first_tech || (pPN512->transceiver.remote_targets_count == MUNFC_MAX_REMOTE_TARGETS))) { 01218 // At least one target found, exit polling loop 01219 pn512_poll_callback(pPN512, NFC_OK); 01220 return; 01221 } 01222 01223 if (ret == NFC_ERR_ABORTED) { 01224 pn512_poll_callback(pPN512, ret); 01225 return; 01226 } 01227 01228 // Resolve polling 01229 pPN512->poll.state = pn512_polling_state_finish_polling; 01230 continue; 01231 } 01232 01233 if (pPN512->poll.state == pn512_polling_state_finish_polling) { 01234 if (pPN512->transceiver.remote_targets_count > 0) { 01235 pn512_poll_callback(pPN512, NFC_OK); 01236 } else { 01237 pn512_poll_callback(pPN512, NFC_ERR_NOPEER); 01238 } 01239 return; 01240 } 01241 01242 } while (true); 01243 } 01244 01245 // Main polling loop function 01246 void pn512_poll_hw(pn512_t *pPN512, pn512_cb_t cb) 01247 { 01248 nfc_transceiver_t *pTransceiver = (nfc_transceiver_t *)pPN512; 01249 pPN512->poll.cb = cb; 01250 01251 //Reset active state 01252 pTransceiver->initiator_ntarget = false; 01253 memset(&pTransceiver->active_tech, 0, sizeof(nfc_tech_t)); 01254 01255 //Reset discovered targets 01256 pTransceiver->remote_targets_count = 0; 01257 01258 //Initialize state machine 01259 pPN512->poll.state = pn512_polling_state_start_listening; 01260 01261 if (!pn512_config_target(pPN512) && !pn512_config_initiator(pPN512)) { 01262 pn512_poll_callback(pPN512, NFC_ERR_PARAMS); 01263 return; 01264 } 01265 01266 //First iteration 01267 pn512_poll_iteration(pPN512, NFC_OK); 01268 }
Generated on Tue Jul 12 2022 13:54:41 by
