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.
rfal_nfca.cpp
00001 00002 /****************************************************************************** 00003 * @attention 00004 * 00005 * <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2> 00006 * 00007 * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License"); 00008 * You may not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at: 00010 * 00011 * http://www.st.com/myliberty 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, 00015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, 00016 * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY, 00017 * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. 00018 * See the License for the specific language governing permissions and 00019 * limitations under the License. 00020 * 00021 ******************************************************************************/ 00022 00023 /* 00024 * PROJECT: ST25R391x firmware 00025 * $Revision: $ 00026 * LANGUAGE: ISO C99 00027 */ 00028 00029 /*! \file rfal_nfca.c 00030 * 00031 * \author Gustavo Patricio 00032 * 00033 * \brief Provides several NFC-A convenience methods and definitions 00034 * 00035 * It provides a Poller (ISO14443A PCD) interface and as well as 00036 * some NFC-A Listener (ISO14443A PICC) helpers. 00037 * 00038 * The definitions and helpers methods provided by this module are only 00039 * up to ISO14443-3 layer 00040 * 00041 */ 00042 00043 /* 00044 ****************************************************************************** 00045 * INCLUDES 00046 ****************************************************************************** 00047 */ 00048 #include <platform1.h> 00049 #include "rfal_nfca.h" 00050 #include "utils.h" 00051 00052 /* 00053 ****************************************************************************** 00054 * ENABLE SWITCH 00055 ****************************************************************************** 00056 */ 00057 00058 #ifndef RFAL_FEATURE_NFCA 00059 #error " RFAL: Module configuration missing. Please enable/disable NFC-A module by setting: RFAL_FEATURE_NFCA " 00060 #endif 00061 00062 #if RFAL_FEATURE_NFCA 00063 00064 /* 00065 ****************************************************************************** 00066 * GLOBAL DEFINES 00067 ****************************************************************************** 00068 */ 00069 00070 #define RFAL_NFCA_SLP_FWT rfalConvMsTo1fc(1) /*!< Check 1ms for any modulation ISO14443-3 6.4.3 */ 00071 #define RFAL_NFCA_SLP_CMD 0x50 /*!< SLP cmd (byte1) Digital 1.1 6.9.1 & Table 20 */ 00072 #define RFAL_NFCA_SLP_BYTE2 0x00 /*!< SLP byte2 Digital 1.1 6.9.1 & Table 20 */ 00073 #define RFAL_NFCA_SLP_CMD_POS 0 /*!< SLP cmd position Digital 1.1 6.9.1 & Table 20 */ 00074 #define RFAL_NFCA_SLP_BYTE2_POS 1 /*!< SLP byte2 position Digital 1.1 6.9.1 & Table 20 */ 00075 00076 #define RFAL_NFCA_SDD_CT 0x88 /*!< Cascade Tag value Digital 1.1 6.7.2 */ 00077 #define RFAL_NFCA_SDD_CT_LEN 1 /*!< Cascade Tag length */ 00078 00079 #define RFAL_NFCA_SLP_REQ_LEN 2 /*!< SLP_REQ length */ 00080 00081 #define RFAL_NFCA_SEL_CMD_LEN 1 /*!< SEL_CMD length */ 00082 #define RFAL_NFCA_SEL_PAR_LEN 1 /*!< SEL_PAR length */ 00083 #define RFAL_NFCA_SEL_SELPAR rfalNfcaSelPar(7, 0)/*!< SEL_PAR on Select is always with 4 data/nfcid */ 00084 #define RFAL_NFCA_BCC_LEN 1 /*!< BCC length */ 00085 00086 #define RFAL_NFCA_SDD_REQ_LEN (RFAL_NFCA_SEL_CMD_LEN + RFAL_NFCA_SEL_PAR_LEN) /*!< SDD_REQ length */ 00087 #define RFAL_NFCA_SDD_RES_LEN (RFAL_NFCA_CASCADE_1_UID_LEN + RFAL_NFCA_BCC_LEN) /*!< SDD_RES length */ 00088 00089 #define RFAL_NFCA_T_RETRANS 5 /*!< t RETRANSMISSION [3, 33]ms EMVCo 2.6 A.5 */ 00090 #define RFAL_NFCA_N_RETRANS 2 /*!< Number of retries EMVCo 2.6 9.6.1.3 */ 00091 00092 00093 /*! SDD_REQ (Select) Cascade Levels */ 00094 enum 00095 { 00096 RFAL_NFCA_SEL_CASCADE_L1 = 0, /*!< SDD_REQ Cascade Level 1 */ 00097 RFAL_NFCA_SEL_CASCADE_L2 = 1, /*!< SDD_REQ Cascade Level 2 */ 00098 RFAL_NFCA_SEL_CASCADE_L3 = 2 /*!< SDD_REQ Cascade Level 3 */ 00099 }; 00100 00101 /*! SDD_REQ (Select) request Cascade Level command Digital 1.1 Table 15 */ 00102 enum 00103 { 00104 RFAL_NFCA_CMD_SEL_CL1 = 0x93, /*!< SDD_REQ command Cascade Level 1 */ 00105 RFAL_NFCA_CMD_SEL_CL2 = 0x95, /*!< SDD_REQ command Cascade Level 2 */ 00106 RFAL_NFCA_CMD_SEL_CL3 = 0x97, /*!< SDD_REQ command Cascade Level 3 */ 00107 }; 00108 00109 /* 00110 ****************************************************************************** 00111 * GLOBAL MACROS 00112 ****************************************************************************** 00113 */ 00114 #define rfalNfcaSelPar( nBy, nbi ) (((nBy<<4) & 0xF0) | (nbi&0x0F) ) /*!< Calculates SEL_PAR with the bytes/bits to be sent */ 00115 #define rfalNfcaCLn2SELCMD( cl ) (RFAL_NFCA_CMD_SEL_CL1 + (2*cl)) /*!< Calculates SEL_CMD with the given cascade level */ 00116 #define rfalNfcaNfcidLen2CL( l ) (l / 5) /*!< Calculates cascade level by the NFCID length */ 00117 00118 /*! Executes the given Tx method (f) and if a Timeout error is detected it retries (rt) times performing a delay of (dl) in between */ 00119 #define rfalNfcaTxRetry( r, f, rt, dl ) {uint8_t rts=rt; do{ r=f; if((rt!=0)&&(dl!=0)) platformDelay(dl); }while((r==ERR_TIMEOUT) && (rts--)); } 00120 00121 /* 00122 ****************************************************************************** 00123 * GLOBAL TYPES 00124 ****************************************************************************** 00125 */ 00126 00127 /*! SLP_REQ (HLTA) format Digital 1.1 6.9.1 & Table 20 */ 00128 typedef struct 00129 { 00130 uint8_t frame[RFAL_NFCA_SLP_REQ_LEN]; /*!< SLP: 0x50 0x00 */ 00131 } rfalNfcaSlpReq; 00132 00133 /* 00134 ****************************************************************************** 00135 * LOCAL FUNCTION PROTOTYPES 00136 ****************************************************************************** 00137 */ 00138 static uint8_t rfalNfcaCalculateBcc( uint8_t* buf, uint8_t bufLen ); 00139 00140 00141 /* 00142 ****************************************************************************** 00143 * LOCAL FUNCTIONS 00144 ****************************************************************************** 00145 */ 00146 00147 static uint8_t rfalNfcaCalculateBcc( uint8_t* buf, uint8_t bufLen ) 00148 { 00149 uint8_t i; 00150 uint8_t BCC; 00151 00152 BCC = 0; 00153 00154 /* BCC is XOR over first 4 bytes of the SDD_RES Digital 1.1 6.7.2 */ 00155 for(i = 0; i < bufLen; i++) 00156 { 00157 BCC ^= *(buf + i); 00158 } 00159 00160 return BCC; 00161 } 00162 00163 /* 00164 ****************************************************************************** 00165 * GLOBAL FUNCTIONS 00166 ****************************************************************************** 00167 */ 00168 00169 /*******************************************************************************/ 00170 ReturnCode rfalNfcaPollerInitialize( SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ) 00171 { 00172 ReturnCode ret; 00173 00174 EXIT_ON_ERR( ret, rfalSetMode( RFAL_MODE_POLL_NFCA , RFAL_BR_106 , RFAL_BR_106 , mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ); 00175 rfalSetErrorHandling( RFAL_ERRORHANDLING_NFC ); 00176 00177 rfalSetGT( RFAL_GT_NFCA ); 00178 rfalSetFDTListen( RFAL_FDT_LISTEN_NFCA_POLLER ); 00179 rfalSetFDTPoll( RFAL_FDT_POLL_NFCA_POLLER ); 00180 00181 return ERR_NONE; 00182 } 00183 00184 00185 /*******************************************************************************/ 00186 ReturnCode rfalNfcaPollerCheckPresence( rfal14443AShortFrameCmd cmd, rfalNfcaSensRes *sensRes, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ) 00187 { 00188 ReturnCode ret; 00189 uint16_t rcvLen; 00190 00191 /* Digital 1.1 6.10.1.3 For Commands ALL_REQ, SENS_REQ, SDD_REQ, and SEL_REQ, the NFC Forum Device * 00192 * MUST treat receipt of a Listen Frame at a time after FDT(Listen, min) as a Timeour Error */ 00193 00194 ret = rfalISO14443ATransceiveShortFrame( cmd, (uint8_t*)sensRes, rfalConvBytesToBits(sizeof(rfalNfcaSensRes )), &rcvLen, RFAL_NFCA_FDTMIN, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00195 if( (ERR_NO_MASK(ret) == ERR_RF_COLLISION) || (ERR_NO_MASK(ret) == ERR_CRC) || (ERR_NO_MASK(ret) == ERR_NOMEM) || 00196 (ERR_NO_MASK(ret) == ERR_FRAMING) || (ERR_NO_MASK(ret) == ERR_PAR) ) 00197 { 00198 ret = ERR_NONE; 00199 } 00200 00201 return ret; 00202 } 00203 00204 00205 /*******************************************************************************/ 00206 ReturnCode rfalNfcaPollerTechnologyDetection( rfalComplianceMode compMode, rfalNfcaSensRes *sensRes, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ) 00207 { 00208 ReturnCode ret; 00209 00210 EXIT_ON_ERR( ret, rfalNfcaPollerCheckPresence( ((compMode == RFAL_COMPLIANCE_MODE_EMV ) ? RFAL_14443A_SHORTFRAME_CMD_WUPA : RFAL_14443A_SHORTFRAME_CMD_REQA ), sensRes , mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ); 00211 00212 /* Send SLP_REQ as Activity 1.1 9.2.3.6 and EMVCo 2.6 9.2.1.3 */ 00213 if( compMode != RFAL_COMPLIANCE_MODE_ISO ) 00214 { 00215 EXIT_ON_ERR( ret, rfalNfcaPollerSleep( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ); 00216 } 00217 return ERR_NONE; 00218 } 00219 00220 /*******************************************************************************/ 00221 ReturnCode rfalNfcaPollerSingleCollisionResolution( uint8_t devLimit, bool *collPending, rfalNfcaSelRes *selRes, uint8_t *nfcId1, uint8_t *nfcId1Len, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ) 00222 { 00223 uint8_t i; 00224 ReturnCode ret; 00225 rfalNfcaSelReq selReq; 00226 uint16_t bytesRx; 00227 uint8_t bytesTxRx; 00228 uint8_t bitsTxRx; 00229 00230 /* Check parameters */ 00231 if( (collPending == NULL) || (selRes == NULL) || (nfcId1 == NULL) || (nfcId1Len == NULL) ) 00232 { 00233 return ERR_PARAM; 00234 } 00235 00236 /* Initialize output parameters */ 00237 *collPending = false; /* Activity 1.1 9.3.4.6 */ 00238 *nfcId1Len = 0; 00239 ST_MEMSET( nfcId1, 0x00, RFAL_NFCA_CASCADE_3_UID_LEN ); 00240 00241 /*******************************************************************************/ 00242 /* Go through all Cascade Levels Activity 1.1 9.3.4 */ 00243 for( i = RFAL_NFCA_SEL_CASCADE_L1; i <= RFAL_NFCA_SEL_CASCADE_L3; i++) 00244 { 00245 /* Initialize the SDD_REQ to send for the new cascade level */ 00246 ST_MEMSET( (uint8_t*)&selReq, 0x00, sizeof(rfalNfcaSelReq ) ); 00247 selReq.selCmd = rfalNfcaCLn2SELCMD(i); 00248 00249 bytesTxRx = RFAL_NFCA_SDD_REQ_LEN; 00250 bitsTxRx = 0; 00251 00252 /*******************************************************************************/ 00253 /* Go through Collision loop */ 00254 do 00255 { 00256 /* Calculate SEL_PAR with the bytes/bits to be sent */ 00257 selReq.selPar = rfalNfcaSelPar(bytesTxRx, bitsTxRx); 00258 00259 /* Send SDD_REQ (Anticollision frame) - Retry upon timeout EMVCo 2.6 9.6.1.3 */ 00260 rfalNfcaTxRetry( ret, rfalISO14443ATransceiveAnticollisionFrame( (uint8_t*)&selReq, &bytesTxRx, &bitsTxRx, &bytesRx, RFAL_NFCA_FDTMIN, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) , ((devLimit==0)?RFAL_NFCA_N_RETRANS:0), RFAL_NFCA_T_RETRANS); 00261 00262 bytesRx = rfalConvBitsToBytes(bytesRx); 00263 00264 if( ret == ERR_RF_COLLISION ) 00265 { 00266 /* Check received length */ 00267 if( (bytesTxRx + (bitsTxRx ? 1 : 0)) > (RFAL_NFCA_CASCADE_1_UID_LEN + RFAL_NFCA_SDD_REQ_LEN) ) 00268 { 00269 return ERR_PROTO; 00270 } 00271 00272 if( (devLimit == 0) && !(*collPending) ) 00273 { 00274 /* Activity 1.0 & 1.1 9.3.4.12: If CON_DEVICES_LIMIT has a value of 0, then 00275 * NFC Forum Device is configured to perform collision detection only */ 00276 *collPending = true; 00277 return ERR_IGNORE; 00278 } 00279 00280 *collPending = true; 00281 00282 /* Set and select the collision bit, with the number of bytes/bits successfully TxRx */ 00283 *((uint8_t*)&selReq + bytesTxRx) |= (1 << bitsTxRx); 00284 bitsTxRx++; 00285 00286 /* Check if number of bits form a byte */ 00287 if( bitsTxRx == RFAL_BITS_IN_BYTE ) 00288 { 00289 bitsTxRx = 0; 00290 bytesTxRx++; 00291 } 00292 } 00293 }while ((ret == ERR_RF_COLLISION) && (RFAL_NFCA_SDD_RES_LEN != bytesRx) ); /* BCC byte should not have collision if NFCID1 data are same */ 00294 00295 00296 /*******************************************************************************/ 00297 /* Check if Collision loop has failed */ 00298 if( ret != ERR_NONE ) 00299 { 00300 return ret; 00301 } 00302 00303 00304 /* If collisions are to be reported check whether the response is complete */ 00305 if( (devLimit == 0) && (bytesRx != sizeof(rfalNfcaSddRes )) ) 00306 { 00307 return ERR_PROTO; 00308 } 00309 00310 /* Check if the received BCC match */ 00311 if( selReq.bcc != rfalNfcaCalculateBcc( selReq.nfcid1, RFAL_NFCA_CASCADE_1_UID_LEN ) ) 00312 { 00313 return ERR_PROTO; 00314 } 00315 00316 /*******************************************************************************/ 00317 /* Anticollision OK, Select this Cascade Level */ 00318 selReq.selPar = RFAL_NFCA_SEL_SELPAR; 00319 00320 /* Send SEL_REQ (Select command) - Retry upon timeout EMVCo 2.6 9.6.1.3 */ 00321 rfalNfcaTxRetry( ret, rfalTransceiveBlockingTxRx( (uint8_t*)&selReq, sizeof(rfalNfcaSelReq ), (uint8_t*)selRes, sizeof(rfalNfcaSelRes ), &bytesRx, RFAL_TXRX_FLAGS_DEFAULT, RFAL_NFCA_FDTMIN, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) , ((devLimit==0)?RFAL_NFCA_N_RETRANS:0), RFAL_NFCA_T_RETRANS); 00322 00323 if( ret != ERR_NONE ) 00324 return ret; 00325 00326 00327 /* Ensure proper response length */ 00328 if( bytesRx != sizeof(rfalNfcaSelRes ) ) 00329 { 00330 return ERR_PROTO; 00331 } 00332 00333 /*******************************************************************************/ 00334 /* Check cascade byte, if cascade tag then go next cascade level */ 00335 if( (ret == ERR_NONE) && (*selReq.nfcid1 == RFAL_NFCA_SDD_CT) ) 00336 { 00337 /* Cascade Tag present, store nfcid1 bytes (excluding cascade tag) and continue for next CL */ 00338 ST_MEMCPY( (nfcId1 + *nfcId1Len), ((uint8_t*)&selReq.nfcid1 + RFAL_NFCA_SDD_CT_LEN), (RFAL_NFCA_CASCADE_1_UID_LEN - RFAL_NFCA_SDD_CT_LEN) ); 00339 *nfcId1Len += (RFAL_NFCA_CASCADE_1_UID_LEN - RFAL_NFCA_SDD_CT_LEN); 00340 } 00341 else 00342 { 00343 /* UID Selection complete, Stop Cascade Level loop */ 00344 ST_MEMCPY( (nfcId1 + *nfcId1Len), (uint8_t*)&selReq.nfcid1, RFAL_NFCA_CASCADE_1_UID_LEN ); 00345 *nfcId1Len += RFAL_NFCA_CASCADE_1_UID_LEN; 00346 return ERR_NONE; 00347 } 00348 } 00349 return ERR_INTERNAL; 00350 } 00351 00352 00353 /*******************************************************************************/ 00354 ReturnCode rfalNfcaPollerFullCollisionResolution( rfalComplianceMode compMode, uint8_t devLimit, rfalNfcaListenDevice *nfcaDevList, uint8_t *devCnt, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ) 00355 { 00356 ReturnCode ret; 00357 bool collPending; 00358 rfalNfcaSensRes sensRes; 00359 uint16_t rcvLen; 00360 00361 if( (nfcaDevList == NULL) || (devCnt == NULL) ) 00362 { 00363 return ERR_PARAM; 00364 } 00365 00366 *devCnt = 0; 00367 ret = ERR_NONE; 00368 00369 /*******************************************************************************/ 00370 /* Send ALL_REQ before Anticollision if a Sleep was sent before Activity 1.1 9.3.4.1 and EMVco 2.6 9.3.2.1 */ 00371 if( compMode != RFAL_COMPLIANCE_MODE_ISO ) 00372 { 00373 ret = rfalISO14443ATransceiveShortFrame( RFAL_14443A_SHORTFRAME_CMD_WUPA , (uint8_t*)&nfcaDevList->sensRes , rfalConvBytesToBits(sizeof(rfalNfcaSensRes )), &rcvLen, RFAL_NFCA_FDTMIN, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00374 if(ret != ERR_NONE) 00375 { 00376 if( (compMode == RFAL_COMPLIANCE_MODE_EMV ) || ((ret != ERR_RF_COLLISION) && (ret != ERR_CRC) && (ret != ERR_FRAMING) && (ret != ERR_PAR)) ) 00377 { 00378 return ret; 00379 } 00380 } 00381 00382 /* Check proper SENS_RES/ATQA size */ 00383 if( (ret == ERR_NONE) && (rfalConvBytesToBits(sizeof(rfalNfcaSensRes )) != rcvLen) ) 00384 { 00385 return ERR_PROTO; 00386 } 00387 } 00388 00389 00390 #if RFAL_FEATURE_T1T 00391 /*******************************************************************************/ 00392 /* Only check for T1T if previous SENS_RES was received without a transmission * 00393 * error. When collisions occur bits in the SENS_RES may look like a T1T */ 00394 /* If T1T Anticollision is not supported Activity 1.1 9.3.4.3 */ 00395 if( rfalNfcaIsSensResT1T( &nfcaDevList->sensRes ) && (devLimit != 0) && (ret == ERR_NONE) && (compMode != RFAL_COMPLIANCE_MODE_EMV ) ) 00396 { 00397 /* RID_REQ shall be performed with rfalT1TPollerRid() Activity 1.1 9.3.4.24 */ 00398 rfalT1TPollerInitialize( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00399 EXIT_ON_ERR( ret, rfalT1TPollerRid( &nfcaDevList->ridRes , mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ); 00400 00401 /* T1T doesn't support Anticollision */ 00402 *devCnt = 1; 00403 nfcaDevList->isSleep = false; 00404 nfcaDevList->type = RFAL_NFCA_T1T; 00405 nfcaDevList->nfcId1Len = RFAL_NFCA_CASCADE_1_UID_LEN; 00406 ST_MEMCPY( &nfcaDevList->nfcId1 , &nfcaDevList->ridRes .uid , RFAL_NFCA_CASCADE_1_UID_LEN ); 00407 00408 return ERR_NONE; 00409 } 00410 #endif /* RFAL_FEATURE_T1T */ 00411 00412 /*******************************************************************************/ 00413 /* Store the SENS_RES from Technology Detection or from WUPA */ 00414 sensRes = nfcaDevList->sensRes ; 00415 00416 ST_MEMSET( nfcaDevList, 0x00, (sizeof(rfalNfcaListenDevice ) * devLimit) ); 00417 00418 /* Restore the prev SENS_RES, assuming that the SENS_RES received is from first device 00419 * When only one device is detected it's not woken up then we'll have no SENS_RES (ATQA) */ 00420 nfcaDevList->sensRes = sensRes; 00421 00422 00423 /*******************************************************************************/ 00424 do 00425 { 00426 EXIT_ON_ERR( ret, rfalNfcaPollerSingleCollisionResolution( devLimit, &collPending, &nfcaDevList[*devCnt].selRes, (uint8_t*)&nfcaDevList[*devCnt].nfcId1, (uint8_t*)&nfcaDevList[*devCnt].nfcId1Len, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ); 00427 00428 /* Assign Listen Device */ 00429 nfcaDevList[*devCnt].type = (rfalNfcaListenDeviceType ) (nfcaDevList[*devCnt].selRes.sak & RFAL_NFCA_SEL_RES_CONF_MASK); 00430 nfcaDevList[*devCnt].isSleep = false; 00431 (*devCnt)++; 00432 00433 00434 /* If a collision was detected and device counter is lower than limit Activity 1.1 9.3.4.21 */ 00435 if( (*devCnt < devLimit) && ((collPending) || (compMode != RFAL_COMPLIANCE_MODE_ISO ) ) ) 00436 { 00437 /* Put this device to Sleep Activity 1.1 9.3.4.22 */ 00438 EXIT_ON_ERR( ret, rfalNfcaPollerSleep( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ); 00439 nfcaDevList[(*devCnt - 1)].isSleep = true; 00440 00441 00442 /* Send a new SENS_REQ to check for other cards Activity 1.1 9.3.4.23 */ 00443 ret = rfalNfcaPollerCheckPresence( RFAL_14443A_SHORTFRAME_CMD_REQA , &nfcaDevList[*devCnt].sensRes, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00444 if( ret == ERR_TIMEOUT ) 00445 { 00446 /* No more devices found */ 00447 return ERR_NONE; 00448 } 00449 /* Another device found, continue loop */ 00450 collPending = true; 00451 } 00452 else 00453 { 00454 return ERR_NONE; 00455 } 00456 }while( (*devCnt < devLimit) && (collPending) ); 00457 00458 return ERR_NONE; 00459 } 00460 00461 00462 /*******************************************************************************/ 00463 ReturnCode rfalNfcaPollerSelect( uint8_t *nfcid1, uint8_t nfcidLen, rfalNfcaSelRes *selRes, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ) 00464 { 00465 uint8_t i; 00466 uint8_t cl; 00467 uint8_t nfcidOffset; 00468 uint16_t rxLen; 00469 ReturnCode ret; 00470 rfalNfcaSelReq selReq; 00471 00472 if( (nfcid1 == NULL) || (nfcidLen > RFAL_NFCA_CASCADE_3_UID_LEN) || (selRes == NULL) ) 00473 { 00474 return ERR_PARAM; 00475 } 00476 00477 00478 /* Calculate Cascate Level */ 00479 cl = rfalNfcaNfcidLen2CL( nfcidLen ); 00480 nfcidOffset = 0; 00481 00482 /*******************************************************************************/ 00483 /* Go through all Cascade Levels Activity 1.1 9.4.4 */ 00484 for( i = RFAL_NFCA_SEL_CASCADE_L1; i <= cl; i++ ) 00485 { 00486 /* Assign SEL_CMD according to the CLn and SEL_PAR*/ 00487 selReq.selCmd = rfalNfcaCLn2SELCMD(i); 00488 selReq.selPar = RFAL_NFCA_SEL_SELPAR; 00489 00490 /* Compute NFCID/Data on the SEL_REQ command Digital 1.1 Table 18 */ 00491 if( cl != i ) 00492 { 00493 *selReq.nfcid1 = RFAL_NFCA_SDD_CT; 00494 ST_MEMCPY( (selReq.nfcid1 + RFAL_NFCA_SDD_CT_LEN ), (nfcid1 + nfcidOffset), (RFAL_NFCA_CASCADE_1_UID_LEN - RFAL_NFCA_SDD_CT_LEN) ); 00495 nfcidOffset += (RFAL_NFCA_CASCADE_1_UID_LEN - RFAL_NFCA_SDD_CT_LEN); 00496 } 00497 else 00498 { 00499 ST_MEMCPY( selReq.nfcid1 , (nfcid1 + nfcidOffset), RFAL_NFCA_CASCADE_1_UID_LEN ); 00500 } 00501 00502 /* Calculate nfcid's BCC */ 00503 selReq.bcc = rfalNfcaCalculateBcc( (uint8_t*)&selReq.nfcid1 , sizeof(selReq.nfcid1 ) ); 00504 00505 /*******************************************************************************/ 00506 /* Send SEL_REQ */ 00507 EXIT_ON_ERR( ret, rfalTransceiveBlockingTxRx( (uint8_t*)&selReq, sizeof(rfalNfcaSelReq ), (uint8_t*)selRes, sizeof(rfalNfcaSelRes ), &rxLen, RFAL_TXRX_FLAGS_DEFAULT, RFAL_NFCA_FDTMIN, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ); 00508 00509 /* Ensure proper response length */ 00510 if( rxLen != sizeof(rfalNfcaSelRes ) ) 00511 { 00512 return ERR_PROTO; 00513 } 00514 } 00515 00516 /* REMARK: Could check if NFCID1 is complete */ 00517 00518 return ERR_NONE; 00519 } 00520 00521 00522 /*******************************************************************************/ 00523 ReturnCode rfalNfcaPollerSleep( SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ) 00524 { 00525 ReturnCode ret; 00526 rfalNfcaSlpReq slpReq; 00527 uint8_t rxBuf; /* dummy buffer, just to perform Rx */ 00528 00529 slpReq.frame[RFAL_NFCA_SLP_CMD_POS] = RFAL_NFCA_SLP_CMD; 00530 slpReq.frame[RFAL_NFCA_SLP_BYTE2_POS] = RFAL_NFCA_SLP_BYTE2; 00531 00532 /* ISO14443-3 6.4.3 HLTA - If PICC responds with any modulation during 1 ms this response shall be interpreted as not acknowledge */ 00533 ret = rfalTransceiveBlockingTxRx( (uint8_t*)&slpReq, sizeof(rfalNfcaSlpReq), &rxBuf, sizeof(rxBuf), NULL, RFAL_TXRX_FLAGS_DEFAULT, RFAL_NFCA_SLP_FWT, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00534 if( ret != ERR_TIMEOUT ) 00535 { 00536 return ret; 00537 } 00538 00539 return ERR_NONE; 00540 } 00541 00542 00543 /*******************************************************************************/ 00544 bool rfalNfcaListenerIsSleepReq( uint8_t *buf, uint16_t bufLen ) 00545 { 00546 /* Check if length and payload match */ 00547 if( (bufLen != sizeof(rfalNfcaSlpReq)) || (buf[RFAL_NFCA_SLP_CMD_POS] != RFAL_NFCA_SLP_CMD) || (buf[RFAL_NFCA_SLP_BYTE2_POS] != RFAL_NFCA_SLP_BYTE2) ) 00548 { 00549 return false; 00550 } 00551 00552 return true; 00553 } 00554 00555 #endif /* RFAL_FEATURE_NFCA */
Generated on Sat Jul 16 2022 13:00:53 by
1.7.2