Functions for accessing M24SR device.
Dependents: Nucleo_NFC_Example I2C_NFC_Master Print_Entire_Nucleo_NFC01A1_Memory
Fork of lib_M24SR by
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>© 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 IC 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 IC 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 IC 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 IC 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 IC command */ 00794 M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_VERIFYBINARYWITHPWD, Command, &NbByte , pBuffer); 00795 } 00796 else 00797 { 00798 /* build the IC 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 IC 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 IC 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 IC 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 IC 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 IC 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 IC 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 IC 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****/
Generated on Fri Jul 15 2022 11:26:09 by 1.7.2