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_rf.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 /* 00025 * PROJECT: ST25R3911 firmware 00026 * $Revision: $ 00027 * LANGUAGE: ISO C99 00028 */ 00029 00030 /*! \file 00031 * 00032 * \author Gustavo Patricio 00033 * 00034 * \brief RF Abstraction Layer (RFAL) 00035 * 00036 * RFAL implementation for ST25R3911 00037 */ 00038 00039 00040 /* 00041 ****************************************************************************** 00042 * INCLUDES 00043 ****************************************************************************** 00044 */ 00045 00046 00047 #include "rfal_rf.h" 00048 00049 #include <rfal_rf.h> 00050 #include "utils.h" 00051 #include "ST25R3911.h" 00052 #include "st25r3911_com.h" 00053 #include "st25r3911_interrupt.h" 00054 #include "rfal_AnalogConfig.h" 00055 #include "rfal_iso15693_2.h" 00056 #include "rfal_chip.h" 00057 #include "platform1.h" 00058 #include <stdint.h> 00059 00060 /* 00061 ****************************************************************************** 00062 * GLOBAL TYPES 00063 ****************************************************************************** 00064 */ 00065 00066 00067 00068 /*! Struct that holds all involved on a Transceive including the context passed by the caller */ 00069 typedef struct{ 00070 rfalTransceiveState state; /*!< Current transceive state */ 00071 rfalTransceiveState lastState; /*!< Last transceive state (debug purposes) */ 00072 ReturnCode status; /*!< Current status/error of the transceive */ 00073 bool rxse; /*!< Flag indicating if RXE was received with RXS */ 00074 00075 rfalTransceiveContext ctx; /*!< The transceive context given by the caller */ 00076 } rfalTxRx; 00077 00078 00079 /*! Struct that holds all context for the Listen Mode */ 00080 typedef struct{ 00081 rfalLmState state; /*!< Current Listen Mode state */ 00082 rfalBitRate brDetected; /*!< Last bit rate detected */ 00083 00084 uint8_t* rxBuf; /*!< Location to store incoming data in Listen Mode */ 00085 uint16_t rxBufLen; /*!< Length of rxBuf */ 00086 uint16_t* rxLen; /*!< Pointer to write the data length placed into rxBuf */ 00087 bool dataFlag; /*!< Listen Mode current Data Flag */ 00088 } rfalLm; 00089 00090 00091 /*! Struct that holds all context for the Wake-Up Mode */ 00092 typedef struct{ 00093 rfalWumState state; /*!< Current Wake-Up Mode state */ 00094 st25r3911WakeUpConfig cfg; /*!< Current Wake-Up Mode context */ 00095 } rfalWum; 00096 00097 00098 /*! Struct that holds the timings GT and FDTs */ 00099 typedef struct{ 00100 uint32_t GT; /*!< GT in 1/fc */ 00101 uint32_t FDTListen; /*!< FDTListen in 1/fc */ 00102 uint32_t FDTPoll; /*!< FDTPoll in 1/fc */ 00103 } rfalTimings; 00104 00105 00106 /*! Struct that holds the software timers */ 00107 typedef struct{ 00108 uint32_t GT; /*!< RFAL's GT timer */ 00109 uint32_t FWT; /*!< FWT/RWT timer for Active P2P*/ 00110 uint32_t RXE; /*!< Timer between RXS and RXE */ 00111 } rfalTimers; 00112 00113 00114 /*! Struct that holds the RFAL's callbacks */ 00115 typedef struct{ 00116 rfalPreTxRxCallback preTxRx; /*!< RFAL's Pre TxRx callback */ 00117 rfalPostTxRxCallback postTxRx; /*!< RFAL's Post TxRx callback */ 00118 } rfalCallbacks; 00119 00120 00121 /*! Struct that holds counters to control the FIFO on Tx and Rx */ 00122 typedef struct{ 00123 uint16_t expWL; /*!< The amount of bytes expected to be Tx when a WL interrupt occours */ 00124 uint16_t bytesTotal; /*!< Total bytes to be transmitted OR the total bytes received */ 00125 uint16_t bytesWritten;/*!< Amount of bytes already written on FIFO (Tx) OR read (RX) from FIFO and written on rxBuffer*/ 00126 uint8_t status[ST25R3911_FIFO_STATUS_LEN]; /*!< FIFO Status Registers */ 00127 } rfalFIFO; 00128 00129 00130 /*! Struct that holds RFAL's configuration settings */ 00131 typedef struct{ 00132 uint8_t obsvModeTx; /*!< RFAL's config of the ST25R3911's observation mode while Tx */ 00133 uint8_t obsvModeRx; /*!< RFAL's config of the ST25R3911's observation mode while Rx */ 00134 rfalEHandling eHandling; /*!< RFAL's error handling config/mode */ 00135 } rfalConfigs; 00136 00137 00138 /*! Struct that holds NFC-F data - Used only inside rfalFelicaPoll() (static to avoid adding it into stack) */ 00139 typedef struct{ 00140 rfalFeliCaPollRes pollResponses[RFAL_FELICA_POLL_MAX_SLOTS]; /* FeliCa Poll response container for 16 slots */ 00141 } rfalNfcfWorkingData; 00142 00143 00144 /*! Struct that holds NFC-V current context 00145 * 00146 * 96 bytes is FIFO size of ST25R3911, codingBuffer has to be big enough for coping with maximum response size (Manchester coded) 00147 * - current implementation expects it be written in one bulk into FIFO 00148 * - needs to be above FIFO water level of ST25R3911 (64) 00149 * - 65 is actually 1 byte too much, but ~75us in 1of256 another byte is already gone 00150 * 00151 * - inventory requests responses: 14 bytes 00152 * - Max read single block responses: 32 bytes 00153 * - Read multiple block responses: variable 00154 * 00155 * ISO15693 frame: SOF + Flags + Data + CRC + EOF 00156 */ 00157 typedef struct{ 00158 uint8_t codingBuffer[((2 + 255 + 3)*2)];/*!< Coding buffer, length MUST be above 64: [65; ...] */ 00159 uint16_t nfcvOffset; /*!< Offset needed for ISO15693 coding function */ 00160 rfalTransceiveContext origCtx; /*!< Context provided by user */ 00161 uint16_t ignoreBits; /*!< Number of bits at the beginning of a frame to be ignored when decoding */ 00162 } rfalNfcvWorkingData; 00163 00164 00165 /*! RFAL instance */ 00166 typedef struct{ 00167 rfalState state; /*!< RFAL's current state */ 00168 rfalMode mode; /*!< RFAL's current mode */ 00169 rfalBitRate txBR; /*!< RFAL's current Tx Bit Rate */ 00170 rfalBitRate rxBR; /*!< RFAL's current Rx Bit Rate */ 00171 bool field; /*!< Current field state (On / Off) */ 00172 00173 rfalConfigs conf; /*!< RFAL's configuration settings */ 00174 rfalTimings timings; /*!< RFAL's timing setting */ 00175 rfalTxRx TxRx; /*!< RFAL's transceive management */ 00176 rfalLm Lm; /*!< RFAL's listen mode management */ 00177 rfalWum wum; /*!< RFAL's Wake-Up mode management */ 00178 00179 rfalFIFO fifo; /*!< RFAL's FIFO management */ 00180 rfalTimers tmr; /*!< RFAL's Software timers */ 00181 rfalCallbacks callbacks; /*!< RFAL's callbacks */ 00182 00183 #if RFAL_FEATURE_NFCF 00184 rfalNfcfWorkingData nfcfData; /*!< RFAL's working data when supporting NFC-F */ 00185 #endif /* RFAL_FEATURE_NFCF */ 00186 00187 #if RFAL_FEATURE_NFCV 00188 rfalNfcvWorkingData nfcvData; /*!< RFAL's working data when supporting NFC-V */ 00189 #endif /* RFAL_FEATURE_NFCV */ 00190 00191 } rfal; 00192 00193 00194 00195 /*! Felica's command set */ 00196 typedef enum 00197 { 00198 FELICA_CMD_POLLING = 0x00, /*!< Felica Poll/REQC command (aka SENSF_REQ) to identify a card */ 00199 FELICA_CMD_POLLING_RES = 0x01, /*!< Felica Poll/REQC command (aka SENSF_RES) response */ 00200 FELICA_CMD_REQUEST_SERVICE = 0x02, /*!< verify the existence of Area and Service */ 00201 FELICA_CMD_REQUEST_RESPONSE = 0x04, /*!< verify the existence of a card */ 00202 FELICA_CMD_READ_WITHOUT_ENCRYPTION = 0x06, /*!< read Block Data from a Service that requires no authentication */ 00203 FELICA_CMD_WRITE_WITHOUT_ENCRYPTION = 0x08, /*!< write Block Data to a Service that requires no authentication */ 00204 FELICA_CMD_REQUEST_SYSTEM_CODE = 0x0c, /*!< acquire the System Code registered to a card */ 00205 FELICA_CMD_AUTHENTICATION1 = 0x10, /*!< authenticate a card */ 00206 FELICA_CMD_AUTHENTICATION2 = 0x12, /*!< allow a card to authenticate a Reader/Writer */ 00207 FELICA_CMD_READ = 0x14, /*!< read Block Data from a Service that requires authentication */ 00208 FELICA_CMD_WRITE = 0x16, /*!< write Block Data to a Service that requires authentication */ 00209 }t_rfalFeliCaCmd ; 00210 00211 /* 00212 ****************************************************************************** 00213 * GLOBAL DEFINES 00214 ****************************************************************************** 00215 */ 00216 00217 #define RFAL_TIMING_NONE 0x00 /*!< Timing disable | Don't apply */ 00218 00219 #define RFAL_FIFO_IN_LT_32 32 /*!< Number of bytes in the FIFO when WL interrupt occurs while Tx ( fifo_lt: 0 ) */ 00220 #define RFAL_FIFO_IN_LT_16 16 /*!< Number of bytes in the FIFO when WL interrupt occurs while Tx ( fifo_lt: 1 ) */ 00221 00222 #define RFAL_FIFO_OUT_LT_32 (ST25R3911_FIFO_DEPTH - RFAL_FIFO_IN_LT_32) /*!< Number of bytes sent/out of the FIFO when WL interrupt occurs while Tx ( fifo_lt: 0 ) */ 00223 #define RFAL_FIFO_OUT_LT_16 (ST25R3911_FIFO_DEPTH - RFAL_FIFO_IN_LT_16) /*!< Number of bytes sent/out of the FIFO when WL interrupt occurs while Tx ( fifo_lt: 1 ) */ 00224 00225 #define RFAL_FIFO_STATUS_REG1 0 /*!< Location of FIFO status register 1 in local copy */ 00226 #define RFAL_FIFO_STATUS_REG2 1 /*!< Location of FIFO status register 2 in local copy */ 00227 #define RFAL_FIFO_STATUS_INVALID 0xFF /*!< Value indicating that the local FIFO status in invalid|cleared */ 00228 00229 #define RFAL_ST25R3911_GPT_MAX_1FC rfalConv8fcTo1fc( 0xFFFF ) /*!< Max GPT steps in 1fc (0xFFFF steps of 8/fc => 0xFFFF * 590ns = 38,7ms) */ 00230 #define RFAL_ST25R3911_NRT_MAX_1FC rfalConv4096fcTo1fc( 0xFFFF ) /*!< Max NRT steps in 1fc (0xFFFF steps of 4096/fc => 0xFFFF * 302us = 19.8s ) */ 00231 #define RFAL_ST25R3911_NRT_DISABLED 0 /*!< NRT Disabled: All 0 No-response timer is not started, wait forever */ 00232 #define RFAL_ST25R3911_MRT_MAX_1FC rfalConv64fcTo1fc( 0x00FF ) /*!< Max MRT steps in 1fc (0x00FF steps of 64/fc => 0x00FF * 4.72us = 1.2ms ) */ 00233 #define RFAL_ST25R3911_MRT_MIN_1FC rfalConv64fcTo1fc( 0x0004 ) /*!< Min MRT steps in 1fc ( 0<=mrt<=4 ; 4 (64/fc) => 0x0004 * 4.72us = 18.88us ) */ 00234 #define RFAL_ST25R3911_GT_MAX_1FC rfalConvMsTo1fc( 5000 ) /*!< Max GT value allowed in 1/fc */ 00235 #define RFAL_ST25R3911_GT_MIN_1FC rfalConvMsTo1fc(RFAL_ST25R3911_SW_TMR_MIN_1MS)/*!< Min GT value allowed in 1/fc */ 00236 #define RFAL_ST25R3911_SW_TMR_MIN_1MS 1 /*!< Min value of a SW timer in ms */ 00237 00238 #define RFAL_OBSMODE_DISABLE 0x00 /*!< Observation Mode disabled */ 00239 00240 #define RFAL_NFC_RX_INCOMPLETE_LEN 1 /*!< Threshold value where incoming rx may be considered as incomplete in NFC */ 00241 #define RFAL_EMVCO_RX_MAXLEN 4 /*!< Maximum value where EMVCo to apply special error handling */ 00242 #define RFAL_EMVCO_RX_MINLEN 2 /*!< Minimum value where EMVCo to apply special error handling */ 00243 00244 #define RFAL_NORXE_TOUT 10 /*!< Timeout to be used on a potential missing RXE - Silicon ST25R3911B Errata #1.1 */ 00245 00246 #define RFAL_ISO14443A_SDD_RES_LEN 5 /*!< SDD_RES | Anticollision (UID CLn) length - rfalNfcaSddRes */ 00247 00248 #define RFAL_FELICA_POLL_DELAY_TIME 512 /*!< FeliCa Poll Processing time is 2.417 ms ~512*64/fc Digital 1.1 A4 */ 00249 #define RFAL_FELICA_POLL_SLOT_TIME 256 /*!< FeliCa Poll Time Slot duration is 1.208 ms ~256*64/fc Digital 1.1 A4 */ 00250 00251 #define RFAL_ISO15693_IGNORE_BITS rfalConvBytesToBits(2) /*!< Ignore collisions before the UID (RES_FLAG + DSFID) */ 00252 00253 00254 /*******************************************************************************/ 00255 00256 #define RFAL_LM_GT rfalConvUsTo1fc(100) /*!< Listen Mode Guard Time enforced (GT - Passive; TIRFG - Active) */ 00257 #define RFAL_FDT_POLL_ADJUSTMENT rfalConvUsTo1fc(80) /*!< FDT Poll adjustment: Time between the expiration of GPT to the actual Tx */ 00258 #define RFAL_FDT_LISTEN_MRT_ADJUSTMENT 64 /*!< MRT jitter adjustment: timeout will be between [ tout ; tout + 64 cycles ] */ 00259 #define RFAL_AP2P_FIELDOFF_TRFW rfalConv8fcTo1fc(64) /*!< Time after TXE and Field Off in AP2P Trfw: 37.76us -> 64 (8/fc) */ 00260 00261 00262 /*! FWT adjustment: 00263 * 64 : NRT jitter between TXE and NRT start */ 00264 #define RFAL_FWT_ADJUSTMENT 64 00265 00266 /*! FWT ISO14443A adjustment: 00267 * 512 : Initial 4bit length */ 00268 #define RFAL_FWT_A_ADJUSTMENT 512 00269 00270 /*! FWT ISO14443B adjustment: 00271 * 2784 : Adjustment for the SOF and initial byte */ 00272 #define RFAL_FWT_B_ADJUSTMENT 2784 00273 00274 00275 /*! FWT FeliCa 212 adjustment: 00276 * 1024 : Length of the two Sync bytes at 212kbps */ 00277 #define RFAL_FWT_F_212_ADJUSTMENT 1024 00278 00279 /*! FWT FeliCa 424 adjustment: 00280 * 512 : Length of the two Sync bytes at 424kbps */ 00281 #define RFAL_FWT_F_424_ADJUSTMENT 512 00282 00283 00284 /*! Time between our field Off and other peer field On : Tadt + (n x Trfw) 00285 * Ecma 340 11.1.2 - Tadt: [56.64 , 188.72] us ; n: [0 , 3] ; Trfw = 37.76 us 00286 * Should be: 189 + (3*38) = 303us ; we'll use a more relaxed setting: 605 us */ 00287 #define RFAL_AP2P_FIELDON_TADTTRFW rfalConvUsTo1fc(605) 00288 00289 00290 /*! FDT Poll adjustment for ISO14443A EMVCo 2.6 4.8.1.3 ; Digital 1.1 6.10 00291 * 00292 * 276: Time from the rising pulse of the pause of the logic '1' (i.e. the time point to measure the deaftime from), 00293 * to the actual end of the EOF sequence (the point where the MRT starts). Please note that the ST25R391x uses the 00294 * ISO14443-2 definition where the EOF consists of logic '0' followed by sequence Y. 00295 */ 00296 #define RFAL_FDT_LISTEN_A_ADJUSTMENT 276 00297 00298 00299 /*! FDT Poll adjustment for ISO14443B EMVCo 2.6 4.8.1.6 ; Digital 1.1 7.9 00300 * 00301 * 340: Time from the rising edge of the EoS to the starting point of the MRT timer (sometime after the final high 00302 * part of the EoS is completed). 00303 * 00304 * -64: Adjustment for the TR1PUTMIN. 00305 * The TR1PUTMIN of the ST25R3911 is 1152/fc (72/fs). The EMVCo test case TB0000 measures the TR1PUTMIN. 00306 * It takes the default value of TR1PUTMIN (79/fs) and reduces it by 128/fc in every iteration. 00307 * This results in a TR1PUTMIN of 1136/fc (71/fs) for the second iteration. The ST25R3911 sends a NAK because 00308 * the TR1PUTMIN of the ST25R3911 (72/fs) is higher than 71/fs. 00309 * Therefore the test suite assumes TR1PUTMIN of 1264/fc (79/fs). 00310 * The test cases TB340.0 and TB435.0 uses the TR1PUTMIN to send frames too early. In order to correctly 00311 * recognise these frames as being sent too early (starting inside reader deaf time), the MRT has to be 00312 * increased by at least 64/fc (8/fs). 00313 */ 00314 #define RFAL_FDT_LISTEN_B_ADJUSTMENT (340 - 64) 00315 00316 00317 00318 /* 00319 ****************************************************************************** 00320 * GLOBAL MACROS 00321 ****************************************************************************** 00322 */ 00323 00324 #define rfalCalcNumBytes( nBits ) (uint32_t)( (nBits + 7) / 8 ) /*!< Returns the number of bytes required to fit given the number of bits */ 00325 00326 #define rfalTimerStart( timer, time_ms ) timer = platformTimerCreate(time_ms) /*!< Configures and starts the RTOX timer */ 00327 #define rfalTimerisExpired( timer ) platformTimerIsExpired( timer ) /*!< Checks if timer has expired */ 00328 00329 #define rfalST25R3911ObsModeDisable() st25r3911WriteTestRegister(0x01, 0x00, mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) /*!< Disable ST25R3911 Observation mode */ 00330 #define rfalST25R3911ObsModeTx() st25r3911WriteTestRegister(0x01, gRFAL.conf.obsvModeTx, mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) /*!< Enable Observation mode 0x0A CSI: Digital TX modulation signal CSO: none */ 00331 #define rfalST25R3911ObsModeRx() st25r3911WriteTestRegister(0x01, gRFAL.conf.obsvModeRx, mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) /*!< Enable Observation mode 0x04 CSI: Digital output of AM channel CSO: Digital output of PM channel */ 00332 00333 00334 #define rfalCheckDisableObsMode() if(gRFAL.conf.obsvModeRx){ rfalST25R3911ObsModeDisable(); } /*!< Checks if the observation mode is enabled, and applies on ST25R3911 */ 00335 #define rfalCheckEnableObsModeTx() if(gRFAL.conf.obsvModeTx){ rfalST25R3911ObsModeTx(); } /*!< Checks if the observation mode is enabled, and applies on ST25R3911 */ 00336 #define rfalCheckEnableObsModeRx() if(gRFAL.conf.obsvModeRx){ rfalST25R3911ObsModeRx(); } /*!< Checks if the observation mode is enabled, and applies on ST25R3911 */ 00337 00338 00339 #define rfalGetIncmplBits( FIFOStatus2 ) (( FIFOStatus2 >> 1) & 0x07) /*!< Returns the number of bits from fifo status */ 00340 #define rfalIsIncompleteByteError( error ) ((error >= ERR_INCOMPLETE_BYTE) && (error <= ERR_INCOMPLETE_BYTE_07)) /*!< Checks if given error is a Incomplete error */ 00341 00342 #define rfalConvBR2ACBR( b ) (((b+1)<<RFAL_ANALOG_CONFIG_BITRATE_SHIFT) & RFAL_ANALOG_CONFIG_BITRATE_MASK) /*!< Converts ST25R391x Bit rate to Analog Configuration bit rate id */ 00343 00344 00345 #define rfalIsModeActiveComm( md ) ( (md == RFAL_MODE_POLL_ACTIVE_P2P) || (md == RFAL_MODE_LISTEN_ACTIVE_P2P) ) /*!< Checks if mode md is Active Communication */ 00346 #define rfalIsModePassiveComm( md ) ( !rfalIsModeActiveComm(md) ) /*!< Checks if mode md is Passive Communication*/ 00347 #define rfalIsModePassiveListen( md ) ( (md == RFAL_MODE_LISTEN_NFCA) || (md == RFAL_MODE_LISTEN_NFCB) || (md == RFAL_MODE_LISTEN_NFCF) ) /*!< Checks if mode md is Passive Listen */ 00348 #define rfalIsModePassivePoll( md ) ( rfalIsModePassiveComm(md) && !rfalIsModePassiveListen(md) ) /*!< Checks if mode md is Passive Poll */ 00349 00350 /* 00351 ****************************************************************************** 00352 * LOCAL VARIABLES 00353 ****************************************************************************** 00354 */ 00355 00356 static rfal gRFAL ; /*!< RFAL module instance */ 00357 00358 /* 00359 ****************************************************************************** 00360 * LOCAL FUNCTION PROTOTYPES 00361 ****************************************************************************** 00362 */ 00363 00364 static void rfalTransceiveTx( 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 ); 00365 static void rfalTransceiveRx( 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 ); 00366 static ReturnCode rfalTransceiveRunBlockingTx( 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 ); 00367 static void rfalPrepareTransceive( 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 ); 00368 static void rfalCleanupTransceive( 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 ); 00369 static void rfalErrorHandling( ST25R3911* mST25, SPI * mspiChannel, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ); 00370 static ReturnCode rfalRunTransceiveWorker( 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 ); 00371 static ReturnCode rfalRunListenModeWorker( 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 ); 00372 static void rfalRunWakeUpModeWorker( 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 ); 00373 00374 static void rfalFIFOStatusUpdate( ST25R3911* mST25, SPI * mspiChannel, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ); 00375 static void rfalFIFOStatusClear( void ); 00376 static bool rfalFIFOStatusIsMissingPar( ST25R3911* mST25, SPI * mspiChannel, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ); 00377 static bool rfalFIFOStatusIsIncompleteByte( ST25R3911* mST25, SPI * mspiChannel, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ); 00378 static uint8_t rfalFIFOStatusGetNumBytes( ST25R3911* mST25, SPI * mspiChannel, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ); 00379 static uint8_t rfalFIFOGetNumIncompleteBits( ST25R3911* mST25, SPI * mspiChannel, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ); 00380 00381 00382 /* 00383 ****************************************************************************** 00384 * GLOBAL FUNCTIONS 00385 ****************************************************************************** 00386 */ 00387 00388 /*******************************************************************************/ 00389 ReturnCode rfalInitialize( SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, 00390 DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, 00391 DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ) 00392 { 00393 00394 st25r3911InitInterrupts( fieldLED_06 ); 00395 00396 /* Initialize chip */ 00397 st25r3911Initialize( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00398 00399 /* Check expected chip: ST25R3911 */ 00400 if( !st25r3911CheckChipID( NULL, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ) 00401 { 00402 return ERR_HW_MISMATCH; 00403 } 00404 00405 /*******************************************************************************/ 00406 /* Apply RF Chip general initialization */ 00407 rfalSetAnalogConfig( RFAL_ANALOG_CONFIG_TECH_CHIP, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00408 00409 /*******************************************************************************/ 00410 /* Set FIFO Water Levels to be used */ 00411 st25r3911ChangeRegisterBits( ST25R3911_REG_IO_CONF1, (ST25R3911_REG_IO_CONF1_fifo_lt | ST25R3911_REG_IO_CONF1_fifo_lr), (ST25R3911_REG_IO_CONF1_fifo_lt_32bytes | ST25R3911_REG_IO_CONF1_fifo_lr_64bytes), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00412 00413 /* Always have CRC in FIFO upon reception */ 00414 st25r3911SetRegisterBits( ST25R3911_REG_AUX, ST25R3911_REG_AUX_crc_2_fifo, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00415 00416 /* Enable External Field Detector */ 00417 st25r3911SetRegisterBits( ST25R3911_REG_AUX, ST25R3911_REG_AUX_en_fd, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00418 00419 /* Disable any previous observation mode */ 00420 rfalST25R3911ObsModeDisable(); 00421 00422 /* Clear FIFO status local copy */ 00423 rfalFIFOStatusClear(); 00424 00425 00426 /*******************************************************************************/ 00427 /* Debug purposes */ 00428 /*logSetLevel( LOG_MODULE_DEFAULT, LOG_LEVEL_INFO ); !!!!!!!!!!!!!!! */ 00429 /* rfalSetObsvMode( 0x0A, 0x04 ); */ 00430 00431 /*******************************************************************************/ 00432 gRFAL .state = RFAL_STATE_INIT; 00433 gRFAL .mode = RFAL_MODE_NONE ; 00434 gRFAL .field = false; 00435 00436 /* Set RFAL default configs */ 00437 gRFAL .conf.obsvModeTx = RFAL_OBSMODE_DISABLE; 00438 gRFAL .conf.obsvModeRx = RFAL_OBSMODE_DISABLE; 00439 gRFAL .conf.eHandling = RFAL_ERRORHANDLING_NONE ; 00440 00441 /* Transceive set to IDLE */ 00442 gRFAL .TxRx.lastState = RFAL_TXRX_STATE_IDLE; 00443 gRFAL .TxRx.state = RFAL_TXRX_STATE_IDLE; 00444 00445 /* Disable all timings */ 00446 gRFAL .timings.FDTListen = RFAL_TIMING_NONE; 00447 gRFAL .timings.FDTPoll = RFAL_TIMING_NONE; 00448 gRFAL .timings.GT = RFAL_TIMING_NONE; 00449 00450 gRFAL .tmr.GT = RFAL_TIMING_NONE; 00451 00452 gRFAL .callbacks.preTxRx = NULL; 00453 gRFAL .callbacks.postTxRx = NULL; 00454 00455 #if RFAL_FEATURE_NFCV 00456 /* Initialize NFC-V Data */ 00457 gRFAL .nfcvData.ignoreBits = 0; 00458 #endif /* RFAL_FEATURE_NFCV */ 00459 00460 /* Initialize Listen Mode */ 00461 gRFAL .Lm.state = RFAL_LM_STATE_NOT_INIT ; 00462 gRFAL .Lm.brDetected = RFAL_BR_KEEP ; 00463 00464 /* Initialize Wake-Up Mode */ 00465 gRFAL .wum.state = RFAL_WUM_STATE_NOT_INIT ; 00466 00467 00468 /*******************************************************************************/ 00469 /* Perform Automatic Calibration (if configured to do so). * 00470 * Registers set by rfalSetAnalogConfig will tell rfalCalibrate what to perform*/ 00471 rfalCalibrate( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00472 00473 return ERR_NONE; 00474 } 00475 00476 00477 /*******************************************************************************/ 00478 ReturnCode rfalCalibrate( 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 ) 00479 { 00480 uint16_t resValue; 00481 00482 /* Check if RFAL is not initialized */ 00483 if( gRFAL .state == RFAL_STATE_IDLE ) 00484 { 00485 return ERR_WRONG_STATE; 00486 } 00487 00488 /*******************************************************************************/ 00489 /* Perform ST25R3911 regulators and antenna calibration */ 00490 /*******************************************************************************/ 00491 00492 /* Automatic regulator adjustment only performed if not set manually on Analog Configs */ 00493 if( st25r3911CheckReg( ST25R3911_REG_REGULATOR_CONTROL, ST25R3911_REG_REGULATOR_CONTROL_reg_s, 0x00, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ) 00494 { 00495 /* Adjust the regulators so that Antenna Calibrate has better Regulator values */ 00496 st25r3911AdjustRegulators( &resValue, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00497 } 00498 00499 /* Automatic Antenna calibration only performed if not set manually on Analog Configs */ 00500 if( st25r3911CheckReg( ST25R3911_REG_ANT_CAL_CONTROL, ST25R3911_REG_ANT_CAL_CONTROL_trim_s, 0x00, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ) 00501 { 00502 st25r3911CalibrateAntenna( (uint8_t*) &resValue, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00503 00504 /*******************************************************************************/ 00505 /* REMARK: Silicon workaround ST25R3911 Errata #1.5 */ 00506 /* Always run the command Calibrate Antenna twice */ 00507 st25r3911CalibrateAntenna( (uint8_t*) &resValue, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00508 /*******************************************************************************/ 00509 00510 } 00511 else 00512 { 00513 /* If no antenna calibration is performed there is no need to perform second regulator adjustment again */ 00514 return ERR_NONE; 00515 } 00516 00517 if( st25r3911CheckReg( ST25R3911_REG_REGULATOR_CONTROL, ST25R3911_REG_REGULATOR_CONTROL_reg_s, 0x00, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ) 00518 { 00519 /* Adjust the regulators again with the Antenna calibrated */ 00520 st25r3911AdjustRegulators( &resValue, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00521 } 00522 00523 return ERR_NONE; 00524 } 00525 00526 00527 /*******************************************************************************/ 00528 ReturnCode rfalAdjustRegulators( uint16_t* result, 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 ) 00529 { 00530 /*******************************************************************************/ 00531 /* Make use of the Automatic Adjust */ 00532 st25r3911ClrRegisterBits( ST25R3911_REG_REGULATOR_CONTROL, ST25R3911_REG_REGULATOR_CONTROL_reg_s, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00533 00534 return st25r3911AdjustRegulators( result, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00535 } 00536 00537 00538 /*******************************************************************************/ 00539 void rfalSetUpperLayerCallback( rfalUpperLayerCallback pFunc ) 00540 { 00541 st25r3911IRQCallbackSet( pFunc ); 00542 } 00543 00544 00545 /*******************************************************************************/ 00546 void rfalSetPreTxRxCallback( rfalPreTxRxCallback pFunc ) 00547 { 00548 gRFAL .callbacks.preTxRx = pFunc; 00549 } 00550 00551 00552 /*******************************************************************************/ 00553 void rfalSetPostTxRxCallback( rfalPostTxRxCallback pFunc ) 00554 { 00555 gRFAL .callbacks.postTxRx = pFunc; 00556 } 00557 00558 00559 /*******************************************************************************/ 00560 ReturnCode rfalDeinitialize( 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 ) 00561 { 00562 /* Deinitialize chip */ 00563 st25r3911Deinitialize(mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00564 00565 gRFAL .state = RFAL_STATE_IDLE; 00566 return ERR_NONE; 00567 } 00568 00569 00570 /*******************************************************************************/ 00571 void rfalSetObsvMode( uint8_t txMode, uint8_t rxMode ) 00572 { 00573 gRFAL .conf.obsvModeTx = txMode; 00574 gRFAL .conf.obsvModeRx = rxMode; 00575 } 00576 00577 00578 /*******************************************************************************/ 00579 void rfalGetObsvMode( uint8_t* txMode, uint8_t* rxMode ) 00580 { 00581 if(txMode != NULL) 00582 { 00583 *txMode = gRFAL .conf.obsvModeTx; 00584 } 00585 00586 if(rxMode != NULL) 00587 { 00588 *rxMode = gRFAL .conf.obsvModeRx; 00589 } 00590 } 00591 00592 00593 /*******************************************************************************/ 00594 void rfalDisableObsvMode( void ) 00595 { 00596 gRFAL .conf.obsvModeTx = RFAL_OBSMODE_DISABLE; 00597 gRFAL .conf.obsvModeRx = RFAL_OBSMODE_DISABLE; 00598 } 00599 00600 00601 /*******************************************************************************/ 00602 ReturnCode rfalSetMode( rfalMode mode, rfalBitRate txBR, rfalBitRate rxBR,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 ) 00603 { 00604 00605 /* Check if RFAL is not initialized */ 00606 if( gRFAL .state == RFAL_STATE_IDLE ) 00607 { 00608 return ERR_WRONG_STATE; 00609 } 00610 00611 /* Check allowed bit rate value */ 00612 if( (txBR == RFAL_BR_KEEP ) || (rxBR == RFAL_BR_KEEP ) ) 00613 { 00614 return ERR_PARAM; 00615 } 00616 00617 switch( mode ) 00618 { 00619 /*******************************************************************************/ 00620 case RFAL_MODE_POLL_NFCA : 00621 00622 /* Disable wake up mode, if set */ 00623 st25r3911ClrRegisterBits( ST25R3911_REG_OP_CONTROL, ST25R3911_REG_OP_CONTROL_wu, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00624 00625 /* Enable ISO14443A mode */ 00626 mST25 -> writeRegister(ST25R3911_REG_MODE, ST25R3911_REG_MODE_om_iso14443a, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00627 00628 /* Set Analog configurations for this mode and bit rate */ 00629 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00630 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00631 break; 00632 00633 /*******************************************************************************/ 00634 case RFAL_MODE_POLL_NFCA_T1T : 00635 /* Disable wake up mode, if set */ 00636 st25r3911ClrRegisterBits( ST25R3911_REG_OP_CONTROL, ST25R3911_REG_OP_CONTROL_wu, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00637 00638 /* Enable Topaz mode */ 00639 mST25 ->writeRegister( ST25R3911_REG_MODE, ST25R3911_REG_MODE_om_topaz, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00640 00641 /* Set Analog configurations for this mode and bit rate */ 00642 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00643 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00644 break; 00645 00646 /*******************************************************************************/ 00647 case RFAL_MODE_POLL_NFCB : 00648 00649 /* Disable wake up mode, if set */ 00650 st25r3911ClrRegisterBits( ST25R3911_REG_OP_CONTROL, ST25R3911_REG_OP_CONTROL_wu, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00651 00652 /* Enable ISO14443B mode */ 00653 mST25 -> writeRegister(ST25R3911_REG_MODE, ST25R3911_REG_MODE_om_iso14443b, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00654 00655 /* Set the EGT, SOF, EOF and EOF */ 00656 st25r3911ChangeRegisterBits( ST25R3911_REG_ISO14443B_1, 00657 (ST25R3911_REG_ISO14443B_1_mask_egt | ST25R3911_REG_ISO14443B_1_mask_sof | ST25R3911_REG_ISO14443B_1_mask_eof), 00658 ( (0<<ST25R3911_REG_ISO14443B_1_shift_egt) | ST25R3911_REG_ISO14443B_1_sof_0_10etu | ST25R3911_REG_ISO14443B_1_sof_1_2etu), 00659 mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00660 00661 /* Set the minimum TR1, SOF, EOF and EOF12 */ 00662 st25r3911ChangeRegisterBits( ST25R3911_REG_ISO14443B_2, 00663 (ST25R3911_REG_ISO14443B_2_mask_tr1 | ST25R3911_REG_ISO14443B_2_no_sof | ST25R3911_REG_ISO14443B_2_no_eof |ST25R3911_REG_ISO14443B_2_eof_12), 00664 (ST25R3911_REG_ISO14443B_2_tr1_80fs80fs | ST25R3911_REG_ISO14443B_2_eof_12_10to11etu ), 00665 mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00666 00667 00668 /* Set Analog configurations for this mode and bit rate */ 00669 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00670 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00671 break; 00672 00673 /*******************************************************************************/ 00674 case RFAL_MODE_POLL_B_PRIME : 00675 00676 /* Disable wake up mode, if set */ 00677 st25r3911ClrRegisterBits( ST25R3911_REG_OP_CONTROL, ST25R3911_REG_OP_CONTROL_wu, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00678 00679 /* Enable ISO14443B mode */ 00680 mST25->writeRegister(ST25R3911_REG_MODE, ST25R3911_REG_MODE_om_iso14443b, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ); 00681 00682 /* Set the EGT, SOF, EOF and EOF */ 00683 st25r3911ChangeRegisterBits( ST25R3911_REG_ISO14443B_1, 00684 (ST25R3911_REG_ISO14443B_1_mask_egt | ST25R3911_REG_ISO14443B_1_mask_sof | ST25R3911_REG_ISO14443B_1_mask_eof), 00685 ( (0<<ST25R3911_REG_ISO14443B_1_shift_egt) | ST25R3911_REG_ISO14443B_1_sof_0_10etu | ST25R3911_REG_ISO14443B_1_sof_1_2etu), 00686 mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00687 00688 /* Set the minimum TR1, EOF and EOF12 */ 00689 st25r3911ChangeRegisterBits( ST25R3911_REG_ISO14443B_2, 00690 (ST25R3911_REG_ISO14443B_2_mask_tr1 | ST25R3911_REG_ISO14443B_2_no_sof | ST25R3911_REG_ISO14443B_2_no_eof |ST25R3911_REG_ISO14443B_2_eof_12), 00691 (ST25R3911_REG_ISO14443B_2_tr1_80fs80fs | ST25R3911_REG_ISO14443B_2_no_sof | ST25R3911_REG_ISO14443B_2_eof_12_10to12etu ), 00692 mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00693 00694 00695 /* Set Analog configurations for this mode and bit rate */ 00696 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00697 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00698 break; 00699 00700 /*******************************************************************************/ 00701 case RFAL_MODE_POLL_B_CTS : 00702 00703 /* Disable wake up mode, if set */ 00704 st25r3911ClrRegisterBits( ST25R3911_REG_OP_CONTROL, ST25R3911_REG_OP_CONTROL_wu, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00705 00706 /* Enable ISO14443B mode */ 00707 mST25->writeRegister(ST25R3911_REG_MODE, ST25R3911_REG_MODE_om_iso14443b, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00708 00709 /* Set the EGT, SOF, EOF and EOF */ 00710 st25r3911ChangeRegisterBits( ST25R3911_REG_ISO14443B_1, 00711 (ST25R3911_REG_ISO14443B_1_mask_egt | ST25R3911_REG_ISO14443B_1_mask_sof | ST25R3911_REG_ISO14443B_1_mask_eof), 00712 ( (0<<ST25R3911_REG_ISO14443B_1_shift_egt) | ST25R3911_REG_ISO14443B_1_sof_0_10etu | ST25R3911_REG_ISO14443B_1_sof_1_2etu), 00713 mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00714 00715 /* Set the minimum TR1, clear SOF, EOF and EOF12 */ 00716 st25r3911ChangeRegisterBits( ST25R3911_REG_ISO14443B_2, 00717 (ST25R3911_REG_ISO14443B_2_mask_tr1 | ST25R3911_REG_ISO14443B_2_no_sof | ST25R3911_REG_ISO14443B_2_no_eof |ST25R3911_REG_ISO14443B_2_eof_12), 00718 (ST25R3911_REG_ISO14443B_2_tr1_80fs80fs | ST25R3911_REG_ISO14443B_2_no_sof | ST25R3911_REG_ISO14443B_2_no_eof ), 00719 mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00720 00721 00722 /* Set Analog configurations for this mode and bit rate */ 00723 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00724 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00725 break; 00726 00727 /*******************************************************************************/ 00728 case RFAL_MODE_POLL_NFCF : 00729 00730 /* Disable wake up mode, if set */ 00731 st25r3911ClrRegisterBits( ST25R3911_REG_OP_CONTROL, ST25R3911_REG_OP_CONTROL_wu, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00732 00733 /* Enable FeliCa mode */ 00734 mST25->writeRegister( ST25R3911_REG_MODE, ST25R3911_REG_MODE_om_felica, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00735 00736 /* Set Analog configurations for this mode and bit rate */ 00737 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCF | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00738 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCF | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00739 break; 00740 00741 /*******************************************************************************/ 00742 case RFAL_MODE_POLL_NFCV : 00743 case RFAL_MODE_POLL_PICOPASS : 00744 00745 /* Disable wake up mode, if set */ 00746 st25r3911ClrRegisterBits( ST25R3911_REG_OP_CONTROL, ST25R3911_REG_OP_CONTROL_wu, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00747 00748 /* Set Analog configurations for this mode and bit rate */ 00749 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCV | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00750 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCV | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00751 break; 00752 00753 /*******************************************************************************/ 00754 case RFAL_MODE_POLL_ACTIVE_P2P : 00755 00756 /* Set NFCIP1 active communication initiator mode and Enable NFC Automatic Response RF Collision Avoidance */ 00757 mST25->writeRegister(ST25R3911_REG_MODE, (ST25R3911_REG_MODE_targ_init | ST25R3911_REG_MODE_om_nfc | ST25R3911_REG_MODE_nfc_ar), 00758 mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00759 00760 /* Set GPT to start after end of TX, as GPT is used in active communication mode to timeout the field switching off */ 00761 /* The field is turned off 37.76us after the end of the transmission Trfw */ 00762 st25r3911StartGPTimer_8fcs( rfalConv1fcTo8fc( RFAL_AP2P_FIELDOFF_TRFW ), ST25R3911_REG_GPT_CONTROL_gptc_etx_nfc, 00763 mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00764 00765 /* Enable External Field Detector */ 00766 st25r3911SetRegisterBits( ST25R3911_REG_AUX, ST25R3911_REG_AUX_en_fd, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00767 00768 /* Set Analog configurations for this mode and bit rate */ 00769 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_AP2P | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00770 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_AP2P | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00771 break; 00772 00773 /*******************************************************************************/ 00774 case RFAL_MODE_LISTEN_ACTIVE_P2P : 00775 00776 /* Set NFCIP1 active communication initiator mode and Enable NFC Automatic Response RF Collision Avoidance */ 00777 mST25-> writeRegister(ST25R3911_REG_MODE, (ST25R3911_REG_MODE_targ_targ | ST25R3911_REG_MODE_om_nfcip1_normal_mode | ST25R3911_REG_MODE_nfc_ar), 00778 mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00779 00780 /* Set GPT to start after end of TX, as GPT is used in active communication mode to timeout the field switching off */ 00781 /* The field is turned off 37.76us after the end of the transmission Trfw */ 00782 st25r3911StartGPTimer_8fcs( rfalConv1fcTo8fc( RFAL_AP2P_FIELDOFF_TRFW ), ST25R3911_REG_GPT_CONTROL_gptc_etx_nfc, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ); 00783 00784 /* Enable External Field Detector */ 00785 st25r3911SetRegisterBits( ST25R3911_REG_AUX, ST25R3911_REG_AUX_en_fd, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00786 00787 /* Set Analog configurations for this mode and bit rate */ 00788 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_AP2P | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00789 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_AP2P | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00790 break; 00791 00792 /*******************************************************************************/ 00793 case RFAL_MODE_LISTEN_NFCA : 00794 case RFAL_MODE_LISTEN_NFCB : 00795 case RFAL_MODE_LISTEN_NFCF : 00796 return ERR_NOTSUPP; 00797 00798 /*******************************************************************************/ 00799 default: 00800 return ERR_NOT_IMPLEMENTED; 00801 } 00802 00803 /* Set state as STATE_MODE_SET only if not initialized yet (PSL) */ 00804 gRFAL .state = ((gRFAL .state < RFAL_STATE_MODE_SET) ? RFAL_STATE_MODE_SET : gRFAL .state); 00805 gRFAL .mode = mode; 00806 00807 /* Apply the given bit rate */ 00808 return rfalSetBitRate(txBR, rxBR, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00809 } 00810 00811 00812 /*******************************************************************************/ 00813 rfalMode rfalGetMode( void ) 00814 { 00815 return gRFAL .mode; 00816 } 00817 00818 00819 /*******************************************************************************/ 00820 ReturnCode rfalSetBitRate( rfalBitRate txBR, rfalBitRate rxBR, 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 ) 00821 { 00822 ReturnCode ret; 00823 00824 /* Check if RFAL is not initialized */ 00825 if( gRFAL .state == RFAL_STATE_IDLE ) 00826 { 00827 return ERR_WRONG_STATE; 00828 } 00829 00830 /* Store the new Bit Rates */ 00831 gRFAL .txBR = ((txBR == RFAL_BR_KEEP ) ? gRFAL .txBR : txBR); 00832 gRFAL .rxBR = ((rxBR == RFAL_BR_KEEP ) ? gRFAL .rxBR : rxBR); 00833 00834 /* Update the bitrate reg if not in NFCV mode (streaming) */ 00835 if( (RFAL_MODE_POLL_NFCV != gRFAL .mode) && (RFAL_MODE_POLL_PICOPASS != gRFAL .mode) ) 00836 { 00837 EXIT_ON_ERR( ret, st25r3911SetBitrate( gRFAL .txBR, gRFAL .rxBR, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ); 00838 } 00839 00840 00841 switch( gRFAL .mode ) 00842 { 00843 /*******************************************************************************/ 00844 case RFAL_MODE_POLL_NFCA : 00845 case RFAL_MODE_POLL_NFCA_T1T : 00846 00847 /* Set Analog configurations for this bit rate */ 00848 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA | rfalConvBR2ACBR(gRFAL .txBR) | RFAL_ANALOG_CONFIG_TX ), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00849 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA | rfalConvBR2ACBR(gRFAL .rxBR) | RFAL_ANALOG_CONFIG_RX ), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00850 break; 00851 00852 /*******************************************************************************/ 00853 case RFAL_MODE_POLL_NFCB : 00854 case RFAL_MODE_POLL_B_PRIME : 00855 case RFAL_MODE_POLL_B_CTS : 00856 00857 /* Set Analog configurations for this bit rate */ 00858 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB | rfalConvBR2ACBR(gRFAL .txBR) | RFAL_ANALOG_CONFIG_TX ), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00859 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB | rfalConvBR2ACBR(gRFAL .rxBR) | RFAL_ANALOG_CONFIG_RX ), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00860 break; 00861 00862 /*******************************************************************************/ 00863 case RFAL_MODE_POLL_NFCF : 00864 00865 /* Set Analog configurations for this bit rate */ 00866 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCF | rfalConvBR2ACBR(gRFAL .txBR) | RFAL_ANALOG_CONFIG_TX ), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00867 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCF | rfalConvBR2ACBR(gRFAL .rxBR) | RFAL_ANALOG_CONFIG_RX ), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00868 break; 00869 00870 /*******************************************************************************/ 00871 case RFAL_MODE_POLL_NFCV : 00872 case RFAL_MODE_POLL_PICOPASS : 00873 00874 #if !RFAL_FEATURE_NFCV 00875 return ERR_DISABLED; 00876 #else 00877 00878 if( ((gRFAL .rxBR != RFAL_BR_26p48 ) && (gRFAL .rxBR != RFAL_BR_52p97 )) || ((gRFAL .txBR != RFAL_BR_1p66 ) && (gRFAL .txBR != RFAL_BR_26p48 )) ) 00879 { 00880 return ERR_PARAM; 00881 } 00882 00883 { 00884 const struct iso15693StreamConfig *stream_config; 00885 iso15693PhyConfig_t config; 00886 00887 config.coding = (( gRFAL .txBR == RFAL_BR_1p66 ) ? ISO15693_VCD_CODING_1_256 : ISO15693_VCD_CODING_1_4); 00888 config.fastMode = (( gRFAL .rxBR == RFAL_BR_52p97 ) ? true : false); 00889 00890 iso15693PhyConfigure(&config, &stream_config); 00891 st25r3911StreamConfigure((struct st25r3911StreamConfig*)stream_config, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00892 } 00893 00894 /* Set Analog configurations for this bit rate */ 00895 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCV | rfalConvBR2ACBR(gRFAL .txBR) | RFAL_ANALOG_CONFIG_TX ), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00896 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCV | rfalConvBR2ACBR(gRFAL .rxBR) | RFAL_ANALOG_CONFIG_RX ), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00897 break; 00898 00899 #endif /* RFAL_FEATURE_NFCV */ 00900 00901 00902 /*******************************************************************************/ 00903 case RFAL_MODE_POLL_ACTIVE_P2P : 00904 00905 /* Set Analog configurations for this bit rate */ 00906 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_AP2P | rfalConvBR2ACBR(gRFAL .txBR) | RFAL_ANALOG_CONFIG_TX ), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00907 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_AP2P | rfalConvBR2ACBR(gRFAL .rxBR) | RFAL_ANALOG_CONFIG_RX ), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00908 break; 00909 00910 /*******************************************************************************/ 00911 case RFAL_MODE_LISTEN_ACTIVE_P2P : 00912 00913 /* Set Analog configurations for this bit rate */ 00914 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_AP2P | rfalConvBR2ACBR(gRFAL .txBR) | RFAL_ANALOG_CONFIG_TX ), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00915 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_AP2P | rfalConvBR2ACBR(gRFAL .rxBR) | RFAL_ANALOG_CONFIG_RX ), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00916 break; 00917 00918 /*******************************************************************************/ 00919 case RFAL_MODE_LISTEN_NFCA : 00920 case RFAL_MODE_LISTEN_NFCB : 00921 case RFAL_MODE_LISTEN_NFCF : 00922 case RFAL_MODE_NONE : 00923 return ERR_WRONG_STATE; 00924 00925 /*******************************************************************************/ 00926 default: 00927 return ERR_NOT_IMPLEMENTED; 00928 } 00929 00930 return ERR_NONE; 00931 } 00932 00933 00934 /*******************************************************************************/ 00935 ReturnCode rfalGetBitRate( rfalBitRate *txBR, rfalBitRate *rxBR ) 00936 { 00937 if( (gRFAL .state == RFAL_STATE_IDLE) || (gRFAL .mode == RFAL_MODE_NONE ) ) 00938 { 00939 return ERR_WRONG_STATE; 00940 } 00941 00942 if( txBR != NULL ) 00943 { 00944 *txBR = gRFAL .txBR; 00945 } 00946 00947 if( rxBR != NULL ) 00948 { 00949 *rxBR = gRFAL .rxBR; 00950 } 00951 00952 return ERR_NONE; 00953 } 00954 00955 00956 /*******************************************************************************/ 00957 ReturnCode rfalSetModulatedRFO( uint8_t rfo, 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 ) 00958 { 00959 mST25->writeRegister( ST25R3911_REG_RFO_AM_ON_LEVEL, rfo, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00960 00961 return ERR_NONE; 00962 } 00963 00964 00965 /*******************************************************************************/ 00966 uint8_t rfalGetModulatedRFO( 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 ) 00967 { 00968 uint8_t ret; 00969 00970 mST25->readRegister(ST25R3911_REG_RFO_AM_ON_LEVEL, &ret, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00971 00972 return ret; 00973 } 00974 00975 00976 /*******************************************************************************/ 00977 ReturnCode rfalMeasureRF( uint8_t* result, 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 ) 00978 { 00979 st25r3911MeasureRF( result, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 00980 00981 return ERR_NONE; 00982 } 00983 00984 00985 /*******************************************************************************/ 00986 void rfalSetErrorHandling( rfalEHandling eHandling ) 00987 { 00988 gRFAL .conf.eHandling = eHandling; 00989 } 00990 00991 00992 /*******************************************************************************/ 00993 rfalEHandling rfalGetErrorHandling( void ) 00994 { 00995 return gRFAL .conf.eHandling; 00996 } 00997 00998 00999 /*******************************************************************************/ 01000 void rfalSetFDTPoll( uint32_t FDTPoll ) 01001 { 01002 gRFAL .timings.FDTPoll = MIN( FDTPoll, RFAL_ST25R3911_GPT_MAX_1FC ); 01003 } 01004 01005 01006 /*******************************************************************************/ 01007 uint32_t rfalGetFDTPoll( void ) 01008 { 01009 return gRFAL .timings.FDTPoll; 01010 } 01011 01012 01013 /*******************************************************************************/ 01014 void rfalSetFDTListen( uint32_t FDTListen ) 01015 { 01016 gRFAL .timings.FDTListen = MIN( FDTListen, RFAL_ST25R3911_MRT_MAX_1FC); 01017 } 01018 01019 /*******************************************************************************/ 01020 uint32_t rfalGetFDTListen( void ) 01021 { 01022 return gRFAL .timings.FDTListen; 01023 } 01024 01025 void rfalSetGT( uint32_t GT ) 01026 { 01027 gRFAL .timings.GT = MIN( GT, RFAL_ST25R3911_GT_MAX_1FC ); 01028 } 01029 01030 /*******************************************************************************/ 01031 uint32_t rfalGetGT( void ) 01032 { 01033 return gRFAL .timings.GT; 01034 } 01035 01036 /*******************************************************************************/ 01037 bool rfalIsGTExpired( void )//check here the platform time 01038 { 01039 if( gRFAL .tmr.GT != RFAL_TIMING_NONE ) 01040 { 01041 if( !rfalTimerisExpired( gRFAL .tmr.GT ) ) 01042 { 01043 return false; 01044 } 01045 } 01046 return true; 01047 } 01048 01049 /*******************************************************************************/ 01050 ReturnCode rfalFieldOnAndStartGT( 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 ) 01051 { 01052 ReturnCode ret; 01053 01054 /* Check if RFAL has been initialized (Oscillator should be running) and also 01055 * if a direct register access has been performed and left the Oscillator Off */ 01056 if( (gRFAL .state < RFAL_STATE_INIT) || !st25r3911CheckReg( ST25R3911_REG_OP_CONTROL, ST25R3911_REG_OP_CONTROL_en, ST25R3911_REG_OP_CONTROL_en, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ) 01057 { 01058 return ERR_WRONG_STATE; 01059 } 01060 01061 ret = ERR_NONE; 01062 01063 /*******************************************************************************/ 01064 /* Perform collision avoidance and turn field On if not already On */ 01065 if( !gRFAL .field || !( st25r3911CheckReg(ST25R3911_REG_OP_CONTROL, ST25R3911_REG_OP_CONTROL_tx_en, ST25R3911_REG_OP_CONTROL_tx_en, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ) ) 01066 { 01067 /* Use Thresholds set by AnalogConfig */ 01068 ret = st25r3911PerformCollisionAvoidance( ST25R3911_CMD_RESPONSE_RF_COLLISION_0, ST25R3911_THRESHOLD_DO_NOT_SET, ST25R3911_THRESHOLD_DO_NOT_SET, 0, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01069 01070 gRFAL .field = ( st25r3911CheckReg(ST25R3911_REG_OP_CONTROL, ST25R3911_REG_OP_CONTROL_tx_en, ST25R3911_REG_OP_CONTROL_tx_en, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ); 01071 01072 /* Only turn on Receiver and Transmitter if field was successfully turned On */ 01073 if(gRFAL .field) 01074 { 01075 st25r3911TxRxOn( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; /* Enable Tx and Rx (Tx is already On) */ 01076 } 01077 } 01078 01079 /*******************************************************************************/ 01080 /* Start GT timer in case the GT value is set */ 01081 if( (gRFAL .timings.GT != RFAL_TIMING_NONE) ) 01082 { 01083 /* Ensure that a SW timer doesn't have a lower value then the minimum */ 01084 rfalTimerStart( gRFAL .tmr.GT, rfalConv1fcToMs( MAX( (gRFAL .timings.GT), RFAL_ST25R3911_GT_MIN_1FC) ) ); 01085 } 01086 01087 return ret; 01088 } 01089 01090 01091 /*******************************************************************************/ 01092 ReturnCode rfalFieldOff( 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 ) 01093 { 01094 /* Check whether a TxRx is not yet finished */ 01095 if( gRFAL .TxRx.state != RFAL_TXRX_STATE_IDLE ) 01096 { 01097 rfalCleanupTransceive(mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01098 } 01099 01100 /* Disable Tx and Rx */ 01101 st25r3911TxRxOff( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01102 gRFAL .field = false; 01103 01104 return ERR_NONE; 01105 } 01106 01107 01108 /*******************************************************************************/ 01109 ReturnCode rfalStartTransceive( rfalTransceiveContext *ctx,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 ) 01110 { 01111 uint32_t FxTAdj; /* FWT or FDT adjustment calculation */ 01112 01113 /* Ensure that RFAL is already Initialized and the mode has been set */ 01114 if( (gRFAL .state >= RFAL_STATE_MODE_SET) /*&& (gRFAL.TxRx.state == RFAL_TXRX_STATE_INIT )*/ ) 01115 { 01116 /*******************************************************************************/ 01117 /* Check whether the field is already On, otherwise no TXE will be received */ 01118 if( !( st25r3911CheckReg(ST25R3911_REG_OP_CONTROL, ST25R3911_REG_OP_CONTROL_tx_en, ST25R3911_REG_OP_CONTROL_tx_en, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ) 01119 && (!rfalIsModePassiveListen( gRFAL .mode ) && (ctx->txBuf != NULL)) ) 01120 { 01121 return ERR_WRONG_STATE; 01122 } 01123 01124 gRFAL .TxRx.ctx = *ctx; 01125 01126 /*******************************************************************************/ 01127 if( gRFAL .timings.FDTListen != RFAL_TIMING_NONE ) 01128 { 01129 /* Calculate MRT adjustment accordingly to the current mode */ 01130 FxTAdj = RFAL_FDT_LISTEN_MRT_ADJUSTMENT; 01131 if(gRFAL .mode == RFAL_MODE_POLL_NFCA ) FxTAdj += RFAL_FDT_LISTEN_A_ADJUSTMENT; 01132 else if(gRFAL .mode == RFAL_MODE_POLL_NFCA_T1T ) FxTAdj += RFAL_FDT_LISTEN_A_ADJUSTMENT; 01133 else if(gRFAL .mode == RFAL_MODE_POLL_NFCB ) FxTAdj += RFAL_FDT_LISTEN_B_ADJUSTMENT; 01134 01135 01136 /* Set Minimum FDT(Listen) in which PICC is not allowed to send a response */ 01137 mST25 -> writeRegister( ST25R3911_REG_MASK_RX_TIMER, rfalConv1fcTo64fc( (FxTAdj > gRFAL .timings.FDTListen) ? RFAL_ST25R3911_MRT_MIN_1FC : (gRFAL .timings.FDTListen - FxTAdj) ), mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ); 01138 } 01139 01140 /*******************************************************************************/ 01141 /* FDT Poll will be loaded in rfalPrepareTransceive() once the previous was expired */ 01142 01143 /*******************************************************************************/ 01144 if( rfalIsModePassiveComm( gRFAL .mode ) ) /* Passive Comms */ 01145 { 01146 if( (gRFAL .TxRx.ctx.fwt != RFAL_FWT_NONE) && (gRFAL .TxRx.ctx.fwt != 0) ) 01147 { 01148 FxTAdj = RFAL_FWT_ADJUSTMENT; 01149 if(gRFAL .mode == RFAL_MODE_POLL_NFCA ) FxTAdj += RFAL_FWT_A_ADJUSTMENT; 01150 else if(gRFAL .mode == RFAL_MODE_POLL_NFCA_T1T ) FxTAdj += RFAL_FWT_A_ADJUSTMENT; 01151 else if(gRFAL .mode == RFAL_MODE_POLL_NFCB ) FxTAdj += RFAL_FWT_B_ADJUSTMENT; 01152 else if(gRFAL .mode == RFAL_MODE_POLL_NFCF ) 01153 { 01154 FxTAdj += ((gRFAL .txBR == RFAL_BR_212 ) ? RFAL_FWT_F_212_ADJUSTMENT : RFAL_FWT_F_424_ADJUSTMENT ); 01155 } 01156 01157 /* Ensure that the given FWT doesn't exceed NRT maximum */ 01158 gRFAL .TxRx.ctx.fwt = MIN( (gRFAL .TxRx.ctx.fwt + FxTAdj), RFAL_ST25R3911_NRT_MAX_1FC ); 01159 01160 /* Set FWT in the NRT */ 01161 st25r3911SetNoResponseTime_64fcs( rfalConv1fcTo64fc( gRFAL .TxRx.ctx.fwt ), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01162 } 01163 else 01164 { 01165 /* Disable NRT, no NRE will be triggered, therefore wait endlessly for Rx */ 01166 st25r3911SetNoResponseTime_64fcs( RFAL_ST25R3911_NRT_DISABLED, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01167 } 01168 } 01169 else /* Active Comms */ 01170 { 01171 /* Setup NRT timer for rf response RF collision timeout. */ 01172 st25r3911SetNoResponseTime_64fcs( rfalConv1fcTo64fc(RFAL_AP2P_FIELDON_TADTTRFW), mspiChannel, mST25, gpio_cs, IRQ , fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ); 01173 01174 /* In Active Mode No Response Timer cannot be used to measure FWT a SW timer is used instead */ 01175 } 01176 01177 gRFAL .state = RFAL_STATE_TXRX; 01178 gRFAL .TxRx.state = RFAL_TXRX_STATE_TX_IDLE; 01179 gRFAL .TxRx.status = ERR_BUSY; 01180 gRFAL .TxRx.rxse = false; 01181 01182 #if RFAL_FEATURE_NFCV 01183 /*******************************************************************************/ 01184 if( (RFAL_MODE_POLL_NFCV == gRFAL .mode) || (RFAL_MODE_POLL_PICOPASS == gRFAL .mode) ) 01185 { /* Exchange receive buffer with internal buffer */ 01186 gRFAL .nfcvData.origCtx = gRFAL .TxRx.ctx; 01187 01188 gRFAL .TxRx.ctx.rxBuf = ((gRFAL .nfcvData.origCtx.rxBuf != NULL) ? gRFAL .nfcvData.codingBuffer : NULL); 01189 gRFAL .TxRx.ctx.rxBufLen = rfalConvBytesToBits(sizeof(gRFAL .nfcvData.codingBuffer)); 01190 gRFAL .TxRx.ctx.flags = RFAL_TXRX_FLAGS_CRC_TX_MANUAL 01191 | RFAL_TXRX_FLAGS_CRC_RX_KEEP 01192 | RFAL_TXRX_FLAGS_NFCIP1_OFF 01193 | (gRFAL .nfcvData.origCtx.flags & RFAL_TXRX_FLAGS_AGC_OFF ) 01194 | RFAL_TXRX_FLAGS_PAR_RX_KEEP 01195 | RFAL_TXRX_FLAGS_PAR_TX_NONE ; 01196 /* In NFCV a transceive with valid txBuf and txBufSize==0 should send first an EOF. 01197 In this case avoid below code for going directly into receive. */ 01198 if (gRFAL .TxRx.ctx.txBuf) return ERR_NONE; 01199 } 01200 #endif /* RFAL_FEATURE_NFCV */ 01201 01202 01203 /*******************************************************************************/ 01204 /* Check if the Transceive start performing Tx or goes directly to Rx */ 01205 if( (gRFAL .TxRx.ctx.txBuf == NULL) || (gRFAL .TxRx.ctx.txBufLen == 0) ) 01206 { 01207 /* Disable our field upon a Rx reEnable on AP2P */ 01208 if( rfalIsModeActiveComm(gRFAL .mode) ) 01209 { 01210 st25r3911ClrRegisterBits((unsigned char)(ST25R3911_REG_OP_CONTROL),(unsigned char)(ST25R3911_REG_OP_CONTROL_tx_en), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01211 } 01212 01213 /* Clear FIFO, Clear and Enable the Interrupts */ 01214 rfalPrepareTransceive( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01215 01216 /* No Tx done, enable the Receiver */ 01217 mST25 -> executeCommand( ST25R3911_CMD_UNMASK_RECEIVE_DATA, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01218 01219 /* Start NRT manually, if FWT = 0 (wait endlessly for Rx) chip will ignore anyhow */ 01220 mST25 -> executeCommand( ST25R3911_CMD_START_NO_RESPONSE_TIMER, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01221 01222 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_IDLE; 01223 } 01224 01225 return ERR_NONE; 01226 } 01227 01228 return ERR_WRONG_STATE; 01229 } 01230 01231 01232 /*******************************************************************************/ 01233 ReturnCode rfalTransceiveBlockingTx( uint8_t* txBuf, uint16_t txBufLen, uint8_t* rxBuf, uint16_t rxBufLen, uint16_t* actLen, uint32_t flags, uint32_t fwt, 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 ) 01234 { 01235 ReturnCode ret; 01236 rfalTransceiveContext ctx; 01237 01238 rfalCreateByteFlagsTxRxContext( ctx, txBuf, txBufLen, rxBuf, rxBufLen, actLen, flags, fwt ); 01239 EXIT_ON_ERR( ret, rfalStartTransceive( &ctx, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ); 01240 01241 return rfalTransceiveRunBlockingTx( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01242 } 01243 01244 01245 /*******************************************************************************/ 01246 static ReturnCode rfalTransceiveRunBlockingTx( 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 ) 01247 { 01248 ReturnCode ret; 01249 01250 do{ 01251 rfalWorker(mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01252 } 01253 while( ((ret = rfalGetTransceiveStatus() ) == ERR_BUSY) && rfalIsTransceiveInTx() ); 01254 01255 if( rfalIsTransceiveInRx() ) 01256 { 01257 return ERR_NONE; 01258 } 01259 01260 return ret; 01261 } 01262 01263 01264 /*******************************************************************************/ 01265 ReturnCode rfalTransceiveBlockingRx( 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 ) 01266 { 01267 ReturnCode ret; 01268 01269 do{ 01270 rfalWorker( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01271 } 01272 while( ((ret = rfalGetTransceiveStatus() ) == ERR_BUSY) && rfalIsTransceiveInRx() ); 01273 01274 return ret; 01275 } 01276 01277 01278 /*******************************************************************************/ 01279 ReturnCode rfalTransceiveBlockingTxRx( uint8_t* txBuf, uint16_t txBufLen, 01280 uint8_t* rxBuf, uint16_t rxBufLen, uint16_t* actLen, uint32_t flags, 01281 uint32_t fwt, 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 ) 01282 { 01283 ReturnCode ret; 01284 01285 EXIT_ON_ERR( ret, rfalTransceiveBlockingTx( txBuf, txBufLen, rxBuf, rxBufLen, actLen, flags, fwt, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ); 01286 ret = rfalTransceiveBlockingRx( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ); 01287 01288 /* Convert received bits to bytes */ 01289 if( actLen != NULL ) 01290 { 01291 *actLen = rfalConvBitsToBytes(*actLen); 01292 } 01293 01294 return ret; 01295 } 01296 01297 01298 /*******************************************************************************/ 01299 static ReturnCode rfalRunTransceiveWorker( 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 ) 01300 { 01301 if( gRFAL .state == RFAL_STATE_TXRX ) 01302 { 01303 /* Run Tx or Rx state machines */ 01304 if( rfalIsTransceiveInTx() ) 01305 { 01306 rfalTransceiveTx( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01307 return rfalGetTransceiveStatus(); 01308 } 01309 else if( rfalIsTransceiveInRx() ) 01310 { 01311 rfalTransceiveRx( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01312 return rfalGetTransceiveStatus(); 01313 } 01314 } 01315 return ERR_WRONG_STATE; 01316 } 01317 01318 /*******************************************************************************/ 01319 rfalTransceiveState rfalGetTransceiveState( void ) 01320 { 01321 return gRFAL .TxRx.state; 01322 } 01323 01324 ReturnCode rfalGetTransceiveStatus( void ) 01325 { 01326 uint16_t ERR = uint16_t(ERR_BUSY); 01327 return ((gRFAL .TxRx.state == RFAL_TXRX_STATE_IDLE) ? gRFAL .TxRx.status : ERR); 01328 } 01329 01330 01331 /*******************************************************************************/ 01332 void rfalWorker( 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 ) 01333 { 01334 switch( gRFAL .state ) 01335 { 01336 case RFAL_STATE_TXRX: 01337 rfalRunTransceiveWorker( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01338 break; 01339 01340 case RFAL_STATE_LM: 01341 rfalRunListenModeWorker( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01342 break; 01343 01344 case RFAL_STATE_WUM: 01345 rfalRunWakeUpModeWorker(mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01346 break; 01347 01348 /* Nothing to be done */ 01349 default: 01350 break; 01351 } 01352 } 01353 01354 01355 /*******************************************************************************/ 01356 static void rfalErrorHandling( ST25R3911* mST25, SPI * mspiChannel, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ) 01357 { 01358 uint8_t fifoBytesToRead; 01359 uint8_t reEnRx[] = { ST25R3911_CMD_CLEAR_FIFO, ST25R3911_CMD_UNMASK_RECEIVE_DATA }; 01360 01361 01362 fifoBytesToRead = rfalFIFOStatusGetNumBytes(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01363 01364 01365 /*******************************************************************************/ 01366 /* EMVCo */ 01367 /*******************************************************************************/ 01368 if( gRFAL .conf.eHandling == RFAL_ERRORHANDLING_EMVCO ) 01369 { 01370 /*******************************************************************************/ 01371 /* EMD Handling - NFC Forum Digital 1.1 4.1.1.1 ; EMVCo 2.6 4.9.2 */ 01372 /* ReEnable the receiver on frames with a length < 4 bytes, upon: */ 01373 /* - Collision or Framing error detected */ 01374 /* - Residual bits are detected (hard framing error) */ 01375 /* - Parity error */ 01376 /* - CRC error */ 01377 /*******************************************************************************/ 01378 01379 /* In case there are residual bits decrement FIFO bytes */ 01380 if( rfalFIFOStatusIsIncompleteByte(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) || rfalFIFOStatusIsMissingPar(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ) 01381 { 01382 fifoBytesToRead--; 01383 } 01384 01385 if( ( (gRFAL .fifo.bytesTotal + fifoBytesToRead) < RFAL_EMVCO_RX_MAXLEN ) && 01386 ( (gRFAL .TxRx.status == ERR_RF_COLLISION) || (gRFAL .TxRx.status == ERR_FRAMING) || 01387 (gRFAL .TxRx.status == ERR_PAR) || (gRFAL .TxRx.status == ERR_CRC) || 01388 rfalFIFOStatusIsIncompleteByte(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) || rfalFIFOStatusIsMissingPar(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ) ) 01389 { 01390 /* Ignore this reception, ReEnable receiver */ 01391 mST25 -> executeCommands( reEnRx, sizeof(reEnRx), mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01392 01393 rfalFIFOStatusClear(); 01394 gRFAL .fifo.bytesTotal = 0; 01395 gRFAL .TxRx.status = ERR_BUSY; 01396 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_WAIT_RXS; 01397 } 01398 return; 01399 } 01400 01401 /*******************************************************************************/ 01402 /* ISO14443A Mode */ 01403 /*******************************************************************************/ 01404 if( gRFAL .mode == RFAL_MODE_POLL_NFCA ) 01405 { 01406 01407 /*******************************************************************************/ 01408 /* If we received one incomplete byte (not a block and a incomplete byte at * 01409 * the end) we`ll raise a specific error ( support for T2T 4 bit ACK / NAK ) * 01410 * Otherwise just leave it as an CRC/FRAMING/PAR error */ 01411 /*******************************************************************************/ 01412 if( (gRFAL .TxRx.status == ERR_PAR) || (gRFAL .TxRx.status == ERR_CRC) ) 01413 { 01414 if( rfalFIFOStatusIsIncompleteByte(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) && (fifoBytesToRead == RFAL_NFC_RX_INCOMPLETE_LEN) ) 01415 { 01416 mST25 -> readFifo( (uint8_t*)(gRFAL .TxRx.ctx.rxBuf), fifoBytesToRead, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01417 if( gRFAL .TxRx.ctx.rxRcvdLen ) *gRFAL .TxRx.ctx.rxRcvdLen = rfalFIFOGetNumIncompleteBits(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01418 01419 gRFAL .TxRx.status = ERR_INCOMPLETE_BYTE; 01420 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_FAIL; 01421 } 01422 } 01423 } 01424 01425 } 01426 01427 01428 /*******************************************************************************/ 01429 static void rfalCleanupTransceive( 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 ) 01430 { 01431 /*******************************************************************************/ 01432 /* Transceive flags */ 01433 /*******************************************************************************/ 01434 01435 /* Restore default settings on NFCIP1 mode, Receiving parity + CRC bits and manual Tx Parity*/ 01436 st25r3911ClrRegisterBits( ST25R3911_REG_ISO14443A_NFC, (ST25R3911_REG_ISO14443A_NFC_no_tx_par | ST25R3911_REG_ISO14443A_NFC_no_rx_par | ST25R3911_REG_ISO14443A_NFC_nfc_f0),mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01437 01438 /* Restore AGC enabled */ 01439 st25r3911SetRegisterBits( ST25R3911_REG_RX_CONF2, ST25R3911_REG_RX_CONF2_agc_en, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01440 01441 /*******************************************************************************/ 01442 01443 01444 01445 /*******************************************************************************/ 01446 /* Execute Post Transceive Callback */ 01447 /*******************************************************************************/ 01448 if( gRFAL .callbacks.postTxRx != NULL ) 01449 { 01450 gRFAL .callbacks.postTxRx(); 01451 } 01452 /*******************************************************************************/ 01453 01454 } 01455 01456 01457 /*******************************************************************************/ 01458 static void rfalPrepareTransceive( 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 ) 01459 { 01460 uint32_t maskInterrupts; 01461 uint8_t reg; 01462 01463 /*******************************************************************************/ 01464 /* In the EMVCo mode the NRT will continue to run. * 01465 * For the clear to stop it, the EMV mode has to be disabled before */ 01466 st25r3911ClrRegisterBits( ST25R3911_REG_GPT_CONTROL, ST25R3911_REG_GPT_CONTROL_nrt_emv, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01467 01468 /* Reset receive logic */ 01469 mST25 -> executeCommand( ST25R3911_CMD_CLEAR_FIFO, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01470 01471 /* Reset Rx Gain */ 01472 mST25 -> executeCommand( ST25R3911_CMD_CLEAR_SQUELCH, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01473 01474 01475 /*******************************************************************************/ 01476 /* FDT Poll */ 01477 /*******************************************************************************/ 01478 if( rfalIsModePassiveComm( gRFAL .mode ) ) /* Passive Comms */ 01479 { 01480 /* In Passive communications General Purpose Timer is used to measure FDT Poll */ 01481 if( gRFAL .timings.FDTPoll != RFAL_TIMING_NONE ) 01482 { 01483 /* Configure GPT to start at RX end */ 01484 st25r3911StartGPTimer_8fcs( rfalConv1fcTo8fc( MIN( gRFAL .timings.FDTPoll, (gRFAL .timings.FDTPoll - RFAL_FDT_POLL_ADJUSTMENT) ) ), ST25R3911_REG_GPT_CONTROL_gptc_erx, 01485 mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01486 } 01487 } 01488 01489 01490 /*******************************************************************************/ 01491 /* Execute Pre Transceive Callback */ 01492 /*******************************************************************************/ 01493 if( gRFAL .callbacks.preTxRx != NULL ) 01494 { 01495 gRFAL .callbacks.preTxRx(); 01496 } 01497 /*******************************************************************************/ 01498 01499 maskInterrupts = ( ST25R3911_IRQ_MASK_FWL | ST25R3911_IRQ_MASK_TXE | 01500 ST25R3911_IRQ_MASK_RXS | ST25R3911_IRQ_MASK_RXE | 01501 ST25R3911_IRQ_MASK_FWL | ST25R3911_IRQ_MASK_NRE | 01502 ST25R3911_IRQ_MASK_PAR | ST25R3911_IRQ_MASK_CRC | 01503 ST25R3911_IRQ_MASK_ERR1 | ST25R3911_IRQ_MASK_ERR2 ); 01504 01505 01506 /*******************************************************************************/ 01507 /* Transceive flags */ 01508 /*******************************************************************************/ 01509 01510 reg = (ST25R3911_REG_ISO14443A_NFC_no_tx_par_off | ST25R3911_REG_ISO14443A_NFC_no_rx_par_off | ST25R3911_REG_ISO14443A_NFC_nfc_f0_off); 01511 01512 /* Check if NFCIP1 mode is to be enabled */ 01513 if( (gRFAL .TxRx.ctx.flags & RFAL_TXRX_FLAGS_NFCIP1_ON ) ) 01514 { 01515 reg |= ST25R3911_REG_ISO14443A_NFC_nfc_f0; 01516 } 01517 01518 /* Check if Parity check is to be skipped and to keep the parity + CRC bits in FIFO */ 01519 if( (gRFAL .TxRx.ctx.flags & RFAL_TXRX_FLAGS_PAR_RX_KEEP ) ) 01520 { 01521 reg |= ST25R3911_REG_ISO14443A_NFC_no_rx_par; 01522 } 01523 01524 /* Check if automatic Parity bits is to be disabled */ 01525 if( (gRFAL .TxRx.ctx.flags & RFAL_TXRX_FLAGS_PAR_TX_NONE ) ) 01526 { 01527 reg |= ST25R3911_REG_ISO14443A_NFC_no_tx_par; 01528 } 01529 01530 /* Apply current TxRx flags on ISO14443A and NFC 106kb/s Settings Register */ 01531 st25r3911ChangeRegisterBits( ST25R3911_REG_ISO14443A_NFC, (ST25R3911_REG_ISO14443A_NFC_no_tx_par | ST25R3911_REG_ISO14443A_NFC_no_rx_par | ST25R3911_REG_ISO14443A_NFC_nfc_f0), 01532 reg, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01533 01534 01535 /* Check if AGC is to be disabled */ 01536 if( (gRFAL .TxRx.ctx.flags & RFAL_TXRX_FLAGS_AGC_OFF ) ) 01537 { 01538 st25r3911ClrRegisterBits( ST25R3911_REG_RX_CONF2, ST25R3911_REG_RX_CONF2_agc_en, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01539 } 01540 else 01541 { 01542 st25r3911SetRegisterBits( ST25R3911_REG_RX_CONF2, ST25R3911_REG_RX_CONF2_agc_en, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01543 } 01544 /*******************************************************************************/ 01545 01546 01547 01548 /*******************************************************************************/ 01549 /* EMVCo NRT mode */ 01550 /*******************************************************************************/ 01551 if( gRFAL .conf.eHandling == RFAL_ERRORHANDLING_EMVCO ) 01552 { 01553 st25r3911SetRegisterBits( ST25R3911_REG_GPT_CONTROL, ST25R3911_REG_GPT_CONTROL_nrt_emv, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01554 } 01555 else 01556 { 01557 st25r3911ClrRegisterBits( ST25R3911_REG_GPT_CONTROL, ST25R3911_REG_GPT_CONTROL_nrt_emv, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01558 } 01559 /*******************************************************************************/ 01560 01561 01562 01563 /* In Active comms enable also External Field interrupts */ 01564 if( rfalIsModeActiveComm( gRFAL .mode ) ) 01565 { 01566 maskInterrupts |= ( ST25R3911_IRQ_MASK_EOF | ST25R3911_IRQ_MASK_EON | ST25R3911_IRQ_MASK_CAT | ST25R3911_IRQ_MASK_CAC ); 01567 } 01568 01569 01570 /*******************************************************************************/ 01571 /* clear and enable these interrupts */ 01572 st25r3911GetInterrupt( maskInterrupts, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01573 st25r3911EnableInterrupts( maskInterrupts, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01574 01575 /* Clear FIFO status local copy */ 01576 rfalFIFOStatusClear(); 01577 } 01578 01579 /*******************************************************************************/ 01580 static void rfalTransceiveTx( 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 ) 01581 { 01582 volatile uint32_t irqs; 01583 uint16_t tmp; 01584 ReturnCode ret; 01585 01586 /* NO_WARNING(ret); */ 01587 01588 irqs = ST25R3911_IRQ_MASK_NONE; 01589 01590 if( gRFAL .TxRx.state != gRFAL .TxRx.lastState ) 01591 { 01592 /* rfalLogD( "RFAL: lastSt: %d curSt: %d \r\n", gRFAL.TxRx.lastState, gRFAL.TxRx.state ); */ 01593 gRFAL .TxRx.lastState = gRFAL .TxRx.state; 01594 } 01595 01596 switch( gRFAL .TxRx.state ) 01597 { 01598 /*******************************************************************************/ 01599 case RFAL_TXRX_STATE_TX_IDLE: 01600 01601 /* Nothing to do */ 01602 01603 gRFAL .TxRx.state = RFAL_TXRX_STATE_TX_WAIT_GT ; 01604 /* fall through */ 01605 01606 01607 /*******************************************************************************/ 01608 case RFAL_TXRX_STATE_TX_WAIT_GT: 01609 01610 if( !rfalIsGTExpired() ) 01611 { 01612 break; 01613 } 01614 01615 gRFAL .tmr.GT = RFAL_TIMING_NONE; 01616 01617 gRFAL .TxRx.state = RFAL_TXRX_STATE_TX_WAIT_FDT; 01618 /* fall through */ 01619 01620 01621 /*******************************************************************************/ 01622 case RFAL_TXRX_STATE_TX_WAIT_FDT: 01623 01624 /* Only in Passive communications GPT is used to measure FDT Poll */ 01625 if( rfalIsModePassiveComm( gRFAL .mode ) ) 01626 { 01627 if( ( st25r3911CheckReg(ST25R3911_REG_REGULATOR_RESULT, ST25R3911_REG_REGULATOR_RESULT_gpt_on, ST25R3911_REG_REGULATOR_RESULT_gpt_on, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ) ) 01628 { 01629 break; 01630 } 01631 } 01632 01633 gRFAL .TxRx.state = RFAL_TXRX_STATE_TX_TRANSMIT; 01634 /* fall through */ 01635 01636 01637 /*******************************************************************************/ 01638 case RFAL_TXRX_STATE_TX_TRANSMIT: 01639 01640 /* Clear FIFO, Clear and Enable the Interrupts */ 01641 rfalPrepareTransceive( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01642 01643 /* Calculate when Water Level Interrupt will be triggered */ 01644 gRFAL .fifo.expWL = ( st25r3911CheckReg( ST25R3911_REG_IO_CONF1, ST25R3911_REG_IO_CONF1_fifo_lt, ST25R3911_REG_IO_CONF1_fifo_lt_16bytes, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ? RFAL_FIFO_OUT_LT_16 : RFAL_FIFO_OUT_LT_32); 01645 01646 #if RFAL_FEATURE_NFCV 01647 /*******************************************************************************/ 01648 /* In NFC-V streaming mode, the FIFO needs to be loaded with the coded bits */ 01649 if( (RFAL_MODE_POLL_NFCV == gRFAL .mode) || (RFAL_MODE_POLL_PICOPASS == gRFAL .mode) ) 01650 { 01651 #if 0 01652 /* Debugging code: output the payload bits by writing into the FIFO and subsequent clearing */ 01653 mST25 -> writeFifo(gRFAL .TxRx.ctx.txBuf, rfalConvBitsToBytes(gRFAL .TxRx.ctx.txBufLen)); 01654 mST25 -> executeCommand( ST25R3911_CMD_CLEAR_FIFO, mspiChannel ); 01655 #endif 01656 /* Calculate the bytes needed to be Written into FIFO (a incomplete byte will be added as 1byte) */ 01657 gRFAL .nfcvData.nfcvOffset = 0; 01658 ret = iso15693VCDCode(gRFAL .TxRx.ctx.txBuf, rfalConvBitsToBytes(gRFAL .TxRx.ctx.txBufLen), ((gRFAL .nfcvData.origCtx.flags & RFAL_TXRX_FLAGS_CRC_TX_MANUAL )?false:true),((gRFAL .nfcvData.origCtx.flags & RFAL_TXRX_FLAGS_NFCV_FLAG_MANUAL )?false:true), (RFAL_MODE_POLL_PICOPASS == gRFAL .mode), 01659 &gRFAL .fifo.bytesTotal, &gRFAL .nfcvData.nfcvOffset, gRFAL .nfcvData.codingBuffer, MIN( ST25R3911_FIFO_DEPTH, sizeof(gRFAL .nfcvData.codingBuffer) ), &gRFAL .fifo.bytesWritten); 01660 01661 if( (ret != ERR_NONE) && (ret != ERR_AGAIN) ) 01662 { 01663 gRFAL .TxRx.status = ret; 01664 gRFAL .TxRx.state = RFAL_TXRX_STATE_TX_FAIL; 01665 break; 01666 } 01667 /* Set the number of full bytes and bits to be transmitted */ 01668 st25r3911SetNumTxBits( rfalConvBytesToBits(gRFAL .fifo.bytesTotal), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01669 01670 /* Load FIFO with coded bytes */ 01671 mST25 -> writeFifo( gRFAL .nfcvData.codingBuffer, gRFAL .fifo.bytesWritten, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01672 01673 } 01674 /*******************************************************************************/ 01675 else 01676 #endif /* RFAL_FEATURE_NFCV */ 01677 { 01678 /* Calculate the bytes needed to be Written into FIFO (a incomplete byte will be added as 1byte) */ 01679 gRFAL .fifo.bytesTotal = rfalCalcNumBytes(gRFAL .TxRx.ctx.txBufLen); 01680 01681 /* Set the number of full bytes and bits to be transmitted */ 01682 st25r3911SetNumTxBits( gRFAL .TxRx.ctx.txBufLen, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01683 01684 /* Load FIFO with total length or FIFO's maximum */ 01685 gRFAL .fifo.bytesWritten = MIN( gRFAL .fifo.bytesTotal, ST25R3911_FIFO_DEPTH ); 01686 mST25 -> writeFifo( gRFAL .TxRx.ctx.txBuf, gRFAL .fifo.bytesWritten, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01687 } 01688 01689 /*Check if Observation Mode is enabled and set it on ST25R391x */ 01690 rfalCheckEnableObsModeTx(); 01691 01692 /*******************************************************************************/ 01693 /* Trigger/Start transmission */ 01694 if( gRFAL .TxRx.ctx.flags & RFAL_TXRX_FLAGS_CRC_TX_MANUAL ) 01695 { 01696 mST25 -> executeCommand( ST25R3911_CMD_TRANSMIT_WITHOUT_CRC, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01697 } 01698 else 01699 { 01700 mST25 -> executeCommand( ST25R3911_CMD_TRANSMIT_WITH_CRC, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01701 } 01702 01703 /* Check if a WL level is expected or TXE should come */ 01704 gRFAL .TxRx.state = (( gRFAL .fifo.bytesWritten < gRFAL .fifo.bytesTotal ) ? RFAL_TXRX_STATE_TX_WAIT_WL : RFAL_TXRX_STATE_TX_WAIT_TXE); 01705 break; 01706 01707 /*******************************************************************************/ 01708 case RFAL_TXRX_STATE_TX_WAIT_WL: 01709 01710 irqs = st25r3911GetInterrupt( (ST25R3911_IRQ_MASK_FWL | ST25R3911_IRQ_MASK_TXE), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01711 if( irqs == ST25R3911_IRQ_MASK_NONE ) 01712 { 01713 break; /* No interrupt to process */ 01714 } 01715 01716 if( (irqs & ST25R3911_IRQ_MASK_FWL) && !(irqs & ST25R3911_IRQ_MASK_TXE) ) 01717 { 01718 gRFAL .TxRx.state = RFAL_TXRX_STATE_TX_RELOAD_FIFO; 01719 } 01720 else 01721 { 01722 gRFAL .TxRx.status = ERR_IO; 01723 gRFAL .TxRx.state = RFAL_TXRX_STATE_TX_FAIL; 01724 break; 01725 } 01726 01727 /* fall through */ 01728 01729 /*******************************************************************************/ 01730 case RFAL_TXRX_STATE_TX_RELOAD_FIFO: 01731 01732 #if RFAL_FEATURE_NFCV 01733 /*******************************************************************************/ 01734 /* In NFC-V streaming mode, the FIFO needs to be loaded with the coded bits */ 01735 if( (RFAL_MODE_POLL_NFCV == gRFAL .mode) || (RFAL_MODE_POLL_PICOPASS == gRFAL .mode) ) 01736 { 01737 uint16_t maxLen; 01738 01739 /* Load FIFO with the remaining length or maximum available (which fit on the coding buffer) */ 01740 maxLen = MIN( (gRFAL .fifo.bytesTotal - gRFAL .fifo.bytesWritten), gRFAL .fifo.expWL); 01741 maxLen = MIN( maxLen, sizeof(gRFAL .nfcvData.codingBuffer) ); 01742 tmp = 0; 01743 01744 /* Calculate the bytes needed to be Written into FIFO (a incomplete byte will be added as 1byte) */ 01745 ret = iso15693VCDCode(gRFAL .TxRx.ctx.txBuf, rfalConvBitsToBytes(gRFAL .TxRx.ctx.txBufLen), ((gRFAL .nfcvData.origCtx.flags & RFAL_TXRX_FLAGS_CRC_TX_MANUAL )?false:true), ((gRFAL .nfcvData.origCtx.flags & RFAL_TXRX_FLAGS_NFCV_FLAG_MANUAL )?false:true), (RFAL_MODE_POLL_PICOPASS == gRFAL .mode), 01746 &gRFAL .fifo.bytesTotal, &gRFAL .nfcvData.nfcvOffset, gRFAL .nfcvData.codingBuffer, maxLen, &tmp); 01747 01748 if( (ret != ERR_NONE) && (ret != ERR_AGAIN) ) 01749 { 01750 gRFAL .TxRx.status = ret; 01751 gRFAL .TxRx.state = RFAL_TXRX_STATE_TX_FAIL; 01752 break; 01753 } 01754 01755 /* Load FIFO with coded bytes */ 01756 mST25 -> writeFifo( gRFAL .nfcvData.codingBuffer, tmp, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01757 } 01758 /*******************************************************************************/ 01759 else 01760 #endif /* RFAL_FEATURE_NFCV */ 01761 { 01762 /* Load FIFO with the remaining length or maximum available */ 01763 tmp = MIN( (gRFAL .fifo.bytesTotal - gRFAL .fifo.bytesWritten), gRFAL .fifo.expWL); /* tmp holds the number of bytes written on this iteration */ 01764 mST25 -> writeFifo( gRFAL .TxRx.ctx.txBuf + gRFAL .fifo.bytesWritten, tmp, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01765 } 01766 01767 /* Update total written bytes to FIFO */ 01768 gRFAL .fifo.bytesWritten += tmp; 01769 01770 /* Check if a WL level is expected or TXE should come */ 01771 gRFAL .TxRx.state = (( gRFAL .fifo.bytesWritten < gRFAL .fifo.bytesTotal ) ? RFAL_TXRX_STATE_TX_WAIT_WL : RFAL_TXRX_STATE_TX_WAIT_TXE); 01772 break; 01773 01774 01775 /*******************************************************************************/ 01776 case RFAL_TXRX_STATE_TX_WAIT_TXE: 01777 01778 irqs = st25r3911GetInterrupt( (ST25R3911_IRQ_MASK_FWL | ST25R3911_IRQ_MASK_TXE), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01779 if( irqs == ST25R3911_IRQ_MASK_NONE ) 01780 { 01781 break; /* No interrupt to process */ 01782 } 01783 01784 01785 if( (irqs & ST25R3911_IRQ_MASK_TXE) ) 01786 { 01787 /* In Active comm start SW timer to measure FWT */ 01788 if( rfalIsModeActiveComm( gRFAL .mode) && (gRFAL .TxRx.ctx.fwt != RFAL_FWT_NONE) && (gRFAL .TxRx.ctx.fwt != 0) ) 01789 { 01790 rfalTimerStart( gRFAL .tmr.FWT, rfalConv1fcToMs( gRFAL .TxRx.ctx.fwt ) ); 01791 } 01792 01793 gRFAL .TxRx.state = RFAL_TXRX_STATE_TX_DONE; 01794 } 01795 else if( (irqs & ST25R3911_IRQ_MASK_FWL) ) 01796 { 01797 /*******************************************************************************/ 01798 /* REMARK: Silicon workaround ST25R3911 Errata #TBD */ 01799 /* ST25R3911 may send a WL even when all bytes have been written to FIFO */ 01800 /*******************************************************************************/ 01801 break; /* Ignore ST25R3911 FIFO WL if total TxLen is already on the FIFO */ 01802 } 01803 else 01804 { 01805 gRFAL .TxRx.status = ERR_IO; 01806 gRFAL .TxRx.state = RFAL_TXRX_STATE_TX_FAIL; 01807 break; 01808 } // @suppress("No break at end of case") 01809 01810 /* fall through */ 01811 01812 01813 /*******************************************************************************/ 01814 case RFAL_TXRX_STATE_TX_DONE: 01815 01816 /* If no rxBuf is provided do not wait/expect Rx */ 01817 if( gRFAL .TxRx.ctx.rxBuf == NULL ) 01818 { 01819 /*Check if Observation Mode was enabled and disable it on ST25R391x */ 01820 rfalCheckDisableObsMode(); 01821 01822 /* Clean up Transceive */ 01823 rfalCleanupTransceive( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01824 01825 gRFAL .TxRx.status = ERR_NONE; 01826 gRFAL .TxRx.state = RFAL_TXRX_STATE_IDLE; 01827 break; 01828 } 01829 01830 rfalCheckEnableObsModeRx(); 01831 01832 /* Goto Rx */ 01833 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_IDLE; 01834 break; 01835 01836 /*******************************************************************************/ 01837 case RFAL_TXRX_STATE_TX_FAIL: 01838 01839 /* Error should be assigned by previous state */ 01840 if( gRFAL .TxRx.status == ERR_BUSY ) 01841 { 01842 gRFAL .TxRx.status = ERR_SYSTEM; 01843 } 01844 01845 /*Check if Observation Mode was enabled and disable it on ST25R391x */ 01846 rfalCheckDisableObsMode(); 01847 01848 /* Clean up Transceive */ 01849 rfalCleanupTransceive( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01850 01851 gRFAL .TxRx.state = RFAL_TXRX_STATE_IDLE; 01852 break; 01853 01854 /*******************************************************************************/ 01855 default: 01856 gRFAL .TxRx.status = ERR_SYSTEM; 01857 gRFAL .TxRx.state = RFAL_TXRX_STATE_TX_FAIL; 01858 break; 01859 } 01860 } 01861 01862 01863 /*******************************************************************************/ 01864 static void rfalTransceiveRx( 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 ) 01865 { 01866 volatile uint32_t irqs; 01867 uint8_t tmp; 01868 uint8_t aux; 01869 01870 irqs = ST25R3911_IRQ_MASK_NONE; 01871 01872 if( gRFAL .TxRx.state != gRFAL .TxRx.lastState ) 01873 { 01874 /* rfalLogD( "RFAL: lastSt: %d curSt: %d \r\n", gRFAL.TxRx.lastState, gRFAL.TxRx.state ); */ 01875 gRFAL .TxRx.lastState = gRFAL .TxRx.state; 01876 } 01877 01878 switch( gRFAL .TxRx.state ) 01879 { 01880 /*******************************************************************************/ 01881 case RFAL_TXRX_STATE_RX_IDLE: 01882 01883 /* Clear rx counters */ 01884 gRFAL .fifo.bytesWritten = 0; /* Total bytes written on RxBuffer */ 01885 gRFAL .fifo.bytesTotal = 0; /* Total bytes in FIFO will now be from Rx */ 01886 if( gRFAL .TxRx.ctx.rxRcvdLen ) *gRFAL .TxRx.ctx.rxRcvdLen = 0; 01887 01888 gRFAL .TxRx.state = ( rfalIsModeActiveComm( gRFAL .mode ) ? RFAL_TXRX_STATE_RX_WAIT_EON : RFAL_TXRX_STATE_RX_WAIT_RXS ); 01889 break; 01890 01891 01892 /*******************************************************************************/ 01893 case RFAL_TXRX_STATE_RX_WAIT_RXS: 01894 01895 /*******************************************************************************/ 01896 /* If in Active comm, Check if FWT SW timer has expired */ 01897 if( rfalIsModeActiveComm( gRFAL .mode ) && (gRFAL .TxRx.ctx.fwt != RFAL_FWT_NONE) && (gRFAL .TxRx.ctx.fwt != 0) ) 01898 { 01899 if( rfalTimerisExpired( gRFAL .tmr.FWT ) ) 01900 { 01901 gRFAL .TxRx.status = ERR_TIMEOUT; 01902 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_FAIL; 01903 break; 01904 } 01905 } 01906 01907 /*******************************************************************************/ 01908 irqs = st25r3911GetInterrupt( ( ST25R3911_IRQ_MASK_RXS | ST25R3911_IRQ_MASK_NRE | ST25R3911_IRQ_MASK_EOF | ST25R3911_IRQ_MASK_RXE), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01909 if( irqs == ST25R3911_IRQ_MASK_NONE ) 01910 { 01911 break; /* No interrupt to process */ 01912 } 01913 01914 01915 /*******************************************************************************/ 01916 /* REMARK: Silicon workaround ST25R3911 Errata #1.7 */ 01917 /* NRE interrupt may be triggered twice */ 01918 /* Ignore NRE if is detected together with no Rx Start */ 01919 /*******************************************************************************/ 01920 01921 /* Only raise Timeout if NRE is detected with no Rx Start (NRT EMV mode) */ 01922 if( (irqs & ST25R3911_IRQ_MASK_NRE) && !(irqs & ST25R3911_IRQ_MASK_RXS) ) 01923 { 01924 gRFAL .TxRx.status = ERR_TIMEOUT; 01925 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_FAIL; 01926 break; 01927 } 01928 01929 /* Only raise Link Loss if EOF is detected with no Rx Start */ 01930 if( (irqs & ST25R3911_IRQ_MASK_EOF) && !(irqs & ST25R3911_IRQ_MASK_RXS) ) 01931 { 01932 gRFAL .TxRx.status = ERR_LINK_LOSS; 01933 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_FAIL; 01934 break; 01935 } 01936 01937 if( (irqs & ST25R3911_IRQ_MASK_RXS) ) 01938 { 01939 /* If we got RXS + RXE together, jump directly into RFAL_TXRX_STATE_RX_ERR_CHECK */ 01940 if( (irqs & ST25R3911_IRQ_MASK_RXE) ) 01941 { 01942 gRFAL .TxRx.rxse = true; 01943 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_ERR_CHECK; 01944 break; 01945 } 01946 else 01947 { 01948 /*******************************************************************************/ 01949 /* REMARK: Silicon workaround ST25R3911 Errata #1.1 */ 01950 /* Rarely on corrupted frames I_rxs gets signaled but I_rxe is not signaled */ 01951 /* Use a SW timer to handle an eventual missing RXE */ 01952 rfalTimerStart( gRFAL .tmr.RXE, RFAL_NORXE_TOUT ); 01953 /*******************************************************************************/ 01954 01955 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_WAIT_RXE; 01956 } 01957 } 01958 else if( (irqs & ST25R3911_IRQ_MASK_RXE) ) 01959 { 01960 /*******************************************************************************/ 01961 /* REMARK: Silicon workaround ST25R3911 Errata #1.9 */ 01962 /* ST25R3911 may indicate RXE without RXS previously, this happens upon some */ 01963 /* noise or incomplete byte frames with less than 4 bits */ 01964 /*******************************************************************************/ 01965 01966 gRFAL .TxRx.status = ERR_IO; 01967 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_FAIL; 01968 01969 rfalErrorHandling(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01970 break; 01971 } 01972 else 01973 { 01974 gRFAL .TxRx.status = ERR_IO; 01975 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_FAIL; 01976 break; 01977 } 01978 01979 /* fall through */ 01980 01981 01982 /*******************************************************************************/ 01983 case RFAL_TXRX_STATE_RX_WAIT_RXE: 01984 01985 irqs = st25r3911GetInterrupt( (ST25R3911_IRQ_MASK_RXE | ST25R3911_IRQ_MASK_FWL | ST25R3911_IRQ_MASK_EOF), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 01986 if( irqs == ST25R3911_IRQ_MASK_NONE ) 01987 { 01988 /*******************************************************************************/ 01989 /* REMARK: Silicon workaround ST25R3911B Errata #1.1 */ 01990 /* ST25R3911 may indicate RXS without RXE afterwards, this happens rarely on */ 01991 /* corrupted frames. */ 01992 /* SW timer is used to timeout upon a missing RXE */ 01993 if( rfalTimerisExpired( gRFAL .tmr.RXE ) ) 01994 { 01995 gRFAL .TxRx.status = ERR_FRAMING; 01996 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_FAIL; 01997 } 01998 /*******************************************************************************/ 01999 02000 break; /* No interrupt to process */ 02001 } 02002 02003 if( (irqs & ST25R3911_IRQ_MASK_FWL) && !(irqs & ST25R3911_IRQ_MASK_RXE) ) 02004 { 02005 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_READ_FIFO; 02006 break; 02007 } 02008 02009 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_ERR_CHECK; 02010 /* fall through */ 02011 02012 02013 /*******************************************************************************/ 02014 case RFAL_TXRX_STATE_RX_ERR_CHECK: 02015 02016 /* Retrieve and check for any error irqs */ 02017 irqs |= st25r3911GetInterrupt( (ST25R3911_IRQ_MASK_CRC | ST25R3911_IRQ_MASK_PAR | ST25R3911_IRQ_MASK_ERR1 | ST25R3911_IRQ_MASK_ERR2 | ST25R3911_IRQ_MASK_COL), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02018 02019 if( (irqs & ST25R3911_IRQ_MASK_ERR1) ) 02020 { 02021 gRFAL .TxRx.status = ERR_FRAMING; 02022 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_READ_DATA; 02023 02024 /* Check if there's a specific error handling for this */ 02025 rfalErrorHandling(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02026 break; 02027 } 02028 /* Discard Soft Framing errors if not in EMVCo error handling */ 02029 else if( (irqs & ST25R3911_IRQ_MASK_ERR2) && (gRFAL .conf.eHandling == RFAL_ERRORHANDLING_EMVCO ) ) 02030 { 02031 gRFAL .TxRx.status = ERR_FRAMING; 02032 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_READ_DATA; 02033 02034 /* Check if there's a specific error handling for this */ 02035 rfalErrorHandling(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02036 break; 02037 } 02038 else if( (irqs & ST25R3911_IRQ_MASK_PAR) ) 02039 { 02040 gRFAL .TxRx.status = ERR_PAR; 02041 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_READ_DATA; 02042 02043 /* Check if there's a specific error handling for this */ 02044 rfalErrorHandling(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02045 break; 02046 } 02047 else if( (irqs & ST25R3911_IRQ_MASK_CRC) ) 02048 { 02049 gRFAL .TxRx.status = ERR_CRC; 02050 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_READ_DATA; 02051 02052 /* Check if there's a specific error handling for this */ 02053 rfalErrorHandling(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02054 break; 02055 } 02056 else if( (irqs & ST25R3911_IRQ_MASK_COL) ) 02057 { 02058 gRFAL .TxRx.status = ERR_RF_COLLISION; 02059 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_READ_DATA; 02060 02061 /* Check if there's a specific error handling for this */ 02062 rfalErrorHandling(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02063 break; 02064 } 02065 else if( (irqs & ST25R3911_IRQ_MASK_EOF) && !(irqs & ST25R3911_IRQ_MASK_RXE) ) 02066 { 02067 gRFAL .TxRx.status = ERR_LINK_LOSS; 02068 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_FAIL; 02069 break; 02070 } 02071 else if( (irqs & ST25R3911_IRQ_MASK_RXE) || gRFAL .TxRx.rxse ) 02072 { 02073 /* Reception ended without any error indication, * 02074 * check FIFO status for malformed or incomplete frames */ 02075 02076 /* Check if the reception ends with an incomplete byte (residual bits) */ 02077 if( rfalFIFOStatusIsIncompleteByte(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ) 02078 { 02079 gRFAL .TxRx.status = ERR_INCOMPLETE_BYTE; 02080 } 02081 /* Check if the reception ends with missing parity bit */ 02082 else if( rfalFIFOStatusIsMissingPar(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ) 02083 { 02084 gRFAL .TxRx.status = ERR_FRAMING; 02085 } 02086 02087 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_READ_DATA; 02088 } 02089 else 02090 { 02091 gRFAL .TxRx.status = ERR_IO; 02092 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_FAIL; 02093 break; 02094 } 02095 02096 /* fall through */ 02097 02098 02099 /*******************************************************************************/ 02100 case RFAL_TXRX_STATE_RX_READ_DATA: 02101 02102 tmp = rfalFIFOStatusGetNumBytes(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02103 02104 /*******************************************************************************/ 02105 /* Check if CRC should not be placed in rxBuf */ 02106 if( !(gRFAL .TxRx.ctx.flags & RFAL_TXRX_FLAGS_CRC_RX_KEEP ) ) 02107 { 02108 /* Check if CRC is being placed into the FIFO and if received frame was bigger than CRC */ 02109 if( ( st25r3911CheckReg(ST25R3911_REG_AUX, ST25R3911_REG_AUX_crc_2_fifo, ST25R3911_REG_AUX_crc_2_fifo, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ) 02110 && ( gRFAL .fifo.bytesTotal + tmp) ) 02111 { 02112 /* By default CRC will not be placed into the rxBuffer */ 02113 if( ( tmp > RFAL_CRC_LEN) ) 02114 { 02115 tmp -= RFAL_CRC_LEN; 02116 } 02117 /* If the CRC was already placed into rxBuffer (due to WL interrupt where CRC was already in FIFO Read) 02118 * cannot remove it from rxBuf. Can only remove it from rxBufLen not indicate the presence of CRC */ 02119 else if(gRFAL .fifo.bytesTotal > RFAL_CRC_LEN) 02120 { 02121 gRFAL .fifo.bytesTotal -= RFAL_CRC_LEN; 02122 } 02123 } 02124 } 02125 02126 gRFAL .fifo.bytesTotal += tmp; /* add to total bytes counter */ 02127 02128 /*******************************************************************************/ 02129 /* Check if remaining bytes fit on the rxBuf available */ 02130 if( gRFAL .fifo.bytesTotal > rfalConvBitsToBytes(gRFAL .TxRx.ctx.rxBufLen) ) 02131 { 02132 tmp = ( rfalConvBitsToBytes(gRFAL .TxRx.ctx.rxBufLen) - gRFAL .fifo.bytesWritten); 02133 02134 gRFAL .TxRx.status = ERR_NOMEM; 02135 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_FAIL; 02136 } 02137 02138 /*******************************************************************************/ 02139 /* Retrieve remaining bytes from FIFO to rxBuf, and assign total length rcvd */ 02140 mST25 -> readFifo( (uint8_t*)(gRFAL .TxRx.ctx.rxBuf + gRFAL .fifo.bytesWritten), tmp, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02141 if( gRFAL .TxRx.ctx.rxRcvdLen ) 02142 { 02143 (*gRFAL .TxRx.ctx.rxRcvdLen) = rfalConvBytesToBits( gRFAL .fifo.bytesTotal ); 02144 if( rfalFIFOStatusIsIncompleteByte(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ) 02145 { 02146 (*gRFAL .TxRx.ctx.rxRcvdLen) -= (RFAL_BITS_IN_BYTE - rfalFIFOGetNumIncompleteBits(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ); 02147 } 02148 } 02149 02150 #if RFAL_FEATURE_NFCV 02151 /*******************************************************************************/ 02152 /* Decode sub bit stream into payload bits for NFCV, if no error found so far */ 02153 if( ((RFAL_MODE_POLL_NFCV == gRFAL .mode) || (RFAL_MODE_POLL_PICOPASS == gRFAL .mode)) && (gRFAL .TxRx.status == ERR_BUSY) ) 02154 { 02155 ReturnCode ret; 02156 uint16_t offset = 0; 02157 02158 ret = iso15693VICCDecode(gRFAL .TxRx.ctx.rxBuf, gRFAL .fifo.bytesTotal, 02159 gRFAL .nfcvData.origCtx.rxBuf, rfalConvBitsToBytes(gRFAL .nfcvData.origCtx.rxBufLen), &offset, gRFAL .nfcvData.origCtx.rxRcvdLen, gRFAL .nfcvData.ignoreBits, (RFAL_MODE_POLL_PICOPASS == gRFAL .mode) ); 02160 02161 if( ((ERR_NONE == ret) || (ERR_CRC == ret)) 02162 && !(RFAL_TXRX_FLAGS_CRC_RX_KEEP & gRFAL .nfcvData.origCtx.flags) 02163 && ((*gRFAL .nfcvData.origCtx.rxRcvdLen % RFAL_BITS_IN_BYTE) == 0) 02164 && (*gRFAL .nfcvData.origCtx.rxRcvdLen >= rfalConvBytesToBits(RFAL_CRC_LEN) ) 02165 ) 02166 { 02167 *gRFAL .nfcvData.origCtx.rxRcvdLen -= rfalConvBytesToBits(RFAL_CRC_LEN); /* Remove CRC */ 02168 } 02169 02170 /* Restore original ctx */ 02171 gRFAL .TxRx.ctx = gRFAL .nfcvData.origCtx; 02172 gRFAL .TxRx.status = ret; 02173 02174 if(gRFAL .TxRx.status) 02175 { 02176 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_FAIL; 02177 break; 02178 } 02179 } 02180 #endif /* RFAL_FEATURE_NFCV */ 02181 02182 /*******************************************************************************/ 02183 /* If an error as been marked/detected don't fall into to RX_DONE */ 02184 if( gRFAL .TxRx.status != ERR_BUSY ) 02185 { 02186 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_FAIL; 02187 break; 02188 } 02189 02190 if( rfalIsModeActiveComm( gRFAL .mode ) ) 02191 { 02192 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_WAIT_EOF; 02193 break; 02194 } 02195 02196 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_DONE; 02197 /* fall through */ 02198 02199 02200 /*******************************************************************************/ 02201 case RFAL_TXRX_STATE_RX_DONE: 02202 02203 /*Check if Observation Mode was enabled and disable it on ST25R391x */ 02204 rfalCheckDisableObsMode(); 02205 02206 /* Clean up Transceive */ 02207 rfalCleanupTransceive( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02208 02209 02210 gRFAL .TxRx.status = ERR_NONE; 02211 gRFAL .TxRx.state = RFAL_TXRX_STATE_IDLE; 02212 break; 02213 02214 02215 /*******************************************************************************/ 02216 case RFAL_TXRX_STATE_RX_READ_FIFO: 02217 02218 /*******************************************************************************/ 02219 /* REMARK: Silicon workaround ST25R3911B Errata #1.1 */ 02220 /* ST25R3911 may indicate RXS without RXE afterwards, this happens rarely on */ 02221 /* corrupted frames. */ 02222 /* Re-Start SW timer to handle an eventual missing RXE */ 02223 rfalTimerStart( gRFAL .tmr.RXE, RFAL_NORXE_TOUT ); 02224 /*******************************************************************************/ 02225 02226 02227 tmp = rfalFIFOStatusGetNumBytes(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02228 gRFAL .fifo.bytesTotal += tmp; 02229 02230 /*******************************************************************************/ 02231 /* Calculate the amount of bytes that still fits in rxBuf */ 02232 aux = (( gRFAL .fifo.bytesTotal > rfalConvBitsToBytes(gRFAL .TxRx.ctx.rxBufLen) ) ? (rfalConvBitsToBytes(gRFAL .TxRx.ctx.rxBufLen) - gRFAL .fifo.bytesWritten) : tmp); 02233 02234 /*******************************************************************************/ 02235 /* Retrieve incoming bytes from FIFO to rxBuf, and store already read amount */ 02236 mST25 -> readFifo( (uint8_t*)(gRFAL .TxRx.ctx.rxBuf + gRFAL .fifo.bytesWritten), aux, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02237 gRFAL .fifo.bytesWritten += aux; 02238 02239 /*******************************************************************************/ 02240 /* If the bytes already read were not the full FIFO WL, dump the remaining * 02241 * FIFO so that ST25R391x can continue with reception */ 02242 if( aux < tmp ) 02243 { 02244 mST25 -> readFifo( NULL, (tmp - aux), mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02245 } 02246 02247 rfalFIFOStatusClear(); 02248 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_WAIT_RXE; 02249 break; 02250 02251 02252 /*******************************************************************************/ 02253 case RFAL_TXRX_STATE_RX_FAIL: 02254 02255 /*Check if Observation Mode was enabled and disable it on ST25R391x */ 02256 rfalCheckDisableObsMode(); 02257 02258 /* Clean up Transceive */ 02259 rfalCleanupTransceive( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02260 02261 /* Error should be assigned by previous state */ 02262 if( gRFAL .TxRx.status == ERR_BUSY ) 02263 { 02264 gRFAL .TxRx.status = ERR_SYSTEM; 02265 } 02266 02267 /*rfalLogD( "RFAL: curSt: %d Error: %d \r\n", gRFAL.TxRx.state, gRFAL.TxRx.status );*/ 02268 gRFAL .TxRx.state = RFAL_TXRX_STATE_IDLE; 02269 break; 02270 02271 02272 /*******************************************************************************/ 02273 case RFAL_TXRX_STATE_RX_WAIT_EON: 02274 02275 irqs = st25r3911GetInterrupt( (ST25R3911_IRQ_MASK_EON | ST25R3911_IRQ_MASK_NRE), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02276 if( irqs == ST25R3911_IRQ_MASK_NONE ) 02277 { 02278 break; /* No interrupt to process */ 02279 } 02280 02281 if( (irqs & ST25R3911_IRQ_MASK_EON) ) 02282 { 02283 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_WAIT_RXS; 02284 } 02285 02286 if( (irqs & ST25R3911_IRQ_MASK_NRE) ) 02287 { 02288 /* ST25R3911 uses the NRT to measure other device's Field On max time: Tadt + (n x Trfw) */ 02289 gRFAL .TxRx.status = ERR_LINK_LOSS; 02290 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_FAIL; 02291 } 02292 break; 02293 02294 02295 /*******************************************************************************/ 02296 case RFAL_TXRX_STATE_RX_WAIT_EOF: 02297 02298 irqs = st25r3911GetInterrupt( (ST25R3911_IRQ_MASK_CAT | ST25R3911_IRQ_MASK_CAC), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02299 if( irqs == ST25R3911_IRQ_MASK_NONE ) 02300 { 02301 break; /* No interrupt to process */ 02302 } 02303 02304 if( (irqs & ST25R3911_IRQ_MASK_CAT) ) 02305 { 02306 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_DONE; 02307 } 02308 else if( (irqs & ST25R3911_IRQ_MASK_CAC) ) 02309 { 02310 gRFAL .TxRx.status = ERR_RF_COLLISION; 02311 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_FAIL; 02312 } 02313 else 02314 { 02315 gRFAL .TxRx.status = ERR_IO; 02316 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_FAIL; 02317 } 02318 break; 02319 02320 02321 /*******************************************************************************/ 02322 default: 02323 gRFAL .TxRx.status = ERR_SYSTEM; 02324 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_FAIL; 02325 break; 02326 } 02327 } 02328 02329 /*******************************************************************************/ 02330 static void rfalFIFOStatusUpdate( ST25R3911* mST25, SPI * mspiChannel, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ) 02331 { 02332 if(gRFAL .fifo.status[RFAL_FIFO_STATUS_REG2] == RFAL_FIFO_STATUS_INVALID) 02333 { 02334 mST25 -> readMultipleRegisters( ST25R3911_REG_FIFO_RX_STATUS1, gRFAL .fifo.status, ST25R3911_FIFO_STATUS_LEN, mspiChannel,mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02335 } 02336 } 02337 02338 02339 /*******************************************************************************/ 02340 static void rfalFIFOStatusClear( void ) 02341 { 02342 gRFAL .fifo.status[RFAL_FIFO_STATUS_REG2] = RFAL_FIFO_STATUS_INVALID; 02343 } 02344 02345 02346 /*******************************************************************************/ 02347 static uint8_t rfalFIFOStatusGetNumBytes( ST25R3911* mST25, SPI * mspiChannel, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ) 02348 { 02349 rfalFIFOStatusUpdate(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02350 02351 return gRFAL .fifo.status[RFAL_FIFO_STATUS_REG1]; 02352 02353 } 02354 02355 02356 /*******************************************************************************/ 02357 static bool rfalFIFOStatusIsIncompleteByte( ST25R3911* mST25, SPI * mspiChannel, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ) 02358 { 02359 rfalFIFOStatusUpdate(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02360 return ((gRFAL .fifo.status[RFAL_FIFO_STATUS_REG2] & (ST25R3911_REG_FIFO_RX_STATUS2_mask_fifo_lb | ST25R3911_REG_FIFO_RX_STATUS2_fifo_ncp)) != 0); 02361 } 02362 02363 02364 /*******************************************************************************/ 02365 static bool rfalFIFOStatusIsMissingPar( ST25R3911* mST25, SPI * mspiChannel, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ) 02366 { 02367 rfalFIFOStatusUpdate(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02368 return ((gRFAL .fifo.status[RFAL_FIFO_STATUS_REG2] & ST25R3911_REG_FIFO_RX_STATUS2_np_lb) != 0); 02369 } 02370 02371 02372 /*******************************************************************************/ 02373 static uint8_t rfalFIFOGetNumIncompleteBits( ST25R3911* mST25, SPI * mspiChannel, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ) 02374 { 02375 rfalFIFOStatusUpdate(mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02376 return ((gRFAL .fifo.status[RFAL_FIFO_STATUS_REG2] & ST25R3911_REG_FIFO_RX_STATUS2_mask_fifo_lb) >> ST25R3911_REG_FIFO_RX_STATUS2_shift_fifo_lb); 02377 } 02378 02379 02380 #if RFAL_FEATURE_NFCA 02381 02382 /*******************************************************************************/ 02383 ReturnCode rfalISO14443ATransceiveShortFrame( rfal14443AShortFrameCmd txCmd, uint8_t* rxBuf, uint8_t rxBufLen, uint16_t* rxRcvdLen, uint32_t fwt, 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 ) 02384 { 02385 ReturnCode ret; 02386 uint8_t directCmd; 02387 02388 /* Check if RFAL is properly initialized */ 02389 if( (gRFAL .state < RFAL_STATE_MODE_SET) || (( gRFAL .mode != RFAL_MODE_POLL_NFCA ) && ( gRFAL .mode != RFAL_MODE_POLL_NFCA_T1T )) || 02390 !( st25r3911CheckReg(ST25R3911_REG_OP_CONTROL, ST25R3911_REG_OP_CONTROL_tx_en, ST25R3911_REG_OP_CONTROL_tx_en, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ) ) 02391 { 02392 return ERR_WRONG_STATE; 02393 } 02394 02395 /* Check for valid parameters */ 02396 if( (rxBuf == NULL) || (rxRcvdLen == NULL) || (fwt == RFAL_FWT_NONE) ) 02397 { 02398 return ERR_PARAM; 02399 } 02400 02401 /*******************************************************************************/ 02402 /* Select the Direct Command to be performed */ 02403 switch (txCmd) 02404 { 02405 case RFAL_14443A_SHORTFRAME_CMD_WUPA : 02406 directCmd = ST25R3911_CMD_TRANSMIT_WUPA; 02407 break; 02408 02409 case RFAL_14443A_SHORTFRAME_CMD_REQA : 02410 directCmd = ST25R3911_CMD_TRANSMIT_REQA; 02411 break; 02412 02413 default: 02414 return ERR_PARAM; 02415 } 02416 02417 02418 /*******************************************************************************/ 02419 /* Enable anti collision to recognise collision in first byte of SENS_REQ */ 02420 st25r3911SetRegisterBits( ST25R3911_REG_ISO14443A_NFC, ST25R3911_REG_ISO14443A_NFC_antcl, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02421 02422 /* Disable CRC while receiving since ATQA has no CRC included */ 02423 st25r3911SetRegisterBits( ST25R3911_REG_AUX, ST25R3911_REG_AUX_no_crc_rx, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02424 02425 02426 /*******************************************************************************/ 02427 /* Wait for GT and FDT */ 02428 while( !rfalIsGTExpired() ); 02429 while( st25r3911CheckReg(ST25R3911_REG_REGULATOR_RESULT, ST25R3911_REG_REGULATOR_RESULT_gpt_on, ST25R3911_REG_REGULATOR_RESULT_gpt_on, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ); 02430 02431 gRFAL .tmr.GT = RFAL_TIMING_NONE; 02432 02433 02434 /*******************************************************************************/ 02435 /* Prepare for Transceive, Receive only (bypass Tx states) */ 02436 gRFAL .TxRx.ctx.flags = ( RFAL_TXRX_FLAGS_CRC_TX_MANUAL | RFAL_TXRX_FLAGS_CRC_RX_KEEP ); 02437 gRFAL .TxRx.ctx.rxBuf = rxBuf; 02438 gRFAL .TxRx.ctx.rxBufLen = rxBufLen; 02439 gRFAL .TxRx.ctx.rxRcvdLen = rxRcvdLen; 02440 02441 /*******************************************************************************/ 02442 /* Load NRT with FWT */ 02443 st25r3911SetNoResponseTime_64fcs( rfalConv1fcTo64fc( MIN( (fwt + RFAL_FWT_ADJUSTMENT + RFAL_FWT_A_ADJUSTMENT), RFAL_ST25R3911_NRT_MAX_1FC ) ), 02444 mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02445 02446 if( gRFAL .timings.FDTListen != RFAL_TIMING_NONE ) 02447 { 02448 /* Set Minimum FDT(Listen) in which PICC is not allowed to send a response */ 02449 mST25 -> writeRegister( ST25R3911_REG_MASK_RX_TIMER, rfalConv1fcTo64fc( ((RFAL_FDT_LISTEN_MRT_ADJUSTMENT + RFAL_FDT_LISTEN_A_ADJUSTMENT) > gRFAL .timings.FDTListen) ? RFAL_ST25R3911_MRT_MIN_1FC : (gRFAL .timings.FDTListen - (RFAL_FDT_LISTEN_MRT_ADJUSTMENT + RFAL_FDT_LISTEN_A_ADJUSTMENT)) ), 02450 mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02451 } 02452 02453 /* In Passive communications General Purpose Timer is used to measure FDT Poll */ 02454 if( gRFAL .timings.FDTPoll != RFAL_TIMING_NONE ) 02455 { 02456 /* Configure GPT to start at RX end */ 02457 st25r3911StartGPTimer_8fcs( rfalConv1fcTo8fc( MIN( gRFAL .timings.FDTPoll, (gRFAL .timings.FDTPoll - RFAL_FDT_POLL_ADJUSTMENT) ) ), ST25R3911_REG_GPT_CONTROL_gptc_erx, 02458 mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02459 } 02460 02461 /*******************************************************************************/ 02462 rfalPrepareTransceive( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02463 02464 /* Also enable bit collision interrupt */ 02465 st25r3911GetInterrupt( ST25R3911_IRQ_MASK_COL, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02466 st25r3911EnableInterrupts( ST25R3911_IRQ_MASK_COL, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02467 02468 /*Check if Observation Mode is enabled and set it on ST25R391x */ 02469 rfalCheckEnableObsModeTx(); 02470 02471 /*******************************************************************************/ 02472 /* Chip bug: Clear nbtx bits before sending WUPA/REQA - otherwise ST25R3911 will report parity error */ 02473 mST25 -> writeRegister( ST25R3911_REG_NUM_TX_BYTES2, 0, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02474 02475 /* Send either WUPA or REQA. All affected tags will backscatter ATQA and change to READY state */ 02476 mST25 -> executeCommand( directCmd, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02477 02478 /* Wait for TXE */ 02479 if( !st25r3911WaitForInterruptsTimed( ST25R3911_IRQ_MASK_TXE, MAX( rfalConv1fcToMs( fwt ), RFAL_ST25R3911_SW_TMR_MIN_1MS ), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ) 02480 { 02481 ret = ERR_IO; 02482 } 02483 else 02484 { 02485 /*Check if Observation Mode is enabled and set it on ST25R391x */ 02486 rfalCheckEnableObsModeRx(); 02487 02488 /* Jump into a transceive Rx state for reception (bypass Tx states) */ 02489 gRFAL .state = RFAL_STATE_TXRX; 02490 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_IDLE; 02491 gRFAL .TxRx.status = ERR_BUSY; 02492 02493 /* Execute Transceive Rx blocking */ 02494 ret = rfalTransceiveBlockingRx( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02495 } 02496 02497 02498 /* Disable Collision interrupt */ 02499 st25r3911DisableInterrupts( (ST25R3911_IRQ_MASK_COL), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02500 02501 /* Disable anti collision again */ 02502 st25r3911ClrRegisterBits( ST25R3911_REG_ISO14443A_NFC, ST25R3911_REG_ISO14443A_NFC_antcl, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02503 02504 /* ReEnable CRC on Rx */ 02505 st25r3911ClrRegisterBits(ST25R3911_REG_AUX, ST25R3911_REG_AUX_no_crc_rx, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ); 02506 02507 return ret; 02508 } 02509 02510 /*******************************************************************************/ 02511 ReturnCode rfalISO14443ATransceiveAnticollisionFrame( uint8_t *buf, uint8_t *bytesToSend, uint8_t *bitsToSend, 02512 uint16_t *rxLength, uint32_t fwt, 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 ) 02513 { 02514 ReturnCode ret; 02515 rfalTransceiveContext ctx; 02516 uint8_t collByte; 02517 uint8_t collData; 02518 02519 /* Check if RFAL is properly initialized */ 02520 if( (gRFAL .state < RFAL_STATE_MODE_SET) || ( gRFAL .mode != RFAL_MODE_POLL_NFCA ) ) 02521 { 02522 return ERR_WRONG_STATE; 02523 } 02524 02525 /* Check for valid parameters */ 02526 if( (buf == NULL) || (bytesToSend == NULL) || (bitsToSend == NULL) || (rxLength == NULL) ) 02527 { 02528 return ERR_PARAM; 02529 } 02530 02531 /*******************************************************************************/ 02532 /* Enable anti collision to recognise collision in first byte of SENS_REQ */ 02533 st25r3911SetRegisterBits( ST25R3911_REG_ISO14443A_NFC, ST25R3911_REG_ISO14443A_NFC_antcl, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02534 02535 /* Disable CRC while receiving */ 02536 st25r3911SetRegisterBits( ST25R3911_REG_AUX, ST25R3911_REG_AUX_no_crc_rx, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02537 02538 02539 02540 /*******************************************************************************/ 02541 /* Prepare for Transceive */ 02542 ctx.flags = ( RFAL_TXRX_FLAGS_CRC_TX_MANUAL | RFAL_TXRX_FLAGS_CRC_RX_KEEP | RFAL_TXRX_FLAGS_AGC_OFF ); /* Disable Automatic Gain Control (AGC) for better detection of collision */ 02543 ctx.txBuf = buf; 02544 ctx.txBufLen = (rfalConvBytesToBits( *bytesToSend ) + *bitsToSend ); 02545 ctx.rxBuf = (buf + (*bytesToSend)); 02546 ctx.rxBufLen = rfalConvBytesToBits( RFAL_ISO14443A_SDD_RES_LEN ); 02547 ctx.rxRcvdLen = rxLength; 02548 ctx.fwt = fwt; 02549 02550 rfalStartTransceive( &ctx, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02551 02552 /* Additionally enable bit collision interrupt */ 02553 st25r3911GetInterrupt( ST25R3911_IRQ_MASK_COL, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02554 st25r3911EnableInterrupts( ST25R3911_IRQ_MASK_COL, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02555 02556 /*******************************************************************************/ 02557 collByte = 0; 02558 02559 /* save the collision byte */ 02560 if ((*bitsToSend) > 0) 02561 { 02562 buf[(*bytesToSend)] <<= (RFAL_BITS_IN_BYTE - (*bitsToSend)); 02563 buf[(*bytesToSend)] >>= (RFAL_BITS_IN_BYTE - (*bitsToSend)); 02564 collByte = buf[(*bytesToSend)]; 02565 } 02566 02567 02568 /*******************************************************************************/ 02569 /* Run Transceive blocking */ 02570 ret = rfalTransceiveRunBlockingTx( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02571 if( ret == ERR_NONE) 02572 { 02573 ret = rfalTransceiveBlockingRx( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ); 02574 02575 /*******************************************************************************/ 02576 if ((*bitsToSend) > 0) 02577 { 02578 buf[(*bytesToSend)] >>= (*bitsToSend); 02579 buf[(*bytesToSend)] <<= (*bitsToSend); 02580 buf[(*bytesToSend)] |= collByte; 02581 } 02582 02583 if( (ERR_RF_COLLISION == ret) ) 02584 { 02585 /* read out collision register */ 02586 mST25 -> readRegister( ST25R3911_REG_COLLISION_STATUS, &collData, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02587 02588 (*bytesToSend) = ((collData >> ST25R3911_REG_COLLISION_STATUS_shift_c_byte) & 0x0F); /* 4-bits Byte information */ 02589 (*bitsToSend) = ((collData >> ST25R3911_REG_COLLISION_STATUS_shift_c_bit) & 0x07); /* 3-bits bit information */ 02590 02591 } 02592 } 02593 02594 02595 /*******************************************************************************/ 02596 /* Disable Collision interrupt */ 02597 st25r3911DisableInterrupts( (ST25R3911_IRQ_MASK_COL), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02598 02599 /* Disable anti collision again */ 02600 st25r3911ClrRegisterBits( ST25R3911_REG_ISO14443A_NFC, ST25R3911_REG_ISO14443A_NFC_antcl, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02601 02602 /* ReEnable CRC on Rx */ 02603 st25r3911ClrRegisterBits( ST25R3911_REG_AUX, ST25R3911_REG_AUX_no_crc_rx, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02604 02605 return ret; 02606 } 02607 02608 #endif /* RFAL_FEATURE_NFCA */ 02609 02610 #if RFAL_FEATURE_NFCV 02611 02612 /*******************************************************************************/ 02613 ReturnCode rfalISO15693TransceiveAnticollisionFrame( uint8_t *txBuf, uint8_t txBufLen, uint8_t *rxBuf, uint8_t rxBufLen, uint16_t *actLen, 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 ) 02614 { 02615 ReturnCode ret; 02616 rfalTransceiveContext ctx; 02617 02618 /* Check if RFAL is properly initialized */ 02619 if( (gRFAL .state < RFAL_STATE_MODE_SET) || ( gRFAL .mode != RFAL_MODE_POLL_NFCV ) ) 02620 { 02621 return ERR_WRONG_STATE; 02622 } 02623 02624 /* Ignoring collisions before the UID (RES_FLAG + DSFID) */ 02625 gRFAL .nfcvData.ignoreBits = RFAL_ISO15693_IGNORE_BITS; 02626 02627 /*******************************************************************************/ 02628 /* Prepare for Transceive */ 02629 ctx.flags = ( ((txBufLen==0)?RFAL_TXRX_FLAGS_CRC_TX_MANUAL :RFAL_TXRX_FLAGS_CRC_TX_AUTO ) | RFAL_TXRX_FLAGS_CRC_RX_KEEP | RFAL_TXRX_FLAGS_AGC_OFF | ((txBufLen==0)?RFAL_TXRX_FLAGS_NFCV_FLAG_MANUAL :RFAL_TXRX_FLAGS_NFCV_FLAG_AUTO ) ); /* Disable Automatic Gain Control (AGC) for better detection of collision */ 02630 ctx.txBuf = txBuf; 02631 ctx.txBufLen = rfalConvBytesToBits(txBufLen); 02632 ctx.rxBuf = rxBuf; 02633 ctx.rxBufLen = rfalConvBytesToBits(rxBufLen); 02634 ctx.rxRcvdLen = actLen; 02635 ctx.fwt = rfalConv64fcTo1fc(ISO15693_NO_RESPONSE_TIME); 02636 02637 rfalStartTransceive( &ctx, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02638 02639 /*******************************************************************************/ 02640 /* Run Transceive blocking */ 02641 ret = rfalTransceiveRunBlockingTx( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02642 if( ret == ERR_NONE) 02643 { 02644 ret = rfalTransceiveBlockingRx( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02645 } 02646 02647 gRFAL .nfcvData.ignoreBits = 0; 02648 return ret; 02649 } 02650 02651 /*******************************************************************************/ 02652 ReturnCode rfalISO15693TransceiveAnticollisionEOF( uint8_t *rxBuf, uint8_t rxBufLen, uint16_t *actLen, SPI* mspiChannel, 02653 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 ) 02654 { 02655 uint8_t dummy; 02656 02657 return rfalISO15693TransceiveAnticollisionFrame( &dummy, 0, rxBuf, rxBufLen, actLen, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02658 } 02659 02660 /*******************************************************************************/ 02661 ReturnCode rfalISO15693TransceiveEOF( uint8_t *rxBuf, uint8_t rxBufLen, uint16_t *actLen, 02662 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 ) 02663 { 02664 ReturnCode ret; 02665 uint8_t dummy; 02666 02667 /* Check if RFAL is properly initialized */ 02668 if( ( gRFAL .state < RFAL_STATE_MODE_SET ) || ( gRFAL .mode != RFAL_MODE_POLL_NFCV ) ) 02669 { 02670 return ERR_WRONG_STATE; 02671 } 02672 02673 /*******************************************************************************/ 02674 /* Run Transceive blocking */ 02675 ret = rfalTransceiveBlockingTxRx( &dummy, 02676 0, 02677 rxBuf, 02678 rxBufLen, 02679 actLen, 02680 ( RFAL_TXRX_FLAGS_CRC_TX_MANUAL | RFAL_TXRX_FLAGS_CRC_RX_KEEP | RFAL_TXRX_FLAGS_AGC_ON ), 02681 rfalConv64fcTo1fc(ISO15693_NO_RESPONSE_TIME), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02682 return ret; 02683 } 02684 02685 #endif /* RFAL_FEATURE_NFCV */ 02686 02687 #if RFAL_FEATURE_NFCF 02688 02689 /*******************************************************************************/ 02690 ReturnCode rfalFeliCaPoll( rfalFeliCaPollSlots slots, uint16_t sysCode, uint8_t reqCode, rfalFeliCaPollRes * pollResList, uint8_t pollResListSize, uint8_t *devicesDetected, 02691 uint8_t *collisionsDetected, SPI* mspiChannel, ST25R3911* mST25, 02692 DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ) 02693 { 02694 ReturnCode ret; 02695 uint8_t frame[RFAL_FELICA_POLL_REQ_LEN - RFAL_FELICA_LEN_LEN]; /* LEN is added by ST25R3911 automatically */ 02696 uint16_t actLen; 02697 uint8_t frameIdx; 02698 uint8_t devDetected; 02699 uint8_t colDetected; 02700 rfalEHandling curHandling; 02701 02702 int index = (int)slots; 02703 02704 /* Check if RFAL is properly initialized */ 02705 if( (gRFAL .state < RFAL_STATE_MODE_SET) || ( gRFAL .mode != RFAL_MODE_POLL_NFCF ) ) 02706 { 02707 return ERR_WRONG_STATE; 02708 } 02709 02710 frameIdx = 0; 02711 colDetected = 0; 02712 devDetected = 0; 02713 02714 /*******************************************************************************/ 02715 /* Compute SENSF_REQ frame */ 02716 frame[frameIdx++] = FELICA_CMD_POLLING ; /* CMD: SENF_REQ */ 02717 frame[frameIdx++] = (uint8_t)(sysCode >> 8); /* System Code (SC) */ 02718 frame[frameIdx++] = (uint8_t)(sysCode & 0xFF); /* System Code (SC) */ 02719 frame[frameIdx++] = reqCode; /* Communication Parameter Request (RC)*/ 02720 frame[frameIdx++] = (uint8_t)slots; /* TimeSlot (TSN) */ 02721 02722 02723 /*******************************************************************************/ 02724 /* NRT should not stop on reception - Use EMVCo mode to run NRT in nrt_emv * 02725 * ERRORHANDLING_EMVCO has no special handling for NFC-F mode */ 02726 curHandling = gRFAL .conf.eHandling; 02727 rfalSetErrorHandling( RFAL_ERRORHANDLING_EMVCO ); 02728 02729 /*******************************************************************************/ 02730 /* Run transceive blocking, 02731 * Calculate Total Response Time in(64/fc): 02732 * 512 PICC process time + (n * 256 Time Slot duration) */ 02733 ret = rfalTransceiveBlockingTx( frame, 02734 frameIdx, 02735 (uint8_t*)gRFAL .nfcfData.pollResponses, 02736 RFAL_FELICA_POLL_RES_LEN, 02737 &actLen, 02738 (RFAL_TXRX_FLAGS_DEFAULT), 02739 rfalConv64fcTo1fc( RFAL_FELICA_POLL_DELAY_TIME + (RFAL_FELICA_POLL_SLOT_TIME * (slots + 1)) ), 02740 mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02741 02742 02743 /*******************************************************************************/ 02744 /* If Tx OK, Wait for all responses, store them as soon as they appear */ 02745 if( ret == ERR_NONE ) 02746 { 02747 do 02748 { 02749 ret = rfalTransceiveBlockingRx( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02750 if( ret == ERR_TIMEOUT ) 02751 { 02752 /* Upon timeout the full Poll Delay + (Slot time)*(slots) has expired */ 02753 break; 02754 } 02755 else 02756 { 02757 /* Reception done, reEnabled Rx for following Slot */ 02758 mST25 -> executeCommand( ST25R3911_CMD_UNMASK_RECEIVE_DATA, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02759 mST25 -> executeCommand( ST25R3911_CMD_CLEAR_SQUELCH, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02760 02761 /* If the reception was OK, new device found */ 02762 if( ret == ERR_NONE ) 02763 { 02764 devDetected++; 02765 02766 /* Overwrite the Transceive context for the next reception */ 02767 gRFAL .TxRx.ctx.rxBuf = (uint8_t*)gRFAL .nfcfData.pollResponses[devDetected]; 02768 } 02769 /* If the reception was not OK, mark as collision */ 02770 else 02771 { 02772 colDetected++; 02773 } 02774 02775 /* Check whether NRT has expired meanwhile */ 02776 if( st25r3911CheckReg( ST25R3911_REG_REGULATOR_RESULT, ST25R3911_REG_REGULATOR_RESULT_nrt_on, 0x00, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ) 02777 { 02778 break; 02779 } 02780 } 02781 02782 /* Jump again into transceive Rx state for the following reception */ 02783 gRFAL .TxRx.status = ERR_BUSY; 02784 gRFAL .state = RFAL_STATE_TXRX; 02785 gRFAL .TxRx.state = RFAL_TXRX_STATE_RX_IDLE; 02786 02787 }while(index--); 02788 } 02789 02790 /*******************************************************************************/ 02791 /* Restore NRT to normal mode - back to previous error handling */ 02792 rfalSetErrorHandling( curHandling ); 02793 02794 /*******************************************************************************/ 02795 /* Assign output parameters if requested */ 02796 02797 if( (pollResList != NULL) && (pollResListSize > 0) && (devDetected > 0) ) 02798 { 02799 ST_MEMCPY( pollResList, gRFAL .nfcfData.pollResponses, (RFAL_FELICA_POLL_RES_LEN * MIN(pollResListSize, devDetected) ) ); 02800 } 02801 02802 if( devicesDetected != NULL ) 02803 { 02804 *devicesDetected = devDetected; 02805 } 02806 02807 if( collisionsDetected != NULL ) 02808 { 02809 *collisionsDetected = colDetected; 02810 } 02811 uint16_t ERR_NONEUI = ERR_NONE; 02812 return (( colDetected || devDetected ) ? ERR_NONEUI : ret); 02813 } 02814 02815 #endif /* RFAL_FEATURE_NFCF */ 02816 02817 02818 /***************************************************************************** 02819 * Listen Mode * 02820 *****************************************************************************/ 02821 02822 02823 02824 /*******************************************************************************/ 02825 bool rfalIsExtFieldOn( 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 ) 02826 { 02827 return st25r3911CheckReg(ST25R3911_REG_AUX_DISPLAY, ST25R3911_REG_AUX_DISPLAY_efd_o, ST25R3911_REG_AUX_DISPLAY_efd_o, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02828 } 02829 02830 02831 /*******************************************************************************/ 02832 ReturnCode rfalListenStart( uint32_t lmMask, rfalLmConfPA *confA, rfalLmConfPB *confB, 02833 rfalLmConfPF *confF, uint8_t *rxBuf, uint16_t rxBufLen, uint16_t *rxLen, 02834 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 ) 02835 { 02836 NO_WARNING(confA); 02837 NO_WARNING(confB); 02838 NO_WARNING(confF); 02839 02840 02841 gRFAL .Lm.state = RFAL_LM_STATE_NOT_INIT ; 02842 02843 02844 /*******************************************************************************/ 02845 if( (lmMask & RFAL_LM_MASK_NFCA) || (lmMask & RFAL_LM_MASK_NFCB) || (lmMask & RFAL_LM_MASK_NFCF) ) 02846 { 02847 return ERR_NOTSUPP; 02848 } 02849 02850 02851 02852 /*******************************************************************************/ 02853 if( (lmMask & RFAL_LM_MASK_ACTIVE_P2P) ) 02854 { 02855 gRFAL .state = RFAL_STATE_LM; 02856 02857 gRFAL .Lm.rxBuf = rxBuf; 02858 gRFAL .Lm.rxBufLen = rxBufLen; 02859 gRFAL .Lm.rxLen = rxLen; 02860 *gRFAL .Lm.rxLen = 0; 02861 gRFAL .Lm.dataFlag = false; 02862 02863 /* On Bit Rate Detection Mode ST25R391x will filter incoming frames during MRT time starting on External Field On event, use 512/fc steps */ 02864 mST25 -> writeRegister( ST25R3911_REG_MASK_RX_TIMER, rfalConv1fcTo512fc( RFAL_LM_GT ), mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02865 02866 /* Restore default settings on NFCIP1 mode, Receiving parity + CRC bits and manual Tx Parity*/ 02867 st25r3911ClrRegisterBits( ST25R3911_REG_ISO14443A_NFC, 02868 (ST25R3911_REG_ISO14443A_NFC_no_tx_par | ST25R3911_REG_ISO14443A_NFC_no_rx_par | ST25R3911_REG_ISO14443A_NFC_nfc_f0), 02869 mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02870 02871 /* Enable External Field Detector */ 02872 st25r3911SetRegisterBits( ST25R3911_REG_AUX, ST25R3911_REG_AUX_en_fd, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02873 02874 /* Enable Receiver */ 02875 st25r3911ChangeRegisterBits( ST25R3911_REG_OP_CONTROL, ST25R3911_REG_OP_CONTROL_rx_en, ST25R3911_REG_OP_CONTROL_rx_en, 02876 mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02877 02878 /* Set Analog configurations for generic Listen mode */ 02879 /* Not on SetState(POWER OFF) as otherwise would be applied on every Field Event */ 02880 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_AP2P | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02881 rfalSetAnalogConfig( (RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_AP2P | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02882 02883 /* Initialize as POWER_OFF and set proper mode in RF Chip */ 02884 rfalListenSetState( RFAL_LM_STATE_POWER_OFF , mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02885 } 02886 else 02887 { 02888 return ERR_REQUEST; /* Listen Start called but no mode was enabled */ 02889 } 02890 02891 return ERR_NONE; 02892 } 02893 02894 02895 02896 /*******************************************************************************/ 02897 static ReturnCode rfalRunListenModeWorker( 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 ) 02898 { 02899 volatile uint32_t irqs; 02900 uint8_t tmp; 02901 02902 if( gRFAL .state != RFAL_STATE_LM ) 02903 { 02904 return ERR_WRONG_STATE; 02905 } 02906 02907 switch( gRFAL .Lm.state ) 02908 { 02909 /*******************************************************************************/ 02910 case RFAL_LM_STATE_POWER_OFF : 02911 02912 irqs = st25r3911GetInterrupt( ( ST25R3911_IRQ_MASK_EON ), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02913 if( irqs == ST25R3911_IRQ_MASK_NONE ) 02914 { 02915 break; /* No interrupt to process */ 02916 } 02917 02918 if( (irqs & ST25R3911_IRQ_MASK_EON) ) 02919 { 02920 rfalListenSetState( RFAL_LM_STATE_IDLE , mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02921 } 02922 else 02923 { 02924 break; 02925 } 02926 /* fall through */ 02927 02928 02929 /*******************************************************************************/ 02930 case RFAL_LM_STATE_IDLE : 02931 02932 irqs = st25r3911GetInterrupt( ( ST25R3911_IRQ_MASK_NFCT | ST25R3911_IRQ_MASK_RXE | ST25R3911_IRQ_MASK_EOF ), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02933 if( irqs == ST25R3911_IRQ_MASK_NONE ) 02934 { 02935 break; /* No interrupt to process */ 02936 } 02937 02938 if( (irqs & ST25R3911_IRQ_MASK_NFCT) ) 02939 { 02940 /* Retrieve bitrate detected */ 02941 mST25 -> readRegister( ST25R3911_REG_NFCIP1_BIT_RATE, (uint8_t*)&gRFAL .Lm.brDetected, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02942 // rfalBitRate test = RFAL_BR_1695; 02943 gRFAL .Lm.brDetected = (rfalBitRate )((int)gRFAL .Lm.brDetected >> ST25R3911_REG_NFCIP1_BIT_RATE_nfc_rate_shift); 02944 //(rfalBitRate) ST25R3911_REG_NFCIP1_BIT_RATE_nfc_rate_shift; 02945 } 02946 else if( (irqs & ST25R3911_IRQ_MASK_RXE) && (gRFAL .Lm.brDetected != RFAL_BR_KEEP ) ) 02947 { 02948 irqs = st25r3911GetInterrupt( ( ST25R3911_IRQ_MASK_RXE | ST25R3911_IRQ_MASK_EOF | ST25R3911_IRQ_MASK_CRC | ST25R3911_IRQ_MASK_PAR | ST25R3911_IRQ_MASK_ERR2 | ST25R3911_IRQ_MASK_ERR1 ), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02949 02950 if( (irqs & ST25R3911_IRQ_MASK_CRC) || (irqs & ST25R3911_IRQ_MASK_PAR) || (irqs & ST25R3911_IRQ_MASK_ERR1) ) 02951 { 02952 /* nfc_ar may have triggered RF Collision Avoidance, disable it before executing Clear (Stop All activities) */ 02953 st25r3911ClrRegisterBits( ST25R3911_REG_MODE, ST25R3911_REG_MODE_nfc_ar, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02954 mST25 -> executeCommand( ST25R3911_CMD_CLEAR_FIFO, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02955 mST25 -> executeCommand( ST25R3911_CMD_UNMASK_RECEIVE_DATA, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02956 st25r3911SetRegisterBits( ST25R3911_REG_MODE, ST25R3911_REG_MODE_nfc_ar, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02957 st25r3911ClrRegisterBits(ST25R3911_REG_OP_CONTROL, ST25R3911_REG_OP_CONTROL_tx_en, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02958 break; /* A bad reception occurred, remain in same state */ 02959 } 02960 02961 /* Retrieve received data */ 02962 mST25 -> readRegister(ST25R3911_REG_FIFO_RX_STATUS1, &tmp, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02963 *gRFAL .Lm.rxLen = tmp; 02964 02965 mST25 -> readFifo( gRFAL .Lm.rxBuf, MIN( *gRFAL .Lm.rxLen, rfalConvBitsToBytes(gRFAL .Lm.rxBufLen) ), mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02966 02967 /* Check if the data we got has at least the CRC and remove it, otherwise leave at 0 */ 02968 *gRFAL .Lm.rxLen -= ((*gRFAL .Lm.rxLen > RFAL_CRC_LEN) ? RFAL_CRC_LEN : *gRFAL .Lm.rxLen); 02969 *gRFAL .Lm.rxLen = rfalConvBytesToBits( *gRFAL .Lm.rxLen ); 02970 gRFAL .Lm.dataFlag = true; 02971 02972 /*Check if Observation Mode was enabled and disable it on ST25R391x */ 02973 rfalCheckDisableObsMode(); 02974 } 02975 else if( (irqs & ST25R3911_IRQ_MASK_EOF) && (!gRFAL .Lm.dataFlag) ) 02976 { 02977 rfalListenSetState( RFAL_LM_STATE_POWER_OFF , mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 02978 } 02979 break; 02980 02981 /*******************************************************************************/ 02982 case RFAL_LM_STATE_READY_F : 02983 case RFAL_LM_STATE_READY_A : 02984 case RFAL_LM_STATE_ACTIVE_A : 02985 case RFAL_LM_STATE_ACTIVE_Ax : 02986 case RFAL_LM_STATE_SLEEP_A : 02987 case RFAL_LM_STATE_SLEEP_B : 02988 case RFAL_LM_STATE_SLEEP_AF : 02989 case RFAL_LM_STATE_READY_Ax : 02990 case RFAL_LM_STATE_CARDEMU_4A : 02991 case RFAL_LM_STATE_CARDEMU_4B : 02992 case RFAL_LM_STATE_CARDEMU_3 : 02993 return ERR_INTERNAL; 02994 02995 case RFAL_LM_STATE_TARGET_F : 02996 case RFAL_LM_STATE_TARGET_A : 02997 break; 02998 02999 /*******************************************************************************/ 03000 default: 03001 return ERR_WRONG_STATE; 03002 } 03003 return ERR_NONE; 03004 } 03005 03006 03007 /*******************************************************************************/ 03008 ReturnCode rfalListenStop( 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 ) 03009 { 03010 gRFAL .Lm.state = RFAL_LM_STATE_NOT_INIT ; 03011 03012 /*Check if Observation Mode was enabled and disable it on ST25R391x */ 03013 rfalCheckDisableObsMode(); 03014 03015 /* Disable Receiver and Transmitter */ 03016 rfalFieldOff( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03017 03018 /* As there's no Off mode, set default value: ISO14443A with automatic RF Collision Avoidance Off */ 03019 mST25 -> writeRegister( ST25R3911_REG_MODE, (ST25R3911_REG_MODE_om_iso14443a | ST25R3911_REG_MODE_nfc_ar_off), mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03020 03021 return ERR_NONE; 03022 } 03023 03024 03025 /*******************************************************************************/ 03026 ReturnCode rfalListenSleepStart( rfalLmState sleepSt, uint8_t *rxBuf, uint16_t rxBufLen, uint16_t *rxLen ) 03027 { 03028 NO_WARNING(sleepSt); 03029 NO_WARNING(rxBuf); 03030 NO_WARNING(rxBufLen); 03031 NO_WARNING(rxLen); 03032 03033 return ERR_NOTSUPP; 03034 } 03035 03036 03037 /*******************************************************************************/ 03038 rfalLmState rfalListenGetState( bool *dataFlag, rfalBitRate *lastBR ) 03039 { 03040 /* Allow state retrieval even if gRFAL.state != RFAL_STATE_LM so * 03041 * that this Lm state can be used by caller after activation */ 03042 03043 if( lastBR != NULL ) 03044 { 03045 *lastBR = gRFAL .Lm.brDetected; 03046 } 03047 03048 if( dataFlag != NULL ) 03049 { 03050 *dataFlag = gRFAL .Lm.dataFlag; 03051 } 03052 03053 return gRFAL .Lm.state; 03054 } 03055 03056 03057 /*******************************************************************************/ 03058 ReturnCode rfalListenSetState( rfalLmState newSt, 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 ) 03059 { 03060 ReturnCode ret; 03061 uint8_t tmp; 03062 03063 /*rfalLogD( "RFAL: curState: %02X newState: %02X \r\n", gRFAL.Lm.state, newSt );*/ 03064 03065 /* SetState clears the Data flag */ 03066 gRFAL .Lm.dataFlag = false; 03067 ret = ERR_NONE; 03068 03069 /*******************************************************************************/ 03070 switch( newSt ) 03071 { 03072 /*******************************************************************************/ 03073 case RFAL_LM_STATE_POWER_OFF : 03074 03075 /*******************************************************************************/ 03076 /* Disable nfc_ar as RF Collision Avoidance timer may have already started */ 03077 st25r3911ClrRegisterBits( ST25R3911_REG_MODE, ST25R3911_REG_MODE_nfc_ar, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03078 03079 mST25 -> executeCommand( ST25R3911_CMD_CLEAR_FIFO, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03080 03081 /* Ensure that our field is Off, as automatic response RF Collision Avoidance may have been triggered */ 03082 st25r3911ClrRegisterBits(ST25R3911_REG_OP_CONTROL, ST25R3911_REG_OP_CONTROL_tx_en, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03083 03084 /*******************************************************************************/ 03085 /* Ensure that the NFCIP1 mode is disabled */ 03086 st25r3911ClrRegisterBits( ST25R3911_REG_ISO14443A_NFC, ST25R3911_REG_ISO14443A_NFC_nfc_f0, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03087 03088 03089 /*******************************************************************************/ 03090 /* Clear and enable required IRQs */ 03091 st25r3911DisableInterrupts( ST25R3911_IRQ_MASK_ALL, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ); 03092 03093 03094 st25r3911GetInterrupt( (ST25R3911_IRQ_MASK_NFCT | ST25R3911_IRQ_MASK_RXS | ST25R3911_IRQ_MASK_CRC | ST25R3911_IRQ_MASK_ERR1 | 03095 ST25R3911_IRQ_MASK_ERR2 | ST25R3911_IRQ_MASK_PAR | ST25R3911_IRQ_MASK_EON | ST25R3911_IRQ_MASK_EOF | ST25R3911_IRQ_MASK_RXE ), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03096 03097 03098 /*******************************************************************************/ 03099 /* REMARK: Silicon workaround ST25R3911 Errata TDB */ 03100 /* RXS and NFCT are triggered very close (specially in higher bitrates). * 03101 * If the interrupt status register is being read when NFCT is trigerred, the * 03102 * IRQ line might go low and NFCT is not signalled on the status register. * 03103 * For initial bitrate detection, mask RXS, only wait for NFCT and RXE. */ 03104 /*******************************************************************************/ 03105 03106 st25r3911EnableInterrupts( (ST25R3911_IRQ_MASK_NFCT | ST25R3911_IRQ_MASK_CRC | ST25R3911_IRQ_MASK_ERR1 | 03107 ST25R3911_IRQ_MASK_ERR2 | ST25R3911_IRQ_MASK_PAR | ST25R3911_IRQ_MASK_EON | ST25R3911_IRQ_MASK_EOF | ST25R3911_IRQ_MASK_RXE ), 03108 mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03109 03110 /*******************************************************************************/ 03111 /* Clear the bitRate previously detected */ 03112 gRFAL .Lm.brDetected = RFAL_BR_KEEP ; 03113 03114 03115 /*******************************************************************************/ 03116 /* Apply the BitRate detection mode mode */ 03117 mST25 -> writeRegister( ST25R3911_REG_MODE, 03118 (ST25R3911_REG_MODE_targ_targ | ST25R3911_REG_MODE_om_bit_rate_detection | ST25R3911_REG_MODE_nfc_ar_on), 03119 mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03120 03121 03122 /*******************************************************************************/ 03123 /* REMARK: Silicon workaround ST25R3911 Errata #1.3 */ 03124 /* Even though bitrate is going to be detected the bitrate must be set to * 03125 * 106kbps to get correct 106kbps parity */ 03126 mST25 -> writeRegister( ST25R3911_REG_BIT_RATE, (ST25R3911_REG_BIT_RATE_txrate_106 | ST25R3911_REG_BIT_RATE_rxrate_106), 03127 mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03128 /*******************************************************************************/ 03129 03130 03131 /*******************************************************************************/ 03132 /* Check if external Field is already On */ 03133 if( rfalIsExtFieldOn( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ) 03134 { 03135 return rfalListenSetState( RFAL_LM_STATE_IDLE , mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; /* Set IDLE state */ 03136 } 03137 break; 03138 03139 /*******************************************************************************/ 03140 case RFAL_LM_STATE_IDLE : 03141 03142 /*******************************************************************************/ 03143 /* In Active P2P the Initiator may: Turn its field On; LM goes into IDLE state; 03144 * Initiator sends an unexpected frame raising a Protocol error; Initiator 03145 * turns its field Off and ST25R3911 performs the automatic RF Collision 03146 * Avoidance keeping our field On; upon a Protocol error upper layer sets 03147 * again the state to IDLE to clear dataFlag and wait for next data. 03148 * 03149 * Ensure that when upper layer calls SetState(IDLE), it restores initial 03150 * configuration and that check whether an external Field is still present */ 03151 03152 /* nfc_ar may have triggered RF Collision Avoidance, disable it before executing Clear (Stop All activities) */ 03153 st25r3911ClrRegisterBits( ST25R3911_REG_MODE, ST25R3911_REG_MODE_nfc_ar, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03154 mST25 -> executeCommand( ST25R3911_CMD_CLEAR_FIFO, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03155 st25r3911SetRegisterBits( ST25R3911_REG_MODE, ST25R3911_REG_MODE_nfc_ar, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03156 03157 /* Ensure that our field is Off, as automatic response RF Collision Avoidance may have been triggered */ 03158 st25r3911ClrRegisterBits(ST25R3911_REG_OP_CONTROL, ST25R3911_REG_OP_CONTROL_tx_en , mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03159 03160 03161 /* Load 2nd/3rd stage gain setting from registers into the receiver */ 03162 mST25 -> executeCommand( ST25R3911_CMD_CLEAR_SQUELCH, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03163 03164 /*******************************************************************************/ 03165 /* REMARK: Silicon workaround ST25R3911 Errata #1.4 */ 03166 /* Enable; disable; enable mixer to make sure the digital decoder is in * 03167 * high state. This also switches the demodulator to mixer mode. */ 03168 mST25 -> readRegister( ST25R3911_REG_RX_CONF1, &tmp, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03169 mST25 -> writeRegister( ST25R3911_REG_RX_CONF1, (tmp | ST25R3911_REG_RX_CONF1_amd_sel), mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03170 mST25 -> writeRegister( ST25R3911_REG_RX_CONF1, (tmp & ~ST25R3911_REG_RX_CONF1_amd_sel), mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03171 mST25 -> writeRegister( ST25R3911_REG_RX_CONF1, (tmp | ST25R3911_REG_RX_CONF1_amd_sel), mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03172 /*******************************************************************************/ 03173 03174 /* ReEnable the receiver */ 03175 mST25 -> executeCommand( ST25R3911_CMD_UNMASK_RECEIVE_DATA, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03176 03177 03178 /* If external Field is no longer detected go back to POWER_OFF */ 03179 if( !st25r3911CheckReg(ST25R3911_REG_AUX_DISPLAY, ST25R3911_REG_AUX_DISPLAY_efd_o, ST25R3911_REG_AUX_DISPLAY_efd_o, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ) 03180 { 03181 return rfalListenSetState( RFAL_LM_STATE_POWER_OFF , mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; /* Set POWER_OFF state */ 03182 } 03183 03184 /*******************************************************************************/ 03185 /*Check if Observation Mode is enabled and set it on ST25R391x */ 03186 rfalCheckEnableObsModeRx(); 03187 break; 03188 03189 /*******************************************************************************/ 03190 case RFAL_LM_STATE_TARGET_A : 03191 case RFAL_LM_STATE_TARGET_F : 03192 /* States not handled by the LM, just keep state context */ 03193 break; 03194 03195 /*******************************************************************************/ 03196 case RFAL_LM_STATE_READY_F : 03197 case RFAL_LM_STATE_CARDEMU_3 : 03198 case RFAL_LM_STATE_READY_Ax : 03199 case RFAL_LM_STATE_READY_A : 03200 case RFAL_LM_STATE_ACTIVE_Ax : 03201 case RFAL_LM_STATE_ACTIVE_A : 03202 case RFAL_LM_STATE_SLEEP_A : 03203 case RFAL_LM_STATE_SLEEP_B : 03204 case RFAL_LM_STATE_SLEEP_AF : 03205 case RFAL_LM_STATE_CARDEMU_4A : 03206 case RFAL_LM_STATE_CARDEMU_4B : 03207 return ERR_NOTSUPP; 03208 03209 /*******************************************************************************/ 03210 default: 03211 return ERR_WRONG_STATE; 03212 } 03213 03214 gRFAL .Lm.state = newSt; 03215 03216 return ret; 03217 } 03218 03219 03220 /******************************************************************************* 03221 * Wake-Up Mode * 03222 *******************************************************************************/ 03223 03224 /*******************************************************************************/ 03225 ReturnCode rfalWakeUpModeStart( void *config, ST25R3911* mST25, SPI* mspiChannel, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ) 03226 { 03227 uint8_t aux; 03228 uint8_t reg; 03229 uint32_t irqs; 03230 03231 /* The Wake-Up procedure is explained in detail in Application Note: AN4985 */ 03232 03233 if( config == NULL) 03234 { 03235 gRFAL .wum.cfg.period = ST25R3911_WUM_PERIDOD_500MS; 03236 gRFAL .wum.cfg.irqTout = false; 03237 03238 gRFAL .wum.cfg.indPha.enabled = true; 03239 gRFAL .wum.cfg.indPha.delta = 3; 03240 gRFAL .wum.cfg.indPha.reference = ST25R3911_WUM_REFRENCE_AUTO; 03241 gRFAL .wum.cfg.indPha.autoAvg = true; 03242 03243 03244 gRFAL .wum.cfg.cap.enabled = false; 03245 gRFAL .wum.cfg.cap.delta = 3; 03246 gRFAL .wum.cfg.cap.reference = ST25R3911_WUM_REFRENCE_AUTO; 03247 gRFAL .wum.cfg.cap.autoAvg = true; 03248 03249 03250 03251 gRFAL .wum.cfg.indAmp.enabled = false; 03252 gRFAL .wum.cfg.indAmp.delta = 3; 03253 gRFAL .wum.cfg.indAmp.reference = ST25R3911_WUM_REFRENCE_AUTO; 03254 gRFAL .wum.cfg.indAmp.autoAvg = true; 03255 } 03256 else 03257 { 03258 gRFAL .wum.cfg = *((st25r3911WakeUpConfig*)config); 03259 } 03260 03261 03262 if( gRFAL .wum.cfg.cap.enabled && (gRFAL .wum.cfg.indAmp.enabled || gRFAL .wum.cfg.indPha.enabled) ) 03263 { 03264 return ERR_PARAM; 03265 } 03266 03267 irqs = ST25R3911_IRQ_MASK_NONE; 03268 03269 03270 03271 ///// conf wake up timer and control register IRQ if diff larger that delta am -> 00000100 03272 03273 //mST25->writeRegister(ST25R3911_REG_WUP_TIMER_CONTROL, ST25R3911_REG_WUP_TIMER_CONTROL_wam, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03274 03275 03276 03277 03278 /*******************************************************************************/ 03279 /* Prepare Wake-Up Timer Control Register */ 03280 reg = ((gRFAL .wum.cfg.period & 0x0F) << ST25R3911_REG_WUP_TIMER_CONTROL_shift_wut); 03281 reg |= ((gRFAL .wum.cfg.period < ST25R3911_WUM_PERIDOD_100MS) ? ST25R3911_REG_WUP_TIMER_CONTROL_wur : 0x00); 03282 03283 if(gRFAL .wum.cfg.irqTout) 03284 { 03285 reg |= ST25R3911_REG_WUP_TIMER_CONTROL_wto; 03286 irqs |= ST25R3911_IRQ_MASK_WT; 03287 } 03288 03289 /*******************************************************************************/ 03290 /* Check if Inductive Amplitude is to be performed */ 03291 if( gRFAL .wum.cfg.indAmp.enabled ) 03292 { 03293 aux = ((gRFAL .wum.cfg.indAmp.delta) << ST25R3911_REG_AMPLITUDE_MEASURE_CONF_shift_am_d); 03294 aux |= (gRFAL .wum.cfg.indAmp.aaInclMeas ? ST25R3911_REG_AMPLITUDE_MEASURE_CONF_am_aam : 0x00); 03295 aux |= ((gRFAL .wum.cfg.indAmp.aaWeight << ST25R3911_REG_AMPLITUDE_MEASURE_CONF_shift_am_aew) & ST25R3911_REG_AMPLITUDE_MEASURE_CONF_mask_am_aew); 03296 aux |= (gRFAL .wum.cfg.indAmp.autoAvg ? ST25R3911_REG_AMPLITUDE_MEASURE_CONF_am_ae : 0x00); 03297 03298 mST25->writeRegister(ST25R3911_REG_AMPLITUDE_MEASURE_CONF, aux, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03299 03300 /* Only need to set the reference if not using Auto Average */ 03301 if( !gRFAL .wum.cfg.indAmp.autoAvg ) 03302 { 03303 if( gRFAL .wum.cfg.indAmp.reference == ST25R3911_WUM_REFRENCE_AUTO ) 03304 { 03305 st25r3911MeasureRF( &aux, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03306 mST25->writeRegister(ST25R3911_REG_AMPLITUDE_MEASURE_REF, aux, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03307 } 03308 else 03309 { 03310 mST25->writeRegister(ST25R3911_REG_AMPLITUDE_MEASURE_REF, gRFAL .wum.cfg.indAmp.reference, mspiChannel, gpio_cs, 03311 IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03312 } 03313 } 03314 03315 reg |= ST25R3911_REG_WUP_TIMER_CONTROL_wam; 03316 irqs |= ST25R3911_IRQ_MASK_WAM; 03317 } 03318 03319 /*******************************************************************************/ 03320 /* Check if Inductive Phase is to be performed */ 03321 if( gRFAL .wum.cfg.indPha.enabled ) 03322 { 03323 aux = ((gRFAL .wum.cfg.indPha.delta) << ST25R3911_REG_PHASE_MEASURE_CONF_shift_pm_d); 03324 aux |= (gRFAL .wum.cfg.indPha.aaInclMeas ? ST25R3911_REG_PHASE_MEASURE_CONF_pm_aam : 0x00); 03325 aux |= ((gRFAL .wum.cfg.indPha.aaWeight << ST25R3911_REG_PHASE_MEASURE_CONF_shift_pm_aew) & ST25R3911_REG_PHASE_MEASURE_CONF_mask_pm_aew); 03326 aux |= (gRFAL .wum.cfg.indPha.autoAvg ? ST25R3911_REG_PHASE_MEASURE_CONF_pm_ae : 0x00); 03327 03328 mST25->writeRegister(ST25R3911_REG_PHASE_MEASURE_CONF, aux, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03329 03330 /* Only need to set the reference if not using Auto Average */ 03331 if( !gRFAL .wum.cfg.indPha.autoAvg ) 03332 { 03333 if( gRFAL .wum.cfg.indPha.reference == ST25R3911_WUM_REFRENCE_AUTO ) 03334 { 03335 st25r3911MeasureAntennaResonance( &aux, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03336 mST25->writeRegister(ST25R3911_REG_PHASE_MEASURE_REF, aux, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03337 } 03338 else 03339 { 03340 03341 mST25->writeRegister(ST25R3911_REG_PHASE_MEASURE_REF, gRFAL .wum.cfg.indPha.reference, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03342 03343 } 03344 } 03345 03346 reg |= ST25R3911_REG_WUP_TIMER_CONTROL_wph; 03347 irqs |= ST25R3911_IRQ_MASK_WPH; 03348 } 03349 03350 /*******************************************************************************/ 03351 /* Check if Capacitive is to be performed */ 03352 if( gRFAL .wum.cfg.cap.enabled ) 03353 { 03354 return ERR_NOT_IMPLEMENTED; 03355 } 03356 03357 /* Disable External Field Detector */ 03358 st25r3911ClrRegisterBits( ST25R3911_REG_AUX, ST25R3911_REG_AUX_en_fd, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03359 03360 /* Disable and clear all interrupts except Wake-Up IRQs */ 03361 st25r3911DisableInterrupts( ST25R3911_IRQ_MASK_ALL, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03362 st25r3911GetInterrupt( irqs, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03363 st25r3911EnableInterrupts( irqs, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03364 03365 /* Enable Low Power Wake-Up Mode */ 03366 mST25->writeRegister(ST25R3911_REG_WUP_TIMER_CONTROL, reg, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03367 mST25->writeRegister(ST25R3911_REG_OP_CONTROL, ST25R3911_REG_OP_CONTROL_wu, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03368 03369 03370 03371 gRFAL .wum.state = RFAL_WUM_STATE_ENABLED ; 03372 gRFAL .state = RFAL_STATE_WUM; 03373 03374 return ERR_NONE; 03375 } 03376 03377 03378 /*******************************************************************************/ 03379 bool rfalWakeUpModeHasWoke( ST25R3911* mST25, SPI* mspiChannel, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ) 03380 { 03381 03382 return (gRFAL .wum.state == RFAL_WUM_STATE_ENABLED_WOKE ); 03383 } 03384 03385 03386 /*******************************************************************************/ 03387 static void rfalRunWakeUpModeWorker( 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 ) 03388 { 03389 uint32_t irqs; 03390 03391 if( gRFAL .state != RFAL_STATE_WUM ) 03392 { 03393 return; 03394 } 03395 03396 switch( gRFAL .wum.state ) 03397 { 03398 case RFAL_WUM_STATE_ENABLED : 03399 case RFAL_WUM_STATE_ENABLED_WOKE : 03400 03401 irqs = st25r3911GetInterrupt( ( ST25R3911_IRQ_MASK_WT | ST25R3911_IRQ_MASK_WAM | ST25R3911_IRQ_MASK_WPH | ST25R3911_IRQ_MASK_WCAP ), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03402 if( irqs == ST25R3911_IRQ_MASK_NONE ) 03403 { 03404 break; /* No interrupt to process */ 03405 } 03406 03407 /*******************************************************************************/ 03408 /* Check and mark which measurement(s) cause interrupt */ 03409 if(irqs & ST25R3911_IRQ_MASK_WAM) 03410 { 03411 gRFAL .wum.state = RFAL_WUM_STATE_ENABLED_WOKE ; 03412 } 03413 03414 if(irqs & ST25R3911_IRQ_MASK_WPH) 03415 { 03416 gRFAL .wum.state = RFAL_WUM_STATE_ENABLED_WOKE ; 03417 } 03418 03419 if(irqs & ST25R3911_IRQ_MASK_WCAP) 03420 { 03421 gRFAL .wum.state = RFAL_WUM_STATE_ENABLED_WOKE ; 03422 } 03423 break; 03424 03425 default: 03426 break; 03427 } 03428 } 03429 03430 03431 /*******************************************************************************/ 03432 ReturnCode rfalWakeUpModeStop( 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 ) 03433 { 03434 if( gRFAL .wum.state == RFAL_WUM_STATE_NOT_INIT ) 03435 { 03436 return ERR_WRONG_STATE; 03437 } 03438 03439 gRFAL .wum.state = RFAL_WUM_STATE_NOT_INIT ; 03440 03441 /* Re-Enable External Field Detector */ 03442 st25r3911SetRegisterBits( ST25R3911_REG_AUX, ST25R3911_REG_AUX_en_fd, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03443 03444 /* Disable Wake-Up Mode */ 03445 st25r3911ClrRegisterBits( ST25R3911_REG_OP_CONTROL, ST25R3911_REG_OP_CONTROL_wu, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03446 st25r3911DisableInterrupts( (ST25R3911_IRQ_MASK_WT | ST25R3911_IRQ_MASK_WAM | ST25R3911_IRQ_MASK_WPH | ST25R3911_IRQ_MASK_WCAP), 03447 mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03448 03449 /* Re-Enable the Oscillator */ 03450 st25r3911OscOn( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03451 03452 return ERR_NONE; 03453 } 03454 03455 03456 /******************************************************************************* 03457 * RF Chip * 03458 *******************************************************************************/ 03459 03460 /*******************************************************************************/ 03461 ReturnCode rfalChipWriteReg( uint16_t reg, uint8_t* values, uint8_t len, 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 ) 03462 { 03463 if( !st25r3911IsRegValid( (uint8_t)reg) ) 03464 { 03465 return ERR_PARAM; 03466 } 03467 03468 mST25 -> writeMultipleRegisters( (uint8_t)reg, values, len, mspiChannel,mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03469 return ERR_NONE; 03470 } 03471 03472 /*******************************************************************************/ 03473 ReturnCode rfalChipReadReg( uint16_t reg, uint8_t* values, uint8_t len, 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 ) 03474 { 03475 if( !st25r3911IsRegValid( (uint8_t)reg) ) 03476 { 03477 return ERR_PARAM; 03478 } 03479 03480 mST25 -> readMultipleRegisters( (uint8_t)reg, values, len, mspiChannel,mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03481 return ERR_NONE; 03482 } 03483 03484 /*******************************************************************************/ 03485 ReturnCode rfalChipExecCmd( uint16_t cmd, 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 ) 03486 { 03487 if( !st25r3911IsCmdValid( (uint8_t)cmd) ) 03488 { 03489 return ERR_PARAM; 03490 } 03491 03492 mST25 -> executeCommand( (uint8_t) cmd, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03493 return ERR_NONE; 03494 } 03495 03496 /*******************************************************************************/ 03497 ReturnCode rfalChipWriteTestReg( uint16_t reg, uint8_t value, 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 ) 03498 { 03499 st25r3911WriteTestRegister( (uint8_t)reg, value, mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03500 return ERR_NONE; 03501 } 03502 03503 /*******************************************************************************/ 03504 ReturnCode rfalChipReadTestReg( uint16_t reg, uint8_t* value, 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 ) 03505 { 03506 st25r3911ReadTestRegister( (uint8_t)reg, value, mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03507 return ERR_NONE; 03508 } 03509 03510 /*******************************************************************************/ 03511 ReturnCode rfalChipChangeRegBits( uint16_t reg, uint8_t valueMask, uint8_t value, SPI* mspiChannel, 03512 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 ) 03513 { 03514 st25r3911ChangeRegisterBits( (uint8_t)reg, valueMask, value, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03515 return ERR_NONE; 03516 } 03517 03518 /*******************************************************************************/ 03519 ReturnCode rfalChipChangeTestRegBits( uint16_t reg, uint8_t valueMask, uint8_t value, SPI * mspiChannel, ST25R3911* mST25, 03520 DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 ) 03521 { 03522 st25r3911ChangeTestRegisterBits( (uint8_t)reg, valueMask, value, mST25, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 03523 return ERR_NONE; 03524 } 03525 03526 03527 03528 void rfalSetWumState( void ) 03529 { 03530 gRFAL .wum.state = RFAL_WUM_STATE_ENABLED_WOKE ; 03531 } 03532 03533 03534 /*******************************************************************************/ 03535 /* extern uint8_t invalid_size_of_stream_configs[(sizeof(struct st25r3911StreamConfig) == sizeof(struct iso15693StreamConfig))?1:(-1)]; */
Generated on Sat Jul 16 2022 13:00:53 by
1.7.2