Fork of the GitHub

Committer:
DiegoOstuni
Date:
Thu Nov 14 14:34:50 2019 +0000
Revision:
0:75fc82583a41
Add files

Who changed what in which revision?

UserRevisionLine numberNew contents of line
DiegoOstuni 0:75fc82583a41 1
DiegoOstuni 0:75fc82583a41 2 /******************************************************************************
DiegoOstuni 0:75fc82583a41 3 * @attention
DiegoOstuni 0:75fc82583a41 4 *
DiegoOstuni 0:75fc82583a41 5 * <h2><center>&copy; COPYRIGHT 2016 STMicroelectronics</center></h2>
DiegoOstuni 0:75fc82583a41 6 *
DiegoOstuni 0:75fc82583a41 7 * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
DiegoOstuni 0:75fc82583a41 8 * You may not use this file except in compliance with the License.
DiegoOstuni 0:75fc82583a41 9 * You may obtain a copy of the License at:
DiegoOstuni 0:75fc82583a41 10 *
DiegoOstuni 0:75fc82583a41 11 * http://www.st.com/myliberty
DiegoOstuni 0:75fc82583a41 12 *
DiegoOstuni 0:75fc82583a41 13 * Unless required by applicable law or agreed to in writing, software
DiegoOstuni 0:75fc82583a41 14 * distributed under the License is distributed on an "AS IS" BASIS,
DiegoOstuni 0:75fc82583a41 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
DiegoOstuni 0:75fc82583a41 16 * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
DiegoOstuni 0:75fc82583a41 17 * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
DiegoOstuni 0:75fc82583a41 18 * See the License for the specific language governing permissions and
DiegoOstuni 0:75fc82583a41 19 * limitations under the License.
DiegoOstuni 0:75fc82583a41 20 *
DiegoOstuni 0:75fc82583a41 21 ******************************************************************************/
DiegoOstuni 0:75fc82583a41 22
DiegoOstuni 0:75fc82583a41 23 /*
DiegoOstuni 0:75fc82583a41 24 * PROJECT: ST25R391x firmware
DiegoOstuni 0:75fc82583a41 25 * $Revision: $
DiegoOstuni 0:75fc82583a41 26 * LANGUAGE: ISO C99
DiegoOstuni 0:75fc82583a41 27 */
DiegoOstuni 0:75fc82583a41 28
DiegoOstuni 0:75fc82583a41 29 /*! \file rfal_nfca.c
DiegoOstuni 0:75fc82583a41 30 *
DiegoOstuni 0:75fc82583a41 31 * \author Gustavo Patricio
DiegoOstuni 0:75fc82583a41 32 *
DiegoOstuni 0:75fc82583a41 33 * \brief Provides several NFC-A convenience methods and definitions
DiegoOstuni 0:75fc82583a41 34 *
DiegoOstuni 0:75fc82583a41 35 * It provides a Poller (ISO14443A PCD) interface and as well as
DiegoOstuni 0:75fc82583a41 36 * some NFC-A Listener (ISO14443A PICC) helpers.
DiegoOstuni 0:75fc82583a41 37 *
DiegoOstuni 0:75fc82583a41 38 * The definitions and helpers methods provided by this module are only
DiegoOstuni 0:75fc82583a41 39 * up to ISO14443-3 layer
DiegoOstuni 0:75fc82583a41 40 *
DiegoOstuni 0:75fc82583a41 41 */
DiegoOstuni 0:75fc82583a41 42
DiegoOstuni 0:75fc82583a41 43 /*
DiegoOstuni 0:75fc82583a41 44 ******************************************************************************
DiegoOstuni 0:75fc82583a41 45 * INCLUDES
DiegoOstuni 0:75fc82583a41 46 ******************************************************************************
DiegoOstuni 0:75fc82583a41 47 */
DiegoOstuni 0:75fc82583a41 48 #include <platform1.h>
DiegoOstuni 0:75fc82583a41 49 #include "rfal_nfca.h"
DiegoOstuni 0:75fc82583a41 50 #include "utils.h"
DiegoOstuni 0:75fc82583a41 51
DiegoOstuni 0:75fc82583a41 52 /*
DiegoOstuni 0:75fc82583a41 53 ******************************************************************************
DiegoOstuni 0:75fc82583a41 54 * ENABLE SWITCH
DiegoOstuni 0:75fc82583a41 55 ******************************************************************************
DiegoOstuni 0:75fc82583a41 56 */
DiegoOstuni 0:75fc82583a41 57
DiegoOstuni 0:75fc82583a41 58 #ifndef RFAL_FEATURE_NFCA
DiegoOstuni 0:75fc82583a41 59 #error " RFAL: Module configuration missing. Please enable/disable NFC-A module by setting: RFAL_FEATURE_NFCA "
DiegoOstuni 0:75fc82583a41 60 #endif
DiegoOstuni 0:75fc82583a41 61
DiegoOstuni 0:75fc82583a41 62 #if RFAL_FEATURE_NFCA
DiegoOstuni 0:75fc82583a41 63
DiegoOstuni 0:75fc82583a41 64 /*
DiegoOstuni 0:75fc82583a41 65 ******************************************************************************
DiegoOstuni 0:75fc82583a41 66 * GLOBAL DEFINES
DiegoOstuni 0:75fc82583a41 67 ******************************************************************************
DiegoOstuni 0:75fc82583a41 68 */
DiegoOstuni 0:75fc82583a41 69
DiegoOstuni 0:75fc82583a41 70 #define RFAL_NFCA_SLP_FWT rfalConvMsTo1fc(1) /*!< Check 1ms for any modulation ISO14443-3 6.4.3 */
DiegoOstuni 0:75fc82583a41 71 #define RFAL_NFCA_SLP_CMD 0x50 /*!< SLP cmd (byte1) Digital 1.1 6.9.1 & Table 20 */
DiegoOstuni 0:75fc82583a41 72 #define RFAL_NFCA_SLP_BYTE2 0x00 /*!< SLP byte2 Digital 1.1 6.9.1 & Table 20 */
DiegoOstuni 0:75fc82583a41 73 #define RFAL_NFCA_SLP_CMD_POS 0 /*!< SLP cmd position Digital 1.1 6.9.1 & Table 20 */
DiegoOstuni 0:75fc82583a41 74 #define RFAL_NFCA_SLP_BYTE2_POS 1 /*!< SLP byte2 position Digital 1.1 6.9.1 & Table 20 */
DiegoOstuni 0:75fc82583a41 75
DiegoOstuni 0:75fc82583a41 76 #define RFAL_NFCA_SDD_CT 0x88 /*!< Cascade Tag value Digital 1.1 6.7.2 */
DiegoOstuni 0:75fc82583a41 77 #define RFAL_NFCA_SDD_CT_LEN 1 /*!< Cascade Tag length */
DiegoOstuni 0:75fc82583a41 78
DiegoOstuni 0:75fc82583a41 79 #define RFAL_NFCA_SLP_REQ_LEN 2 /*!< SLP_REQ length */
DiegoOstuni 0:75fc82583a41 80
DiegoOstuni 0:75fc82583a41 81 #define RFAL_NFCA_SEL_CMD_LEN 1 /*!< SEL_CMD length */
DiegoOstuni 0:75fc82583a41 82 #define RFAL_NFCA_SEL_PAR_LEN 1 /*!< SEL_PAR length */
DiegoOstuni 0:75fc82583a41 83 #define RFAL_NFCA_SEL_SELPAR rfalNfcaSelPar(7, 0)/*!< SEL_PAR on Select is always with 4 data/nfcid */
DiegoOstuni 0:75fc82583a41 84 #define RFAL_NFCA_BCC_LEN 1 /*!< BCC length */
DiegoOstuni 0:75fc82583a41 85
DiegoOstuni 0:75fc82583a41 86 #define RFAL_NFCA_SDD_REQ_LEN (RFAL_NFCA_SEL_CMD_LEN + RFAL_NFCA_SEL_PAR_LEN) /*!< SDD_REQ length */
DiegoOstuni 0:75fc82583a41 87 #define RFAL_NFCA_SDD_RES_LEN (RFAL_NFCA_CASCADE_1_UID_LEN + RFAL_NFCA_BCC_LEN) /*!< SDD_RES length */
DiegoOstuni 0:75fc82583a41 88
DiegoOstuni 0:75fc82583a41 89 #define RFAL_NFCA_T_RETRANS 5 /*!< t RETRANSMISSION [3, 33]ms EMVCo 2.6 A.5 */
DiegoOstuni 0:75fc82583a41 90 #define RFAL_NFCA_N_RETRANS 2 /*!< Number of retries EMVCo 2.6 9.6.1.3 */
DiegoOstuni 0:75fc82583a41 91
DiegoOstuni 0:75fc82583a41 92
DiegoOstuni 0:75fc82583a41 93 /*! SDD_REQ (Select) Cascade Levels */
DiegoOstuni 0:75fc82583a41 94 enum
DiegoOstuni 0:75fc82583a41 95 {
DiegoOstuni 0:75fc82583a41 96 RFAL_NFCA_SEL_CASCADE_L1 = 0, /*!< SDD_REQ Cascade Level 1 */
DiegoOstuni 0:75fc82583a41 97 RFAL_NFCA_SEL_CASCADE_L2 = 1, /*!< SDD_REQ Cascade Level 2 */
DiegoOstuni 0:75fc82583a41 98 RFAL_NFCA_SEL_CASCADE_L3 = 2 /*!< SDD_REQ Cascade Level 3 */
DiegoOstuni 0:75fc82583a41 99 };
DiegoOstuni 0:75fc82583a41 100
DiegoOstuni 0:75fc82583a41 101 /*! SDD_REQ (Select) request Cascade Level command Digital 1.1 Table 15 */
DiegoOstuni 0:75fc82583a41 102 enum
DiegoOstuni 0:75fc82583a41 103 {
DiegoOstuni 0:75fc82583a41 104 RFAL_NFCA_CMD_SEL_CL1 = 0x93, /*!< SDD_REQ command Cascade Level 1 */
DiegoOstuni 0:75fc82583a41 105 RFAL_NFCA_CMD_SEL_CL2 = 0x95, /*!< SDD_REQ command Cascade Level 2 */
DiegoOstuni 0:75fc82583a41 106 RFAL_NFCA_CMD_SEL_CL3 = 0x97, /*!< SDD_REQ command Cascade Level 3 */
DiegoOstuni 0:75fc82583a41 107 };
DiegoOstuni 0:75fc82583a41 108
DiegoOstuni 0:75fc82583a41 109 /*
DiegoOstuni 0:75fc82583a41 110 ******************************************************************************
DiegoOstuni 0:75fc82583a41 111 * GLOBAL MACROS
DiegoOstuni 0:75fc82583a41 112 ******************************************************************************
DiegoOstuni 0:75fc82583a41 113 */
DiegoOstuni 0:75fc82583a41 114 #define rfalNfcaSelPar( nBy, nbi ) (((nBy<<4) & 0xF0) | (nbi&0x0F) ) /*!< Calculates SEL_PAR with the bytes/bits to be sent */
DiegoOstuni 0:75fc82583a41 115 #define rfalNfcaCLn2SELCMD( cl ) (RFAL_NFCA_CMD_SEL_CL1 + (2*cl)) /*!< Calculates SEL_CMD with the given cascade level */
DiegoOstuni 0:75fc82583a41 116 #define rfalNfcaNfcidLen2CL( l ) (l / 5) /*!< Calculates cascade level by the NFCID length */
DiegoOstuni 0:75fc82583a41 117
DiegoOstuni 0:75fc82583a41 118 /*! Executes the given Tx method (f) and if a Timeout error is detected it retries (rt) times performing a delay of (dl) in between */
DiegoOstuni 0:75fc82583a41 119 #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--)); }
DiegoOstuni 0:75fc82583a41 120
DiegoOstuni 0:75fc82583a41 121 /*
DiegoOstuni 0:75fc82583a41 122 ******************************************************************************
DiegoOstuni 0:75fc82583a41 123 * GLOBAL TYPES
DiegoOstuni 0:75fc82583a41 124 ******************************************************************************
DiegoOstuni 0:75fc82583a41 125 */
DiegoOstuni 0:75fc82583a41 126
DiegoOstuni 0:75fc82583a41 127 /*! SLP_REQ (HLTA) format Digital 1.1 6.9.1 & Table 20 */
DiegoOstuni 0:75fc82583a41 128 typedef struct
DiegoOstuni 0:75fc82583a41 129 {
DiegoOstuni 0:75fc82583a41 130 uint8_t frame[RFAL_NFCA_SLP_REQ_LEN]; /*!< SLP: 0x50 0x00 */
DiegoOstuni 0:75fc82583a41 131 } rfalNfcaSlpReq;
DiegoOstuni 0:75fc82583a41 132
DiegoOstuni 0:75fc82583a41 133 /*
DiegoOstuni 0:75fc82583a41 134 ******************************************************************************
DiegoOstuni 0:75fc82583a41 135 * LOCAL FUNCTION PROTOTYPES
DiegoOstuni 0:75fc82583a41 136 ******************************************************************************
DiegoOstuni 0:75fc82583a41 137 */
DiegoOstuni 0:75fc82583a41 138 static uint8_t rfalNfcaCalculateBcc( uint8_t* buf, uint8_t bufLen );
DiegoOstuni 0:75fc82583a41 139
DiegoOstuni 0:75fc82583a41 140
DiegoOstuni 0:75fc82583a41 141 /*
DiegoOstuni 0:75fc82583a41 142 ******************************************************************************
DiegoOstuni 0:75fc82583a41 143 * LOCAL FUNCTIONS
DiegoOstuni 0:75fc82583a41 144 ******************************************************************************
DiegoOstuni 0:75fc82583a41 145 */
DiegoOstuni 0:75fc82583a41 146
DiegoOstuni 0:75fc82583a41 147 static uint8_t rfalNfcaCalculateBcc( uint8_t* buf, uint8_t bufLen )
DiegoOstuni 0:75fc82583a41 148 {
DiegoOstuni 0:75fc82583a41 149 uint8_t i;
DiegoOstuni 0:75fc82583a41 150 uint8_t BCC;
DiegoOstuni 0:75fc82583a41 151
DiegoOstuni 0:75fc82583a41 152 BCC = 0;
DiegoOstuni 0:75fc82583a41 153
DiegoOstuni 0:75fc82583a41 154 /* BCC is XOR over first 4 bytes of the SDD_RES Digital 1.1 6.7.2 */
DiegoOstuni 0:75fc82583a41 155 for(i = 0; i < bufLen; i++)
DiegoOstuni 0:75fc82583a41 156 {
DiegoOstuni 0:75fc82583a41 157 BCC ^= *(buf + i);
DiegoOstuni 0:75fc82583a41 158 }
DiegoOstuni 0:75fc82583a41 159
DiegoOstuni 0:75fc82583a41 160 return BCC;
DiegoOstuni 0:75fc82583a41 161 }
DiegoOstuni 0:75fc82583a41 162
DiegoOstuni 0:75fc82583a41 163 /*
DiegoOstuni 0:75fc82583a41 164 ******************************************************************************
DiegoOstuni 0:75fc82583a41 165 * GLOBAL FUNCTIONS
DiegoOstuni 0:75fc82583a41 166 ******************************************************************************
DiegoOstuni 0:75fc82583a41 167 */
DiegoOstuni 0:75fc82583a41 168
DiegoOstuni 0:75fc82583a41 169 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 170 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 )
DiegoOstuni 0:75fc82583a41 171 {
DiegoOstuni 0:75fc82583a41 172 ReturnCode ret;
DiegoOstuni 0:75fc82583a41 173
DiegoOstuni 0:75fc82583a41 174 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 ) );
DiegoOstuni 0:75fc82583a41 175 rfalSetErrorHandling( RFAL_ERRORHANDLING_NFC );
DiegoOstuni 0:75fc82583a41 176
DiegoOstuni 0:75fc82583a41 177 rfalSetGT( RFAL_GT_NFCA );
DiegoOstuni 0:75fc82583a41 178 rfalSetFDTListen( RFAL_FDT_LISTEN_NFCA_POLLER );
DiegoOstuni 0:75fc82583a41 179 rfalSetFDTPoll( RFAL_FDT_POLL_NFCA_POLLER );
DiegoOstuni 0:75fc82583a41 180
DiegoOstuni 0:75fc82583a41 181 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 182 }
DiegoOstuni 0:75fc82583a41 183
DiegoOstuni 0:75fc82583a41 184
DiegoOstuni 0:75fc82583a41 185 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 186 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 )
DiegoOstuni 0:75fc82583a41 187 {
DiegoOstuni 0:75fc82583a41 188 ReturnCode ret;
DiegoOstuni 0:75fc82583a41 189 uint16_t rcvLen;
DiegoOstuni 0:75fc82583a41 190
DiegoOstuni 0:75fc82583a41 191 /* Digital 1.1 6.10.1.3 For Commands ALL_REQ, SENS_REQ, SDD_REQ, and SEL_REQ, the NFC Forum Device *
DiegoOstuni 0:75fc82583a41 192 * MUST treat receipt of a Listen Frame at a time after FDT(Listen, min) as a Timeour Error */
DiegoOstuni 0:75fc82583a41 193
DiegoOstuni 0:75fc82583a41 194 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 ) ;
DiegoOstuni 0:75fc82583a41 195 if( (ERR_NO_MASK(ret) == ERR_RF_COLLISION) || (ERR_NO_MASK(ret) == ERR_CRC) || (ERR_NO_MASK(ret) == ERR_NOMEM) ||
DiegoOstuni 0:75fc82583a41 196 (ERR_NO_MASK(ret) == ERR_FRAMING) || (ERR_NO_MASK(ret) == ERR_PAR) )
DiegoOstuni 0:75fc82583a41 197 {
DiegoOstuni 0:75fc82583a41 198 ret = ERR_NONE;
DiegoOstuni 0:75fc82583a41 199 }
DiegoOstuni 0:75fc82583a41 200
DiegoOstuni 0:75fc82583a41 201 return ret;
DiegoOstuni 0:75fc82583a41 202 }
DiegoOstuni 0:75fc82583a41 203
DiegoOstuni 0:75fc82583a41 204
DiegoOstuni 0:75fc82583a41 205 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 206 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 )
DiegoOstuni 0:75fc82583a41 207 {
DiegoOstuni 0:75fc82583a41 208 ReturnCode ret;
DiegoOstuni 0:75fc82583a41 209
DiegoOstuni 0:75fc82583a41 210 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 ) );
DiegoOstuni 0:75fc82583a41 211
DiegoOstuni 0:75fc82583a41 212 /* Send SLP_REQ as Activity 1.1 9.2.3.6 and EMVCo 2.6 9.2.1.3 */
DiegoOstuni 0:75fc82583a41 213 if( compMode != RFAL_COMPLIANCE_MODE_ISO)
DiegoOstuni 0:75fc82583a41 214 {
DiegoOstuni 0:75fc82583a41 215 EXIT_ON_ERR( ret, rfalNfcaPollerSleep( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) );
DiegoOstuni 0:75fc82583a41 216 }
DiegoOstuni 0:75fc82583a41 217 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 218 }
DiegoOstuni 0:75fc82583a41 219
DiegoOstuni 0:75fc82583a41 220 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 221 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 )
DiegoOstuni 0:75fc82583a41 222 {
DiegoOstuni 0:75fc82583a41 223 uint8_t i;
DiegoOstuni 0:75fc82583a41 224 ReturnCode ret;
DiegoOstuni 0:75fc82583a41 225 rfalNfcaSelReq selReq;
DiegoOstuni 0:75fc82583a41 226 uint16_t bytesRx;
DiegoOstuni 0:75fc82583a41 227 uint8_t bytesTxRx;
DiegoOstuni 0:75fc82583a41 228 uint8_t bitsTxRx;
DiegoOstuni 0:75fc82583a41 229
DiegoOstuni 0:75fc82583a41 230 /* Check parameters */
DiegoOstuni 0:75fc82583a41 231 if( (collPending == NULL) || (selRes == NULL) || (nfcId1 == NULL) || (nfcId1Len == NULL) )
DiegoOstuni 0:75fc82583a41 232 {
DiegoOstuni 0:75fc82583a41 233 return ERR_PARAM;
DiegoOstuni 0:75fc82583a41 234 }
DiegoOstuni 0:75fc82583a41 235
DiegoOstuni 0:75fc82583a41 236 /* Initialize output parameters */
DiegoOstuni 0:75fc82583a41 237 *collPending = false; /* Activity 1.1 9.3.4.6 */
DiegoOstuni 0:75fc82583a41 238 *nfcId1Len = 0;
DiegoOstuni 0:75fc82583a41 239 ST_MEMSET( nfcId1, 0x00, RFAL_NFCA_CASCADE_3_UID_LEN );
DiegoOstuni 0:75fc82583a41 240
DiegoOstuni 0:75fc82583a41 241 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 242 /* Go through all Cascade Levels Activity 1.1 9.3.4 */
DiegoOstuni 0:75fc82583a41 243 for( i = RFAL_NFCA_SEL_CASCADE_L1; i <= RFAL_NFCA_SEL_CASCADE_L3; i++)
DiegoOstuni 0:75fc82583a41 244 {
DiegoOstuni 0:75fc82583a41 245 /* Initialize the SDD_REQ to send for the new cascade level */
DiegoOstuni 0:75fc82583a41 246 ST_MEMSET( (uint8_t*)&selReq, 0x00, sizeof(rfalNfcaSelReq) );
DiegoOstuni 0:75fc82583a41 247 selReq.selCmd = rfalNfcaCLn2SELCMD(i);
DiegoOstuni 0:75fc82583a41 248
DiegoOstuni 0:75fc82583a41 249 bytesTxRx = RFAL_NFCA_SDD_REQ_LEN;
DiegoOstuni 0:75fc82583a41 250 bitsTxRx = 0;
DiegoOstuni 0:75fc82583a41 251
DiegoOstuni 0:75fc82583a41 252 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 253 /* Go through Collision loop */
DiegoOstuni 0:75fc82583a41 254 do
DiegoOstuni 0:75fc82583a41 255 {
DiegoOstuni 0:75fc82583a41 256 /* Calculate SEL_PAR with the bytes/bits to be sent */
DiegoOstuni 0:75fc82583a41 257 selReq.selPar = rfalNfcaSelPar(bytesTxRx, bitsTxRx);
DiegoOstuni 0:75fc82583a41 258
DiegoOstuni 0:75fc82583a41 259 /* Send SDD_REQ (Anticollision frame) - Retry upon timeout EMVCo 2.6 9.6.1.3 */
DiegoOstuni 0:75fc82583a41 260 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);
DiegoOstuni 0:75fc82583a41 261
DiegoOstuni 0:75fc82583a41 262 bytesRx = rfalConvBitsToBytes(bytesRx);
DiegoOstuni 0:75fc82583a41 263
DiegoOstuni 0:75fc82583a41 264 if( ret == ERR_RF_COLLISION )
DiegoOstuni 0:75fc82583a41 265 {
DiegoOstuni 0:75fc82583a41 266 /* Check received length */
DiegoOstuni 0:75fc82583a41 267 if( (bytesTxRx + (bitsTxRx ? 1 : 0)) > (RFAL_NFCA_CASCADE_1_UID_LEN + RFAL_NFCA_SDD_REQ_LEN) )
DiegoOstuni 0:75fc82583a41 268 {
DiegoOstuni 0:75fc82583a41 269 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 270 }
DiegoOstuni 0:75fc82583a41 271
DiegoOstuni 0:75fc82583a41 272 if( (devLimit == 0) && !(*collPending) )
DiegoOstuni 0:75fc82583a41 273 {
DiegoOstuni 0:75fc82583a41 274 /* Activity 1.0 & 1.1 9.3.4.12: If CON_DEVICES_LIMIT has a value of 0, then
DiegoOstuni 0:75fc82583a41 275 * NFC Forum Device is configured to perform collision detection only */
DiegoOstuni 0:75fc82583a41 276 *collPending = true;
DiegoOstuni 0:75fc82583a41 277 return ERR_IGNORE;
DiegoOstuni 0:75fc82583a41 278 }
DiegoOstuni 0:75fc82583a41 279
DiegoOstuni 0:75fc82583a41 280 *collPending = true;
DiegoOstuni 0:75fc82583a41 281
DiegoOstuni 0:75fc82583a41 282 /* Set and select the collision bit, with the number of bytes/bits successfully TxRx */
DiegoOstuni 0:75fc82583a41 283 *((uint8_t*)&selReq + bytesTxRx) |= (1 << bitsTxRx);
DiegoOstuni 0:75fc82583a41 284 bitsTxRx++;
DiegoOstuni 0:75fc82583a41 285
DiegoOstuni 0:75fc82583a41 286 /* Check if number of bits form a byte */
DiegoOstuni 0:75fc82583a41 287 if( bitsTxRx == RFAL_BITS_IN_BYTE )
DiegoOstuni 0:75fc82583a41 288 {
DiegoOstuni 0:75fc82583a41 289 bitsTxRx = 0;
DiegoOstuni 0:75fc82583a41 290 bytesTxRx++;
DiegoOstuni 0:75fc82583a41 291 }
DiegoOstuni 0:75fc82583a41 292 }
DiegoOstuni 0:75fc82583a41 293 }while ((ret == ERR_RF_COLLISION) && (RFAL_NFCA_SDD_RES_LEN != bytesRx) ); /* BCC byte should not have collision if NFCID1 data are same */
DiegoOstuni 0:75fc82583a41 294
DiegoOstuni 0:75fc82583a41 295
DiegoOstuni 0:75fc82583a41 296 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 297 /* Check if Collision loop has failed */
DiegoOstuni 0:75fc82583a41 298 if( ret != ERR_NONE )
DiegoOstuni 0:75fc82583a41 299 {
DiegoOstuni 0:75fc82583a41 300 return ret;
DiegoOstuni 0:75fc82583a41 301 }
DiegoOstuni 0:75fc82583a41 302
DiegoOstuni 0:75fc82583a41 303
DiegoOstuni 0:75fc82583a41 304 /* If collisions are to be reported check whether the response is complete */
DiegoOstuni 0:75fc82583a41 305 if( (devLimit == 0) && (bytesRx != sizeof(rfalNfcaSddRes)) )
DiegoOstuni 0:75fc82583a41 306 {
DiegoOstuni 0:75fc82583a41 307 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 308 }
DiegoOstuni 0:75fc82583a41 309
DiegoOstuni 0:75fc82583a41 310 /* Check if the received BCC match */
DiegoOstuni 0:75fc82583a41 311 if( selReq.bcc != rfalNfcaCalculateBcc( selReq.nfcid1, RFAL_NFCA_CASCADE_1_UID_LEN ) )
DiegoOstuni 0:75fc82583a41 312 {
DiegoOstuni 0:75fc82583a41 313 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 314 }
DiegoOstuni 0:75fc82583a41 315
DiegoOstuni 0:75fc82583a41 316 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 317 /* Anticollision OK, Select this Cascade Level */
DiegoOstuni 0:75fc82583a41 318 selReq.selPar = RFAL_NFCA_SEL_SELPAR;
DiegoOstuni 0:75fc82583a41 319
DiegoOstuni 0:75fc82583a41 320 /* Send SEL_REQ (Select command) - Retry upon timeout EMVCo 2.6 9.6.1.3 */
DiegoOstuni 0:75fc82583a41 321 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);
DiegoOstuni 0:75fc82583a41 322
DiegoOstuni 0:75fc82583a41 323 if( ret != ERR_NONE )
DiegoOstuni 0:75fc82583a41 324 return ret;
DiegoOstuni 0:75fc82583a41 325
DiegoOstuni 0:75fc82583a41 326
DiegoOstuni 0:75fc82583a41 327 /* Ensure proper response length */
DiegoOstuni 0:75fc82583a41 328 if( bytesRx != sizeof(rfalNfcaSelRes) )
DiegoOstuni 0:75fc82583a41 329 {
DiegoOstuni 0:75fc82583a41 330 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 331 }
DiegoOstuni 0:75fc82583a41 332
DiegoOstuni 0:75fc82583a41 333 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 334 /* Check cascade byte, if cascade tag then go next cascade level */
DiegoOstuni 0:75fc82583a41 335 if( (ret == ERR_NONE) && (*selReq.nfcid1 == RFAL_NFCA_SDD_CT) )
DiegoOstuni 0:75fc82583a41 336 {
DiegoOstuni 0:75fc82583a41 337 /* Cascade Tag present, store nfcid1 bytes (excluding cascade tag) and continue for next CL */
DiegoOstuni 0:75fc82583a41 338 ST_MEMCPY( (nfcId1 + *nfcId1Len), ((uint8_t*)&selReq.nfcid1 + RFAL_NFCA_SDD_CT_LEN), (RFAL_NFCA_CASCADE_1_UID_LEN - RFAL_NFCA_SDD_CT_LEN) );
DiegoOstuni 0:75fc82583a41 339 *nfcId1Len += (RFAL_NFCA_CASCADE_1_UID_LEN - RFAL_NFCA_SDD_CT_LEN);
DiegoOstuni 0:75fc82583a41 340 }
DiegoOstuni 0:75fc82583a41 341 else
DiegoOstuni 0:75fc82583a41 342 {
DiegoOstuni 0:75fc82583a41 343 /* UID Selection complete, Stop Cascade Level loop */
DiegoOstuni 0:75fc82583a41 344 ST_MEMCPY( (nfcId1 + *nfcId1Len), (uint8_t*)&selReq.nfcid1, RFAL_NFCA_CASCADE_1_UID_LEN );
DiegoOstuni 0:75fc82583a41 345 *nfcId1Len += RFAL_NFCA_CASCADE_1_UID_LEN;
DiegoOstuni 0:75fc82583a41 346 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 347 }
DiegoOstuni 0:75fc82583a41 348 }
DiegoOstuni 0:75fc82583a41 349 return ERR_INTERNAL;
DiegoOstuni 0:75fc82583a41 350 }
DiegoOstuni 0:75fc82583a41 351
DiegoOstuni 0:75fc82583a41 352
DiegoOstuni 0:75fc82583a41 353 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 354 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 )
DiegoOstuni 0:75fc82583a41 355 {
DiegoOstuni 0:75fc82583a41 356 ReturnCode ret;
DiegoOstuni 0:75fc82583a41 357 bool collPending;
DiegoOstuni 0:75fc82583a41 358 rfalNfcaSensRes sensRes;
DiegoOstuni 0:75fc82583a41 359 uint16_t rcvLen;
DiegoOstuni 0:75fc82583a41 360
DiegoOstuni 0:75fc82583a41 361 if( (nfcaDevList == NULL) || (devCnt == NULL) )
DiegoOstuni 0:75fc82583a41 362 {
DiegoOstuni 0:75fc82583a41 363 return ERR_PARAM;
DiegoOstuni 0:75fc82583a41 364 }
DiegoOstuni 0:75fc82583a41 365
DiegoOstuni 0:75fc82583a41 366 *devCnt = 0;
DiegoOstuni 0:75fc82583a41 367 ret = ERR_NONE;
DiegoOstuni 0:75fc82583a41 368
DiegoOstuni 0:75fc82583a41 369 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 370 /* 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 */
DiegoOstuni 0:75fc82583a41 371 if( compMode != RFAL_COMPLIANCE_MODE_ISO )
DiegoOstuni 0:75fc82583a41 372 {
DiegoOstuni 0:75fc82583a41 373 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 ) ;
DiegoOstuni 0:75fc82583a41 374 if(ret != ERR_NONE)
DiegoOstuni 0:75fc82583a41 375 {
DiegoOstuni 0:75fc82583a41 376 if( (compMode == RFAL_COMPLIANCE_MODE_EMV) || ((ret != ERR_RF_COLLISION) && (ret != ERR_CRC) && (ret != ERR_FRAMING) && (ret != ERR_PAR)) )
DiegoOstuni 0:75fc82583a41 377 {
DiegoOstuni 0:75fc82583a41 378 return ret;
DiegoOstuni 0:75fc82583a41 379 }
DiegoOstuni 0:75fc82583a41 380 }
DiegoOstuni 0:75fc82583a41 381
DiegoOstuni 0:75fc82583a41 382 /* Check proper SENS_RES/ATQA size */
DiegoOstuni 0:75fc82583a41 383 if( (ret == ERR_NONE) && (rfalConvBytesToBits(sizeof(rfalNfcaSensRes)) != rcvLen) )
DiegoOstuni 0:75fc82583a41 384 {
DiegoOstuni 0:75fc82583a41 385 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 386 }
DiegoOstuni 0:75fc82583a41 387 }
DiegoOstuni 0:75fc82583a41 388
DiegoOstuni 0:75fc82583a41 389
DiegoOstuni 0:75fc82583a41 390 #if RFAL_FEATURE_T1T
DiegoOstuni 0:75fc82583a41 391 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 392 /* Only check for T1T if previous SENS_RES was received without a transmission *
DiegoOstuni 0:75fc82583a41 393 * error. When collisions occur bits in the SENS_RES may look like a T1T */
DiegoOstuni 0:75fc82583a41 394 /* If T1T Anticollision is not supported Activity 1.1 9.3.4.3 */
DiegoOstuni 0:75fc82583a41 395 if( rfalNfcaIsSensResT1T( &nfcaDevList->sensRes ) && (devLimit != 0) && (ret == ERR_NONE) && (compMode != RFAL_COMPLIANCE_MODE_EMV) )
DiegoOstuni 0:75fc82583a41 396 {
DiegoOstuni 0:75fc82583a41 397 /* RID_REQ shall be performed with rfalT1TPollerRid() Activity 1.1 9.3.4.24 */
DiegoOstuni 0:75fc82583a41 398 rfalT1TPollerInitialize( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
DiegoOstuni 0:75fc82583a41 399 EXIT_ON_ERR( ret, rfalT1TPollerRid( &nfcaDevList->ridRes, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) );
DiegoOstuni 0:75fc82583a41 400
DiegoOstuni 0:75fc82583a41 401 /* T1T doesn't support Anticollision */
DiegoOstuni 0:75fc82583a41 402 *devCnt = 1;
DiegoOstuni 0:75fc82583a41 403 nfcaDevList->isSleep = false;
DiegoOstuni 0:75fc82583a41 404 nfcaDevList->type = RFAL_NFCA_T1T;
DiegoOstuni 0:75fc82583a41 405 nfcaDevList->nfcId1Len = RFAL_NFCA_CASCADE_1_UID_LEN;
DiegoOstuni 0:75fc82583a41 406 ST_MEMCPY( &nfcaDevList->nfcId1, &nfcaDevList->ridRes.uid, RFAL_NFCA_CASCADE_1_UID_LEN );
DiegoOstuni 0:75fc82583a41 407
DiegoOstuni 0:75fc82583a41 408 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 409 }
DiegoOstuni 0:75fc82583a41 410 #endif /* RFAL_FEATURE_T1T */
DiegoOstuni 0:75fc82583a41 411
DiegoOstuni 0:75fc82583a41 412 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 413 /* Store the SENS_RES from Technology Detection or from WUPA */
DiegoOstuni 0:75fc82583a41 414 sensRes = nfcaDevList->sensRes;
DiegoOstuni 0:75fc82583a41 415
DiegoOstuni 0:75fc82583a41 416 ST_MEMSET( nfcaDevList, 0x00, (sizeof(rfalNfcaListenDevice) * devLimit) );
DiegoOstuni 0:75fc82583a41 417
DiegoOstuni 0:75fc82583a41 418 /* Restore the prev SENS_RES, assuming that the SENS_RES received is from first device
DiegoOstuni 0:75fc82583a41 419 * When only one device is detected it's not woken up then we'll have no SENS_RES (ATQA) */
DiegoOstuni 0:75fc82583a41 420 nfcaDevList->sensRes = sensRes;
DiegoOstuni 0:75fc82583a41 421
DiegoOstuni 0:75fc82583a41 422
DiegoOstuni 0:75fc82583a41 423 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 424 do
DiegoOstuni 0:75fc82583a41 425 {
DiegoOstuni 0:75fc82583a41 426 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 ) );
DiegoOstuni 0:75fc82583a41 427
DiegoOstuni 0:75fc82583a41 428 /* Assign Listen Device */
DiegoOstuni 0:75fc82583a41 429 nfcaDevList[*devCnt].type = (rfalNfcaListenDeviceType) (nfcaDevList[*devCnt].selRes.sak & RFAL_NFCA_SEL_RES_CONF_MASK);
DiegoOstuni 0:75fc82583a41 430 nfcaDevList[*devCnt].isSleep = false;
DiegoOstuni 0:75fc82583a41 431 (*devCnt)++;
DiegoOstuni 0:75fc82583a41 432
DiegoOstuni 0:75fc82583a41 433
DiegoOstuni 0:75fc82583a41 434 /* If a collision was detected and device counter is lower than limit Activity 1.1 9.3.4.21 */
DiegoOstuni 0:75fc82583a41 435 if( (*devCnt < devLimit) && ((collPending) || (compMode != RFAL_COMPLIANCE_MODE_ISO) ) )
DiegoOstuni 0:75fc82583a41 436 {
DiegoOstuni 0:75fc82583a41 437 /* Put this device to Sleep Activity 1.1 9.3.4.22 */
DiegoOstuni 0:75fc82583a41 438 EXIT_ON_ERR( ret, rfalNfcaPollerSleep( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) );
DiegoOstuni 0:75fc82583a41 439 nfcaDevList[(*devCnt - 1)].isSleep = true;
DiegoOstuni 0:75fc82583a41 440
DiegoOstuni 0:75fc82583a41 441
DiegoOstuni 0:75fc82583a41 442 /* Send a new SENS_REQ to check for other cards Activity 1.1 9.3.4.23 */
DiegoOstuni 0:75fc82583a41 443 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 ) ;
DiegoOstuni 0:75fc82583a41 444 if( ret == ERR_TIMEOUT )
DiegoOstuni 0:75fc82583a41 445 {
DiegoOstuni 0:75fc82583a41 446 /* No more devices found */
DiegoOstuni 0:75fc82583a41 447 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 448 }
DiegoOstuni 0:75fc82583a41 449 /* Another device found, continue loop */
DiegoOstuni 0:75fc82583a41 450 collPending = true;
DiegoOstuni 0:75fc82583a41 451 }
DiegoOstuni 0:75fc82583a41 452 else
DiegoOstuni 0:75fc82583a41 453 {
DiegoOstuni 0:75fc82583a41 454 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 455 }
DiegoOstuni 0:75fc82583a41 456 }while( (*devCnt < devLimit) && (collPending) );
DiegoOstuni 0:75fc82583a41 457
DiegoOstuni 0:75fc82583a41 458 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 459 }
DiegoOstuni 0:75fc82583a41 460
DiegoOstuni 0:75fc82583a41 461
DiegoOstuni 0:75fc82583a41 462 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 463 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 )
DiegoOstuni 0:75fc82583a41 464 {
DiegoOstuni 0:75fc82583a41 465 uint8_t i;
DiegoOstuni 0:75fc82583a41 466 uint8_t cl;
DiegoOstuni 0:75fc82583a41 467 uint8_t nfcidOffset;
DiegoOstuni 0:75fc82583a41 468 uint16_t rxLen;
DiegoOstuni 0:75fc82583a41 469 ReturnCode ret;
DiegoOstuni 0:75fc82583a41 470 rfalNfcaSelReq selReq;
DiegoOstuni 0:75fc82583a41 471
DiegoOstuni 0:75fc82583a41 472 if( (nfcid1 == NULL) || (nfcidLen > RFAL_NFCA_CASCADE_3_UID_LEN) || (selRes == NULL) )
DiegoOstuni 0:75fc82583a41 473 {
DiegoOstuni 0:75fc82583a41 474 return ERR_PARAM;
DiegoOstuni 0:75fc82583a41 475 }
DiegoOstuni 0:75fc82583a41 476
DiegoOstuni 0:75fc82583a41 477
DiegoOstuni 0:75fc82583a41 478 /* Calculate Cascate Level */
DiegoOstuni 0:75fc82583a41 479 cl = rfalNfcaNfcidLen2CL( nfcidLen );
DiegoOstuni 0:75fc82583a41 480 nfcidOffset = 0;
DiegoOstuni 0:75fc82583a41 481
DiegoOstuni 0:75fc82583a41 482 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 483 /* Go through all Cascade Levels Activity 1.1 9.4.4 */
DiegoOstuni 0:75fc82583a41 484 for( i = RFAL_NFCA_SEL_CASCADE_L1; i <= cl; i++ )
DiegoOstuni 0:75fc82583a41 485 {
DiegoOstuni 0:75fc82583a41 486 /* Assign SEL_CMD according to the CLn and SEL_PAR*/
DiegoOstuni 0:75fc82583a41 487 selReq.selCmd = rfalNfcaCLn2SELCMD(i);
DiegoOstuni 0:75fc82583a41 488 selReq.selPar = RFAL_NFCA_SEL_SELPAR;
DiegoOstuni 0:75fc82583a41 489
DiegoOstuni 0:75fc82583a41 490 /* Compute NFCID/Data on the SEL_REQ command Digital 1.1 Table 18 */
DiegoOstuni 0:75fc82583a41 491 if( cl != i )
DiegoOstuni 0:75fc82583a41 492 {
DiegoOstuni 0:75fc82583a41 493 *selReq.nfcid1 = RFAL_NFCA_SDD_CT;
DiegoOstuni 0:75fc82583a41 494 ST_MEMCPY( (selReq.nfcid1 + RFAL_NFCA_SDD_CT_LEN ), (nfcid1 + nfcidOffset), (RFAL_NFCA_CASCADE_1_UID_LEN - RFAL_NFCA_SDD_CT_LEN) );
DiegoOstuni 0:75fc82583a41 495 nfcidOffset += (RFAL_NFCA_CASCADE_1_UID_LEN - RFAL_NFCA_SDD_CT_LEN);
DiegoOstuni 0:75fc82583a41 496 }
DiegoOstuni 0:75fc82583a41 497 else
DiegoOstuni 0:75fc82583a41 498 {
DiegoOstuni 0:75fc82583a41 499 ST_MEMCPY( selReq.nfcid1, (nfcid1 + nfcidOffset), RFAL_NFCA_CASCADE_1_UID_LEN );
DiegoOstuni 0:75fc82583a41 500 }
DiegoOstuni 0:75fc82583a41 501
DiegoOstuni 0:75fc82583a41 502 /* Calculate nfcid's BCC */
DiegoOstuni 0:75fc82583a41 503 selReq.bcc = rfalNfcaCalculateBcc( (uint8_t*)&selReq.nfcid1, sizeof(selReq.nfcid1) );
DiegoOstuni 0:75fc82583a41 504
DiegoOstuni 0:75fc82583a41 505 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 506 /* Send SEL_REQ */
DiegoOstuni 0:75fc82583a41 507 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 ) );
DiegoOstuni 0:75fc82583a41 508
DiegoOstuni 0:75fc82583a41 509 /* Ensure proper response length */
DiegoOstuni 0:75fc82583a41 510 if( rxLen != sizeof(rfalNfcaSelRes) )
DiegoOstuni 0:75fc82583a41 511 {
DiegoOstuni 0:75fc82583a41 512 return ERR_PROTO;
DiegoOstuni 0:75fc82583a41 513 }
DiegoOstuni 0:75fc82583a41 514 }
DiegoOstuni 0:75fc82583a41 515
DiegoOstuni 0:75fc82583a41 516 /* REMARK: Could check if NFCID1 is complete */
DiegoOstuni 0:75fc82583a41 517
DiegoOstuni 0:75fc82583a41 518 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 519 }
DiegoOstuni 0:75fc82583a41 520
DiegoOstuni 0:75fc82583a41 521
DiegoOstuni 0:75fc82583a41 522 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 523 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 )
DiegoOstuni 0:75fc82583a41 524 {
DiegoOstuni 0:75fc82583a41 525 ReturnCode ret;
DiegoOstuni 0:75fc82583a41 526 rfalNfcaSlpReq slpReq;
DiegoOstuni 0:75fc82583a41 527 uint8_t rxBuf; /* dummy buffer, just to perform Rx */
DiegoOstuni 0:75fc82583a41 528
DiegoOstuni 0:75fc82583a41 529 slpReq.frame[RFAL_NFCA_SLP_CMD_POS] = RFAL_NFCA_SLP_CMD;
DiegoOstuni 0:75fc82583a41 530 slpReq.frame[RFAL_NFCA_SLP_BYTE2_POS] = RFAL_NFCA_SLP_BYTE2;
DiegoOstuni 0:75fc82583a41 531
DiegoOstuni 0:75fc82583a41 532 /* ISO14443-3 6.4.3 HLTA - If PICC responds with any modulation during 1 ms this response shall be interpreted as not acknowledge */
DiegoOstuni 0:75fc82583a41 533 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 ) ;
DiegoOstuni 0:75fc82583a41 534 if( ret != ERR_TIMEOUT )
DiegoOstuni 0:75fc82583a41 535 {
DiegoOstuni 0:75fc82583a41 536 return ret;
DiegoOstuni 0:75fc82583a41 537 }
DiegoOstuni 0:75fc82583a41 538
DiegoOstuni 0:75fc82583a41 539 return ERR_NONE;
DiegoOstuni 0:75fc82583a41 540 }
DiegoOstuni 0:75fc82583a41 541
DiegoOstuni 0:75fc82583a41 542
DiegoOstuni 0:75fc82583a41 543 /*******************************************************************************/
DiegoOstuni 0:75fc82583a41 544 bool rfalNfcaListenerIsSleepReq( uint8_t *buf, uint16_t bufLen )
DiegoOstuni 0:75fc82583a41 545 {
DiegoOstuni 0:75fc82583a41 546 /* Check if length and payload match */
DiegoOstuni 0:75fc82583a41 547 if( (bufLen != sizeof(rfalNfcaSlpReq)) || (buf[RFAL_NFCA_SLP_CMD_POS] != RFAL_NFCA_SLP_CMD) || (buf[RFAL_NFCA_SLP_BYTE2_POS] != RFAL_NFCA_SLP_BYTE2) )
DiegoOstuni 0:75fc82583a41 548 {
DiegoOstuni 0:75fc82583a41 549 return false;
DiegoOstuni 0:75fc82583a41 550 }
DiegoOstuni 0:75fc82583a41 551
DiegoOstuni 0:75fc82583a41 552 return true;
DiegoOstuni 0:75fc82583a41 553 }
DiegoOstuni 0:75fc82583a41 554
DiegoOstuni 0:75fc82583a41 555 #endif /* RFAL_FEATURE_NFCA */