Functions for accessing M24SR device.
Dependents: Nucleo_NFC_Example I2C_NFC_Master Print_Entire_Nucleo_NFC01A1_Memory
Fork of lib_M24SR by
lib_M24SR.c
00001 /** 00002 ****************************************************************************** 00003 * @file lib_M24SR.c 00004 * @author MMY Application Team 00005 * @version V1.1.0 00006 * @date 20-October-2014 00007 * @brief This file help to manage M24SR in a NFC forum context. 00008 ****************************************************************************** 00009 * @attention 00010 * 00011 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> 00012 * 00013 * Redistribution and use in source and binary forms, with or without modification, 00014 * are permitted provided that the following conditions are met: 00015 * 1. Redistributions of source code must retain the above copyright notice, 00016 * this list of conditions and the following disclaimer. 00017 * 2. Redistributions in binary form must reproduce the above copyright notice, 00018 * this list of conditions and the following disclaimer in the documentation 00019 * and/or other materials provided with the distribution. 00020 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00021 * may be used to endorse or promote products derived from this software 00022 * without specific prior written permission. 00023 * 00024 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00025 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00026 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00027 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00028 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00029 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00030 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00031 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00032 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00033 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 * 00035 ****************************************************************************** 00036 */ 00037 00038 00039 /* Includes ------------------------------------------------------------------*/ 00040 #include "lib_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 /** @addtogroup lib_M24SR 00048 * @{ 00049 * @brief This is the library to interface with the M24SR dynamic tag. 00050 * This layer simplify the use of the M24SR driver by sequencing 00051 * some commands. 00052 */ 00053 00054 uint8_t I2CPassword[16]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00055 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 00056 00057 static uint32_t NDEFSessionOpenID=NDEF_SESSION_CLOSED; 00058 00059 /* Init NDEF_FileID with bad value in case Init failed */ 00060 static uint16_t NDEF_FileID = 0xDEAD; 00061 00062 #ifdef __MBED__ 00063 extern void wait_ms(int ms); 00064 #endif 00065 00066 /** @defgroup libM24SR_Private_Functions 00067 * @{ 00068 */ 00069 00070 /** 00071 * @} 00072 */ 00073 00074 00075 /** @defgroup libM24SR_Public_Functions 00076 * @{ 00077 */ 00078 00079 /** 00080 * @brief This fonction initialize the M24SR 00081 * @param CCBuffer : pointer on the buffer to store CC file 00082 * @param size : number of byte of data to read 00083 * @retval SUCCESS : Initalization done 00084 * @retval ERROR : Not able to Initialize. 00085 */ 00086 uint16_t M24SR_Initialization ( uint8_t* CCBuffer, uint8_t size ) 00087 { 00088 uint16_t status = ERROR; 00089 uint16_t trials = 5; /* wait 1sec, driver is configured to let 200ms for command to complete */ 00090 /* which is enough for all commands except GetSession if RF session is already opened */ 00091 /* Smartphone generaly release the session within the second, but customer can modify this value */ 00092 00093 /* Perform HW initialization */ 00094 M24SR_Init(); 00095 00096 /* Read CC file */ 00097 while( status != M24SR_ACTION_COMPLETED && trials) 00098 { 00099 //printf("Calling M24SR_GetSession(), attempts remaining %d\n", trials); 00100 status = M24SR_GetSession(); 00101 //printf("M24SR_GetSession() returned: %d\n", status); 00102 trials--; 00103 } 00104 if (status != M24SR_ACTION_COMPLETED) 00105 { 00106 //printf("M24SR_GetSession() failed\n"); 00107 return ERROR; 00108 } 00109 /*===================================*/ 00110 /* Select the NFC type 4 application */ 00111 /*===================================*/ 00112 errorchk( M24SR_SelectApplication() ); 00113 00114 /*==================*/ 00115 /* select a CC file */ 00116 /*==================*/ 00117 errorchk (M24SR_SelectCCfile() ); 00118 00119 /* read the first 15 bytes of the CC file */ 00120 if( M24SR_ReadData ( 0x0000 , 0x0F , CCBuffer )== M24SR_ACTION_COMPLETED) 00121 { 00122 NDEF_FileID = (uint16_t) ((CCBuffer[0x09]<<8) | CCBuffer[0x0A]); 00123 errorchk( M24SR_Deselect () ); 00124 return SUCCESS; 00125 } 00126 else 00127 errorchk( M24SR_Deselect () ); 00128 00129 Error: 00130 printf("Error in M24SR_Initialization\n"); 00131 return ERROR; 00132 00133 } 00134 00135 /** 00136 * @brief This fonction retrieve the NDEF file ID of NDEF file present in M24SR 00137 * @param NDEF_fileID : To store NDEF ID 00138 * @retval SUCCESS : File ID read 00139 * @retval ERROR : Not able to read file ID. 00140 */ 00141 uint16_t M24SR_GetNDEFFileId ( uint16_t *NDEF_fileID ) 00142 { 00143 if( NDEF_FileID != 0xDEAD) 00144 { 00145 *NDEF_fileID = NDEF_FileID; 00146 return SUCCESS; 00147 } 00148 else 00149 { 00150 return ERROR; 00151 } 00152 } 00153 00154 00155 /** 00156 * @brief This fonction configure the M24SR to access NDEF message by I2C 00157 * @param NDEF_fileID : NDEF identification to select NDEF in M24SR 00158 * @param Priority: 2 options: check if M24SR available to open session (no RF session on going) 00159 * Kill RF session and open I2C sesssion. 00160 * @retval SUCCESS : Session is opened 00161 * @retval ERROR : Not able to open session. 00162 */ 00163 uint16_t M24SR_OpenNDEFSession ( uint16_t NDEF_fileID, uint16_t Priority ) 00164 { 00165 uint16_t status = ERROR; 00166 uint16_t trials = 5; /* wait 1sec, driver is configured to let 200ms for command to complete */ 00167 /* which is enough for all commands except GetSession if RF session is already opened */ 00168 /* Smartphone generaly release the session within the second, but customer can modify this value */ 00169 00170 if(NDEFSessionOpenID == NDEF_SESSION_CLOSED) 00171 { 00172 if( Priority == TAKE_SESSION) 00173 { 00174 status = M24SR_KillSession(); 00175 } 00176 else 00177 { 00178 while( status != M24SR_ACTION_COMPLETED && trials) 00179 { 00180 status = M24SR_GetSession(); 00181 trials--; 00182 } 00183 } 00184 if (status != M24SR_ACTION_COMPLETED) 00185 { 00186 /* seems session already open on RF side */ 00187 /* But in case of I2C issue try to init again */ 00188 M24SR_Init(); 00189 return ERROR; 00190 } 00191 00192 /*===================================*/ 00193 /* Select the NFC type 4 application */ 00194 /*===================================*/ 00195 errorchk( M24SR_SelectApplication() ); 00196 00197 /*====================*/ 00198 /* select NDEF file */ 00199 /*====================*/ 00200 errorchk( M24SR_SelectNDEFfile(NDEF_fileID) ); 00201 00202 NDEFSessionOpenID = (uint32_t)(NDEF_fileID); 00203 00204 return SUCCESS; 00205 } 00206 else if(NDEFSessionOpenID == NDEF_fileID) 00207 { 00208 /* Session already Open not an issue caller can perform access in NDEF file */ 00209 return SUCCESS; 00210 } 00211 00212 Error: 00213 return ERROR; 00214 } 00215 00216 /** 00217 * @brief This fonction close the NDEF Session. 00218 * @param NDEF_fileID : NDEF identification to select NDEF in M24SR 00219 * @retval SUCCESS : Session is closed 00220 * @retval ERROR : Not able to close session. 00221 */ 00222 uint16_t M24SR_CloseNDEFSession ( uint16_t NDEF_fileID ) 00223 { 00224 uint16_t status = ERROR; 00225 00226 if(NDEFSessionOpenID == (uint32_t)(NDEF_fileID)) 00227 { 00228 errorchk( M24SR_Deselect () ); 00229 NDEFSessionOpenID = NDEF_SESSION_CLOSED; 00230 00231 return SUCCESS; 00232 } 00233 else if(NDEFSessionOpenID == NDEF_SESSION_CLOSED) 00234 { 00235 /* Not an error as session is already closed */ 00236 return SUCCESS; 00237 } 00238 00239 Error: 00240 return ERROR; 00241 } 00242 00243 /** 00244 * @brief This fonction read the data stored in M24SR at defined offset 00245 * @param Offset : Offset in the NDEF file in M24SR 00246 * @param DataSize : Number of byte to read 00247 * @param pData : pointer on buffer to store read data 00248 * @retval Status (SW1&SW2) : Status of the operation. 00249 */ 00250 uint16_t M24SR_ReadData ( uint16_t Offset , uint16_t DataSize , uint8_t* pData) 00251 { 00252 uint16_t status; 00253 00254 if( DataSize > M24SR_READ_MAX_NBBYTE) 00255 { 00256 do 00257 { 00258 status = M24SR_ReadBinary ( Offset, M24SR_READ_MAX_NBBYTE , pData); 00259 Offset += M24SR_READ_MAX_NBBYTE; 00260 pData += M24SR_READ_MAX_NBBYTE; 00261 DataSize -= M24SR_READ_MAX_NBBYTE; 00262 }while( DataSize > M24SR_READ_MAX_NBBYTE && status == M24SR_ACTION_COMPLETED); 00263 if( status == M24SR_ACTION_COMPLETED && DataSize) 00264 status = M24SR_ReadBinary ( Offset, (uint8_t)(DataSize) , pData); 00265 } 00266 else 00267 status = M24SR_ReadBinary ( Offset, (uint8_t)(DataSize) , pData); 00268 00269 return status; 00270 } 00271 00272 /** 00273 * @brief This fonction read the data stored in M24SR at defined offset without NDEF concideration 00274 * @param Offset : Offset in the NDEF file in M24SR 00275 * @param DataSize : Number of byte to read 00276 * @param pData : pointer on buffer to store read data 00277 * @retval Status (SW1&SW2) : Status of the operation. 00278 */ 00279 uint16_t M24SR_ForceReadData ( uint16_t Offset , uint16_t DataSize , uint8_t* pData) 00280 { 00281 uint16_t status; 00282 00283 if( DataSize > M24SR_READ_MAX_NBBYTE) 00284 { 00285 do 00286 { 00287 status = M24SR_STReadBinary ( Offset, M24SR_READ_MAX_NBBYTE , pData); 00288 Offset += M24SR_READ_MAX_NBBYTE; 00289 pData += M24SR_READ_MAX_NBBYTE; 00290 DataSize -= M24SR_READ_MAX_NBBYTE; 00291 }while( DataSize > M24SR_READ_MAX_NBBYTE && status == M24SR_ACTION_COMPLETED); 00292 if( status == M24SR_ACTION_COMPLETED && DataSize) 00293 status = M24SR_STReadBinary ( Offset, (uint8_t)(DataSize) , pData); 00294 } 00295 else 00296 status = M24SR_STReadBinary ( Offset, (uint8_t)(DataSize) , pData); 00297 00298 return status; 00299 } 00300 00301 /** 00302 * @brief This fonction write data in M24SR at defined offset 00303 * @param Offset : Offset in the NDEF file in M24SR 00304 * @param DataSize : Number of byte to read 00305 * @param pData : pointer on buffer to copy in M24SR 00306 * @retval Status (SW1&SW2) : Status of the operation. 00307 */ 00308 uint16_t M24SR_WriteData ( uint16_t Offset , uint16_t DataSize , uint8_t* pData) 00309 { 00310 uint16_t status; 00311 00312 if( DataSize > M24SR_WRITE_MAX_NBBYTE) 00313 { 00314 do 00315 { 00316 status = M24SR_UpdateBinary ( Offset, M24SR_WRITE_MAX_NBBYTE , pData); 00317 Offset += M24SR_WRITE_MAX_NBBYTE; 00318 pData += M24SR_WRITE_MAX_NBBYTE; 00319 DataSize -= M24SR_WRITE_MAX_NBBYTE; 00320 }while( DataSize > M24SR_WRITE_MAX_NBBYTE && status == M24SR_ACTION_COMPLETED); 00321 if( status == M24SR_ACTION_COMPLETED && DataSize) 00322 status = M24SR_UpdateBinary ( Offset, (uint8_t)(DataSize) , pData); 00323 } 00324 else 00325 status = M24SR_UpdateBinary ( Offset, (uint8_t)(DataSize) , pData); 00326 00327 return status; 00328 } 00329 00330 /** 00331 * @brief This fonction activate the need of a password for next read access 00332 * @param pCurrentWritePassword : Write password is needed to have the right to enable Read Password 00333 * @param pNewPassword : The password that will be requiered for next read access 00334 * @retval SUCCESS : Read password is activated 00335 * @retval ERROR : operation does not complete 00336 */ 00337 uint16_t M24SR_EnableReadPassword( uint8_t* pCurrentWritePassword, uint8_t* pNewPassword) 00338 { 00339 uint16_t status = SUCCESS; 00340 00341 if(M24SR_Verify( WRITE_PWD ,0x10 ,pCurrentWritePassword ) == M24SR_PWD_CORRECT) 00342 { 00343 /* Set new password */ 00344 M24SR_ChangeReferenceData ( READ_PWD, pNewPassword ); 00345 M24SR_EnableVerificationRequirement( READ_PWD ); 00346 status = SUCCESS; 00347 } 00348 else 00349 { 00350 /* M24SR already lock but password not known */ 00351 status = ERROR; 00352 } 00353 00354 return status; 00355 } 00356 00357 /** 00358 * @brief This fonction desactivate the need of a password for next read access 00359 * @param pCurrentWritePassword : Write password is needed to have the right to disable Read Password 00360 * @retval SUCCESS : Read password is desactivated 00361 * @retval ERROR : operation does not complete 00362 */ 00363 uint16_t M24SR_DisableReadPassword( uint8_t* pCurrentWritePassword) 00364 { 00365 uint16_t status = SUCCESS; 00366 00367 if(M24SR_Verify( WRITE_PWD ,0x10 ,pCurrentWritePassword ) == M24SR_PWD_CORRECT) 00368 { 00369 /* Set new password */ 00370 M24SR_DisableVerificationRequirement( READ_PWD ); 00371 status = SUCCESS; 00372 } 00373 else 00374 { 00375 /* M24SR already lock but password not known */ 00376 status = ERROR; 00377 } 00378 00379 return status; 00380 } 00381 00382 /** 00383 * @brief This fonction activate the need of a password for next write access 00384 * @param pCurrentWritePassword : Write password must be prensented to have the right to modify write Password 00385 * @param pNewPassword : The password that will be requiered for next write access 00386 * @retval SUCCESS : Write password is activated 00387 * @retval ERROR : operation does not complete 00388 */ 00389 uint16_t M24SR_EnableWritePassword( uint8_t* pCurrentWritePassword, uint8_t* pNewPassword) 00390 { 00391 uint16_t status; 00392 00393 /* check we have the good password */ 00394 if (M24SR_Verify( WRITE_PWD ,0x10 ,pCurrentWritePassword )== M24SR_PWD_CORRECT) 00395 { 00396 /* Set new password */ 00397 M24SR_ChangeReferenceData ( WRITE_PWD, pNewPassword ); 00398 M24SR_EnableVerificationRequirement( WRITE_PWD ); 00399 status = SUCCESS; 00400 } 00401 else /* we don't have the good password */ 00402 { 00403 status = ERROR; 00404 } 00405 00406 return status; 00407 } 00408 00409 /** 00410 * @brief This fonction desactivate the need of a password for next write access 00411 * @param pCurrentWritePassword : Write password must be prensented to have the right to disable it 00412 * @retval SUCCESS : Write password is desactivated 00413 * @retval ERROR : operation does not complete 00414 */ 00415 uint16_t M24SR_DisableWritePassword( uint8_t* pCurrentWritePassword) 00416 { 00417 uint16_t status = SUCCESS; 00418 00419 if(M24SR_Verify( WRITE_PWD ,0x10 ,pCurrentWritePassword ) == M24SR_PWD_CORRECT) 00420 { 00421 M24SR_DisableVerificationRequirement( WRITE_PWD ); 00422 status = SUCCESS; 00423 } 00424 else 00425 { 00426 /* M24SR already lock but password not known */ 00427 status = ERROR; 00428 } 00429 00430 return status; 00431 } 00432 00433 /** 00434 * @brief This fonction desactivate the need of read and write password for next access 00435 * @param pSuperUserPassword : I2C super user password to overwrite read and write password 00436 * @retval SUCCESS : M24SR access is now free (no password needed) 00437 * @retval ERROR : operation does not complete 00438 */ 00439 uint16_t M24SR_DisableAllPassword( uint8_t* pSuperUserPassword) 00440 { 00441 uint16_t status = SUCCESS; 00442 00443 if(M24SR_Verify( I2C_PWD ,0x10 ,pSuperUserPassword ) == M24SR_PWD_CORRECT) 00444 { 00445 M24SR_DisablePermanentState( READ_PWD ); 00446 M24SR_DisablePermanentState( WRITE_PWD ); 00447 00448 M24SR_DisableVerificationRequirement( READ_PWD ); 00449 M24SR_DisableVerificationRequirement( WRITE_PWD ); 00450 00451 /* reset password */ 00452 M24SR_ChangeReferenceData ( READ_PWD, pSuperUserPassword ); 00453 M24SR_ChangeReferenceData ( WRITE_PWD, pSuperUserPassword ); 00454 status = SUCCESS; 00455 } 00456 else 00457 { 00458 /* M24SR already lock but password not known */ 00459 status = ERROR; 00460 } 00461 00462 return status; 00463 } 00464 00465 /** 00466 * @brief This fonction enable read only mode 00467 * @param pCurrentWritePassword : Write password is needed to have right to enable read only mode 00468 * @retval SUCCESS : M24SR access is now forbidden in write mode 00469 * @retval ERROR : operation does not complete 00470 */ 00471 uint16_t M24SR_EnableReadOnly( uint8_t* pCurrentWritePassword) 00472 { 00473 uint16_t status = SUCCESS; 00474 00475 if(M24SR_Verify( WRITE_PWD ,0x10 ,pCurrentWritePassword ) == M24SR_PWD_CORRECT) 00476 { 00477 M24SR_EnablePermanentState( WRITE_PWD ); /* lock write to have read only */ 00478 status = SUCCESS; 00479 } 00480 else 00481 { 00482 /* M24SR already lock but password not known */ 00483 status = ERROR; 00484 } 00485 00486 return status; 00487 } 00488 00489 /** 00490 * @brief This fonction disable read only mode 00491 * @param pCurrentWritePassword : Write password is needed to have right to disable read only mode 00492 * @retval SUCCESS : M24SR write access is now allowed 00493 * @retval ERROR : operation does not complete 00494 */ 00495 uint16_t M24SR_DisableReadOnly( uint8_t* pCurrentWritePassword) 00496 { 00497 uint16_t status = SUCCESS; 00498 00499 if(M24SR_Verify( I2C_PWD ,0x10 ,I2CPassword ) == M24SR_PWD_CORRECT) 00500 { 00501 M24SR_DisablePermanentState( WRITE_PWD ); /* disable write protection to disable read only mode */ 00502 M24SR_DisableVerificationRequirement( WRITE_PWD ); 00503 status = SUCCESS; 00504 } 00505 else 00506 { 00507 /* we don't have the good I2C password nothing to do anymore */ 00508 status = ERROR; 00509 } 00510 00511 return status; 00512 } 00513 00514 /** 00515 * @brief This fonction enable write only mode 00516 * @param pCurrentWritePassword : Write password is needed to have right to enable write only mode 00517 * @retval SUCCESS : M24SR access is now forbidden in read mode 00518 * @retval ERROR : operation does not complete 00519 */ 00520 uint16_t M24SR_EnableWriteOnly( uint8_t* pCurrentWritePassword) 00521 { 00522 uint16_t status = SUCCESS; 00523 00524 if(M24SR_Verify( WRITE_PWD ,0x10 ,pCurrentWritePassword ) == M24SR_PWD_CORRECT) 00525 { 00526 M24SR_EnablePermanentState( READ_PWD ); /* disable read access and keep write */ 00527 status = SUCCESS; 00528 } 00529 else 00530 { 00531 /* M24SR already lock but password not known */ 00532 status = ERROR; 00533 } 00534 00535 return status; 00536 } 00537 00538 /** 00539 * @brief This fonction disable write only mode 00540 * @param pCurrentWritePassword : Write password is needed to have right to disable write only mode 00541 * @retval SUCCESS : M24SR read access is now allowed 00542 * @retval ERROR : operation does not complete 00543 */ 00544 uint16_t M24SR_DisableWriteOnly( uint8_t* pCurrentWritePassword) 00545 { 00546 uint16_t status = SUCCESS; 00547 00548 if(M24SR_Verify( I2C_PWD ,0x10 ,I2CPassword ) == M24SR_PWD_CORRECT) 00549 { 00550 M24SR_DisablePermanentState( READ_PWD ); /* disable write only -> enable write acces */ 00551 M24SR_DisableVerificationRequirement( READ_PWD ); 00552 status = SUCCESS; 00553 } 00554 else 00555 { 00556 /* M24SR already lock but password not known */ 00557 status = ERROR; 00558 } 00559 00560 return status; 00561 } 00562 00563 /** 00564 * @brief This function configure GPO purpose for RF session 00565 * @param GPO_config: GPO configuration to set 00566 * @param mode: select RF or I2C, GPO config to update 00567 * @retval Status : Status of the operation. 00568 */ 00569 uint16_t M24SR_ManageGPO( uc8 GPO_config, uc8 mode) 00570 { 00571 uint16_t status; 00572 00573 if( mode == RF_GPO) 00574 { 00575 status = M24SR_ManageRFGPO ( GPO_config ); 00576 } 00577 else 00578 { 00579 status = M24SR_ManageI2CGPO ( GPO_config ); 00580 } 00581 return status; 00582 } 00583 00584 /** 00585 * @} 00586 */ 00587 00588 /** 00589 * @} 00590 */ 00591 00592 /** 00593 * @} 00594 */ 00595 00596 /******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/ 00597 00598
Generated on Fri Jul 15 2022 11:26:09 by 1.7.2