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 lib_M24SR.c Source File

lib_M24SR.c

Go to the documentation of this file.
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>&copy; 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