ST Expansion SW Team / RFAL

Dependents:   mbed-os-nfc05a1

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers rfal_nfca.cpp Source File

rfal_nfca.cpp

00001 
00002 /******************************************************************************
00003   * @attention
00004   *
00005   * <h2><center>&copy; 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 */