ST Expansion SW Team / RFAL

Dependents:   mbed-os-nfc05a1

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers rfal_nfcv.cpp Source File

rfal_nfcv.cpp

00001 
00002 /******************************************************************************
00003   * @attention
00004   *
00005   * <h2><center>&copy; COPYRIGHT 2016 STMicroelectronics</center></h2>
00006   *
00007   * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
00008   * You may not use this file except in compliance with the License.
00009   * You may obtain a copy of the License at:
00010   *
00011   *        http://www.st.com/myliberty
00012   *
00013   * Unless required by applicable law or agreed to in writing, software 
00014   * distributed under the License is distributed on an "AS IS" BASIS, 
00015   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
00016   * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
00017   * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
00018   * See the License for the specific language governing permissions and
00019   * limitations under the License.
00020   *
00021 ******************************************************************************/
00022 
00023 /*
00024  *      PROJECT:   ST25R391x firmware
00025  *      $Revision: $
00026  *      LANGUAGE:  ISO C99
00027  */
00028 
00029 /*! \file rfal_nfcv.c
00030  *
00031  *  \author Gustavo Patricio
00032  *
00033  *  \brief Implementation of NFC-V Poller (ISO15693) device
00034  *
00035  *  The definitions and helpers methods provided by this module are 
00036  *  aligned with NFC-V (ISO15693)
00037  *
00038  */
00039 
00040 /*
00041  ******************************************************************************
00042  * INCLUDES
00043  ******************************************************************************
00044  */
00045 #include <platform1.h>
00046 #include "rfal_nfcv.h"
00047 #include "utils.h"
00048 
00049 /*
00050  ******************************************************************************
00051  * ENABLE SWITCH
00052  ******************************************************************************
00053  */
00054 
00055 #ifndef RFAL_FEATURE_NFCV
00056     #error " RFAL: Module configuration missing. Please enable/disable NFC-V module by setting: RFAL_FEATURE_NFCV "
00057 #endif
00058 
00059 #if RFAL_FEATURE_NFCV
00060 
00061 /*
00062  ******************************************************************************
00063  * GLOBAL DEFINES
00064  ******************************************************************************
00065  */
00066 
00067 #define RFAL_NFCV_INV_REQ_FLAG            0x06  /*!< INVENTORY_REQ  INV_FLAG  Digital  2.0  9.6.1                      */
00068 #define RFAL_NFCV_INV_REQ_FLAG            0x06  /*!< INVENTORY_REQ  INV_FLAG  Digital  2.0  9.6.1                      */
00069 #define RFAL_NFCV_MASKVAL_MAX_LEN         8     /*!< Mask value max length: 64 bits  (UID length)                      */
00070 #define RFAL_NFCV_MASKVAL_MAX_1SLOT_LEN   64    /*!< Mask value max length in 1 Slot mode in bits  Digital 2.0 9.6.1.6 */
00071 #define RFAL_NFCV_MASKVAL_MAX_16SLOT_LEN  60    /*!< Mask value max length in 16 Slot mode in bits Digital 2.0 9.6.1.6 */
00072 #define RFAL_NFCV_INV_REQ_HEADER_LEN     3     /*!< INVENTORY_REQ header length (INV_FLAG, CMD, MASK_LEN)  */
00073 #define RFAL_NFCV_INV_RES_LEN            10    /*!< INVENTORY_RES length                                   */
00074 #define RFAL_NFCV_CRC_LEN                2     /*!< NFC-V CRC length                                       */
00075 #define RFAL_NFCV_MAX_SLOTS               16    /*!< NFC-V max number of Slots                                         */
00076 #define RFAL_NFCV_MAX_GEN_DATA_LEN        (RFAL_NFCV_MAX_BLOCK_LEN + RFAL_NFCV_UID_LEN) /*!< Max number of generic data*/
00077 
00078 #define RFAL_CMD_LEN                      1     /*!< Commandbyte length                                                */
00079 #define RFAL_NFCV_FLAG_LEN                1     /*!< Flag byte length                                                  */
00080 #define RFAL_NFCV_DSFI_LEN                1     /*!< DSFID length                                                      */
00081 #define RFAL_NFCV_SLPREQ_REQ_FLAG        0x22  /*!< SLPV_REQ request flags Digital 2.0 (Candidate) 9.7.1.1 */
00082 
00083 #define RFAL_NFCV_MAX_COLL_SUPPORTED      16    /*!< Maximum number of collisions supported by the Anticollision loop  */
00084 
00085 #define RFAL_FDT_POLL_MAX                 rfalConvMsTo1fc(20) /*!< */
00086 
00087 
00088 
00089 /*! Time between EOFs - ISO 15693 defines t3min depending on modulation depth and data rate
00090  *                    - NFC Forum defines FDTV,EOF = [10 ; 20]ms    ISO15693 2000 8.4   Digital 2.0  9.7.4 */ 
00091 #define RFAL_NFCV_FDT_EOF                 5
00092 
00093 
00094 
00095 /*
00096  ******************************************************************************
00097  * GLOBAL MACROS
00098  ******************************************************************************
00099  */
00100 
00101 
00102 /*
00103 ******************************************************************************
00104 * GLOBAL TYPES
00105 ******************************************************************************
00106 */
00107 
00108 /*! NFC-V INVENTORY_REQ format   Digital 2.0 9.6.1 */
00109 typedef struct
00110 {
00111     uint8_t  INV_FLAG;                              /*!< Inventory Flags    */
00112     uint8_t  CMD;                                   /*!< Command code: 01h  */
00113     uint8_t  MASK_LEN;                              /*!< Mask Value Length  */
00114     uint8_t  MASK_VALUE[RFAL_NFCV_MASKVAL_MAX_LEN]; /*!< Mask Value         */
00115 } rfalNfcvInventoryReq;
00116 
00117 
00118 /*! NFC-V SLP_REQ format   Digital 2.0 (Candidate) 9.7.1 */
00119 typedef struct
00120 {
00121     uint8_t  REQ_FLAG;                              /*!< Request Flags      */
00122     uint8_t  CMD;                                   /*!< Command code: 02h  */
00123     uint8_t  UID[RFAL_NFCV_UID_LEN];                /*!< Mask Value         */
00124 } rfalNfcvSlpvReq;
00125 
00126 
00127 /*! NFC-V Generic Req format  */
00128 typedef struct
00129 {
00130     uint8_t  REQ_FLAG;                              /*!< Request Flags      */
00131     uint8_t  CMD;                                   /*!< Command code       */
00132     union {
00133         uint8_t  UID[RFAL_NFCV_UID_LEN];                /*!< Mask Value         */
00134         uint8_t  data[RFAL_NFCV_MAX_GEN_DATA_LEN];      /*!< Data               */
00135     }payload;
00136 } rfalNfcvGenericReq;
00137 
00138 
00139 /*! NFC-V Generic Response format */
00140 typedef struct
00141 {
00142     uint8_t  RES_FLAG;                              /*!< Response Flags     */
00143     uint8_t  data[RFAL_NFCV_MAX_GEN_DATA_LEN];      /*!< Data               */
00144 } rfalNfcvGenericRes;
00145 
00146 
00147 /*! Container for a collision found during Anticollsion loop */
00148 typedef struct
00149 {
00150     uint8_t  maskLen;
00151     uint8_t  maskVal[RFAL_NFCV_MASKVAL_MAX_LEN];
00152 }rfalNfcvCollision;
00153 
00154 
00155 /*
00156 ******************************************************************************
00157 * LOCAL FUNCTION PROTOTYPES
00158 ******************************************************************************
00159 */
00160 static ReturnCode rfalNfvParseError( uint8_t err );
00161 
00162 /*
00163 ******************************************************************************
00164 * LOCAL VARIABLES
00165 ******************************************************************************
00166 */
00167 
00168 /*
00169 ******************************************************************************
00170 * LOCAL FUNCTIONS
00171 ******************************************************************************
00172 */
00173 
00174 /*******************************************************************************/
00175 static ReturnCode rfalNfvParseError( uint8_t err )
00176 {
00177     switch(err)
00178     {
00179         case RFAL_NFCV_ERROR_CMD_NOT_SUPPORTED :
00180         case RFAL_NFCV_ERROR_OPTION_NOT_SUPPORTED :
00181             return ERR_NOTSUPP;
00182             
00183         case RFAL_NFCV_ERROR_CMD_NOT_RECOGNIZED :
00184             return ERR_PROTO;
00185             
00186         case RFAL_NFCV_ERROR_WRITE_FAILED :
00187             return ERR_WRITE;
00188             
00189         default:
00190             return ERR_REQUEST;
00191     }
00192 }
00193 
00194 /*
00195 ******************************************************************************
00196 * GLOBAL FUNCTIONS
00197 ******************************************************************************
00198 */
00199 
00200 /*******************************************************************************/
00201 ReturnCode rfalNfcvPollerInitialize( 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 )
00202 {
00203     ReturnCode ret;
00204             
00205     EXIT_ON_ERR( ret, rfalSetMode( RFAL_MODE_POLL_NFCV , RFAL_BR_26p48 , RFAL_BR_26p48 , mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 )  );
00206     rfalSetErrorHandling( RFAL_ERRORHANDLING_NFC  );
00207     
00208     rfalSetGT( RFAL_GT_NFCV_ADJUSTED  );
00209     rfalSetFDTListen( RFAL_FDT_LISTEN_NFCV_POLLER  );
00210     rfalSetFDTPoll( RFAL_FDT_POLL_NFCV_POLLER  );
00211     
00212     return ERR_NONE;
00213 }
00214 
00215 /*******************************************************************************/
00216 ReturnCode rfalNfcvPollerCheckPresence( rfalNfcvInventoryRes  *invRes, 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 )
00217 {
00218     ReturnCode ret;
00219     
00220     /* INVENTORY_REQ with 1 slot and no Mask   Activity 2.0 (Candidate) 9.2.3.32 */
00221     ret = rfalNfcvPollerInventory( RFAL_NFCV_NUM_SLOTS_1 , 0, NULL, invRes, NULL, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00222     
00223     if( (ret == ERR_RF_COLLISION) || (ret == ERR_CRC)  || 
00224         (ret == ERR_FRAMING)      || (ret == ERR_PROTO)  )
00225     {
00226         ret = ERR_NONE;
00227     }
00228     
00229     return ret;
00230 }
00231 
00232 /*******************************************************************************/
00233 ReturnCode rfalNfcvPollerInventory( rfalNfcvNumSlots  nSlots, uint8_t maskLen, uint8_t *maskVal, rfalNfcvInventoryRes  *invRes, uint16_t* rcvdLen, 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 )
00234 {
00235     ReturnCode           ret;
00236     rfalNfcvInventoryReq invReq;
00237     uint16_t             rxLen;
00238     
00239     if( ((maskVal == NULL) && (maskLen != 0)) || (invRes == NULL) )
00240     {
00241         return ERR_PARAM;
00242     }
00243     
00244     invReq.INV_FLAG = (RFAL_NFCV_INV_REQ_FLAG | nSlots);
00245     invReq.CMD      = RFAL_NFCF_CMD_INVENTORY ;
00246     invReq.MASK_LEN = MIN( maskLen, ((nSlots == RFAL_NFCV_NUM_SLOTS_1 ) ? RFAL_NFCV_MASKVAL_MAX_1SLOT_LEN : RFAL_NFCV_MASKVAL_MAX_16SLOT_LEN) );   /* Digital 2.0  9.6.1.6 */
00247     ST_MEMCPY( invReq.MASK_VALUE, maskVal, rfalConvBitsToBytes(invReq.MASK_LEN) );
00248     
00249     ret = rfalISO15693TransceiveAnticollisionFrame( (uint8_t*)&invReq, (RFAL_NFCV_INV_REQ_HEADER_LEN + rfalConvBitsToBytes(invReq.MASK_LEN)), (uint8_t*)invRes, sizeof(rfalNfcvInventoryRes ), &rxLen, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00250     
00251     /* Check for optional output parameter */
00252     if( rcvdLen != NULL )
00253     {
00254         *rcvdLen = rxLen;
00255     }
00256     
00257     if( ret == ERR_NONE )
00258     {
00259         if( rxLen != rfalConvBytesToBits(RFAL_NFCV_INV_RES_LEN + RFAL_NFCV_CRC_LEN) )
00260         {
00261             return ERR_PROTO;
00262         }
00263     }
00264     
00265     return ret;
00266 }
00267 
00268 /*******************************************************************************/
00269 ReturnCode rfalNfcvPollerCollisionResolution( uint8_t devLimit, rfalNfcvListenDevice  *nfcvDevList, uint8_t *devCnt, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00270 {
00271     ReturnCode ret;
00272     uint8_t           slotNum;
00273     uint16_t          rcvdLen;
00274     uint8_t           colIt;
00275     uint8_t           colCnt;
00276    /* bool              colPending; */
00277     rfalNfcvCollision colFound[RFAL_NFCV_MAX_COLL_SUPPORTED];
00278     
00279    /* NO_WARNING(colPending); */
00280     
00281     if( (nfcvDevList == NULL) || (devCnt == NULL) )
00282     {
00283         return ERR_PARAM;
00284     }
00285     
00286     /* Initialize parameters */
00287     *devCnt = 0;
00288     colIt         = 0;
00289     colCnt        = 0;
00290    /* colPending    = false; */
00291     ST_MEMSET(nfcvDevList, 0x00, (sizeof(rfalNfcvListenDevice )*devLimit) );
00292     ST_MEMSET(colFound, 0x00, (sizeof(rfalNfcvCollision)*RFAL_NFCV_MAX_COLL_SUPPORTED) );
00293     
00294     
00295     /* Send INVENTORY_REQ with one slot   Activity 2.0  9.3.7.1  (Symbol 0)  */
00296     ret = rfalNfcvPollerInventory( RFAL_NFCV_NUM_SLOTS_1 , 0, NULL, &nfcvDevList->InvRes , NULL, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00297     
00298     if( ret == ERR_TIMEOUT )    /* Exit if no device found     Activity 2.0  9.3.7.2 (Symbol 1)  */
00299     {
00300         return ERR_NONE;
00301     }
00302     if( ret == ERR_NONE )  /* Device found without transmission error/collision    Activity 2.0  9.3.7.3 (Symbol 2)  */
00303     {
00304         (*devCnt)++;
00305         return ERR_NONE;
00306     }
00307     
00308     /* A Collision has been identified  Activity 2.0  9.3.7.2  (Symbol 3) */
00309    /* colPending = true; */ 
00310     
00311     /* Check if the Collision Resolution is set to perform only Collision detection   Activity 2.0  9.3.7.5 (Symbol 4)*/
00312     if( devLimit == 0 )
00313     {
00314         return ERR_RF_COLLISION;
00315     }
00316     
00317     
00318     /*******************************************************************************/
00319     /* Collisions pending, Anticollision loop must be executed                     */
00320     /*******************************************************************************/
00321     
00322     /* Execute until all collisions are resolved Activity 2.0  9.3.7.16  (Symbol 17) */
00323     do
00324     {
00325         /* Activity 2.0  9.3.7.5  (Symbol 6) */
00326         slotNum    = 0;
00327        /* colPending = false; */
00328         
00329         
00330         /* Send INVENTORY_REQ with 16 slots   Activity 2.0  9.3.7.7  (Symbol 8) */
00331         ret = rfalNfcvPollerInventory( RFAL_NFCV_NUM_SLOTS_16 , colFound[colIt].maskLen, colFound[colIt].maskVal, &nfcvDevList[(*devCnt)].InvRes, &rcvdLen, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00332         
00333         /* If collision have already been found, move to next one */
00334         if( colCnt > 0 )
00335         {
00336             colIt++;
00337         }
00338         
00339         do
00340         {
00341             /*******************************************************************************/
00342             if( ret != ERR_TIMEOUT )
00343             {
00344                 if( ret == ERR_NONE )
00345                 {
00346                     /* Check if the device found is already on the list and its response is a valid INVENTORY_RES */
00347                     if( rcvdLen == rfalConvBytesToBits(RFAL_NFCV_INV_RES_LEN + RFAL_NFCV_CRC_LEN) )
00348                     {
00349                         /* Activity 2.0  9.3.7.15  (Symbol 16) */
00350                         (*devCnt)++;
00351                     }
00352                 }
00353                 /*******************************************************************************/
00354                 else if(ret == ERR_RF_COLLISION)
00355                 {
00356                     /* Activity 2.0  9.3.7.15  (Symbol 16) */
00357                   /* colPending = true; */
00358                     
00359                     /* Ensure that the frame received has at least the FLAGS + DSFI */
00360                     if( rcvdLen <= rfalConvBytesToBits( RFAL_NFCV_FLAG_LEN + RFAL_NFCV_DSFI_LEN ) )
00361                     {
00362                         return ERR_RF_COLLISION;
00363                     }
00364 
00365                     /*******************************************************************************/
00366                     /* Ensure that this collision still fits on the container */
00367                     if( colCnt < RFAL_NFCV_MAX_COLL_SUPPORTED )
00368                     {
00369                         /* Store this collision on the container to be resolved later */
00370                         colFound[colCnt].maskLen = ( rcvdLen - rfalConvBytesToBits( RFAL_NFCV_FLAG_LEN + RFAL_NFCV_DSFI_LEN ) );
00371                         ST_MEMCPY(colFound[colCnt].maskVal, nfcvDevList[(*devCnt)].InvRes.UID, RFAL_NFCV_UID_LEN);
00372                         colCnt++;
00373                     }
00374                 }
00375             }
00376             
00377             /* Check if devices found have reached device limit   Activity 2.0  9.3.7.15  (Symbol 16) */
00378             if( *devCnt >= devLimit )
00379             {
00380                 return ERR_NONE;
00381             }
00382             
00383             platformDelay(RFAL_NFCV_FDT_EOF); /* Fulfil FDT EOF */
00384             ret = rfalISO15693TransceiveAnticollisionEOF( (uint8_t*)&nfcvDevList[(*devCnt)].InvRes, sizeof(rfalNfcvInventoryRes ), &rcvdLen, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00385             slotNum++;
00386             
00387         }
00388         while( slotNum < RFAL_NFCV_MAX_SLOTS );  /* Slot loop             */
00389     }while( colIt < colCnt );                    /* Collisions found loop */
00390     
00391     return ERR_NONE;
00392 }
00393 
00394 /*******************************************************************************/
00395 ReturnCode rfalNfvPollerSleep( uint8_t flags, uint8_t* uid, 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 )
00396 {
00397     ReturnCode      ret;
00398     rfalNfcvSlpvReq slpReq;
00399     uint8_t         rxBuf;    /* dummy buffer, just to perform Rx */
00400     
00401     if( uid == NULL )
00402     {
00403         return ERR_PARAM;
00404     }
00405     
00406     /* Compute SLPV_REQ */
00407     slpReq.REQ_FLAG = (flags | RFAL_NFCV_REQ_FLAG_ADDRESS );   /* Should be with UID according Digital 2.0 (Candidate) 9.7.1.1 */
00408     slpReq.CMD      = RFAL_NFCF_CMD_SLPV ;
00409     ST_MEMCPY( slpReq.UID, uid, RFAL_NFCV_UID_LEN );
00410     
00411     /* NFC Forum device SHALL wait at least FDTVpp to consider the SLPV acknowledged (FDTVpp = FDTVpoll)  Digital 2.0 (Candidate)  9.7  9.8.2  */
00412     ret = rfalTransceiveBlockingTxRx( (uint8_t*)&slpReq, sizeof(rfalNfcvSlpvReq), &rxBuf, sizeof(rxBuf), NULL, RFAL_TXRX_FLAGS_DEFAULT, RFAL_FDT_POLL_NFCV_POLLER , mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00413     if( ret != ERR_TIMEOUT )
00414     {
00415         return ret;
00416     }
00417     
00418     return ERR_NONE;
00419 }
00420 
00421 /*******************************************************************************/
00422 ReturnCode rfalNfvSelect( uint8_t flags, uint8_t* uid, 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 )
00423 {
00424     uint16_t           rcvLen;
00425     ReturnCode         ret;
00426     rfalNfcvGenericReq req;
00427     rfalNfcvGenericRes res;
00428 
00429     if( uid == NULL )
00430     {
00431         return ERR_PARAM;
00432     }
00433     
00434     /* Compute Request Command */
00435     req.REQ_FLAG = (flags | RFAL_NFCV_REQ_FLAG_ADDRESS );
00436     req.CMD      = RFAL_NFCF_CMD_SELECT ;
00437     ST_MEMCPY( req.payload.UID, uid, RFAL_NFCV_UID_LEN );
00438     
00439     ret = rfalTransceiveBlockingTxRx( (uint8_t*)&req, (RFAL_CMD_LEN + RFAL_NFCV_FLAG_LEN + RFAL_NFCV_UID_LEN), (uint8_t*)&res, sizeof(rfalNfcvGenericRes), &rcvLen, RFAL_TXRX_FLAGS_DEFAULT, RFAL_FDT_POLL_MAX, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00440     if( ret != ERR_NONE )
00441     {
00442         return ret;
00443     }
00444     
00445     /* Check if the response minimum length has been received */
00446     if( rcvLen < RFAL_NFCV_FLAG_LEN )
00447     {
00448         return ERR_PROTO;
00449     }
00450     
00451     /* Check if an error has been signalled */
00452     if( res.RES_FLAG & RFAL_NFCV_RES_FLAG_ERROR  )
00453     {
00454         return rfalNfvParseError( *res.data );
00455     }
00456     
00457     return ERR_NONE;
00458 }
00459 
00460 /*******************************************************************************/
00461 ReturnCode rfalNfvReadSingleBlock( uint8_t flags, uint8_t* uid, uint8_t blockNum, uint8_t* rxBuf, uint16_t rxBufLen, uint16_t *rcvLen, 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 )
00462 {
00463     ReturnCode         ret;
00464     rfalNfcvGenericReq req;
00465     rfalNfcvGenericRes *res;
00466     uint8_t            msgIt;
00467     
00468     msgIt = 0;
00469     res   = (rfalNfcvGenericRes*)rxBuf;
00470     
00471     /* Compute Request Command */
00472     req.REQ_FLAG  = (flags & (~RFAL_NFCV_REQ_FLAG_ADDRESS  & ~RFAL_NFCV_REQ_FLAG_SELECT ));
00473     req.CMD       = RFAL_NFCF_CMD_READ_SINGLE_BLOCK ;
00474     
00475     /* Check if request is to be sent in Addressed or Selected mode */
00476     if( uid != NULL )
00477     {
00478         req.REQ_FLAG |= RFAL_NFCV_REQ_FLAG_ADDRESS ;
00479         ST_MEMCPY( req.payload.UID, uid, RFAL_NFCV_UID_LEN );
00480         msgIt += RFAL_NFCV_UID_LEN;
00481         req.payload.data[ (RFAL_NFCV_UID_LEN + msgIt++) ] = blockNum;
00482     }
00483     else
00484     {
00485         req.REQ_FLAG |= RFAL_NFCV_REQ_FLAG_SELECT ;
00486         req.payload.data[msgIt++] = blockNum;
00487     }
00488     
00489     /* Transceive Command */
00490     ret = rfalTransceiveBlockingTxRx( (uint8_t*)&req, (RFAL_CMD_LEN + RFAL_NFCV_FLAG_LEN + msgIt), rxBuf, rxBufLen, rcvLen, RFAL_TXRX_FLAGS_DEFAULT, RFAL_FDT_POLL_MAX, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00491     if( ret != ERR_NONE )
00492     {
00493         return ret;
00494     }
00495     
00496     /* Check if the response minimum length has been received */
00497     if( (*rcvLen) < RFAL_NFCV_FLAG_LEN )
00498     {
00499         return ERR_PROTO;
00500     }
00501     
00502     /* Check if an error has been signalled */
00503     if( res->RES_FLAG & RFAL_NFCV_RES_FLAG_ERROR  )
00504     {
00505         return rfalNfvParseError( *(res->data) );
00506     }
00507     
00508     return ERR_NONE;
00509 }
00510 
00511 /*******************************************************************************/
00512 ReturnCode rfalNfvWriteSingleBlock( uint8_t flags, uint8_t* uid, uint8_t blockNum, uint8_t* wrData, uint8_t blockLen, 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 )
00513 {
00514     ReturnCode         ret;
00515     uint16_t           rcvLen;
00516     rfalNfcvGenericReq req;
00517     rfalNfcvGenericRes res;
00518     uint8_t            msgIt;
00519 
00520     if( blockLen > RFAL_NFCV_MAX_BLOCK_LEN )
00521     {
00522         return ERR_PARAM;
00523     }
00524     
00525     msgIt = 0;
00526     
00527     /* Compute Request Command */
00528     req.REQ_FLAG  = (flags & (~RFAL_NFCV_REQ_FLAG_ADDRESS  & ~RFAL_NFCV_REQ_FLAG_SELECT ));
00529     req.CMD       = RFAL_NFCF_CMD_WRITE_SINGLE_BLOCK ;
00530     
00531     /* Check if request is to be sent in Addressed or Selected mode */
00532     if( uid != NULL )
00533     {
00534         req.REQ_FLAG |= RFAL_NFCV_REQ_FLAG_ADDRESS ;
00535         ST_MEMCPY( req.payload.UID, uid, RFAL_NFCV_UID_LEN );
00536         msgIt += RFAL_NFCV_UID_LEN;
00537         req.payload.data[msgIt++] = blockNum;
00538         ST_MEMCPY( &req.payload.data[msgIt], wrData, blockLen );
00539         msgIt += blockLen;
00540     }
00541     else
00542     {
00543         req.REQ_FLAG |= RFAL_NFCV_REQ_FLAG_SELECT ;
00544         req.payload.data[msgIt++] = blockNum;
00545         ST_MEMCPY( &req.payload.data[msgIt], wrData, blockLen );
00546         msgIt += blockLen;
00547     }
00548     
00549     /* Transceive Command */
00550     ret = rfalTransceiveBlockingTxRx( (uint8_t*)&req, (RFAL_CMD_LEN + RFAL_NFCV_FLAG_LEN + msgIt), (uint8_t*)&res, sizeof(rfalNfcvGenericRes), &rcvLen, RFAL_TXRX_FLAGS_DEFAULT, RFAL_FDT_POLL_MAX, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00551     
00552     if( ret != ERR_NONE )
00553     {
00554         return ret;
00555     }
00556     
00557     /* Check if the response minimum length has been received */
00558     if( rcvLen < RFAL_NFCV_FLAG_LEN )
00559     {
00560         return ERR_PROTO;
00561     }
00562     
00563     /* Check if an error has been signalled */
00564     if( res.RES_FLAG & RFAL_NFCV_RES_FLAG_ERROR  )
00565     {
00566         return rfalNfvParseError( *res.data );
00567     }
00568     
00569     return ERR_NONE;
00570 }
00571 
00572 /*******************************************************************************/
00573 ReturnCode rfalNfvReadMultipleBlocks( uint8_t flags, uint8_t* uid, uint8_t firstBlockNum, uint8_t numOfBlocks, uint8_t* rxBuf, uint16_t rxBufLen, uint16_t *rcvLen, 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 )
00574 {
00575     ReturnCode          ret;
00576     rfalNfcvGenericReq  req;
00577     rfalNfcvGenericRes  *res;
00578     uint8_t             msgIt;
00579     
00580     msgIt = 0;
00581     res   = (rfalNfcvGenericRes*)rxBuf;
00582     
00583     /* Compute Request Command */
00584     req.REQ_FLAG  = (flags & (~RFAL_NFCV_REQ_FLAG_ADDRESS  & ~RFAL_NFCV_REQ_FLAG_SELECT ));
00585     req.CMD       = RFAL_NFCF_CMD_READ_MULTIPLE_BLOCKS ;
00586     
00587     /* Check if request is to be sent in Addressed or Selected mode */
00588     if( uid != NULL )
00589     {
00590         req.REQ_FLAG |= RFAL_NFCV_REQ_FLAG_ADDRESS ;
00591         ST_MEMCPY( req.payload.UID, uid, RFAL_NFCV_UID_LEN );
00592         msgIt += RFAL_NFCV_UID_LEN;
00593         req.payload.data[ (RFAL_NFCV_UID_LEN + msgIt++) ] = firstBlockNum;
00594         req.payload.data[ (RFAL_NFCV_UID_LEN + msgIt++) ] = numOfBlocks;
00595     }
00596     else
00597     {
00598         req.REQ_FLAG |= RFAL_NFCV_REQ_FLAG_SELECT ;
00599         req.payload.data[msgIt++] = firstBlockNum;
00600         req.payload.data[msgIt++] = numOfBlocks;
00601     }
00602     
00603     /* Transceive Command */
00604     ret = rfalTransceiveBlockingTxRx( (uint8_t*)&req, (RFAL_CMD_LEN + RFAL_NFCV_FLAG_LEN + msgIt), rxBuf, rxBufLen, rcvLen, RFAL_TXRX_FLAGS_DEFAULT, RFAL_FDT_POLL_MAX, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00605     if( ret != ERR_NONE )
00606     {
00607         return ret;
00608     }
00609     
00610     /* Check if the response minimum length has been received */
00611     if( (*rcvLen) < RFAL_NFCV_FLAG_LEN )
00612     {
00613         return ERR_PROTO;
00614     }
00615     
00616     /* Check if an error has been signalled */
00617     if( res->RES_FLAG & RFAL_NFCV_RES_FLAG_ERROR  )
00618     {
00619         return rfalNfvParseError( *(res->data) );
00620     }
00621     
00622     return ERR_NONE;
00623 }
00624 
00625 #endif /* RFAL_FEATURE_NFCV */