Functions for accessing M24SR device.

Dependents:   Nucleo_NFC_Example I2C_NFC_Master Print_Entire_Nucleo_NFC01A1_Memory

Fork of lib_M24SR by Enrico Gregoratto

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers m24sr.c Source File

m24sr.c

00001 /**
00002   ******************************************************************************
00003   * @file    drv_M24SR.c
00004   * @author  MMY Application Team
00005   * @version V1.1.0
00006   * @date    20-October-2014
00007   * @brief   This file provides a set of functions to interface with the M24SR
00008   *          device.
00009   ******************************************************************************
00010   * @attention
00011   *
00012   * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
00013   *
00014   * Redistribution and use in source and binary forms, with or without modification,
00015   * are permitted provided that the following conditions are met:
00016   *   1. Redistributions of source code must retain the above copyright notice,
00017   *      this list of conditions and the following disclaimer.
00018   *   2. Redistributions in binary form must reproduce the above copyright notice,
00019   *      this list of conditions and the following disclaimer in the documentation
00020   *      and/or other materials provided with the distribution.
00021   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00022   *      may be used to endorse or promote products derived from this software
00023   *      without specific prior written permission.
00024   *
00025   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00026   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00028   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00029   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00031   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00032   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00033   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00034   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035   *
00036   ******************************************************************************
00037   */
00038 
00039 /* Includes ------------------------------------------------------------------*/
00040 #include "m24sr.h"
00041 
00042 /** @addtogroup M24SR_Driver
00043   * @{
00044   * @brief  <b>This folder contains the driver layer of M24SR family (M24SR64, M24SR16, M24SR04, M24SR02)</b> 
00045   */
00046 
00047 
00048 /** @addtogroup drv_M24SR
00049   * @{
00050     *   @brief  This file contains the driver which implements all the M24SR commands.
00051   */
00052 
00053 static C_APDU                           Command;
00054 //static R_APDU                         Response;
00055 static uint8_t                      DataBuffer[0xFF];
00056 uint8_t                                     uM24SRbuffer [0xFF];
00057 static uint8_t                      uDIDbyte =0x00;
00058 
00059 
00060 static uint16_t M24SR_UpdateCrc                         ( uint8_t ch, uint16_t *lpwCrc);
00061 static uint16_t M24SR_ComputeCrc                        ( uc8 *Data, uint8_t Length);
00062 static uint16_t M24SR_IsCorrectCRC16Residue ( uc8 *DataIn,uc8 Length);
00063 static void M24SR_InitStructure                         ( void );
00064 static void M24SR_BuildIBlockCommand                ( uc16 CommandStructure, C_APDU Command, uint16_t *NbByte , uint8_t *pCommand);
00065 static int8_t IsSBlock                                          (uc8 *pBuffer);
00066 #if 0
00067 static int8_t IsRBlock                                          (uc8 *pBuffer);
00068 static int8_t IsIBlock                                          (uc8 *pBuffer);
00069 #endif
00070 static uint16_t M24SR_FWTExtension                  ( uint8_t FWTbyte );
00071 
00072 /** @defgroup drvM24SR_Private_Functions
00073   * @{
00074   */ 
00075     
00076     /**
00077   * @brief  This function updates the CRC 
00078   * @param  None
00079   * @retval None
00080   */
00081 static uint16_t M24SR_UpdateCrc (uint8_t ch, uint16_t *lpwCrc)
00082 {
00083   ch = (ch^(uint8_t)((*lpwCrc) & 0x00FF));
00084   ch = (ch^(ch<<4));
00085   *lpwCrc = (*lpwCrc >> 8)^((uint16_t)ch << 8)^((uint16_t)ch<<3)^((uint16_t)ch>>4);
00086     
00087   return(*lpwCrc);
00088 }
00089 
00090 /**
00091   * @brief  This function returns the CRC 16 
00092   * @param  Data : pointer on the data used to compute the CRC16
00093   * @param  Length : number of byte of the data
00094   * @retval CRC16 
00095   */
00096 static uint16_t M24SR_ComputeCrc(uc8 *Data, uint8_t Length)
00097 {
00098   uint8_t chBlock;
00099   uint16_t wCrc;
00100   
00101   wCrc = 0x6363; // ITU-V.41
00102   
00103   do {
00104     chBlock = *Data++;
00105     M24SR_UpdateCrc(chBlock, &wCrc);
00106   } while (--Length);
00107   
00108   return wCrc ;
00109 }
00110 
00111 
00112 /**  
00113 * @brief    This function computes the CRC16 residue as defined by CRC ISO/IEC 13239
00114 * @param    DataIn      :   input to data 
00115 * @param        Length      :   Number of bits of DataIn
00116 * @retval   Status (SW1&SW2)    :   CRC16 residue is correct    
00117 * @retval   M24SR_ERROR_CRC     :  CRC16 residue is false
00118 */
00119 static uint16_t M24SR_IsCorrectCRC16Residue (uc8 *DataIn,uc8 Length)
00120 {
00121   uint16_t ResCRC=0;
00122   
00123     /* check the CRC16 Residue */
00124     if (Length !=0)
00125         ResCRC= M24SR_ComputeCrc (DataIn, Length);
00126     
00127     if ( ResCRC == 0x0000)
00128     {
00129         /* Good CRC, but error status from M24SR */
00130     return( ((DataIn[Length-UB_STATUS_OFFSET]<<8) & 0xFF00) | (DataIn[Length-LB_STATUS_OFFSET] & 0x00FF) ); 
00131     }
00132     else
00133     {
00134         ResCRC=0;
00135         ResCRC= M24SR_ComputeCrc (DataIn, 5);
00136         if ( ResCRC != 0x0000)
00137         {
00138             /* Bad CRC */
00139             return M24SR_ERROR_CRC;
00140         }
00141         else
00142         {
00143             /* Good CRC, but error status from M24SR */
00144             return( ((DataIn[1]<<8) & 0xFF00) | (DataIn[2] & 0x00FF) ); 
00145         }
00146     }   
00147 }
00148 
00149 /**
00150   * @brief  Initialize the command and response structure 
00151   * @param  None
00152   * @retval None
00153   */
00154 static void M24SR_InitStructure ( void )
00155 {
00156     /* build the command */
00157     Command.Header.CLA = 0x00;
00158     Command.Header.INS = 0x00;
00159     /* copy the offset */
00160     Command.Header.P1 = 0x00 ;
00161     Command.Header.P2 = 0x00 ;
00162     /* copy the number of byte of the data field */
00163     Command.Body.LC = 0x00 ;
00164     /* copy the number of byte to read */
00165     Command.Body.LE = 0x00 ;
00166     Command.Body.pData = DataBuffer; 
00167     
00168   //    /* initializes the response structure*/
00169   //    Response.pData = DataBuffer; 
00170   //    Response.SW1 = 0x00;
00171   //    Response.SW2 = 0x00;
00172 }
00173 
00174 /**
00175   * @brief      This functions creates an I block command according to the structures CommandStructure and Command. 
00176     * @param        Command : structue which contains the field of the different parameter
00177     * @param        CommandStructure : structure that contain the structure of the command (if the different field are presnet or not 
00178     * @param        NbByte : number of byte of the command
00179     * @param        pCommand : pointer of the command created
00180   */
00181 static void M24SR_BuildIBlockCommand ( uc16 CommandStructure, C_APDU Command, uint16_t *NbByte , uint8_t *pCommand)
00182 {
00183     uint16_t    uCRC16; 
00184     static uint8_t BlockNumber = 0x01;
00185     
00186     (*NbByte) = 0;
00187     
00188     /* add the PCD byte */
00189     if ((CommandStructure & M24SR_PCB_NEEDED) !=0)
00190     {
00191         /* toggle the block number */
00192         BlockNumber = TOGGLE ( BlockNumber );
00193         /* Add the I block byte */
00194         pCommand[(*NbByte)++] = 0x02 |  BlockNumber; 
00195     }
00196     
00197     /* add the DID byte */
00198     if ((BlockNumber & M24SR_DID_NEEDED) !=0)
00199     {
00200         /* Add the I block byte */
00201         pCommand[(*NbByte)++] = uDIDbyte; 
00202     }
00203     
00204     /* add the Class byte */
00205     if ((CommandStructure & M24SR_CLA_NEEDED) !=0)
00206     {
00207         pCommand[(*NbByte)++] = Command.Header.CLA ;
00208     }
00209     /* add the instruction byte byte */
00210     if ( (CommandStructure & M24SR_INS_NEEDED) !=0)
00211     {
00212         pCommand[(*NbByte)++] = Command.Header.INS ;
00213     }
00214     /* add the Selection Mode byte */
00215     if ((CommandStructure & M24SR_P1_NEEDED) !=0)
00216     {
00217         pCommand[(*NbByte)++] = Command.Header.P1 ;
00218     }
00219     /* add the Selection Mode byte */
00220     if ((CommandStructure & M24SR_P2_NEEDED) !=0)
00221     {
00222         pCommand[(*NbByte)++] = Command.Header.P2 ;
00223     }
00224     /* add Data field lengthbyte */
00225     if ((CommandStructure & M24SR_LC_NEEDED) !=0)
00226     {
00227         pCommand[(*NbByte)++] = Command.Body.LC ;
00228     }
00229     /* add Data field  */
00230     if ((CommandStructure & M24SR_DATA_NEEDED) !=0)
00231     {
00232         memcpy(&(pCommand[(*NbByte)]) ,Command.Body.pData,Command.Body.LC ) ;
00233         (*NbByte) += Command.Body.LC ;
00234     }
00235     /* add Le field  */
00236     if ((CommandStructure & M24SR_LE_NEEDED) !=0)
00237     {
00238         pCommand[(*NbByte)++] = Command.Body.LE ;
00239     }
00240     /* add CRC field  */
00241     if ((CommandStructure & M24SR_CRC_NEEDED) !=0)
00242     {
00243         uCRC16 = M24SR_ComputeCrc (pCommand,(uint8_t) (*NbByte));
00244         /* append the CRC16 */
00245         pCommand [(*NbByte)++] = GETLSB (uCRC16 ) ;
00246         pCommand [(*NbByte)++] = GETMSB (uCRC16 ) ; 
00247     }
00248   
00249 }
00250 
00251 #if 0
00252 /**  
00253 * @brief    This function return M24SR_STATUS_SUCCESS if the pBuffer is an I-block
00254 * @param    pBuffer     :   pointer of the data
00255 * @retval   M24SR_STATUS_SUCCESS  :  the data is a I-Block
00256 * @retval   M24SR_ERROR_DEFAULT     :  the data is not a I-Block
00257 */
00258 static int8_t IsIBlock (uc8 *pBuffer)
00259 {
00260   
00261     if ((pBuffer[M24SR_OFFSET_PCB] & M24SR_MASK_BLOCK) == M24SR_MASK_IBLOCK)
00262     {
00263         return M24SR_STATUS_SUCCESS;
00264     }
00265     else 
00266     {   
00267         return M24SR_ERROR_DEFAULT;
00268     }
00269     
00270 }
00271 
00272 /**  
00273 * @brief    This function return M24SR_STATUS_SUCCESS if the pBuffer is an R-block
00274 * @param    pBuffer     :   pointer of the data
00275 * @retval   M24SR_STATUS_SUCCESS  :  the data is a R-Block
00276 * @retval   M24SR_ERROR_DEFAULT     :  the data is not a R-Block
00277 */
00278 static int8_t IsRBlock (uc8 *pBuffer)
00279 {
00280   
00281     if ((pBuffer[M24SR_OFFSET_PCB] & M24SR_MASK_BLOCK) == M24SR_MASK_RBLOCK)
00282     {
00283         return M24SR_STATUS_SUCCESS;
00284     }
00285     else 
00286     {   
00287         return M24SR_ERROR_DEFAULT;
00288     }
00289     
00290 }
00291 #endif  
00292     
00293 /**  
00294 * @brief    This function return M24SR_STATUS_SUCCESS if the pBuffer is an s-block
00295 * @param    pBuffer     :   pointer of the data
00296 * @retval   M24SR_STATUS_SUCCESS  :  the data is a S-Block
00297 * @retval   M24SR_ERROR_DEFAULT     :  the data is not a S-Block
00298 */
00299 static int8_t IsSBlock (uc8 *pBuffer)
00300 {
00301   
00302     if ((pBuffer[M24SR_OFFSET_PCB] & M24SR_MASK_BLOCK) == M24SR_MASK_SBLOCK)
00303     {
00304         return M24SR_STATUS_SUCCESS;
00305     }
00306     else 
00307     {   
00308         return M24SR_ERROR_DEFAULT;
00309     }
00310     
00311 }
00312 
00313 /**
00314   * @brief  This function sends the FWT extension command (S-Block format)
00315     * @param    FWTbyte : FWT value
00316   * @retval Status (SW1&SW2) : Status of the operation to complete.
00317     * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
00318   */
00319 static uint16_t M24SR_FWTExtension ( uint8_t FWTbyte )
00320 {
00321   uint8_t   pBuffer[M24SR_STATUSRESPONSE_NBBYTE];
00322   uint16_t      status ; 
00323   uint16_t  NthByte = 0,
00324   uCRC16;
00325   
00326     /* create the response */
00327     pBuffer[NthByte++] = 0xF2 ; 
00328     pBuffer[NthByte++] = FWTbyte ;
00329     /* compute the CRC */
00330     uCRC16 = M24SR_ComputeCrc (pBuffer,0x02);
00331     /* append the CRC16 */
00332     pBuffer [NthByte++] = GETLSB    (uCRC16 ) ;
00333     pBuffer [NthByte++]=    GETMSB  (uCRC16 ) ; 
00334     
00335     /* send the request */ 
00336     errchk( M24SR_SendI2Ccommand ( NthByte , pBuffer ));
00337     errchk( M24SR_IsAnswerReady ( ));
00338     /* read the response */ 
00339     errchk( M24SR_ReceiveI2Cresponse ( M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
00340     
00341     status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE); 
00342     return status;
00343     
00344 Error :
00345     return M24SR_ERROR_I2CTIMEOUT;
00346 }
00347 
00348 /**
00349   * @}
00350   */
00351 
00352 
00353 /** @defgroup drvM24SR_Public_Functions
00354   * @{
00355   */ 
00356 
00357 /**
00358   * @brief  This function initialize the M24SR device
00359   * @retval None 
00360   */
00361 void M24SR_Init( void )
00362 {       
00363     M24SR_I2CInit();
00364     // M24SR_GPOInit(); // Empty function
00365     
00366     M24SR_InitStructure();
00367   
00368 #if defined (I2C_GPO_SYNCHRO_ALLOWED) || defined (I2C_GPO_INTERRUPT_ALLOWED)
00369     if( M24SR_KillSession() == M24SR_ACTION_COMPLETED)
00370     {
00371     M24SR_ManageI2CGPO(I2C_ANSWER_READY);
00372       M24SR_Deselect ();
00373     } 
00374 #endif /* I2C_GPO_SYNCHRO_ALLOWED */
00375 }
00376 
00377 /**
00378   * @brief  This function sends the GetSession command to the M24SR device
00379     * @retval M24SR_ACTION_COMPLETED : the function is succesful.
00380   * @retval Status (SW1&SW2) : if operation does not complete.
00381   */
00382 uint16_t M24SR_GetSession ( void )
00383 {
00384     uint8_t Buffer = M24SR_OPENSESSION;
00385     int16_t     status;
00386   
00387     errchk(M24SR_SendI2Ccommand ( 0x01 , &Buffer ));
00388     
00389     /* Insure no access will be done just after open session */ 
00390     /* The only way here is to poll I2C to know when M24SR is ready */
00391     /* GPO can not be use with GetSession command */
00392     errchk(M24SR_PollI2C ( )); 
00393   
00394     return M24SR_ACTION_COMPLETED;
00395 Error :
00396     return M24SR_ERROR_I2CTIMEOUT;  
00397 }
00398 
00399 
00400 
00401 /**
00402   * @brief  This function sends the KillSession command to the M24SR device
00403   * @param  None
00404     * @retval M24SR_ACTION_COMPLETED : the function is succesful. 
00405     * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
00406   */
00407 uint16_t M24SR_KillSession ( void )
00408 {
00409     uint8_t pBuffer[] = {M24SR_KILLSESSION};
00410     int8_t  status;
00411   
00412     errchk(M24SR_SendI2Ccommand ( 0x01 , pBuffer ));
00413   
00414     /* Insure no access will be done just after open session */ 
00415     /* The only way here is to poll I2C to know when M24SR is ready */
00416     /* GPO can not be use with KillSession command */
00417     errchk(M24SR_PollI2C ( ));  
00418     
00419     return M24SR_ACTION_COMPLETED;
00420 Error :
00421     return M24SR_ERROR_I2CTIMEOUT;
00422 }
00423 
00424 
00425 /**
00426   * @brief  This function sends the Deselect command (S-Block format)
00427     * @retval M24SR_ACTION_COMPLETED : the function is succesful. 
00428     * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured. 
00429   */
00430 uint16_t M24SR_Deselect ( void )
00431 {
00432   uint8_t   pBuffer[] = {0xC2,0xE0,0xB4} ;
00433     int8_t      status ; 
00434     
00435     /* send the request */ 
00436     errchk( M24SR_SendI2Ccommand ( M24SR_DESELECTREQUEST_NBBYTE , pBuffer ));
00437     
00438     errchk( M24SR_IsAnswerReady ( ));   
00439     /* flush the M24SR buffer */ 
00440     errchk( M24SR_ReceiveI2Cresponse ( M24SR_DESELECTREQUEST_NBBYTE , pBuffer ));
00441     
00442     return M24SR_ACTION_COMPLETED;
00443   
00444 Error :
00445     return M24SR_ERROR_I2CTIMEOUT;
00446 }
00447 
00448 
00449 
00450 
00451 /**
00452   * @brief  This function sends the SelectApplication command
00453     * @retval M24SR_ACTION_COMPLETED : the function is succesful. 
00454     * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
00455   */
00456 uint16_t M24SR_SelectApplication ( void )
00457 {
00458   uint8_t   *pBuffer = uM24SRbuffer ,
00459   NbByteToRead = M24SR_STATUSRESPONSE_NBBYTE;
00460   uint8_t       uLc = 0x07,
00461   pData[] = {0xD2,0x76,0x00,0x00,0x85,0x01,0x01},
00462   uLe = 0x00;
00463   uint16_t  status ; 
00464   uint16_t  uP1P2 =0x0400,
00465   NbByte;
00466     
00467     /* build the command */
00468     Command.Header.CLA = C_APDU_CLA_DEFAULT;
00469     Command.Header.INS = C_APDU_SELECT_FILE;
00470     /* copy the offset */
00471     Command.Header.P1 = GETMSB  (uP1P2 ) ;
00472     Command.Header.P2 = GETLSB  (uP1P2 ) ;
00473     /* copy the number of byte of the data field */
00474     Command.Body.LC = uLc ;
00475     /* copy the data */
00476     memcpy(Command.Body.pData, pData, uLc);
00477     /* copy the number of byte to read */
00478     Command.Body.LE = uLe ;
00479     /* build the I￿C command */
00480     M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_SELECTAPPLICATION,  Command, &NbByte , pBuffer);
00481     
00482     /* send the request */ 
00483     errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer ));
00484     errchk( M24SR_IsAnswerReady ( ));   
00485     /* read the response */ 
00486     errchk( M24SR_ReceiveI2Cresponse ( NbByteToRead , pBuffer ));
00487     
00488     status = M24SR_IsCorrectCRC16Residue (pBuffer,NbByteToRead); 
00489     return status;
00490     
00491 Error :
00492     return M24SR_ERROR_I2CTIMEOUT;
00493 }
00494 
00495 /**
00496   * @brief  This function sends the SelectCCFile command
00497     * @retval M24SR_ACTION_COMPLETED : the function is succesful. 
00498     * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
00499   * @retval Status (SW1&SW2) : if operation does not complete for another reason.
00500   */
00501 uint16_t M24SR_SelectCCfile ( void )
00502 {
00503   uint8_t   *pBuffer = uM24SRbuffer ,
00504   NbByteToRead = M24SR_STATUSRESPONSE_NBBYTE;
00505   uint8_t       uLc = 0x02;
00506   uint16_t  status ; 
00507   uint16_t  uP1P2 =0x000C,
00508   uNbFileId =CC_FILE_ID,
00509   NbByte;
00510     
00511     /* build the command */
00512     Command.Header.CLA = C_APDU_CLA_DEFAULT;
00513     Command.Header.INS = C_APDU_SELECT_FILE;
00514     /* copy the offset */
00515     Command.Header.P1 = GETMSB  (uP1P2 ) ;
00516     Command.Header.P2 = GETLSB  (uP1P2 ) ;
00517     /* copy the number of byte of the data field */
00518     Command.Body.LC = uLc ;
00519     /* copy the File Id */
00520     Command.Body.pData[0] = GETMSB  (uNbFileId ) ;
00521     Command.Body.pData[1] = GETLSB  (uNbFileId ) ;
00522     /* build the I￿C command */
00523     M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_SELECTCCFILE,  Command, &NbByte , pBuffer);
00524     
00525     /* send the request */ 
00526     errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer ));
00527     errchk( M24SR_IsAnswerReady ( ));
00528     /* read the response */ 
00529     errchk( M24SR_ReceiveI2Cresponse ( NbByteToRead , pBuffer ));
00530     
00531     status = M24SR_IsCorrectCRC16Residue (pBuffer,NbByteToRead); 
00532     return status; 
00533     
00534 Error :
00535     return M24SR_ERROR_I2CTIMEOUT;
00536 }
00537 
00538 
00539 /**
00540   * @brief  This function sends the SelectSystemFile command
00541   * @retval Status (SW1&SW2) : Status of the operation to complete.
00542     * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
00543   */
00544 uint16_t M24SR_SelectSystemfile ( void )
00545 {
00546   uint8_t   *pBuffer = uM24SRbuffer ,
00547   NbByteToRead = M24SR_STATUSRESPONSE_NBBYTE;
00548   uint8_t       uLc = 0x02;
00549   uint16_t  status ; 
00550   uint16_t  uP1P2 =0x000C,
00551   uNbFileId =SYSTEM_FILE_ID,
00552   NbByte;
00553     
00554     /* build the command */
00555     Command.Header.CLA = C_APDU_CLA_DEFAULT;
00556     Command.Header.INS = C_APDU_SELECT_FILE;
00557     /* copy the offset */
00558     Command.Header.P1 = GETMSB  (uP1P2 ) ;
00559     Command.Header.P2 = GETLSB  (uP1P2 ) ;
00560     /* copy the number of byte of the data field */
00561     Command.Body.LC = uLc ;
00562     /* copy the File Id */
00563     Command.Body.pData[0] = GETMSB  (uNbFileId ) ;
00564     Command.Body.pData[1] = GETLSB  (uNbFileId ) ;
00565     /* build the I￿C command */
00566     M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_SELECTCCFILE,  Command, &NbByte , pBuffer);
00567     
00568     /* send the request */ 
00569     errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer ));
00570     errchk( M24SR_IsAnswerReady ( ));
00571     /* read the response */ 
00572     errchk( M24SR_ReceiveI2Cresponse ( NbByteToRead , pBuffer ));
00573     
00574     status = M24SR_IsCorrectCRC16Residue (pBuffer,NbByteToRead); 
00575     return status;
00576   
00577 Error :
00578     return M24SR_ERROR_I2CTIMEOUT;
00579 }
00580 
00581 /**
00582   * @brief  This function sends the SelectNDEFfile command
00583   * @retval Status (SW1&SW2) : Status of the operation to complete.
00584     * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
00585   */
00586 uint16_t M24SR_SelectNDEFfile ( uc16 NDEFfileId )
00587 {
00588   uint8_t   *pBuffer = uM24SRbuffer ,
00589   NbByteToRead = M24SR_STATUSRESPONSE_NBBYTE;
00590   uint8_t       uLc = 0x02;
00591   uint16_t  status ; 
00592   uint16_t  uP1P2 =0x000C,
00593   NbByte;
00594     
00595     /* build the command */
00596     Command.Header.CLA = C_APDU_CLA_DEFAULT;
00597     Command.Header.INS = C_APDU_SELECT_FILE;
00598     /* copy the offset */
00599     Command.Header.P1 = GETMSB  (uP1P2 ) ;
00600     Command.Header.P2 = GETLSB  (uP1P2 ) ;
00601     /* copy the number of byte of the data field */
00602     Command.Body.LC = uLc ;
00603     /* copy the offset */
00604     Command.Body.pData[0] = GETMSB  (NDEFfileId ) ;
00605     Command.Body.pData[1] = GETLSB  (NDEFfileId ) ;
00606     /* build the I￿C command */
00607     M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_SELECTNDEFFILE,  Command, &NbByte , pBuffer);
00608     
00609     /* send the request */ 
00610     errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer ));
00611     errchk( M24SR_IsAnswerReady ( ));
00612     /* read the response */ 
00613     errchk( M24SR_ReceiveI2Cresponse ( NbByteToRead , pBuffer ));
00614     
00615     status = M24SR_IsCorrectCRC16Residue (pBuffer,NbByteToRead); 
00616     return status;
00617     
00618 Error :
00619     return M24SR_ERROR_I2CTIMEOUT;
00620     
00621 }
00622 
00623 /**
00624   * @brief  This function sends a read binary command
00625     * @param    Offset : first byte to read
00626     * @param    NbByteToRead : number of byte to read
00627     * @param    pBufferRead : pointer of the buffer read from the M24SR device
00628   * @retval Status (SW1&SW2) : Status of the operation to complete.
00629     * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
00630   */
00631 uint16_t M24SR_ReadBinary ( uc16 Offset ,uc8 NbByteToRead , uint8_t *pBufferRead )
00632 {
00633     uint8_t     *pBuffer = uM24SRbuffer ;
00634     uint16_t    status ; 
00635     uint16_t    NbByte;
00636     
00637     /* build the command */
00638     Command.Header.CLA = C_APDU_CLA_DEFAULT;
00639     Command.Header.INS = C_APDU_READ_BINARY;
00640     /* copy the offset */
00641     Command.Header.P1 = GETMSB  (Offset ) ;
00642     Command.Header.P2 = GETLSB  (Offset ) ;
00643     /* copy the number of byte to read */
00644     Command.Body.LE = NbByteToRead ;
00645   
00646     M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_READBINARY,  Command, &NbByte , pBuffer);
00647   
00648     errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer ));
00649     errchk( M24SR_IsAnswerReady ( ));
00650     errchk( M24SR_ReceiveI2Cresponse ( NbByteToRead + M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
00651     
00652     status = M24SR_IsCorrectCRC16Residue (pBuffer,NbByteToRead+ M24SR_STATUSRESPONSE_NBBYTE); 
00653     /* retrieve the data without SW1 & SW2 as provided as return value of the function */
00654     memcpy(pBufferRead ,&pBuffer[1],NbByteToRead);
00655     return status;
00656     
00657 Error :
00658     return M24SR_ERROR_I2CTIMEOUT;
00659     
00660 }
00661 
00662 
00663 
00664 /**
00665   * @brief  This function sends a ST read binary command (no error if access is not inside NDEF file)
00666     * @param    Offset : first byte to read
00667     * @param    NbByteToRead : number of byte to read
00668     * @param    pBufferRead : pointer of the buffer read from the M24SR device
00669   * @retval Status (SW1&SW2) : Status of the operation to complete.
00670     * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured. 
00671   */
00672 uint16_t M24SR_STReadBinary ( uc16 Offset, uc8 NbByteToRead, uint8_t *pBufferRead )
00673 {
00674   uint8_t   *pBuffer = uM24SRbuffer ;
00675   uint16_t  status ; 
00676   uint16_t  NbByte;
00677     
00678     /* build the command */
00679     Command.Header.CLA = C_APDU_CLA_ST;
00680     Command.Header.INS = C_APDU_READ_BINARY;
00681     /* copy the offset */
00682     Command.Header.P1 = GETMSB  (Offset ) ;
00683     Command.Header.P2 = GETLSB  (Offset ) ;
00684     /* copy the number of byte to read */
00685     Command.Body.LE = NbByteToRead ;
00686   
00687     M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_READBINARY,  Command, &NbByte , pBuffer);
00688   
00689     errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer ));
00690     errchk( M24SR_IsAnswerReady ( ));
00691     errchk( M24SR_ReceiveI2Cresponse ( NbByteToRead + M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
00692     
00693     status = M24SR_IsCorrectCRC16Residue (pBuffer,NbByteToRead+ M24SR_STATUSRESPONSE_NBBYTE); 
00694     /* retrieve the data without SW1 & SW2 as provided as return value of the function */
00695     memcpy(pBufferRead ,&pBuffer[1],NbByteToRead);
00696     return status;
00697     
00698 Error :
00699     return M24SR_ERROR_I2CTIMEOUT;
00700     
00701 }
00702 
00703 /**
00704   * @brief  This function sends a Update binary command
00705     * @param    Offset : first byte to read
00706     * @param    NbByteToWrite : number of byte to write
00707     * @param    pBufferRead : pointer of the buffer read from the M24SR device
00708   * @retval Status (SW1&SW2) : Status of the operation to complete.
00709     * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
00710   */
00711 uint16_t M24SR_UpdateBinary ( uc16 Offset ,uc8 NbByteToWrite,uc8 *pDataToWrite )
00712 {
00713   uint8_t   *pBuffer = uM24SRbuffer ;
00714   uint16_t  status ; 
00715   uint16_t  NbByte;
00716     
00717     /* build the command */
00718     Command.Header.CLA = C_APDU_CLA_DEFAULT;
00719     Command.Header.INS = C_APDU_UPDATE_BINARY;
00720     /* copy the offset */
00721     Command.Header.P1 = GETMSB  (Offset ) ;
00722     Command.Header.P2 = GETLSB  (Offset ) ;
00723     /* copy the number of byte of the data field */
00724     Command.Body.LC = NbByteToWrite ;
00725     /* copy the File Id */
00726     memcpy(Command.Body.pData ,pDataToWrite, NbByteToWrite );
00727   
00728     M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_UPDATEBINARY,  Command, &NbByte , pBuffer);
00729   
00730     errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer ));
00731     errchk( M24SR_IsAnswerReady ( ));
00732     errchk( M24SR_ReceiveI2Cresponse ( M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
00733     /* if the response is a Watiting frame extenstion request */ 
00734     if (IsSBlock (pBuffer) == M24SR_STATUS_SUCCESS)
00735     {
00736         /*check the CRC */ 
00737         if (M24SR_IsCorrectCRC16Residue (pBuffer , M24SR_WATINGTIMEEXTRESPONSE_NBBYTE) != M24SR_ERROR_CRC)
00738         {
00739             /* send the FrameExension response*/ 
00740             status = M24SR_FWTExtension (  pBuffer [M24SR_OFFSET_PCB+1] );
00741         }
00742     }
00743     else
00744     {   
00745         status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE); 
00746     }
00747     
00748     return status;
00749   
00750     
00751 Error :
00752     return M24SR_ERROR_I2CTIMEOUT;
00753 }
00754 
00755 
00756 /**
00757   * @brief  This function sends the Verify command
00758     * @param    uPwdId : PasswordId ( 0x0001 : Read NDEF pwd or 0x0002 : Write NDEF pwd or 0x0003 : I2C pwd)
00759     * @param    NbPwdByte : Number of byte ( 0x00 or 0x10)
00760     * @param    pPwd : pointer on the passwaord
00761   * @retval Status (SW1&SW2) : Status of the operation to complete.
00762     * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
00763   */
00764 uint16_t M24SR_Verify ( uc16 uPwdId,uc8 NbPwdByte ,uc8 *pPwd )
00765 {
00766   uint8_t   *pBuffer = uM24SRbuffer ;
00767   uint16_t  status = 0x0000 ; 
00768   uint16_t  NbByte;
00769   
00770     /*check the parameters */
00771     if (uPwdId > 0x0003)
00772     {   
00773         return M24SR_ERROR_PARAMETER;
00774     }
00775     if ( (NbPwdByte != 0x00) && (NbPwdByte != 0x10))
00776     {   
00777         return M24SR_ERROR_PARAMETER;
00778     }
00779   
00780     /* build the command */
00781     Command.Header.CLA = C_APDU_CLA_DEFAULT;
00782     Command.Header.INS = C_APDU_VERIFY;
00783     /* copy the Password Id */
00784     Command.Header.P1 = GETMSB  (uPwdId ) ;
00785     Command.Header.P2 = GETLSB  (uPwdId ) ;
00786     /* copy the number of byte of the data field */
00787     Command.Body.LC = NbPwdByte ;
00788   
00789     if (NbPwdByte == 0x10) 
00790     {
00791         /* copy the password */
00792         memcpy(Command.Body.pData, pPwd, NbPwdByte);
00793         /* build the I￿C command */
00794         M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_VERIFYBINARYWITHPWD,  Command, &NbByte , pBuffer);
00795     }
00796     else 
00797     {
00798         /* build the I￿C command */
00799         M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_VERIFYBINARYWOPWD,  Command, &NbByte , pBuffer);
00800     }
00801     
00802     /* send the request */ 
00803     errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer ));
00804     /* wait for answer ready */
00805     errchk( M24SR_IsAnswerReady ( ));
00806     /* read the response */ 
00807     errchk( M24SR_ReceiveI2Cresponse ( M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
00808     
00809     status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE); 
00810     return status;
00811     
00812 Error :
00813     return M24SR_ERROR_I2CTIMEOUT;
00814 }
00815 
00816 
00817 /**
00818   * @brief  This function sends the ChangeReferenceData command
00819     * @param    uPwdId : PasswordId ( 0x0001 : Read NDEF pwd or 0x0002 : Write NDEF pwd or 0x0003 : I2C pwd)
00820     * @param    pPwd : pointer on the passwaord
00821   * @retval Status (SW1&SW2) : Status of the operation to complete.
00822     * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
00823   */
00824 uint16_t M24SR_ChangeReferenceData ( uc16 uPwdId,uc8 *pPwd )
00825 {
00826   uint8_t   *pBuffer = uM24SRbuffer;
00827   uint16_t  status ; 
00828   uint16_t  NbByte;
00829   
00830     /*check the parameters */
00831     if (uPwdId > 0x0003)
00832     {   
00833         return M24SR_ERROR_PARAMETER;
00834     }
00835   
00836     /* build the command */
00837     Command.Header.CLA = C_APDU_CLA_DEFAULT;
00838     Command.Header.INS = C_APDU_CHANGE;
00839     /* copy the Password Id */
00840     Command.Header.P1 = GETMSB  (uPwdId ) ;
00841     Command.Header.P2 = GETLSB  (uPwdId ) ;
00842     /* copy the number of byte of the data field */
00843     Command.Body.LC = M24SR_PASSWORD_NBBYTE ;
00844     /* copy the password */
00845     memcpy(Command.Body.pData, pPwd, M24SR_PASSWORD_NBBYTE);
00846     /* build the I￿C command */
00847     M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_CHANGEREFDATA,  Command, &NbByte , pBuffer);
00848   
00849     
00850     /* send the request */ 
00851     errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer ));
00852     errchk( M24SR_IsAnswerReady ( ));
00853     /* read the response */ 
00854     errchk( M24SR_ReceiveI2Cresponse ( M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
00855     
00856     status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE); 
00857     return status;
00858   
00859 Error :
00860     return M24SR_ERROR_I2CTIMEOUT;
00861 }
00862 
00863 
00864 /**
00865   * @brief  This function sends the EnableVerificationRequirement command
00866     * @param    uReadOrWrite : enable the read or write protection ( 0x0001 : Read or 0x0002 : Write  )
00867   * @retval Status (SW1&SW2) : Status of the operation to complete.
00868     * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
00869   */
00870 uint16_t M24SR_EnableVerificationRequirement ( uc16 uReadOrWrite  )
00871 {
00872   uint8_t   *pBuffer = uM24SRbuffer;
00873   uint16_t  status ; 
00874   uint16_t  NbByte;
00875   
00876     /*check the parameters */
00877     if ( (uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002))
00878     {   
00879         return M24SR_ERROR_PARAMETER;
00880     }
00881   
00882     /* build the command */
00883     Command.Header.CLA = C_APDU_CLA_DEFAULT;
00884     Command.Header.INS = C_APDU_ENABLE;
00885     /* copy the Password Id */
00886     Command.Header.P1 = GETMSB  (uReadOrWrite ) ;
00887     Command.Header.P2 = GETLSB  (uReadOrWrite ) ;
00888     /* build the I￿C command */
00889     M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_ENABLEVERIFREQ,  Command, &NbByte , pBuffer);
00890   
00891     /* send the request */ 
00892     errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer ));
00893     /* The right access to be updated in EEPROM need at least 6ms */    
00894     errchk( M24SR_IsAnswerReady ( ));
00895     /* read the response */ 
00896     errchk( M24SR_ReceiveI2Cresponse ( M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
00897   
00898     status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE); 
00899     return status;
00900     
00901 Error :
00902     return M24SR_ERROR_I2CTIMEOUT;
00903 }
00904 
00905 /**
00906   * @brief  This function sends the DisableVerificationRequirement command
00907     * @param    uReadOrWrite : enable the read or write protection ( 0x0001 : Read or 0x0002 : Write  )
00908   * @retval Status (SW1&SW2) : Status of the operation to complete.
00909     * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
00910   */
00911 uint16_t M24SR_DisableVerificationRequirement ( uc16 uReadOrWrite  )
00912 {
00913   uint8_t   *pBuffer = uM24SRbuffer;
00914   uint16_t  status ; 
00915   uint16_t  NbByte;
00916   
00917     /*check the parameters */
00918     if ( (uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002))
00919     {   
00920         return M24SR_ERROR_PARAMETER;
00921     }
00922   
00923     /* build the command */
00924     Command.Header.CLA = C_APDU_CLA_DEFAULT;
00925     Command.Header.INS = C_APDU_DISABLE;
00926     /* copy the Password Id */
00927     Command.Header.P1 = GETMSB  (uReadOrWrite ) ;
00928     Command.Header.P2 = GETLSB  (uReadOrWrite ) ;
00929     /* build the I￿C command */
00930     M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_DISABLEVERIFREQ,  Command, &NbByte , pBuffer);
00931   
00932     /* send the request */ 
00933     errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer ));
00934     /* The right access to be updated in EEPROM need at least 6ms */        
00935     errchk( M24SR_IsAnswerReady ( ));
00936     /* read the response */ 
00937     errchk( M24SR_ReceiveI2Cresponse ( M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
00938   
00939     status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE); 
00940     return status;
00941     
00942 Error :
00943     return M24SR_ERROR_I2CTIMEOUT;
00944 }
00945 
00946 /**
00947   * @brief  This function sends the EnablePermananentState command
00948     * @param    uReadOrWrite : enable the read or write protection ( 0x0001 : Read or 0x0002 : Write  )
00949   * @retval Status (SW1&SW2) : Status of the operation to complete.
00950     * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
00951   */
00952 uint16_t M24SR_EnablePermanentState ( uc16 uReadOrWrite  )
00953 {
00954   uint8_t   *pBuffer = uM24SRbuffer;
00955   uint16_t  status ; 
00956   uint16_t  NbByte;
00957   
00958     /*check the parameters */
00959     if ( (uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002))
00960     {   
00961         return M24SR_ERROR_PARAMETER;
00962     }
00963   
00964     /* build the command */
00965     Command.Header.CLA = C_APDU_CLA_ST;
00966     Command.Header.INS = C_APDU_ENABLE;
00967     /* copy the Password Id */
00968     Command.Header.P1 = GETMSB  (uReadOrWrite ) ;
00969     Command.Header.P2 = GETLSB  (uReadOrWrite ) ;
00970     /* build the I￿C command */
00971     M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_ENABLEVERIFREQ,  Command, &NbByte , pBuffer);
00972   
00973     /* send the request */ 
00974     errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer ));
00975     errchk( M24SR_IsAnswerReady ( ));
00976     /* read the response */ 
00977     errchk( M24SR_ReceiveI2Cresponse ( M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
00978   
00979     status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE); 
00980     return status;
00981     
00982 Error :
00983     return M24SR_ERROR_I2CTIMEOUT;
00984 }
00985 
00986 /**
00987   * @brief  This function sends the DisablePermanentState command
00988     * @param    uReadOrWrite : enable the read or write protection ( 0x0001 : Read or 0x0002 : Write  )
00989   * @retval Status (SW1&SW2) : Status of the operation to complete.
00990     * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
00991   */
00992 uint16_t M24SR_DisablePermanentState ( uc16 uReadOrWrite  )
00993 {
00994   uint8_t   *pBuffer = uM24SRbuffer;
00995   uint16_t  status ; 
00996   uint16_t  NbByte;
00997   
00998     /*check the parameters */
00999     if ( (uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002))
01000     {   
01001         return M24SR_ERROR_PARAMETER;
01002     }
01003   
01004     /* build the command */
01005     Command.Header.CLA = C_APDU_CLA_ST;
01006     Command.Header.INS = C_APDU_DISABLE;
01007     /* copy the Password Id */
01008     Command.Header.P1 = GETMSB  (uReadOrWrite ) ;
01009     Command.Header.P2 = GETLSB  (uReadOrWrite ) ;
01010     /* build the I￿C command */
01011     M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_DISABLEVERIFREQ,  Command, &NbByte , pBuffer);
01012   
01013     /* send the request */ 
01014     errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer ));
01015     errchk( M24SR_IsAnswerReady ( ));
01016     /* read the response */ 
01017     errchk( M24SR_ReceiveI2Cresponse ( M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
01018   
01019     status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE); 
01020     return status;
01021     
01022 Error :
01023     return M24SR_ERROR_I2CTIMEOUT;
01024 }
01025 
01026 /**
01027   * @brief  This function generates a interrupt on GPO pin
01028     * @param    None
01029   * @retval Status (SW1&SW2) : Status of the operation to complete.
01030     * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
01031   */
01032 uint16_t M24SR_SendInterrupt ( void  )
01033 {
01034     uint8_t     *pBuffer = uM24SRbuffer;
01035     uint16_t    uP1P2 =0x001E;
01036     uint16_t    status ; 
01037     uint16_t    NbByte;
01038     
01039     status = M24SR_ManageI2CGPO( INTERRUPT);
01040     
01041     /* build the command */
01042     Command.Header.CLA = C_APDU_CLA_ST;
01043     Command.Header.INS = C_APDU_INTERRUPT;
01044     /* copy the Password Id */
01045     Command.Header.P1 = GETMSB  (uP1P2 ) ;
01046     Command.Header.P2 = GETLSB  (uP1P2 ) ;
01047     Command.Body.LC = 0x00 ;
01048     /* build the I￿C command */
01049     M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_SENDINTERRUPT,  Command, &NbByte , pBuffer);
01050   
01051     /* send the request */ 
01052     errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer ));
01053     errchk( M24SR_IsAnswerReady ( ));
01054     /* read the response */ 
01055     errchk( M24SR_ReceiveI2Cresponse ( M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
01056   
01057     status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE); 
01058     return status;
01059     
01060 Error :
01061     return M24SR_ERROR_I2CTIMEOUT;
01062 }
01063 
01064 /**
01065   * @brief  This function force GPO pin to low state or high Z
01066     * @param    uSetOrReset : select if GPO must be low (reset) or HiZ
01067   * @retval Status (SW1&SW2) : Status of the operation to complete.
01068     * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
01069   */
01070 uint16_t M24SR_StateControl ( uc8 uSetOrReset )
01071 {
01072     uint8_t     *pBuffer = uM24SRbuffer;
01073     uint16_t    uP1P2 =0x001F;
01074     uint16_t    status ; 
01075     uint16_t    NbByte;
01076     
01077     /*check the parameters */
01078     if ( (uSetOrReset != 0x01) && (uSetOrReset != 0x00))
01079     {   
01080         return M24SR_ERROR_PARAMETER;
01081     }
01082     
01083     status = M24SR_ManageI2CGPO( STATE_CONTROL);
01084     
01085     /* build the command */
01086     Command.Header.CLA = C_APDU_CLA_ST;
01087     Command.Header.INS = C_APDU_INTERRUPT;
01088     /* copy the Password Id */
01089     Command.Header.P1 = GETMSB  (uP1P2 ) ;
01090     Command.Header.P2 = GETLSB  (uP1P2 ) ;
01091     Command.Body.LC = 0x01 ;
01092     /* copy the data */
01093     memcpy(Command.Body.pData , &uSetOrReset, 0x01 );
01094     //Command.Body.LE = 0x00 ;
01095     /* build the I￿C command */
01096     M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_GPOSTATE,  Command, &NbByte , pBuffer);
01097   
01098     /* send the request */ 
01099     errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer ));
01100     errchk( M24SR_IsAnswerReady ( ));
01101     /* read the response */ 
01102     errchk( M24SR_ReceiveI2Cresponse ( M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
01103   
01104     status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE); 
01105     return status;
01106     
01107 Error :
01108     return M24SR_ERROR_I2CTIMEOUT;
01109 }
01110 
01111 /**
01112   * @brief  This function configure GPO purpose for I2C session
01113     * @param    GPO_I2Cconfig: GPO configuration to set
01114   * @retval Status (SW1&SW2) : Status of the operation to complete.
01115   */
01116 uint16_t M24SR_ManageI2CGPO( uc8 GPO_I2Cconfig)
01117 {
01118     uint16_t status;
01119     uint8_t GPO_config;
01120     uint8_t DefaultPassword[16]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
01121   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
01122     
01123     if( GPO_I2Cconfig > STATE_CONTROL)
01124     {   
01125         return M24SR_ERROR_PARAMETER;
01126     }
01127     
01128     /* we must not be in interrupt mode for I2C synchro as we will change GPO purpose */
01129     M24SR_SetI2CSynchroMode(M24SR_WAITINGTIME_POLLING);
01130     
01131     M24SR_SelectApplication();
01132     M24SR_SelectSystemfile();
01133     M24SR_ReadBinary ( 0x0004 , 0x01 , &GPO_config );
01134   
01135   /* Update only GPO purpose for I2C */ 
01136     GPO_config = (GPO_config & 0xF0) | GPO_I2Cconfig;
01137     M24SR_SelectSystemfile();
01138     M24SR_Verify( I2C_PWD ,0x10 ,DefaultPassword );
01139     status = M24SR_UpdateBinary ( 0x0004 ,0x01, &(GPO_config) );
01140     
01141     /* if we have set interrupt mode for I2C synchro we can enable interrupt mode */
01142     if ( GPO_I2Cconfig == I2C_ANSWER_READY && status == M24SR_ACTION_COMPLETED)
01143 #ifdef I2C_GPO_SYNCHRO_ALLOWED
01144         M24SR_SetI2CSynchroMode(M24SR_WAITINGTIME_GPO);
01145 #else
01146   M24SR_SetI2CSynchroMode(M24SR_INTERRUPT_GPO);
01147 #endif
01148     
01149     return status;
01150 }
01151 
01152 /**
01153   * @brief  This function configure GPO purpose for RF session
01154     * @param    GPO_RFconfig: GPO configuration to set
01155   * @retval Status (SW1&SW2) : Status of the operation to complete.
01156   */
01157 uint16_t M24SR_ManageRFGPO( uc8 GPO_RFconfig)
01158 {
01159     uint16_t status;
01160     uint8_t GPO_config;
01161     uint8_t DefaultPassword[16]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
01162   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
01163     
01164     if( GPO_RFconfig > STATE_CONTROL)
01165     {   
01166         return M24SR_ERROR_PARAMETER;
01167     }
01168     
01169     M24SR_SelectApplication();
01170     M24SR_SelectSystemfile();
01171     M24SR_ReadBinary ( 0x0004 , 0x01 , &GPO_config );
01172   
01173   /* Update only GPO purpose for I2C */ 
01174     GPO_config = (GPO_config & 0x0F) | (GPO_RFconfig<<4);
01175     M24SR_SelectSystemfile();
01176     M24SR_Verify( I2C_PWD ,0x10 ,DefaultPassword );
01177     status = M24SR_UpdateBinary ( 0x0004 ,0x01, &(GPO_config) );
01178     
01179     return status;
01180 }
01181 
01182 
01183 /**
01184   * @brief  This function enable or disable RF communication
01185     * @param    OnOffChoice: GPO configuration to set
01186   * @retval Status (SW1&SW2) : Status of the operation to complete.
01187   */
01188 void M24SR_RFConfig( uc8 OnOffChoice)
01189 {
01190     M24SR_RFConfig_Hard(OnOffChoice);
01191 }
01192 
01193 /**
01194   * @}
01195   */
01196 
01197 /**
01198   * @}
01199   */
01200 
01201 /**
01202   * @}
01203   */
01204 
01205 /******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/