X_NUCLEO_NFC02A1 library for M24LR

Dependencies:   ST_INTERFACES

Dependents:   HelloWorld_NFC02A1_mbedOS HelloWorld_NFC02A1laatste HelloWorld_NFC02A1

Fork of X_NUCLEO_NFC02A1 by ST Expansion SW Team

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers M24LR.cpp Source File

M24LR.cpp

00001 /**
00002   ******************************************************************************
00003   * @file       m24lr.cpp
00004   * @author     AMG Central Lab
00005   * @version    V2.0.0
00006   * @date       19 May 2017
00007   * @brief      M24LR driver file.
00008   ******************************************************************************
00009   * @attention
00010   *
00011   * <h2><center>&copy; COPYRIGHT(c) 2015 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 #include "M24LR.h"
00039 
00040 uint8_t M24LR::NfctagInitialized = 0; 
00041 
00042 /**
00043   * @brief  Activate Energy Harvesting mode.
00044   */
00045 void M24LR::enable_energy_harvesting( void )
00046 {
00047   /* Initialise M24LR Board */
00048   
00049   /* Enable Energy Harvesting */
00050   i2c_set_EH( );
00051 
00052   /* Store configuration in non Volatile Memory */
00053   i2c_enable_EH_mode();
00054   i2c_write_EH_cfg( M24LR_EH_Cfg_6MA );
00055 }
00056 
00057 /**
00058   * @brief  Set M24LR nfctag Initialization
00059   * @param  None
00060   * @retval NFCTAG enum status
00061   */
00062 NFCTAG_StatusTypeDef M24LR::initialization( void )
00063 { 
00064   uint8_t nfctag_id = 0;
00065   
00066   if ( NfctagInitialized == 0 ) {
00067     /* M24LR Init */
00068     if ( i2c_init() != NFCTAG_OK ) {
00069       return NFCTAG_ERROR;
00070     }
00071       
00072     /* Check M24LR driver ID */
00073     i2c_read_id(&nfctag_id);
00074     if ( (nfctag_id == I_AM_M24LR04) || (nfctag_id == I_AM_M24LR16) || (nfctag_id == I_AM_M24LR64) ) {
00075       NfctagInitialized = 1;
00076       // Nfctag_Drv = &M24lr_i2c_Drv;
00077       // Nfctag_Drv->pData = &M24lr_i2c_ExtDrv;
00078     } else {
00079       NfctagInitialized = 0;
00080       // Nfctag_Drv = NULL;
00081       // NfctagInitialized = 0;
00082       return NFCTAG_ERROR;
00083     }
00084   }
00085   
00086   return NFCTAG_OK;
00087 }
00088 
00089 /**
00090   * @brief  Set M24LR Initialization
00091   * @param  None
00092   * @retval NFCTAG enum status
00093   */
00094 NFCTAG_StatusTypeDef M24LR::i2c_init( void )
00095 {
00096   /* Configure the low level interface */
00097   return(NFCTAG_OK);
00098   //eturn mM24LR_IO.Init( );
00099 }
00100 
00101 /**
00102   * @brief  Read M24LR ID
00103   * @param  pICRef : pointer to store ID
00104   * @retval NFCTAG enum status
00105   */
00106 NFCTAG_StatusTypeDef M24LR::i2c_read_id( uint8_t * const pData )
00107 {
00108   uint8_t *pBuffer = (uint8_t *)pData;
00109   NFCTAG_StatusTypeDef status;
00110   /* Read ICRef on device */
00111   //return M24LR_i2c_read_register( pICRef, M24LR_ICREF_REG, 1 );
00112   /* Before calling this function M24LR must be ready, here is a check to detect an issue */
00113   status = i2c_read_register(pBuffer, M24LR_ICREF_REG, 1);
00114 
00115   if (status  == 0) {
00116     return NFCTAG_OK;
00117   }
00118   return NFCTAG_TIMEOUT;
00119  
00120 }
00121 
00122 /**
00123   * @brief  Check M24LR availability
00124   * @param  Trials : number of max tentative tried
00125   * @retval NFCTAG enum status
00126   */
00127 NFCTAG_StatusTypeDef M24LR::i2c_is_device_ready( const uint32_t Trials )
00128 {
00129   /* Test i2c with M24LR */
00130   //return mM24LR_IO.IsDeviceReady( M24LR_ADDR_DATA_I2C, Trials );
00131   uint8_t status = 1;
00132   char buffer;
00133   while (status != 0) {
00134     /* for device is ready address in M24Lr is M24LR_ADDR_DATA_I2C */
00135     status = dev_I2C.read(i2c_address_data, &buffer, 1, false);
00136   }
00137   if ( status == 0 ) {
00138     return NFCTAG_OK;
00139   } else {
00140     return NFCTAG_TIMEOUT;
00141   }
00142 }
00143 
00144 /**
00145   * @brief  Configure M24LR GPO
00146   * @param  ITConf : 0x01 = RFBUSY, 0x02 = RFWIP
00147   * @retval NFCTAG enum status
00148   */
00149 NFCTAG_StatusTypeDef M24LR::i2c_configure_GPO( const uint16_t ITConf )
00150 {
00151   NFCTAG_StatusTypeDef status = NFCTAG_ERROR;
00152   
00153   /* Configure GPO function on M24LR */
00154   if ( (ITConf & M24LR_IT_BUSY_MASK) == M24LR_IT_BUSY_MASK ) {
00155     status = i2c_setRF_Busy( );
00156   } else if ( (ITConf & M24LR_IT_WIP_MASK) == M24LR_IT_WIP_MASK ) {
00157     status = i2c_set_RF_WIP( );
00158   }
00159   return status;
00160 }
00161 
00162 /**
00163   * @brief  Configure GPO as RF WriteInProgress
00164   * @param  None
00165   * @retval NFCTAG enum status
00166   */
00167 NFCTAG_StatusTypeDef M24LR::i2c_set_RF_WIP( void )
00168 {
00169   uint8_t reg_value;
00170   NFCTAG_StatusTypeDef status;
00171   status = i2c_read_register(&reg_value, M24LR_CFG_REG, 1);
00172   
00173   if ( status != NFCTAG_OK ) {
00174     return status;
00175   }
00176   
00177   /* Update register value for WIP configuration */
00178   reg_value |= M24LR_CFG_WIPBUSY_MASK;
00179   
00180   /* Write CFG register */
00181   return i2c_write_register( &reg_value, M24LR_CFG_REG, 1 );
00182 }
00183 
00184 /**
00185   * @brief  Get Configuration of M24LR GPO
00186   * @param  GPOStatus : 0x01 = RFBUSY, 0x02 = RFWIP
00187   * @retval NFCTAG enum status
00188   */
00189 NFCTAG_StatusTypeDef M24LR::i2c_get_GPO_status( uint16_t * const pGPOStatus )
00190 {
00191   uint8_t reg_value;
00192   NFCTAG_StatusTypeDef status;
00193   
00194   /* Read actual value of CFG register */
00195   status = i2c_read_register( &reg_value, M24LR_CFG_REG, 1 );
00196   if ( status != NFCTAG_OK ) {
00197     return status;
00198   }
00199   
00200   /* Extract RF WIP/BUSY information */
00201   if ( (reg_value & M24LR_CFG_WIPBUSY_MASK) == M24LR_CFG_WIPBUSY_MASK ) {
00202     *pGPOStatus = M24LR_IT_WIP_MASK;
00203   } else {
00204     *pGPOStatus = M24LR_IT_BUSY_MASK;
00205   }
00206   
00207   return NFCTAG_OK;
00208 }
00209 
00210 /**
00211   * @brief  Read N bytes starting from specified I2C address
00212   * @param  pData : pointer of the data to store
00213   * @param  TarAddr : I2C data memory address to read
00214   * @param  NbByte : number of bytes to read
00215   * @retval NFCTAG enum status
00216   */
00217 NFCTAG_StatusTypeDef M24LR::i2c_read_data( uint8_t * const pData, const uint16_t TarAddr, const uint16_t NbByte )
00218 {  
00219   int status;
00220   /* Before calling this function M24LR must be ready, here is a check to detect an issue */
00221   if ( i2c_is_device_ready( 1 ) != NFCTAG_OK ) {
00222     return NFCTAG_TIMEOUT;
00223   }
00224   /* Rosarium: To check M24LR_ADDR_DATA_I2C is this case */
00225   /* return M24lr_IO_MemRead( pData, M24LR_ADDR_DATA_I2C, TarAddr, NbByte ); */
00226   status = dev_I2C.i2c_read(pData, i2c_address_data, TarAddr, NbByte);
00227   if ( status == 0 ) {
00228     return NFCTAG_OK;
00229   } else {
00230     return NFCTAG_TIMEOUT;
00231   }
00232 }
00233 
00234 /**
00235   * @brief  Write N data bytes starting from specified I2C Address
00236   * @brief  if I2C_Write_Lock bit = 0 or I2C_Password present => ack (modification OK)
00237   * @brief  if I2C_Write_Lock bit = 1  and no I2C_Password present => No ack (no modification)
00238   * @param  pData : pointer of the data to write
00239   * @param  TarAddr : I2C data memory address to write
00240   * @param  NbByte : number of bytes to write
00241   * @retval NFCTAG enum status
00242   */
00243 NFCTAG_StatusTypeDef M24LR::i2c_write_data( const uint8_t * const pData, const uint16_t TarAddr, const uint16_t NbByte )
00244 { 
00245   int status;
00246   uint8_t align_mem_offset;
00247   uint16_t bytes_to_write = NbByte;
00248   uint16_t mem_addr = TarAddr;
00249   uint8_t *pdata_index = (uint8_t *)pData;
00250   
00251   /* Before calling this function M24LR must be ready, here is a check to detect an issue */
00252   if ( i2c_is_device_ready( 1 ) != NFCTAG_OK ) {
00253     return NFCTAG_TIMEOUT;
00254   }
00255   
00256   /* M24LR can write a maximum of 4 bytes in EEPROM per i2c communication */
00257   do {
00258     /* To write data in M24LR, data must be aligned on the same row in memory */
00259     /* align_mem_offset is used to copy only Bytes that are on the same row  in memory */
00260     if ( bytes_to_write > M24LR_PAGEWRITE_NBBYTE ) {
00261       /* DataSize higher than max page write, copy data by page */
00262       align_mem_offset = M24LR_PAGEWRITE_NBBYTE - (mem_addr % M24LR_PAGEWRITE_NBBYTE);
00263     } else {
00264       /* DataSize lower or equal to max page write, copy only last bytes */
00265       align_mem_offset = bytes_to_write;
00266     }
00267 
00268     /* Write align_mem_offset bytes in memory */
00269     /* Rosarium: to Check as the address here is 0xA6 rather than 0xAE */
00270     /* dev_I2C.i2c_write(pdata_index, M24LR_ADDR_DATA_I2C, mem_addr, align_mem_offset); */
00271     status = dev_I2C.i2c_write(pdata_index, i2c_address_data, mem_addr, align_mem_offset);
00272     
00273     /* update index, dest address, size for next write */
00274     pdata_index += align_mem_offset;
00275     mem_addr += align_mem_offset;
00276     bytes_to_write -= align_mem_offset;
00277 
00278     /* Poll until EEPROM is available */
00279     while ( i2c_is_device_ready( 1 ) != NFCTAG_OK ) {};
00280   }
00281   while ( ( bytes_to_write > 0 ) && ( status == NFCTAG_OK ) );
00282   if ( status == 0 ) {
00283     return NFCTAG_OK;
00284   }
00285   else {
00286     return NFCTAG_ERROR;
00287   }
00288 }
00289 
00290 /**
00291   * @brief  Read N register bytes starting from specified I2C address
00292   * @param  pData : pointer of the data to store
00293   * @param  TarAddr : I2C memory address to read
00294   * @param  NbByte : number of bytes to read
00295   * @retval NFCTAG enum status
00296   */
00297 NFCTAG_StatusTypeDef M24LR::i2c_read_register( uint8_t * const pData, const uint16_t TarAddr, const uint16_t NbByte )
00298 {  
00299   /* Before calling read function M24LR must be ready, here is a check to detect an issue */
00300   int status;
00301   
00302   /* Before calling any read function M24LR must be ready, here is a check to detect an issue */
00303   if ( i2c_is_device_ready( 1 ) != NFCTAG_OK ) {
00304     return NFCTAG_TIMEOUT;
00305   }
00306   
00307   /* Read actual value of register */
00308   status = dev_I2C.i2c_read(pData, i2c_address_syst, TarAddr, NbByte);
00309   
00310   if ( status == 0 ) {
00311     return NFCTAG_OK;
00312   } else {
00313     return NFCTAG_TIMEOUT;
00314   }
00315 }
00316 
00317 /**
00318   * @brief  Write N bytes to specific register
00319   * @param  pData : pointer of the data to write
00320   * @param  TarAddr : I2C register address to write
00321   * @param  NbByte : number of bytes to write
00322   * @retval NFCTAG enum status
00323   */
00324 NFCTAG_StatusTypeDef M24LR::i2c_write_register( const uint8_t * const pData, const uint16_t TarAddr, const uint16_t NbByte )
00325 { 
00326   int status;
00327   uint8_t align_mem_offset;
00328   uint16_t bytes_to_write = NbByte;
00329   uint16_t mem_addr = TarAddr;
00330   uint8_t *pdata_index = (uint8_t *)pData;
00331   
00332   /* Before calling this function M24LR must be ready, here is a check to detect an issue */
00333   if ( i2c_is_device_ready( 1 ) != NFCTAG_OK ) {
00334     return NFCTAG_TIMEOUT;
00335   }
00336   
00337   /* M24LR can write a maximum of 4 bytes in EEPROM per i2c communication */
00338   do {
00339     /* To write data in M24LR, data must be aligned on the same row in memory */
00340     /* align_mem_offset is used to copy only Bytes that are on the same row  in memory */
00341     if ( bytes_to_write > M24LR_PAGEWRITE_NBBYTE ) {
00342       /* DataSize higher than max page write, copy data by page */
00343       align_mem_offset = M24LR_PAGEWRITE_NBBYTE - (mem_addr % M24LR_PAGEWRITE_NBBYTE);
00344     } else {
00345       /* DataSize lower or equal to max page write, copy only last bytes */
00346       align_mem_offset = bytes_to_write;
00347     }
00348     
00349     /* Write align_mem_offset bytes in register */
00350     // status = M24lr_IO_MemWrite( pdata_index, M24LR_ADDR_SYST_I2C, mem_addr, align_mem_offset );
00351     status = dev_I2C.i2c_write(pdata_index, i2c_address_syst, mem_addr, align_mem_offset);
00352     
00353     /* update index, dest address, size for next write */
00354     pdata_index += align_mem_offset;
00355     mem_addr += align_mem_offset;
00356     bytes_to_write -= align_mem_offset;
00357     
00358     /* Poll until EEPROM is available */
00359     while ( i2c_is_device_ready( 1 ) != NFCTAG_OK ) {};
00360   }
00361   while ( ( bytes_to_write > 0 ) && ( status == NFCTAG_OK ) );
00362   
00363   if ( status == 0 ) {
00364     return NFCTAG_OK;
00365   } else {
00366     return NFCTAG_ERROR;
00367   }
00368 }
00369 
00370 /**
00371   * @brief  Read M24LR UID
00372   * @param  UID : M24LR_UID pointer of the UID to store
00373   * @retval NFCTAG enum status
00374   */
00375 NFCTAG_StatusTypeDef M24LR::i2c_read_UID( M24LR_UID * const pUid )
00376 {
00377   uint8_t areg_value[8];
00378   uint8_t i;
00379   NFCTAG_StatusTypeDef status;
00380   
00381   /* Read actual value of UID registers */
00382   status = i2c_read_register( areg_value, M24LR_UID_REG, 8 );
00383 
00384   if ( status != NFCTAG_OK ) {
00385     return status;
00386   }
00387   
00388   /* Store information in 2 WORD */
00389   pUid->MSB_UID = 0;
00390   
00391   for ( i = 0; i < 4; i++ ) {
00392     pUid->MSB_UID = (pUid->MSB_UID << 8) | areg_value[7 - i];
00393   }
00394   pUid->LSB_UID = 0;
00395   
00396   for ( i = 0; i < 4; i++ ) {
00397     pUid->LSB_UID = (pUid->LSB_UID << 8) | areg_value[3 - i];
00398   }
00399   
00400   return NFCTAG_OK;
00401 }
00402 
00403 /**
00404   * @brief  Read DSFID
00405   * @param  pData : pointer of the DSFID to store
00406   * @retval NFCTAG enum status
00407   */
00408 NFCTAG_StatusTypeDef M24LR::i2c_read_DSFID( uint8_t * const pDsfid )
00409 {
00410   /* Read actual value of DSFID register */
00411   return i2c_read_register( pDsfid, M24LR_DSFID_REG, 1 );
00412 }
00413 
00414 /**
00415   * @brief  Read AFI
00416   * @param  pData : pointer of the AFI to store
00417   * @retval NFCTAG enum status
00418   */
00419 NFCTAG_StatusTypeDef M24LR::i2c_read_AFI( uint8_t * const pAfi )
00420 {
00421   /* Read actual value of AFI register */
00422   return i2c_read_register( pAfi, M24LR_AFI_REG, 1 );
00423 }
00424 
00425 /**
00426   * @brief  Read status of I2C Lock Sectors
00427   * @param  Lock_sector : M24LR_Lock_Sectors pointer of the I2c lock sector status to store
00428   * @retval NFCTAG enum status
00429   */
00430 NFCTAG_StatusTypeDef M24LR::i2c_read_I2C_lock_sector( M24LR_Lock_Sectors * const pLock_sector )
00431 {
00432   uint8_t areg_value[8];
00433   NFCTAG_StatusTypeDef status;
00434 
00435   /* Read actual value of I2c Write Lock registers */
00436   status = i2c_read_register( areg_value, M24LR_LOCK_REG, 8 );
00437   if ( status != NFCTAG_OK ) {
00438     return status;
00439   }
00440   
00441   /* Dispatch information to corresponding struct member */
00442   pLock_sector->sectors_63_56 = areg_value[7];
00443   pLock_sector->sectors_55_48 = areg_value[6];
00444   pLock_sector->sectors_47_40 = areg_value[5];
00445   pLock_sector->sectors_39_32 = areg_value[4];
00446   pLock_sector->sectors_31_24 = areg_value[3];
00447   pLock_sector->sectors_23_16 = areg_value[2];
00448   pLock_sector->sectors_15_8 = areg_value[1];
00449   pLock_sector->sectors_7_0 = areg_value[0];
00450   
00451   return NFCTAG_OK;
00452 }
00453 
00454 /**
00455   * @brief  Lock I2C write on an EEPROM Sectors
00456   * @brief  Need a presentation of I2C Password to be effective
00457   * @param  Sector : EEPROM Sector number to lock (between 0 to 63)
00458   * @retval NFCTAG enum status
00459   */
00460 NFCTAG_StatusTypeDef M24LR::i2c_I2C_lock_sector( const uint8_t Sector )
00461 {
00462   NFCTAG_StatusTypeDef status;
00463   uint8_t reg_value = 0;
00464   uint16_t sector_write_lock_addr;
00465   
00466   /* Compute register address */
00467   sector_write_lock_addr = M24LR_LOCK_REG | (Sector >> 3);
00468   
00469   /* Read actual WriteLockStatus */
00470   status = i2c_read_register( &reg_value, sector_write_lock_addr, 1 );
00471   if ( status != NFCTAG_OK ) {
00472     return status;
00473   }
00474   
00475   /* Compute and update new WriteLockStatus */
00476   reg_value |= 1 << ( Sector % 8 );
00477 
00478   /* Write WriteLock register */
00479   return i2c_write_register( &reg_value, sector_write_lock_addr, 1 );
00480 }
00481 
00482 /**
00483   * @brief  UnLock I2C write on a EEPROM Sector
00484   * @brief  Need an presentation of I2C Password to be effective
00485   * @param  pSector : EEPROM Sector number to unlock (between 0 to 63)
00486   * @retval NFCTAG enum status
00487   */
00488 NFCTAG_StatusTypeDef M24LR::i2c_I2C_unlock_sector( const uint8_t Sector )
00489 {
00490   NFCTAG_StatusTypeDef status;
00491   uint8_t reg_value = 0;
00492   uint16_t sector_write_lock_addr;
00493   
00494   /* Compute register address */
00495   sector_write_lock_addr = M24LR_LOCK_REG | (Sector >> 3);
00496   
00497   /* Read actual WriteLockStatus */
00498   status = i2c_read_register( &reg_value, sector_write_lock_addr, 1 );
00499   if ( status != NFCTAG_OK ) {
00500     return status;
00501   }
00502   
00503   /* Compute and update new WriteLockStatus */
00504   reg_value &= ~( 1 << ( Sector % 8 ) );
00505 
00506   /* Write WriteLock register */
00507   return i2c_write_register( &reg_value, sector_write_lock_addr, 1 );
00508 }
00509 
00510 /**
00511   * @brief  Present I2C password, authorize I2C write
00512   * @param  PassWord : Password value on 32bits
00513   * @retval NFCTAG enum status
00514   */
00515 NFCTAG_StatusTypeDef M24LR::i2c_present_I2C_password( const uint32_t PassWord )
00516 {
00517   uint8_t ai2c_message[9] = {0};
00518   uint8_t i;
00519   
00520   /* Build I2C Message with Password + Validation code 0x09 + Password */
00521   ai2c_message[4] = 0x09;
00522   i = 0;
00523   while ( i < 4 ) {
00524     ai2c_message[i] = ( PassWord >> (i * 8) ) & 0xFF;
00525     ai2c_message[i + 5] = ( PassWord >> (i * 8) ) & 0xFF;
00526     i++;
00527   };
00528   
00529   /* Present password to M24LR */
00530   return i2c_write_register( ai2c_message, M24LR_I2C_PWD_REG, 9 );
00531 }
00532 
00533 /**
00534   * @brief  Write new I2C password
00535   * @brief  Need to present good I2CPassword before using this function
00536   * @param  PassWord : new I2C PassWord value on 32bits
00537   * @retval NFCTAG enum status
00538   */
00539 NFCTAG_StatusTypeDef M24LR::i2c_write_I2C_password( const uint32_t PassWord )
00540 {
00541   uint8_t ai2c_message[9] = {0};
00542   uint8_t i;
00543   
00544   /* Build I2C Message with Password + Validation code 0x07 + Password */
00545   ai2c_message[4] = 0x07;
00546   i = 0;
00547   while ( i < 4 ) {
00548     ai2c_message[i] = ( PassWord >> (i * 8) ) & 0xFF;
00549     ai2c_message[i + 5] = ( PassWord >> (i * 8) ) & 0xFF;
00550     i++;
00551   };
00552   
00553   /* Write Password to register */
00554   return i2c_write_register( ai2c_message, M24LR_I2C_PWD_REG, 9 );
00555 }
00556 
00557 /**
00558   * @brief  Read SectorSecurityStatus (defining RF access allowed)
00559   * @param  SectorNb : Sector number to get RF security status
00560   * @param  pData : M24LR_SECTOR_SEC pointer of the data to store
00561   * @retval NFCTAG enum status
00562   */
00563 NFCTAG_StatusTypeDef M24LR::i2c_read_SSSx( const uint8_t SectorNb, M24LR_SECTOR_SEC * const pData )
00564 {
00565   uint8_t reg_value;
00566   NFCTAG_StatusTypeDef status;
00567   uint16_t sector_security_addr;
00568   
00569   /* Compute Sector Security register address */
00570   sector_security_addr = M24LR_SSS_REG | SectorNb;
00571   
00572   /* Read actual value of SectorSecurityStatus register */
00573   status = i2c_read_register( &reg_value, sector_security_addr, 1 );
00574   if ( status != NFCTAG_OK ) {
00575     return status;
00576   }
00577   
00578   /* Extract Sector Security Status configuration */
00579   pData->SectorLock = reg_value & M24LR_SSS_LOCK_MASK;
00580   pData->RW_Protection = (reg_value & M24LR_SSS_RW_MASK) >> 1;
00581   pData->PassCtrl = (reg_value & M24LR_SSS_PASSCTRL_MASK) >> 3;
00582   
00583   return NFCTAG_OK;
00584 }
00585 
00586 /**
00587   * @brief  Write SectorSecurityStatus (defining RF access allowed)
00588   * @brief  Need an presentation of I2C Password to be effective
00589   * @param  SectorNb : Sector number to set RF security
00590   * @param  pData : M24LR_SECTOR_SEC pointer of the data to write
00591   * @retval NFCTAG enum status
00592   */
00593 NFCTAG_StatusTypeDef M24LR::i2c_write_SSSx( const uint8_t SectorNb, const M24LR_SECTOR_SEC * const pData )
00594 {
00595   uint8_t reg_value;
00596   uint16_t sector_security_addr;
00597   
00598   /* Compute Sector Security register address */
00599   sector_security_addr = M24LR_SSS_REG | SectorNb;
00600   
00601   /* Update Sector Security Status */ 
00602   reg_value = (pData->PassCtrl << 3) & M24LR_SSS_PASSCTRL_MASK;
00603   reg_value |= ((pData->RW_Protection << 1) & M24LR_SSS_RW_MASK);
00604   reg_value |= (pData->SectorLock & M24LR_SSS_LOCK_MASK);
00605   
00606   /* Write SectorSecurityStatus register */
00607   return i2c_write_register( &reg_value, sector_security_addr, 1 );
00608 }
00609 
00610 /**
00611   * @brief  Read Memory Size info
00612   * @param  SizeInfo : M24LR_Mem_Size pointer of the data to store
00613   * @retval NFCTAG enum status
00614   */
00615 NFCTAG_StatusTypeDef M24LR::i2c_read_mem_size( M24LR_Mem_Size * const pSizeInfo )
00616 {
00617   uint8_t areg_value[3];
00618   NFCTAG_StatusTypeDef status;
00619   
00620   /* Read actual value of Mem_Size register */
00621   status = i2c_read_register( areg_value, M24LR_MEMSIZE_REG, 3 );
00622   if ( status != NFCTAG_OK ) {
00623     return status;
00624   }
00625   
00626   /* Extract Mem information */
00627   pSizeInfo->BlockSize = areg_value[2];
00628   pSizeInfo->Mem_Size = areg_value[1];
00629   pSizeInfo->Mem_Size = (pSizeInfo->Mem_Size << 8) | areg_value[0];
00630 
00631   return NFCTAG_OK;
00632 }
00633 
00634 /**
00635   * @brief  Get GPO Configuration status
00636   * @param  Rf_Wip_Busy : M24LR_GPO_STATUS pointer of the data to store
00637   * @retval NFCTAG enum status
00638   */
00639 NFCTAG_StatusTypeDef M24LR::i2c_get_RF_WIP_busy( M24LR_GPO_STATUS * const pRf_Wip_Busy )
00640 {
00641   uint8_t reg_value;
00642   NFCTAG_StatusTypeDef status;
00643   
00644   /* Read actual value of CFG register */
00645   status = i2c_read_register( &reg_value, M24LR_CFG_REG, 1 );
00646   if ( status != NFCTAG_OK ) {
00647     return status;
00648   }
00649   
00650   /* Extract RF WIP/BUSY information */
00651   if ( (reg_value & M24LR_CFG_WIPBUSY_MASK) == M24LR_CFG_WIPBUSY_MASK ) {
00652     *pRf_Wip_Busy = M24LR_GPO_WIP;
00653   } else {
00654     *pRf_Wip_Busy = M24LR_GPO_BUSY;
00655   }
00656 
00657   return NFCTAG_OK;
00658 }
00659 
00660 /**
00661   * @brief  Configure GPO as RF Busy
00662   * @param  None
00663   * @retval NFCTAG enum status
00664   */
00665 NFCTAG_StatusTypeDef M24LR::i2c_setRF_Busy( void )
00666 {
00667   uint8_t reg_value;
00668   int status;
00669   
00670   /* Read actual value of CFG register */
00671   status = dev_I2C.i2c_read( &reg_value, i2c_address_syst, (uint16_t)M24LR_CFG_REG, 1 );
00672   if ( status != 0 ) {
00673     return NFCTAG_TIMEOUT;
00674   }
00675   
00676   /* Update register value for BUSY configuration */
00677   reg_value &= !M24LR_CFG_WIPBUSY_MASK;
00678   
00679   /* Write CFG register */
00680   status = i2c_write_register( &reg_value, M24LR_CFG_REG, 1 );
00681   if ( status == 0 ) {
00682     return NFCTAG_OK;
00683   } else {
00684     return NFCTAG_TIMEOUT;
00685   }
00686 }
00687 
00688 /**
00689   * @brief  Get Energy harvesting mode status
00690   * @param  EH_mode : M24LR_EH_MODE_STATUS pointer of the data to store
00691   * @retval NFCTAG enum status
00692   */
00693 NFCTAG_StatusTypeDef M24LR::i2c_read_EH_mode( M24LR_EH_MODE_STATUS * const pEH_mode )
00694 {
00695   uint8_t reg_value;
00696   NFCTAG_StatusTypeDef status;
00697   
00698   /* Read actual value of CFG register */
00699   status = i2c_read_register( &reg_value, M24LR_CFG_REG, 1 );
00700   if ( status != NFCTAG_OK ) {
00701     return status;
00702   }
00703   
00704   /* Extract EH_mode configuration */
00705   if ( (reg_value & M24LR_CFG_EHMODE_MASK) == M24LR_CFG_EHMODE_MASK ) {
00706     *pEH_mode = M24LR_EH_MODE_DISABLE;
00707   } else {
00708     *pEH_mode = M24LR_EH_MODE_ENABLE;
00709   }
00710   
00711   return NFCTAG_OK;
00712 }
00713 
00714 /**
00715   * @brief  Enable Energy harvesting mode
00716   * @param  None
00717   * @retval NFCTAG enum status
00718   */
00719 NFCTAG_StatusTypeDef M24LR::i2c_enable_EH_mode( void )
00720 {
00721   uint8_t reg_value;
00722   NFCTAG_StatusTypeDef status;
00723   
00724   /* Read actual value of CFG register */
00725   status = i2c_read_register( &reg_value, M24LR_CFG_REG, 1 );
00726   if ( status != NFCTAG_OK ) {
00727     return status;
00728   }
00729   
00730   /* Update EH_mode */
00731   reg_value &= ~M24LR_CFG_EHMODE_MASK;
00732   
00733   /* Write CFG register */
00734   return i2c_write_register( &reg_value, M24LR_CFG_REG, 1 );
00735 }
00736 
00737 /**
00738   * @brief  Disable Energy harvesting mode
00739   * @param  None
00740   * @retval NFCTAG enum status
00741   */
00742 NFCTAG_StatusTypeDef M24LR::i2c_disable_EH_mode( void )
00743 {
00744   uint8_t reg_value;
00745   NFCTAG_StatusTypeDef status;
00746   
00747   /* Read actual value of CFG register */
00748   status = i2c_read_register( &reg_value, M24LR_CFG_REG, 1 );
00749   if ( status != NFCTAG_OK ) {
00750     return status;
00751   }
00752   
00753   /* Update EH_mode */
00754   reg_value |= M24LR_CFG_EHMODE_MASK;
00755   
00756   /* Write CFG register */
00757   return i2c_write_register( &reg_value, M24LR_CFG_REG, 1 );
00758 }
00759 
00760 /**
00761   * @brief  Read Vout sink current configuration status for Energy Harvesting
00762   * @param  EH_Cfg : M24LR_EH_CFG_VOUT pointer of the data to store
00763   * @retval NFCTAG enum status
00764   */
00765 NFCTAG_StatusTypeDef M24LR::i2c_read_EH_cfg( M24LR_EH_CFG_VOUT * const pEH_Cfg )
00766 {
00767   uint8_t reg_value;
00768   NFCTAG_StatusTypeDef status;
00769   
00770   /* Read actual value of CFG register */
00771   status = i2c_read_register( &reg_value, M24LR_CFG_REG, 1 );
00772   if ( status != NFCTAG_OK ) {
00773     return status;
00774   }
00775   
00776   /* Extract Vout configuration for EH information */
00777   reg_value &= (M24LR_CFG_EHCFG1_MASK | M24LR_CFG_EHCFG0_MASK);
00778   switch ( reg_value ) {
00779     case 0: {
00780       *pEH_Cfg = M24LR_EH_Cfg_6MA;
00781       break;
00782     }
00783     case 1: {
00784       *pEH_Cfg = M24LR_EH_Cfg_3MA;
00785       break;
00786     }
00787     case 2: {
00788       *pEH_Cfg = M24LR_EH_Cfg_1MA;
00789       break;
00790     }
00791     case 3: {
00792       *pEH_Cfg = M24LR_EH_Cfg_300UA;
00793       break;
00794     }
00795     default: {
00796       *pEH_Cfg = M24LR_EH_Cfg_6MA;
00797     }
00798   } 
00799   
00800   return NFCTAG_OK;
00801 }
00802 
00803 /**
00804   * @brief  Write Vout sink current configuration status for Energy Harvesting
00805   * @param  EH_Cfg : M24LR_EH_CFG_VOUT value to configure Vout
00806   * @retval NFCTAG enum status
00807   */
00808 NFCTAG_StatusTypeDef M24LR::i2c_write_EH_cfg( const M24LR_EH_CFG_VOUT EH_Cfg )
00809 {
00810   uint8_t reg_value;
00811   NFCTAG_StatusTypeDef status;
00812   
00813   /* Read actual value of CFG register */
00814   status = i2c_read_register( &reg_value, M24LR_CFG_REG, 1 );
00815   if ( status != NFCTAG_OK ) {
00816     return status;
00817   }
00818   
00819   /* Update Vout configuration */
00820   reg_value &= ~(M24LR_CFG_EHCFG1_MASK | M24LR_CFG_EHCFG0_MASK);
00821   reg_value |= EH_Cfg;
00822   
00823   /* Write CFG register */
00824   return i2c_write_register( &reg_value, M24LR_CFG_REG, 1 );
00825 }
00826 
00827 /**
00828   * @brief  Get Energy Harvesting status
00829   * @param  EH_Val : M24LR_EH_STATUS pointer of the data to store
00830   * @retval NFCTAG enum status
00831   */
00832 NFCTAG_StatusTypeDef M24LR::i2c_get_EH( M24LR_EH_STATUS * const pEH_Val )
00833 {
00834   uint8_t reg_value;
00835   NFCTAG_StatusTypeDef status;
00836   
00837   /* Read actual value of CTRL register */
00838   status = i2c_read_register( &reg_value, M24LR_CTRL_REG, 1 );
00839   if ( status != NFCTAG_OK ) {
00840     return status;
00841   }
00842   
00843   /* Extract EH information */
00844   if ( (reg_value & M24LR_CTRL_EHEN_MASK) == M24LR_CTRL_EHEN_MASK ) {
00845     *pEH_Val = M24LR_EH_ENABLE;
00846   } else {
00847     *pEH_Val = M24LR_EH_DISABLE;
00848   }
00849   
00850   return NFCTAG_OK;
00851 }
00852 
00853 /**
00854   * @brief  Enable Energy Harvesting
00855   * @param  None
00856   * @retval NFCTAG enum status
00857   */
00858 NFCTAG_StatusTypeDef M24LR::i2c_set_EH( void )
00859 {
00860   uint8_t reg_value;
00861   NFCTAG_StatusTypeDef status;
00862   
00863   /* Read actual value of CTRL register */
00864   status = i2c_read_register( &reg_value, M24LR_CTRL_REG, 1 );
00865   if ( status != NFCTAG_OK ) {
00866     return status;
00867   }
00868   
00869   /* Update EH configuration */
00870   reg_value |= M24LR_CTRL_EHEN_MASK;
00871   
00872   /* Write CTRL Register */
00873   return i2c_write_register( &reg_value, M24LR_CTRL_REG, 1 );
00874 }
00875 
00876 /**
00877   * @brief  Disable Energy Harvesting
00878   * @param  None
00879   * @retval NFCTAG enum status
00880   */
00881 NFCTAG_StatusTypeDef M24LR::i2c_reset_EH( void )
00882 {
00883   uint8_t reg_value;
00884   NFCTAG_StatusTypeDef status;
00885   
00886   /* Read actual value of CTRL register */
00887   status = i2c_read_register( &reg_value, M24LR_CTRL_REG, 1 );
00888   if ( status != NFCTAG_OK ) {
00889     return status;
00890   }
00891   
00892   /* Update EH configuration */
00893   reg_value &= ~M24LR_CTRL_EHEN_MASK;
00894   
00895   /* Write CTRL register */
00896   return i2c_write_register( &reg_value, M24LR_CTRL_REG, 1 );
00897 }
00898 
00899 /**
00900   * @brief  Check if RF Field is present in front of M24LR
00901   * @param  pRF_Field :  M24LR_FIELD_STATUS pointer of the data to store
00902   * @retval NFCTAG enum status
00903   */
00904 NFCTAG_StatusTypeDef M24LR::i2c_get_RF_field( M24LR_FIELD_STATUS * const pRF_Field )
00905 {
00906   NFCTAG_StatusTypeDef status;
00907   uint8_t reg_value = 0;
00908 
00909   /* Read actual value of CTRL register */
00910   status = i2c_read_register( &reg_value, M24LR_CTRL_REG, 1 );
00911   
00912   /* Extract RF Field information */
00913   if ( status == NFCTAG_OK ) {
00914     if ( (reg_value & M24LR_CTRL_FIELD_MASK) == M24LR_CTRL_FIELD_MASK ) {
00915       *pRF_Field = M24LR_FIELD_ON;
00916     } else {
00917       *pRF_Field = M24LR_FIELD_OFF;
00918     }
00919     
00920     return NFCTAG_OK;
00921   }
00922   
00923   return status;
00924 }
00925 
00926 /**
00927   * @brief  Check if Write Timing is good
00928   * @param  pT_Prog : M24LR_T_PROG_STATUS pointer of the data to store
00929   * @retval NFCTAG enum status
00930   */
00931 NFCTAG_StatusTypeDef M24LR::i2c_get_TProg( M24LR_T_PROG_STATUS * const pT_Prog )
00932 {
00933   NFCTAG_StatusTypeDef status;
00934   uint8_t reg_value = 0;
00935   
00936   /* Read actual value of CTRL register */
00937   status = i2c_read_register( &reg_value, M24LR_CTRL_REG, 1 );
00938   
00939   /* Extract T-Prog information */
00940   if ( status == NFCTAG_OK ) {
00941     if ( (reg_value & M24LR_CTRL_TPROG_MASK) == M24LR_CTRL_TPROG_MASK ) {
00942       *pT_Prog = M24LR_T_PROG_OK;
00943     } else {
00944       *pT_Prog = M24LR_T_PROG_NO;
00945     }
00946 
00947     return NFCTAG_OK;
00948   } else {
00949     return status;
00950   }
00951 }
00952 
00953 
00954 /******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/