ST Expansion SW Team / RFAL

Dependents:   mbed-os-nfc05a1

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers rfal_rf.cpp Source File

rfal_rf.cpp

Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003   * @attention
00004   *
00005   * <h2><center>&copy; COPYRIGHT 2016 STMicroelectronics</center></h2>
00006   *
00007   * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
00008   * You may not use this file except in compliance with the License.
00009   * You may obtain a copy of the License at:
00010   *
00011   *        http://www.st.com/myliberty
00012   *
00013   * Unless required by applicable law or agreed to in writing, software 
00014   * distributed under the License is distributed on an "AS IS" BASIS, 
00015   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
00016   * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
00017   * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
00018   * See the License for the specific language governing permissions and
00019   * limitations under the License.
00020   *
00021 ******************************************************************************/
00022 
00023 
00024 /*
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)]; */