NB-IoT

Dependencies:   NDefLib X_NUCLEO_NFC02A1 hdc1080 mbed

Fork of HelloWorld_NFC02A1 by ST

Files at this revision

API Documentation at this revision

Comitter:
rosarium
Date:
Wed Jul 27 09:25:33 2016 +0000
Child:
1:11ae12d41082
Commit message:
first release of the complete mbed library for HelloWorld_NFC02A1

Changed in this revision

Lib_NDEF/lib_NDEF.cpp Show annotated file Show diff for this revision Revisions of this file
Lib_NDEF/lib_NDEF.h Show annotated file Show diff for this revision Revisions of this file
Lib_NDEF/lib_NDEF_URI.cpp Show annotated file Show diff for this revision Revisions of this file
Lib_NDEF/lib_NDEF_URI.h Show annotated file Show diff for this revision Revisions of this file
Lib_NDEF/tagtype5_wrapper.cpp Show annotated file Show diff for this revision Revisions of this file
Lib_NDEF/tagtype5_wrapper.h Show annotated file Show diff for this revision Revisions of this file
X_NUCLEO_NFC02A1/Common/common.h Show annotated file Show diff for this revision Revisions of this file
X_NUCLEO_NFC02A1/Interfaces/X_NUCLEO_NFC02A1.cpp Show annotated file Show diff for this revision Revisions of this file
X_NUCLEO_NFC02A1/Interfaces/X_NUCLEO_NFC02A1.h Show annotated file Show diff for this revision Revisions of this file
X_NUCLEO_NFC02A1/X_NUCLEO_COMMON/DevI2C/DevI2C.h Show annotated file Show diff for this revision Revisions of this file
X_NUCLEO_NFC02A1/m24lr/m24lr.cpp Show annotated file Show diff for this revision Revisions of this file
X_NUCLEO_NFC02A1/m24lr/m24lr.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Lib_NDEF/lib_NDEF.cpp	Wed Jul 27 09:25:33 2016 +0000
@@ -0,0 +1,591 @@
+/**
+  ******************************************************************************
+  * @file    lib_NDEF.c
+  * @author  MMY Application Team
+  * @version $Revision: 1583 $
+  * @date    $Date: 2016-02-03 15:06:51 +0100 (Wed, 03 Feb 2016) $
+  * @brief   This file help to manage NDEF file, to parse and identify them.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
+  *
+  * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+  * You may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at:
+  *
+  *        http://www.st.com/myliberty  
+  *
+  * Unless required by applicable law or agreed to in writing, software 
+  * distributed under the License is distributed on an "AS IS" BASIS, 
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+  * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+  * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF.h"
+#include <stdint.h>
+#include <string.h>
+/** @addtogroup NFC_libraries
+ *  @{
+ *  @brief  <b>This is the library used to manage the content of the TAG (data)
+ *          But also the specific feature of the tag, for instance
+ *          password, gpo... </b>
+ */
+
+
+/** @addtogroup libNFC_FORUM
+  * @{
+  * @brief  This part of the library manage data which follow NFC forum organisation.
+  */
+
+/** @defgroup libNDEF_Private_Functions
+  * @{
+  */
+
+
+
+/**
+  * @brief  This function check that the tag contain a NDEF message.
+  * @retval NDEF_OK : There is a NDEF file stored in tag.
+  * @retval NDEF_ERROR : No NDEF in the tag.
+  */
+uint16_t NDEF::NDEF_IsNDEFPresent( void )
+{
+  uint16_t FileSize;
+  uint8_t uNDEFHeader [0x2];
+
+  /* Check NDEF existence */
+  ReadData( NDEF_SIZE_OFFSET, 2, uNDEFHeader );
+  FileSize = (uint16_t)( (uNDEFHeader[0x00]<<8) | uNDEFHeader[0x01] );
+
+  if( FileSize != 0 )
+    return NDEF_OK;
+  else
+    return NDEF_ERROR;
+}
+
+/**
+  * @brief  This function identify the type of record.
+  * @param  pRecordStruct : pointer on the record structure to fill.
+  * @param  pPayload : pointer on the payload.
+  * @retval Status : Status of the operation.
+  */
+uint16_t NDEF::NDEF_IdentifySPRecord( sRecordInfo *pRecordStruct, uint8_t* pPayload )
+{
+  uint16_t status = NDEF_ERROR;
+  uint16_t SizeOfRecordHeader, TypeNbByte, PayloadLengthField, IDLengthField, IDNbByte;
+
+  /* Is ID length field present */
+  if( (*pPayload) & IL_Mask )
+  {
+    IDLengthField = ID_LENGTH_FIELD;
+  }
+  else
+  {
+    IDLengthField = 0;
+  }
+
+  /* it's a SR */
+  if( (*pPayload) & SR_Mask )
+  {
+    TypeNbByte = pPayload[1];
+    PayloadLengthField = 1;
+    if( IDLengthField == ID_LENGTH_FIELD )
+      IDNbByte = pPayload[3];
+    else
+      IDNbByte = 0;
+  }
+  else
+  {
+    TypeNbByte = pPayload[1];
+    PayloadLengthField = 4;
+    if( IDLengthField == ID_LENGTH_FIELD )
+      IDNbByte = pPayload[6];
+    else
+      IDNbByte = 0;
+  }
+
+  SizeOfRecordHeader = RECORD_FLAG_FIELD + TYPE_LENGTH_FIELD + PayloadLengthField + IDLengthField + TypeNbByte + IDNbByte;
+
+  /* it's a SR */
+  if( pPayload[0] & SR_Mask )
+  {
+    pRecordStruct->RecordFlags = pPayload[0];
+    pRecordStruct->TypeLength = TypeNbByte;
+    pRecordStruct->PayloadLength3 = 0;
+    pRecordStruct->PayloadLength2 = 0;
+    pRecordStruct->PayloadLength1 = 0;
+    pRecordStruct->PayloadLength0 = pPayload[2];
+    pRecordStruct->IDLength = IDNbByte;
+    memcpy( pRecordStruct->Type, &pPayload[3+IDNbByte], TypeNbByte );
+    memcpy( pRecordStruct->ID, &pPayload[3+IDNbByte+TypeNbByte], IDNbByte );
+    pRecordStruct->PayloadOffset = SizeOfRecordHeader;
+  }
+  else
+  {
+    pRecordStruct->RecordFlags = pPayload[0];
+    pRecordStruct->TypeLength = TypeNbByte;
+    pRecordStruct->PayloadLength3 = pPayload[2];
+    pRecordStruct->PayloadLength2 = pPayload[3];
+    pRecordStruct->PayloadLength1 = pPayload[4];
+    pRecordStruct->PayloadLength0 = pPayload[5];
+    pRecordStruct->IDLength = IDNbByte;
+    memcpy( pRecordStruct->Type, &pPayload[6+IDNbByte], TypeNbByte );
+    memcpy( pRecordStruct->ID, &pPayload[6+IDNbByte+TypeNbByte], IDNbByte );
+    pRecordStruct->PayloadOffset = SizeOfRecordHeader;
+  }
+
+  pRecordStruct->PayloadBufferAdd = (uint32_t)( pPayload + SizeOfRecordHeader );
+
+  status = NDEF_ParseRecordHeader( pRecordStruct );
+
+  return status;
+}
+
+/**
+  * @brief  This function parse the record header and dispatch regarding TNF value.
+  * @param  pRecordStruct : pointer on the record structure to fill.
+  * @retval NDEF_OK : record identified and structure filled.
+  * @retval NDEF_ERROR : Not supported.
+  */
+uint16_t NDEF::NDEF_ParseRecordHeader( sRecordInfo *pRecordStruct )
+{
+  uint16_t status = NDEF_OK;
+
+  switch( (pRecordStruct->RecordFlags & TNF_Mask) )
+  {
+    case TNF_WellKnown:
+      NDEF_ParseWellKnownType( pRecordStruct );
+      break;
+
+    case TNF_MediaType:
+      NDEF_ParseMediaType( pRecordStruct );
+      break;
+
+    case TNF_NFCForumExternal:
+      NDEF_ParseForumExternalType( pRecordStruct);
+      break;
+
+  default:
+      /* currently not supported or unknown*/
+      pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
+      status = NDEF_ERROR;
+  }
+  return status;
+}
+
+/**
+  * @brief  This function parse the Well Known type record.
+  * @param  pRecordStruct : pointer on the record structure to fill.
+  */
+void NDEF::NDEF_ParseWellKnownType( sRecordInfo *pRecordStruct )
+{
+  uint8_t* pPayload;
+
+  pPayload = (uint8_t*)( pRecordStruct->PayloadBufferAdd );
+
+  if( !memcmp( &(pRecordStruct->Type), SMART_POSTER_TYPE_STRING, pRecordStruct->TypeLength ) )
+  { 
+    /* special case where   we have to parse others records */
+    pRecordStruct->NDEF_Type = SMARTPOSTER_TYPE;
+    NDEF_ParseSP( pRecordStruct );
+  }
+
+  else if( !memcmp( &(pRecordStruct->Type), URI_TYPE_STRING, pRecordStruct->TypeLength ) )
+  { 
+    /* it's an URI Type check if it's an URL or SMS or ... */
+    /* check identifier */
+    if( *pPayload == URI_ID_0x00 ) 
+    {
+      NDEF_ParseURI( pRecordStruct );
+    }
+    else if( (*pPayload > URI_ID_0x00) && (*pPayload < URI_RFU) ) 
+    {
+      /* email special case  */
+      if( *pPayload == (uint8_t) URI_ID_0x06 )
+      {
+        pRecordStruct->NDEF_Type = URI_EMAIL_TYPE;
+      }
+      else
+      {
+        pRecordStruct->NDEF_Type = WELL_KNOWN_ABRIDGED_URI_TYPE;
+      }
+    }
+    else
+    {
+      pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
+    }
+  }
+
+  else if( !memcmp( &(pRecordStruct->Type), TEXT_TYPE_STRING, pRecordStruct->TypeLength ) )
+  {
+    pRecordStruct->NDEF_Type = TEXT_TYPE;
+  }
+  else
+    pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
+}
+
+/**
+  * @brief  This function parse the Media type record.
+  * @param  pRecordStruct : pointer on the record structure to fill.
+  */
+void NDEF::NDEF_ParseMediaType( sRecordInfo *pRecordStruct )
+{
+  if( !memcmp( &(pRecordStruct->Type), VCARD_TYPE_STRING, pRecordStruct->TypeLength ) )
+    pRecordStruct->NDEF_Type = VCARD_TYPE;
+  else if( !memcmp( &(pRecordStruct->Type), XVCARD_TYPE_STRING, pRecordStruct->TypeLength ) )
+    pRecordStruct->NDEF_Type = VCARD_TYPE;
+  else if( !memcmp( &(pRecordStruct->Type), XVCARD2_TYPE_STRING, pRecordStruct->TypeLength ) )
+    pRecordStruct->NDEF_Type = VCARD_TYPE;
+  else
+    pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
+}
+
+/**
+  * @brief  This function parse the Forum External type record.
+  * @param  pRecordStruct : pointer on the record structure to fill.
+  */
+void NDEF::NDEF_ParseForumExternalType( sRecordInfo *pRecordStruct )
+{
+  if( !memcmp( &(pRecordStruct->Type), M24SR_DISCOVERY_APP_STRING, pRecordStruct->TypeLength ) )
+    pRecordStruct->NDEF_Type = M24SR_DISCOVERY_APP_TYPE;
+  else
+    pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
+}
+
+/**
+  * @brief  This function parse the URI type record.
+  * @param  pRecordStruct : pointer on the record structure to fill.
+  */
+void NDEF::NDEF_ParseURI( sRecordInfo *pRecordStruct )
+{
+  uint8_t* pPayload;
+
+  pPayload = (uint8_t*)( pRecordStruct->PayloadBufferAdd );
+  pPayload++; /* to skip URI identifier first URI payload byte */
+
+  if( !memcmp( pPayload, SMS_TYPE_STRING, strlen(SMS_TYPE_STRING) ) )
+  {
+    pRecordStruct->NDEF_Type = URI_SMS_TYPE;
+  }
+  else if( !memcmp( pPayload, GEO_TYPE_STRING, strlen(GEO_TYPE_STRING) ) )
+  {
+    pRecordStruct->NDEF_Type = URI_GEO_TYPE;
+  }
+  else
+    pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
+}
+
+/**
+  * @brief  This function parse the Smart Poster.
+  * @param  pRecordStruct : pointer on the record structure to fill.
+  */
+void NDEF::NDEF_ParseSP( sRecordInfo *pRecordStruct )
+{
+  uint8_t* pPayload;
+  uint32_t PayloadSize = 0;
+  uint32_t SPPayloadSize = 0;
+  uint32_t OffsetInSPPayload = 0;
+  uint32_t RecordPosition = 0;
+  sRecordInfo *pSPRecordStruct;
+
+  /* initialize variable with size of the payload and poiter on data */
+  PayloadSize = ((uint32_t)(pRecordStruct->PayloadLength3) << 24) | ((uint32_t)(pRecordStruct->PayloadLength2) << 16) |
+                ((uint32_t)(pRecordStruct->PayloadLength1) << 8)  | pRecordStruct->PayloadLength0;
+
+  pPayload = (uint8_t*)( pRecordStruct->PayloadBufferAdd );
+
+  pSPRecordStruct = SPRecordStructAdd[0];
+
+  /* Initailize the number of record find in the SP payload */
+  pRecordStruct->NbOfRecordInSPPayload = 0;
+
+  do
+  {
+    pSPRecordStruct = SPRecordStructAdd[RecordPosition];
+    /* identify the record in the SP payload */
+    if( NDEF_IdentifySPRecord( pSPRecordStruct, pPayload ) == NDEF_OK )
+    {
+      /* store add of structure that will contain the other record information */
+      pRecordStruct->NbOfRecordInSPPayload++;
+      pRecordStruct->SPRecordStructAdd[RecordPosition] = pSPRecordStruct;
+
+      /* After SPRecord + First Record check if we are at the end of NDEF file */
+      SPPayloadSize = ((uint32_t)(pSPRecordStruct->PayloadLength3) << 24) | ((uint32_t)(pSPRecordStruct->PayloadLength2) << 16) |
+                      ((uint32_t)(pSPRecordStruct->PayloadLength1) << 8)  | pSPRecordStruct->PayloadLength0;
+
+      OffsetInSPPayload += pSPRecordStruct->PayloadOffset + SPPayloadSize;
+      pPayload += OffsetInSPPayload;
+    }
+    else /* Recommended Action Record for example */
+    {
+      SPPayloadSize = 0;
+    }
+    RecordPosition++;
+  }
+  while( (OffsetInSPPayload < PayloadSize) && RecordPosition<SP_MAX_RECORD); /* there is another record */
+}
+
+/**
+  * @}
+  */
+
+/** @defgroup libNDEF_Public_Functions
+  * @{
+  */
+
+
+/**
+  * @brief  This function identify the NDEF message stored in tag.
+  * @param  pRecordStruct : Structure to fill with record information.
+  * @param  pNDEF : pointer on the NDEF message data.
+  * @retval NDEF_OK : record struct filled.
+  * @retval NDEF_ERROR : record struct not updated.
+  */
+uint16_t NDEF::NDEF_IdentifyNDEF( sRecordInfo *pRecordStruct, uint8_t* pNDEF )
+{
+  uint16_t status = NDEF_ERROR;
+  uint16_t SizeOfRecordHeader, TypeNbByte, PayloadLengthField, IDLengthField, IDNbByte;
+  uint32_t PayloadSize;
+
+  /* check NDEF present */
+  if( NDEF_IsNDEFPresent() != NDEF_OK )
+  {
+    return NDEF_ERROR;
+  }
+
+  /* Analyse record layout */
+  ReadData( FIRST_RECORD_OFFSET, 1, pNDEF );
+
+  /* Is ID length field present */
+  if( (*pNDEF) & IL_Mask )
+  {
+    IDLengthField = ID_LENGTH_FIELD;
+  }
+  else
+  {
+    IDLengthField = 0;
+  }
+
+  /* it's a SR */
+  if( (*pNDEF) & SR_Mask )
+  {
+    /* Analyse short record layout */
+    ReadData( FIRST_RECORD_OFFSET, 4, pNDEF );
+    TypeNbByte = pNDEF[1];
+    PayloadLengthField = 1;
+    if( IDLengthField == ID_LENGTH_FIELD )
+      IDNbByte = pNDEF[3];
+    else
+      IDNbByte = 0;
+  }
+  else
+  {
+    /* Analyse normal record layout */
+    ReadData( FIRST_RECORD_OFFSET, 7, pNDEF );
+    TypeNbByte = pNDEF[1];
+    PayloadLengthField = 4;
+    if( IDLengthField == ID_LENGTH_FIELD )
+      IDNbByte = pNDEF[6];
+    else
+      IDNbByte = 0;
+  }
+
+  SizeOfRecordHeader = RECORD_FLAG_FIELD + TYPE_LENGTH_FIELD + PayloadLengthField + IDLengthField + TypeNbByte + IDNbByte;
+
+  /* Read record header */
+  ReadData( FIRST_RECORD_OFFSET, SizeOfRecordHeader, pNDEF );
+  /* it's a SR */
+  if( pNDEF[0] & SR_Mask )
+  {
+    pRecordStruct->RecordFlags = pNDEF[0];
+    pRecordStruct->TypeLength = TypeNbByte;
+    pRecordStruct->PayloadLength3 = 0;
+    pRecordStruct->PayloadLength2 = 0;
+    pRecordStruct->PayloadLength1 = 0;
+    pRecordStruct->PayloadLength0 = pNDEF[2];
+    pRecordStruct->IDLength = IDNbByte;
+    memcpy( pRecordStruct->Type, &pNDEF[3+IDNbByte], TypeNbByte );
+    memcpy( pRecordStruct->ID, &pNDEF[3+IDNbByte+TypeNbByte], IDNbByte );
+    pRecordStruct->PayloadOffset = SizeOfRecordHeader;
+  }
+  else
+  {
+    pRecordStruct->RecordFlags = pNDEF[0];
+    pRecordStruct->TypeLength = TypeNbByte;
+    pRecordStruct->PayloadLength3 = pNDEF[2];
+    pRecordStruct->PayloadLength2 = pNDEF[3];
+    pRecordStruct->PayloadLength1 = pNDEF[4];
+    pRecordStruct->PayloadLength0 = pNDEF[5];
+    pRecordStruct->IDLength = IDNbByte;
+    memcpy( pRecordStruct->Type, &pNDEF[6+IDNbByte], TypeNbByte );
+    memcpy( pRecordStruct->ID, &pNDEF[6+IDNbByte+TypeNbByte], IDNbByte );
+    pRecordStruct->PayloadOffset = SizeOfRecordHeader;
+  }
+
+  PayloadSize = ((uint32_t)(pRecordStruct->PayloadLength3) << 24) | ((uint32_t)(pRecordStruct->PayloadLength2) << 16) |
+                ((uint32_t)(pRecordStruct->PayloadLength1) << 8)  | pRecordStruct->PayloadLength0;
+
+  /* read Payload */
+  status = ReadData( (uint16_t)((FIRST_RECORD_OFFSET) + pRecordStruct->PayloadOffset) , PayloadSize , pNDEF );
+
+  if( status != NDEF_OK )
+    return NDEF_ERROR;
+  else
+    pRecordStruct->PayloadBufferAdd = (uint32_t)(pNDEF);
+
+  NDEF_ParseRecordHeader( pRecordStruct );
+
+  return NDEF_OK;
+}
+
+/**
+  * @brief  This function read the NDEF content of the TAG.
+  * @param  pNDEF : pointer on the buffer to store NDEF data.
+  * @retval NDEF_OK : NDEF file data retrieve and store in the buffer.
+  * @retval NDEF_ERROR : not able to read NDEF from tag.
+  * @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot read tag.
+  * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
+  * @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
+  * @retval NDEF_ERROR_LOCKED : Tag locked, cannot be read.
+  */
+uint16_t NDEF::NDEF_ReadNDEF( uint8_t* pNDEF )
+{
+  uint16_t status = NDEF_ERROR;
+  uint16_t NDEF_Size = 0;
+
+  status = ReadData( 0, 2, pNDEF );
+
+  if( status == NDEF_OK )
+  {
+    NDEF_Size = (uint16_t)(*pNDEF << 8);
+    NDEF_Size = NDEF_Size | (uint16_t)(*++pNDEF );
+
+    status = ReadData( 0, NDEF_Size + 2, --pNDEF );
+  }
+
+  return status;
+}
+
+/**
+  * @brief  This function write the NDEF in the TAG.
+  * @param  pNDEF : pointer on the buffer containing the NDEF data.
+  * @retval NDEF_OK : NDEF file data written in the tag.
+  * @retval NDEF_ERROR : not able to store NDEF in tag.
+  * @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
+  * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
+  * @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
+  * @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
+  */
+uint16_t NDEF::NDEF_WriteNDEF( uint8_t *pNDEF )
+{
+  uint16_t status = NDEF_ERROR;
+  uint16_t NDEF_Size = 0;
+
+  NDEF_Size = (uint16_t)(*pNDEF << 8);
+  NDEF_Size = NDEF_Size | (uint16_t)(*++pNDEF );
+
+  status = WriteData( 0, NDEF_Size + 2, --pNDEF );
+
+  return status;
+}
+
+/**
+  * @brief  This function identify the NDEF message stored in tag.
+  * @param  pRecordStruct : Structure to fill with record information.
+  * @param  pNDEF : pointer on the NDEF message data.
+  * @retval NDEF_OK : record struct filled.
+  * @retval NDEF_ERROR : record struct not updated.
+  */
+uint16_t NDEF::NDEF_IdentifyBuffer( sRecordInfo *pRecordStruct, uint8_t* pNDEF )
+{
+  uint16_t SizeOfRecordHeader, TypeNbByte, PayloadLengthField, IDLengthField, IDNbByte;
+
+  /* Is ID length field present */
+  if( (*pNDEF) & IL_Mask )
+  {
+    IDLengthField = ID_LENGTH_FIELD;
+  }
+  else
+  {
+    IDLengthField = 0;
+  }
+
+  /* it's a SR */
+  if( (*pNDEF) & SR_Mask )
+  {
+    /* Analyse short record layout */
+    TypeNbByte = pNDEF[1];
+    PayloadLengthField = 1;
+    if( IDLengthField == ID_LENGTH_FIELD )
+      IDNbByte = pNDEF[3];
+    else
+      IDNbByte = 0;
+  }
+  else
+  {
+    /* Analyse normal record layout */
+    TypeNbByte = pNDEF[1];
+    PayloadLengthField = 4;
+    if( IDLengthField == ID_LENGTH_FIELD )
+      IDNbByte = pNDEF[6];
+    else
+      IDNbByte = 0;
+  }
+
+  SizeOfRecordHeader = RECORD_FLAG_FIELD + TYPE_LENGTH_FIELD + PayloadLengthField + IDLengthField + TypeNbByte + IDNbByte;
+
+  /* it's a SR */
+  if( pNDEF[0] & SR_Mask )
+  {
+    pRecordStruct->RecordFlags = pNDEF[0];
+    pRecordStruct->TypeLength = TypeNbByte;
+    pRecordStruct->PayloadLength3 = 0;
+    pRecordStruct->PayloadLength2 = 0;
+    pRecordStruct->PayloadLength1 = 0;
+    pRecordStruct->PayloadLength0 = pNDEF[2];
+    pRecordStruct->IDLength = IDNbByte;
+    memcpy( pRecordStruct->Type, &pNDEF[3+IDNbByte], TypeNbByte );
+    memcpy( pRecordStruct->ID, &pNDEF[3+IDNbByte+TypeNbByte], IDNbByte );
+    pRecordStruct->PayloadOffset = SizeOfRecordHeader;
+  }
+  else
+  {
+    pRecordStruct->RecordFlags = pNDEF[0];
+    pRecordStruct->TypeLength = TypeNbByte;
+    pRecordStruct->PayloadLength3 = pNDEF[2];
+    pRecordStruct->PayloadLength2 = pNDEF[3];
+    pRecordStruct->PayloadLength1 = pNDEF[4];
+    pRecordStruct->PayloadLength0 = pNDEF[5];
+    pRecordStruct->IDLength = IDNbByte;
+    memcpy( pRecordStruct->Type, &pNDEF[6+IDNbByte], TypeNbByte );
+    memcpy( pRecordStruct->ID, &pNDEF[6+IDNbByte+TypeNbByte], IDNbByte );
+    pRecordStruct->PayloadOffset = SizeOfRecordHeader;
+  }
+
+  pRecordStruct->PayloadBufferAdd = (uint32_t)(&pNDEF[pRecordStruct->PayloadOffset]);
+
+  NDEF_ParseRecordHeader( pRecordStruct );
+
+  return NDEF_OK;
+}
+    
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Lib_NDEF/lib_NDEF.h	Wed Jul 27 09:25:33 2016 +0000
@@ -0,0 +1,297 @@
+/**
+  ******************************************************************************
+  * @file    lib_NDEF.h
+  * @author  MMY Application Team
+  * @version $Revision: 1329 $
+  * @date    $Date: 2015-11-05 10:34:25 +0100 (Thu, 05 Nov 2015) $
+  * @brief   This file help to manage NDEF file.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
+  *
+  * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+  * You may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at:
+  *
+  *        http://www.st.com/myliberty  
+  *
+  * Unless required by applicable law or agreed to in writing, software 
+  * distributed under the License is distributed on an "AS IS" BASIS, 
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+  * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+  * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __LIB_NDEF_H
+#define __LIB_NDEF_H
+
+
+/* Includes ------------------------------------------------------------------*/
+/* include file which match the HW configuration */
+//#include "common.h"
+//#include "lib_wrapper.h"
+#include <stdint.h>
+#include "tagtype5_wrapper.h"
+
+#define NDEF_ACTION_COMPLETED       0x9000
+
+#ifndef errorchk
+#define errorchk(fCall) if (status = (fCall), status != NDEF_ACTION_COMPLETED) \
+  {goto Error;} else
+#endif
+
+/* Error codes for Higher level */
+    
+    
+#define NFCTAG_4M_SIZE            0x200
+#define NFCTAG_16M_SIZE           0x800
+#define NFCTAG_64M_SIZE           0x2000
+#ifndef MIN
+#define MIN(x, y) (((x) < (y)) ? (x) : (y))
+#endif
+
+/* Exported constants --------------------------------------------------------*/
+#define MAX_NDEF_MEM                 0x200
+#define M24LR_MAX_SIZE               NFCTAG_4M_SIZE
+#define M24LR_NDEF_MAX_SIZE          MIN(M24LR_MAX_SIZE,MAX_NDEF_MEM)
+#define NFC_DEVICE_MAX_NDEFMEMORY    M24LR_NDEF_MAX_SIZE
+    
+#define NDEF_OK                     0x00
+#define NDEF_ERROR                  1
+#define NDEF_ERROR_MEMORY_TAG       2
+#define NDEF_ERROR_MEMORY_INTERNAL  3
+#define NDEF_ERROR_LOCKED           4
+#define NDEF_ERROR_NOT_FORMATED     5
+
+#define NDEF_MAX_SIZE               NFC_DEVICE_MAX_NDEFMEMORY
+
+#define NDEF_SIZE_OFFSET            0
+#define FIRST_RECORD_OFFSET         2
+
+#define RECORD_FLAG_FIELD           1
+#define TYPE_LENGTH_FIELD           1
+#define ID_LENGTH_FIELD             1
+
+
+#define MB_Mask                     ((uint8_t)(0x80))
+#define ME_Mask                     ((uint8_t)(0x40))
+#define CF_Mask                     ((uint8_t)(0x20))
+#define SR_Mask                     ((uint8_t)(0x10))
+#define IL_Mask                     ((uint8_t)(0x08))
+#define TNF_Mask                    ((uint8_t)(0x07))
+
+#define TNF_Empty                   0x00
+#define TNF_WellKnown               0x01
+#define TNF_MediaType               0x02
+#define TNF_AbsoluteURI             0x03
+#define TNF_NFCForumExternal        0x04
+#define TNF_Unknown                 0x05
+#define TNF_Unchanged               0x06
+#define TNF_Reserved                0x07
+
+#define SP_MAX_RECORD               4
+
+#define AAR_TYPE_STRING                         "android.com:pkg"
+#define AAR_TYPE_STRING_LENGTH                  15
+
+#define M24SR_DISCOVERY_APP_STRING              "st.com:m24sr_discovery_democtrl"
+#define M24SR_DISCOVERY_APP_STRING_LENGTH       31
+
+#define VCARD_TYPE_STRING                       "text/vcard"
+#define VCARD_TYPE_STRING_LENGTH                10
+
+#define XVCARD_TYPE_STRING                      "text/x-vCard"
+#define XVCARD_TYPE_STRING_LENGTH               12
+
+#define XVCARD2_TYPE_STRING                     "text/x-vcard"
+#define XVCARD2_TYPE_STRING_LENGTH              12
+
+#define SMART_POSTER_TYPE_STRING                "Sp"
+#define SMART_POSTER_TYPE_STRING_LENGTH         2
+     
+#define URI_TYPE_STRING                         "U"
+#define URI_TYPE_STRING_LENGTH                  1
+     
+#define SMS_TYPE_STRING                         "sms:"
+#define SMS_TYPE_STRING_LENGTH                  4
+
+#define GEO_TYPE_STRING                         "geo:"
+#define GEO_TYPE_STRING_LENGTH                  4
+
+#define URI_LATITUDE_END                        ","
+#define URI_LATITUDE_END_LENGTH                 1
+
+#define EMAIL_TYPE_STRING                       "mailto:"
+#define EMAIL_TYPE_STRING_LENGTH                7
+
+#define URI_FIRST_DATA_END                      "?"
+#define URI_FIRST_DATA_END_LENGTH               1
+
+#define SUBJECT_BEGIN_STRING                    "subject="
+#define SUBJECT_BEGIN_STRING_LENGTH             8
+
+#define MESSAGE_BEGIN_STRING                    "body="
+#define MESSAGE_BEGIN_STRING_LENGTH             5
+
+#define URI_SECOND_DATA_END                     "&"
+#define URI_SECOND_DATA_END_LENGTH              1
+
+#define TEXT_TYPE_STRING                        "T"
+#define TEXT_TYPE_STRING_LENGTH                 1
+
+#define ISO_ENGLISH_CODE_STRING                 "en"
+#define ISO_ENGLISH_CODE_STRING_LENGTH          2
+
+
+#define URI_ID_0x00                 0x00
+#define URI_ID_0x01                 0x01
+#define URI_ID_0x02                 0x02
+#define URI_ID_0x03                 0x03
+#define URI_ID_0x04                 0x04
+#define URI_ID_0x05                 0x05
+#define URI_ID_0x06                 0x06
+#define URI_ID_0x07                 0x07
+#define URI_ID_0x08                 0x08
+#define URI_ID_0x09                 0x09
+#define URI_ID_0x0A                 0x0A
+#define URI_ID_0x0B                 0x0B
+#define URI_ID_0x0C                 0x0C
+#define URI_ID_0x0D                 0x0D
+#define URI_ID_0x0E                 0x0E
+#define URI_ID_0x0F                 0x0F
+#define URI_ID_0x10                 0x10
+#define URI_ID_0x11                 0x11
+#define URI_ID_0x12                 0x12
+#define URI_ID_0x13                 0x13
+#define URI_ID_0x14                 0x14
+#define URI_ID_0x15                 0x15
+#define URI_ID_0x16                 0x16
+#define URI_ID_0x17                 0x17
+#define URI_ID_0x18                 0x18
+#define URI_ID_0x19                 0x19
+#define URI_ID_0x1A                 0x1A
+#define URI_ID_0x1B                 0x1B
+#define URI_ID_0x1C                 0x1C
+#define URI_ID_0x1D                 0x1D
+#define URI_ID_0x1E                 0x1E
+#define URI_ID_0x1F                 0x1F
+#define URI_ID_0x20                 0x20
+#define URI_ID_0x21                 0x21
+#define URI_ID_0x22                 0x22
+#define URI_ID_0x23                 0x23
+#define URI_RFU                     0x24
+
+#define URI_ID_0x01_STRING          "http://www.\0"
+#define URI_ID_0x02_STRING          "https://www.\0"
+#define URI_ID_0x03_STRING          "http://\0"
+#define URI_ID_0x04_STRING          "https://\0"
+#define URI_ID_0x05_STRING          "tel:\0"
+#define URI_ID_0x06_STRING          "mailto:\0"
+#define URI_ID_0x07_STRING          "ftp://anonymous:anonymous@\0"
+#define URI_ID_0x08_STRING          "ftp://ftp.\0"
+#define URI_ID_0x09_STRING          "ftps://\0"
+#define URI_ID_0x0A_STRING          "sftp://\0"
+#define URI_ID_0x0B_STRING          "smb://\0"
+#define URI_ID_0x0C_STRING          "nfs://\0"
+#define URI_ID_0x0D_STRING          "ftp://\0"
+#define URI_ID_0x0E_STRING          "dav://\0"
+#define URI_ID_0x0F_STRING          "news:\0"
+#define URI_ID_0x10_STRING          "telnet://\0"
+#define URI_ID_0x11_STRING          "imap:\0"
+#define URI_ID_0x12_STRING          "rtsp://\0"
+#define URI_ID_0x13_STRING          "urn:\0"
+#define URI_ID_0x14_STRING          "pop:\0"
+#define URI_ID_0x15_STRING          "sip:\0"
+#define URI_ID_0x16_STRING          "sips:\0"
+#define URI_ID_0x17_STRING          "tftp:\0"
+#define URI_ID_0x18_STRING          "btspp://\0"
+#define URI_ID_0x19_STRING          "btl2cap://\0"
+#define URI_ID_0x1A_STRING          "btgoep://\0"
+#define URI_ID_0x1B_STRING          "tcpobex://\0"
+#define URI_ID_0x1C_STRING          "irdaobex://\0"
+#define URI_ID_0x1D_STRING          "file://\0"
+#define URI_ID_0x1E_STRING          "urn:epc:id:\0"
+#define URI_ID_0x1F_STRING          "urn:epc:tag\0"
+#define URI_ID_0x20_STRING          "urn:epc:pat:\0"
+#define URI_ID_0x21_STRING          "urn:epc:raw:\0"
+#define URI_ID_0x22_STRING          "urn:epc:\0"
+#define URI_ID_0x23_STRING          "urn:nfc:\0"
+
+typedef enum
+{
+  UNKNOWN_TYPE = 0,
+  VCARD_TYPE,
+  WELL_KNOWN_ABRIDGED_URI_TYPE,
+  URI_SMS_TYPE,
+  URI_GEO_TYPE,
+  URI_EMAIL_TYPE,
+  SMARTPOSTER_TYPE,
+  URL_TYPE,
+  TEXT_TYPE,
+  BT_TYPE,
+  /* list of "external type" known by this demo, other external type will be addressed as UNKNWON_TYPE */
+  M24SR_DISCOVERY_APP_TYPE
+} NDEF_TypeDef;
+
+//typedef struct sRecordInfo sRecordInfo;
+typedef struct sRecordInfo
+{
+  uint8_t RecordFlags;
+  uint8_t TypeLength;
+  uint8_t PayloadLength3;
+  uint8_t PayloadLength2;
+  uint8_t PayloadLength1;
+  uint8_t PayloadLength0;
+ uint8_t IDLength;
+  uint8_t Type[0xFF];
+  uint8_t ID[0xFF];
+  uint16_t PayloadOffset;
+  uint32_t PayloadBufferAdd;    /* add where payload content has been stored */
+ NDEF_TypeDef NDEF_Type;  /* to store identification ID for application */
+  sRecordInfo *SPRecordStructAdd[SP_MAX_RECORD]; /*in case of smart poster array to store add of other sRecordInfo struct */
+  uint8_t NbOfRecordInSPPayload;
+}sRecordInfo;
+
+class NDEF : public NFCType5 {
+public:
+  
+uint16_t NDEF_IsNDEFPresent( void );
+ uint16_t NDEF_ParseRecordHeader( sRecordInfo *pRecordStruct );
+ void NDEF_ParseWellKnownType( sRecordInfo *pRecordStruct );
+void NDEF_ParseMediaType( sRecordInfo *pRecordStruct );
+void NDEF_ParseForumExternalType( sRecordInfo *pRecordStruct );
+ void NDEF_ParseURI( sRecordInfo *pRecordStruct );
+void NDEF_ParseSP( sRecordInfo *pRecordStruct );
+uint16_t NDEF_IdentifySPRecord( sRecordInfo *pRecordStruct, uint8_t* pPayload );
+uint16_t NDEF_IdentifyNDEF( sRecordInfo *pRecordStruct, uint8_t* pNDEF );
+uint16_t NDEF_ReadNDEF( uint8_t* pNDEF );
+uint16_t NDEF_WriteNDEF( uint8_t *pNDEF );
+uint16_t NDEF_IdentifyBuffer( sRecordInfo *pRecordStruct, uint8_t* pNDEF );
+
+void NDEF_initialize(void);
+uint8_t NDEF_Buffer [NDEF_MAX_SIZE];
+
+NDEF()
+{
+   SPRecordStructAdd[0] = &SPRecordStruct1;
+    SPRecordStructAdd[1] = &SPRecordStruct2;
+    SPRecordStructAdd[2] = &SPRecordStruct3;
+    SPRecordStructAdd[3] = &SPRecordStruct4;
+    
+}
+
+/* In case of smart Poster composed with different record, 3 records supported so far */
+sRecordInfo SPRecordStruct1, SPRecordStruct2, SPRecordStruct3, SPRecordStruct4;
+sRecordInfo *SPRecordStructAdd[SP_MAX_RECORD];
+};
+
+#endif /* __LIB_NDEF_H */
+
+
+/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Lib_NDEF/lib_NDEF_URI.cpp	Wed Jul 27 09:25:33 2016 +0000
@@ -0,0 +1,550 @@
+/**
+  ******************************************************************************
+  * @file    lib_NDEF_URI.c
+  * @author  MMY Application Team
+  * @version $Revision: 1583 $
+  * @date    $Date: 2016-02-03 15:06:51 +0100 (Wed, 03 Feb 2016) $
+  * @brief   This file help to manage NDEF file that represent URI.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
+  *
+  * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+  * You may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at:
+  *
+  *        http://www.st.com/myliberty  
+  *
+  * Unless required by applicable law or agreed to in writing, software 
+  * distributed under the License is distributed on an "AS IS" BASIS, 
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+  * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+  * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  *
+  ******************************************************************************
+  */
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF_URI.h"
+#include <string.h>
+
+/** @addtogroup NFC_libraries
+  * @{
+  * @brief  <b>This is the library used to manage the content of the TAG (data)
+  *          But also the specific feature of the tag, for instance
+  *          password, gpo... </b>
+  */
+
+
+/** @addtogroup libNFC_FORUM
+  * @{
+  * @brief  This part of the library manage data which follow NFC forum organisation.
+  */
+
+/**
+  * @brief  This buffer contains the data send/received by TAG
+  */
+extern uint8_t NDEF_Buffer [];
+
+
+
+/**
+  * @brief  This function read the URI information and store data in a structure.
+  * @param  pRecordStruct : Pointer on the record structure.
+  * @param  pURI : pointer on the structure to fill.
+  */
+void NDEF_URI::NDEF_Parse_WellKnowType( sRecordInfo *pRecordStruct, sURI_Info* pURI )
+{
+  uint32_t PayloadSize;
+  uint8_t Offset;
+  uint8_t* pPayload;
+
+  pPayload = (uint8_t*)(pRecordStruct->PayloadBufferAdd);
+
+  switch( *pPayload )
+  {
+    case URI_ID_0x01:
+      memcpy( pURI->protocol, URI_ID_0x01_STRING, strlen(URI_ID_0x01_STRING) );
+      Offset = strlen( URI_ID_0x01_STRING );
+      break;
+
+    case URI_ID_0x02:
+      memcpy( pURI->protocol, URI_ID_0x02_STRING, strlen(URI_ID_0x02_STRING) );
+      Offset = strlen( URI_ID_0x02_STRING );
+      break;
+
+    case URI_ID_0x03:
+      memcpy( pURI->protocol, URI_ID_0x03_STRING, strlen(URI_ID_0x03_STRING) );
+      Offset = strlen( URI_ID_0x03_STRING );
+      break;
+
+    case URI_ID_0x04:
+      memcpy( pURI->protocol, URI_ID_0x04_STRING, strlen(URI_ID_0x04_STRING) );
+      Offset = strlen( URI_ID_0x04_STRING );
+      break;
+
+    case URI_ID_0x05:
+      memcpy( pURI->protocol, URI_ID_0x05_STRING, strlen(URI_ID_0x05_STRING) );
+      Offset = strlen( URI_ID_0x05_STRING );
+      break;
+
+    case URI_ID_0x06:
+      memcpy( pURI->protocol, URI_ID_0x06_STRING, strlen(URI_ID_0x06_STRING) );
+      Offset = strlen( URI_ID_0x06_STRING );
+      break;
+
+    case URI_ID_0x07:
+      memcpy( pURI->protocol, URI_ID_0x07_STRING, strlen(URI_ID_0x07_STRING) );
+      Offset = strlen( URI_ID_0x07_STRING );
+      break;
+
+    case URI_ID_0x08:
+      memcpy( pURI->protocol, URI_ID_0x08_STRING, strlen(URI_ID_0x08_STRING) );
+      Offset = strlen( URI_ID_0x08_STRING );
+      break;
+
+    case URI_ID_0x09:
+      memcpy( pURI->protocol, URI_ID_0x09_STRING, strlen(URI_ID_0x09_STRING) );
+      Offset = strlen( URI_ID_0x09_STRING );
+      break;
+
+    case URI_ID_0x0A:
+      memcpy( pURI->protocol, URI_ID_0x0A_STRING, strlen(URI_ID_0x0A_STRING) );
+      Offset = strlen( URI_ID_0x0A_STRING );
+      break;
+
+    case URI_ID_0x0B:
+      memcpy( pURI->protocol, URI_ID_0x0B_STRING, strlen(URI_ID_0x0B_STRING) );
+      Offset = strlen( URI_ID_0x0B_STRING );
+      break;
+
+    case URI_ID_0x0C:
+      memcpy( pURI->protocol, URI_ID_0x0C_STRING, strlen(URI_ID_0x0C_STRING) );
+      Offset = strlen( URI_ID_0x0C_STRING );
+      break;
+
+    case URI_ID_0x0D:
+      memcpy( pURI->protocol, URI_ID_0x0D_STRING, strlen(URI_ID_0x0D_STRING) );
+      Offset = strlen( URI_ID_0x0D_STRING );
+      break;
+
+    case URI_ID_0x0E:
+      memcpy( pURI->protocol, URI_ID_0x0E_STRING, strlen(URI_ID_0x0E_STRING) );
+      Offset = strlen( URI_ID_0x0E_STRING );
+      break;
+
+    case URI_ID_0x0F:
+      memcpy( pURI->protocol, URI_ID_0x0F_STRING, strlen(URI_ID_0x0F_STRING) );
+      Offset = strlen( URI_ID_0x0F_STRING );
+      break;
+
+    case URI_ID_0x10:
+      memcpy( pURI->protocol, URI_ID_0x10_STRING, strlen(URI_ID_0x10_STRING) );
+      Offset = strlen( URI_ID_0x10_STRING );
+      break;
+
+    case URI_ID_0x11:
+      memcpy( pURI->protocol, URI_ID_0x11_STRING, strlen(URI_ID_0x11_STRING) );
+      Offset = strlen( URI_ID_0x11_STRING );
+      break;
+
+    case URI_ID_0x12:
+      memcpy( pURI->protocol, URI_ID_0x12_STRING, strlen(URI_ID_0x12_STRING) );
+      Offset = strlen( URI_ID_0x12_STRING );
+      break;
+
+    case URI_ID_0x13:
+      memcpy( pURI->protocol, URI_ID_0x13_STRING, strlen(URI_ID_0x13_STRING) );
+      Offset = strlen( URI_ID_0x13_STRING );
+      break;
+
+    case URI_ID_0x14:
+      memcpy( pURI->protocol, URI_ID_0x14_STRING, strlen(URI_ID_0x14_STRING) );
+      Offset = strlen( URI_ID_0x14_STRING );
+      break;
+
+    case URI_ID_0x15:
+      memcpy( pURI->protocol, URI_ID_0x15_STRING, strlen(URI_ID_0x15_STRING) );
+      Offset = strlen( URI_ID_0x15_STRING );
+      break;
+
+    case URI_ID_0x16:
+      memcpy( pURI->protocol, URI_ID_0x16_STRING, strlen(URI_ID_0x16_STRING) );
+      Offset = strlen( URI_ID_0x16_STRING );
+      break;
+
+    case URI_ID_0x17:
+      memcpy( pURI->protocol, URI_ID_0x17_STRING, strlen(URI_ID_0x17_STRING) );
+      Offset = strlen( URI_ID_0x17_STRING );
+      break;
+
+    case URI_ID_0x18:
+      memcpy( pURI->protocol, URI_ID_0x18_STRING, strlen(URI_ID_0x18_STRING) );
+      Offset = strlen( URI_ID_0x18_STRING );
+      break;
+
+    case URI_ID_0x19:
+      memcpy( pURI->protocol, URI_ID_0x19_STRING, strlen(URI_ID_0x19_STRING) );
+      Offset = strlen( URI_ID_0x19_STRING );
+      break;
+
+    case URI_ID_0x1A:
+      memcpy( pURI->protocol, URI_ID_0x1A_STRING, strlen(URI_ID_0x1A_STRING) );
+      Offset = strlen( URI_ID_0x1A_STRING );
+      break;
+
+    case URI_ID_0x1B:
+      memcpy( pURI->protocol, URI_ID_0x1B_STRING, strlen(URI_ID_0x1B_STRING) );
+      Offset = strlen( URI_ID_0x1B_STRING );
+      break;
+
+    case URI_ID_0x1C:
+      memcpy( pURI->protocol, URI_ID_0x1C_STRING, strlen(URI_ID_0x1C_STRING) );
+      Offset = strlen( URI_ID_0x1C_STRING );
+      break;
+
+    case URI_ID_0x1D:
+      memcpy( pURI->protocol, URI_ID_0x1D_STRING, strlen(URI_ID_0x1D_STRING) );
+      Offset = strlen( URI_ID_0x1D_STRING );
+      break;
+
+    case URI_ID_0x1E:
+      memcpy( pURI->protocol, URI_ID_0x1E_STRING, strlen(URI_ID_0x1E_STRING) );
+      Offset = strlen( URI_ID_0x1E_STRING );
+      break;
+
+    case URI_ID_0x1F:
+      memcpy( pURI->protocol, URI_ID_0x1F_STRING, strlen(URI_ID_0x1F_STRING) );
+      Offset = strlen( URI_ID_0x1F_STRING );
+      break;
+
+    case URI_ID_0x20:
+      memcpy( pURI->protocol, URI_ID_0x20_STRING, strlen(URI_ID_0x20_STRING) );
+      Offset = strlen( URI_ID_0x20_STRING );
+      break;
+
+    case URI_ID_0x21:
+      memcpy( pURI->protocol, URI_ID_0x21_STRING, strlen(URI_ID_0x21_STRING) );
+      Offset = strlen( URI_ID_0x21_STRING );
+      break;
+
+    case URI_ID_0x22:
+      memcpy( pURI->protocol, URI_ID_0x22_STRING, strlen(URI_ID_0x22_STRING) );
+      Offset = strlen( URI_ID_0x22_STRING );
+      break;
+
+    case URI_ID_0x23:
+      memcpy( pURI->protocol, URI_ID_0x23_STRING, strlen(URI_ID_0x23_STRING) );
+      Offset = strlen( URI_ID_0x23_STRING );
+      break;
+
+    default:
+      Offset = 0;
+      /* Should not happened */
+      break;
+  }
+  /* add end of string character */
+  pURI->protocol[Offset] = '\0';
+
+  pPayload++; /* go after well know byte */
+
+  PayloadSize = ((uint32_t)(pRecordStruct->PayloadLength3) << 24) | ((uint32_t)(pRecordStruct->PayloadLength2) << 16) |
+                ((uint32_t)(pRecordStruct->PayloadLength1) << 8)  | pRecordStruct->PayloadLength0;
+
+  PayloadSize = PayloadSize - 1; /* remove well know byte */
+
+  memcpy( pURI->URI_Message, pPayload, PayloadSize );
+  /* add end of string character */
+  pURI->URI_Message[PayloadSize] = '\0';
+
+}
+
+/**
+  * @}
+  */
+
+/** @defgroup libURI_Public_Functions
+  * @{
+  * @brief  This file is used to manage URI (stored or loaded in tag)
+  */ 
+
+/**
+  * @brief  This function read NDEF and retrieve URI information if any.
+  * @param  pRecordStruct : Pointer on the record structure.
+  * @param  pURI : pointer on the structure to fill.
+  * @retval NDEF_OK : URI information from NDEF have been retrieved.
+  * @retval NDEF_ERROR : Not able to retrieve URI information.
+  */
+uint16_t NDEF_URI::NDEF_ReadURI( sRecordInfo *pRecordStruct, sURI_Info *pURI )
+{
+  uint16_t status = NDEF_ERROR;
+  sRecordInfo *pSPRecordStruct;
+  uint32_t PayloadSize, RecordPosition;
+  uint8_t* pData;
+
+  if( pRecordStruct->NDEF_Type == WELL_KNOWN_ABRIDGED_URI_TYPE )
+  {
+    NDEF_Parse_WellKnowType( pRecordStruct, pURI );
+    status = NDEF_OK;
+  }
+  else if( pRecordStruct->NDEF_Type == SMARTPOSTER_TYPE )
+  {
+    for( RecordPosition = 0; RecordPosition < pRecordStruct->NbOfRecordInSPPayload; RecordPosition++ )
+    {
+      pSPRecordStruct = pRecordStruct->SPRecordStructAdd[RecordPosition];
+      if( pSPRecordStruct->NDEF_Type == WELL_KNOWN_ABRIDGED_URI_TYPE )
+      {
+        NDEF_Parse_WellKnowType( pSPRecordStruct, pURI );
+        status = NDEF_OK;
+      }
+      if( pSPRecordStruct->NDEF_Type == TEXT_TYPE )
+      {
+        PayloadSize = ((uint32_t)(pSPRecordStruct->PayloadLength3) << 24) | ((uint32_t)(pSPRecordStruct->PayloadLength2) << 16) |
+                      ((uint32_t)(pSPRecordStruct->PayloadLength1) << 8)  | pSPRecordStruct->PayloadLength0;
+
+        /* The instruction content the UTF-8 language code that is not used here */
+        pData = (uint8_t*)pSPRecordStruct->PayloadBufferAdd;
+        PayloadSize -= *pData + 1; /* remove not usefull data */
+        pData += *pData + 1;
+
+        memcpy( pURI->Information, pData, PayloadSize );
+      }
+    }
+  }
+  else 
+  {
+    status = NDEF_ERROR;
+  }
+
+  return status;
+}
+
+/**
+  * @brief  This function prepare the NDEF message with the URI data given in the structure.
+  * @param  pURI : pointer on structure that contain the URI information.
+  * @param  pNDEFMessage : pointer on the NDEF message.
+  * @param  size : to store the size of the NDEF message generated.
+  */
+void NDEF_URI::NDEF_PrepareURIMessage( sURI_Info *pURI, uint8_t *pNDEFMessage, uint16_t *size )
+{
+  uint32_t uriSize, totalSize, Offset = 0;
+  uint32_t infoSize = 0;
+  char type;
+
+  /* An URI can be included in a smart poster to add text to give instruction to user for instance */
+
+  /* URI (smart poster) Record Header */
+/************************************/
+/*  7 |  6 |  5 |  4 |  3 | 2  1  0 */
+/*----------------------------------*/
+/* MB   ME   CF   SR   IL    TNF    */  /* <---- CF=0, IL=0 and SR=1 TNF=1 NFC Forum Well-known type*/
+/*----------------------------------*/
+/*          TYPE LENGTH             */
+/*----------------------------------*/
+/*        PAYLOAD LENGTH 3          */  /* <---- Used only if SR=0 */
+/*----------------------------------*/
+/*        PAYLOAD LENGTH 2          */  /* <---- Used only if SR=0 */
+/*----------------------------------*/
+/*        PAYLOAD LENGTH 1          */  /* <---- Used only if SR=0 */
+/*----------------------------------*/
+/*        PAYLOAD LENGTH 0          */
+/*----------------------------------*/
+/*          ID LENGTH               */  /* <---- Not Used  */
+/*----------------------------------*/
+/*              TYPE                */
+/*----------------------------------*/
+/*               ID                 */  /* <---- Not Used  */
+/************************************/
+
+  /* We need to know the URI type in order to define if an abreviation is available */
+  type = getUriType( pURI->protocol );
+
+  /* URI : 1+URI for abreviate protocol*/
+  if( type != URI_ID_0x00 )
+    uriSize = 1 + strlen(pURI->URI_Message);
+  else /*: 1+protocol+URI else*/
+    uriSize = 1 + strlen(pURI->protocol) + strlen(pURI->URI_Message);
+
+  /* Check if a Smart poster is needed */
+  if( pURI->Information[0] != '\0' )
+  {
+    /* Info : 1+2+info */
+    infoSize = 1 + ISO_ENGLISH_CODE_STRING_LENGTH + strlen(pURI->Information);
+    /* Total */
+    totalSize = 4 + uriSize + 4 + infoSize;
+    if( uriSize > 255 ) totalSize += 3;   /* Normal URI size */
+    if( infoSize > 255 ) totalSize += 3;  /* Normal Info size */
+
+    /* SmartPoster header */
+    if( totalSize > 255 )
+    {
+      pNDEFMessage[Offset++] = 0xC1;
+      pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH;
+      pNDEFMessage[Offset++] = (totalSize & 0xFF000000) >> 24;
+      pNDEFMessage[Offset++] = (totalSize & 0x00FF0000) >> 16;
+      pNDEFMessage[Offset++] = (totalSize & 0x0000FF00) >> 8;
+      pNDEFMessage[Offset++] = totalSize & 0x000000FF;
+    }
+    else
+    {
+      pNDEFMessage[Offset++] = 0xD1;
+      pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH;
+      pNDEFMessage[Offset++] = (uint8_t)totalSize;
+    }
+    memcpy( &pNDEFMessage[Offset], SMART_POSTER_TYPE_STRING, SMART_POSTER_TYPE_STRING_LENGTH );
+    Offset += SMART_POSTER_TYPE_STRING_LENGTH;
+  }
+
+  /* URI header */
+  pNDEFMessage[Offset] = 0x81;
+  if( uriSize < 256 ) pNDEFMessage[Offset] |= 0x10;                      // Set the SR bit
+  if( pURI->Information[0] == '\0' ) pNDEFMessage[Offset] |= 0x40;       // Set the ME bit
+  Offset++;
+
+  pNDEFMessage[Offset++] = URI_TYPE_STRING_LENGTH;
+  if( uriSize > 255 )
+  {
+    pNDEFMessage[Offset++] = (uriSize & 0xFF000000) >> 24;
+    pNDEFMessage[Offset++] = (uriSize & 0x00FF0000) >> 16;
+    pNDEFMessage[Offset++] = (uriSize & 0x0000FF00) >> 8;
+    pNDEFMessage[Offset++] = uriSize & 0x000000FF;
+  }
+  else
+  {
+    pNDEFMessage[Offset++] = (uint8_t)uriSize;
+  }
+  memcpy( &pNDEFMessage[Offset], URI_TYPE_STRING, URI_TYPE_STRING_LENGTH );
+  Offset += URI_TYPE_STRING_LENGTH;
+
+  pNDEFMessage[Offset++] = type;
+  if( type == URI_ID_0x00 ) // No abreviation
+  {
+    memcpy( &pNDEFMessage[Offset], pURI->protocol, strlen(pURI->protocol) );
+    Offset += strlen(pURI->protocol);
+  }
+
+  memcpy( &pNDEFMessage[Offset], pURI->URI_Message, strlen(pURI->URI_Message) );
+  Offset += strlen(pURI->URI_Message);
+
+  /* Information header */
+  if( pURI->Information[0] != '\0' )
+  {
+    if( infoSize > 255 )
+    {
+      pNDEFMessage[Offset++] = 0x41;
+      pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH;
+      pNDEFMessage[Offset++] = (infoSize & 0xFF000000) >> 24;
+      pNDEFMessage[Offset++] = (infoSize & 0x00FF0000) >> 16;
+      pNDEFMessage[Offset++] = (infoSize & 0x0000FF00) >> 8;
+      pNDEFMessage[Offset++] = infoSize & 0x000000FF;
+    }
+    else
+    {
+      pNDEFMessage[Offset++] = 0x51;
+      pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH;
+      pNDEFMessage[Offset++] = (uint8_t)infoSize;
+    }
+
+    memcpy( &pNDEFMessage[Offset], TEXT_TYPE_STRING, TEXT_TYPE_STRING_LENGTH );
+    Offset+=TEXT_TYPE_STRING_LENGTH;
+    pNDEFMessage[Offset++] = ISO_ENGLISH_CODE_STRING_LENGTH; /* UTF-8 with x byte language code */
+    memcpy( &pNDEFMessage[Offset], ISO_ENGLISH_CODE_STRING, ISO_ENGLISH_CODE_STRING_LENGTH );
+    Offset += ISO_ENGLISH_CODE_STRING_LENGTH;
+
+    /* Information payload */
+    memcpy( &pNDEFMessage[Offset], pURI->Information, strlen(pURI->Information) );
+    Offset += strlen(pURI->Information);
+  }
+
+  *size = Offset;
+
+}
+/**
+  * @brief  This function write the NDEF file with the URI data given in the structure.
+  * @param  pURI : pointer on structure that contain the URI information.
+  * @retval NDEF_OK : NDEF file data written in the tag.
+  * @retval NDEF_ERROR : not able to store NDEF in tag.
+  * @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
+  * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
+  * @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
+  * @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
+  */
+uint16_t NDEF_URI::NDEF_WriteURI( sURI_Info *pURI )
+{
+  uint16_t status = NDEF_ERROR, Offset = 0;
+
+  NDEF_PrepareURIMessage( pURI, &NDEF_Buffer[FIRST_RECORD_OFFSET], &Offset );
+
+  /* Write NDEF */
+  NDEF_Buffer[0] = (Offset & 0xFF00) >> 8;
+  NDEF_Buffer[1] = Offset & 0x00FF;
+
+  status = WriteData( 0x00, Offset + FIRST_RECORD_OFFSET, NDEF_Buffer );
+
+  return status;
+}
+
+char NDEF_URI::getUriType( char *protocol )
+{
+  if( !memcmp( protocol, URI_ID_0x01_STRING, strlen(URI_ID_0x01_STRING) ) ) return URI_ID_0x01;
+  else if( !memcmp( protocol, URI_ID_0x02_STRING, strlen(URI_ID_0x02_STRING) ) ) return URI_ID_0x02;
+  else if( !memcmp( protocol, URI_ID_0x03_STRING, strlen(URI_ID_0x03_STRING) ) ) return URI_ID_0x03;
+  else if( !memcmp( protocol, URI_ID_0x04_STRING, strlen(URI_ID_0x04_STRING) ) ) return URI_ID_0x04;
+  else if( !memcmp( protocol, URI_ID_0x05_STRING, strlen(URI_ID_0x05_STRING) ) ) return URI_ID_0x05;
+  else if( !memcmp( protocol, URI_ID_0x06_STRING, strlen(URI_ID_0x06_STRING) ) ) return URI_ID_0x06;
+  else if( !memcmp( protocol, URI_ID_0x07_STRING, strlen(URI_ID_0x07_STRING) ) ) return URI_ID_0x07;
+  else if( !memcmp( protocol, URI_ID_0x08_STRING, strlen(URI_ID_0x08_STRING) ) ) return URI_ID_0x08;
+  else if( !memcmp( protocol, URI_ID_0x09_STRING, strlen(URI_ID_0x09_STRING) ) ) return URI_ID_0x09;
+  else if( !memcmp( protocol, URI_ID_0x0A_STRING, strlen(URI_ID_0x0A_STRING) ) ) return URI_ID_0x0A;
+  else if( !memcmp( protocol, URI_ID_0x0B_STRING, strlen(URI_ID_0x0B_STRING) ) ) return URI_ID_0x0B;
+  else if( !memcmp( protocol, URI_ID_0x0C_STRING, strlen(URI_ID_0x0C_STRING) ) ) return URI_ID_0x0C;
+  else if( !memcmp( protocol, URI_ID_0x0D_STRING, strlen(URI_ID_0x0D_STRING) ) ) return URI_ID_0x0D;
+  else if( !memcmp( protocol, URI_ID_0x0E_STRING, strlen(URI_ID_0x0E_STRING) ) ) return URI_ID_0x0E;
+  else if( !memcmp( protocol, URI_ID_0x0F_STRING, strlen(URI_ID_0x0F_STRING) ) ) return URI_ID_0x0F;
+  else if( !memcmp( protocol, URI_ID_0x10_STRING, strlen(URI_ID_0x10_STRING) ) ) return URI_ID_0x10;
+  else if( !memcmp( protocol, URI_ID_0x11_STRING, strlen(URI_ID_0x11_STRING) ) ) return URI_ID_0x11;
+  else if( !memcmp( protocol, URI_ID_0x12_STRING, strlen(URI_ID_0x12_STRING) ) ) return URI_ID_0x12;
+  else if( !memcmp( protocol, URI_ID_0x13_STRING, strlen(URI_ID_0x13_STRING) ) ) return URI_ID_0x13;
+  else if( !memcmp( protocol, URI_ID_0x14_STRING, strlen(URI_ID_0x14_STRING) ) ) return URI_ID_0x14;
+  else if( !memcmp( protocol, URI_ID_0x15_STRING, strlen(URI_ID_0x15_STRING) ) ) return URI_ID_0x15;
+  else if( !memcmp( protocol, URI_ID_0x16_STRING, strlen(URI_ID_0x16_STRING) ) ) return URI_ID_0x16;
+  else if( !memcmp( protocol, URI_ID_0x17_STRING, strlen(URI_ID_0x17_STRING) ) ) return URI_ID_0x17;
+  else if( !memcmp( protocol, URI_ID_0x18_STRING, strlen(URI_ID_0x18_STRING) ) ) return URI_ID_0x18;
+  else if( !memcmp( protocol, URI_ID_0x19_STRING, strlen(URI_ID_0x19_STRING) ) ) return URI_ID_0x19;
+  else if( !memcmp( protocol, URI_ID_0x1A_STRING, strlen(URI_ID_0x1A_STRING) ) ) return URI_ID_0x1A;
+  else if( !memcmp( protocol, URI_ID_0x1B_STRING, strlen(URI_ID_0x1B_STRING) ) ) return URI_ID_0x1B;
+  else if( !memcmp( protocol, URI_ID_0x1C_STRING, strlen(URI_ID_0x1C_STRING) ) ) return URI_ID_0x1C;
+  else if( !memcmp( protocol, URI_ID_0x1D_STRING, strlen(URI_ID_0x1D_STRING) ) ) return URI_ID_0x1D;
+  else if( !memcmp( protocol, URI_ID_0x1E_STRING, strlen(URI_ID_0x1E_STRING) ) ) return URI_ID_0x1E;
+  else if( !memcmp( protocol, URI_ID_0x1F_STRING, strlen(URI_ID_0x1F_STRING) ) ) return URI_ID_0x1F;
+  else if( !memcmp( protocol, URI_ID_0x20_STRING, strlen(URI_ID_0x20_STRING) ) ) return URI_ID_0x20;
+  else if( !memcmp( protocol, URI_ID_0x21_STRING, strlen(URI_ID_0x21_STRING) ) ) return URI_ID_0x21;
+  else if( !memcmp( protocol, URI_ID_0x22_STRING, strlen(URI_ID_0x22_STRING) ) ) return URI_ID_0x22;
+  else if( !memcmp( protocol, URI_ID_0x23_STRING, strlen(URI_ID_0x23_STRING) ) ) return URI_ID_0x23;
+  else return URI_ID_0x00; // No abreviation for this protocol  
+}
+
+NFCTAG_StatusTypeDef NDEF_URI::NFCTAG_ReadData( uint8_t * const pData, const uint16_t TarAddr, const uint16_t Size )
+{
+  return(mM24LRp->i2c_ReadData(pData, TarAddr, Size ));
+}
+NFCTAG_StatusTypeDef NDEF_URI::NFCTAG_WriteData( const uint8_t * const pData, const uint16_t TarAddr, const uint16_t Size )
+{
+  return(mM24LRp->i2c_WriteData( pData, TarAddr, Size ));
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Lib_NDEF/lib_NDEF_URI.h	Wed Jul 27 09:25:33 2016 +0000
@@ -0,0 +1,72 @@
+/**
+  ******************************************************************************
+  * @file    lib_NDEF_URI.h
+  * @author  MMY Application Team
+  * @version $Revision: 1582 $
+  * @date    $Date: 2016-02-03 15:06:14 +0100 (Wed, 03 Feb 2016) $
+  * @brief   This file help to manage URI NDEF file.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
+  *
+  * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+  * You may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at:
+  *
+  *        http://www.st.com/myliberty  
+  *
+  * Unless required by applicable law or agreed to in writing, software 
+  * distributed under the License is distributed on an "AS IS" BASIS, 
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+  * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+  * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __LIB_NDEF_URI_H
+#define __LIB_NDEF_URI_H
+
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF.h"
+#include "m24lr.h"
+typedef struct 
+{
+  char protocol[80];
+  char URI_Message[400];
+  char Information[400];
+}sURI_Info;
+
+typedef struct sRecordInfo sRecordInfo_t;
+
+class NDEF_URI : public NDEF 
+{
+public:
+uint16_t NDEF_ReadURI(sRecordInfo *pRecordStruct, sURI_Info *pURI);
+uint16_t NDEF_WriteURI(sURI_Info *pURI);
+void NDEF_Parse_WellKnowType( sRecordInfo *pRecordStruct, sURI_Info* pURI );
+
+virtual NFCTAG_StatusTypeDef NFCTAG_ReadData( uint8_t * const pData, const uint16_t TarAddr, const uint16_t Size );
+virtual NFCTAG_StatusTypeDef NFCTAG_WriteData( const uint8_t * const pData, const uint16_t TarAddr, const uint16_t Size );
+
+void NDEF_PrepareURIMessage( sURI_Info *pURI, uint8_t *pNDEFMessage, uint16_t *size );
+char getUriType( char *protocol );
+
+NFCTAG_StatusTypeDef (*ReadDataPtr)( uint8_t * const pData, const uint16_t TarAddr, const uint16_t NbByte );
+NFCTAG_StatusTypeDef (*WriteDataPtr)( const uint8_t * const pData, const uint16_t TarAddr, const uint16_t NbByte );
+
+void setM24LR (M24LR *m24LRr) {mM24LRp=m24LRr; }
+M24LR *mM24LRp;
+
+};
+
+
+#endif /* __LIB_NDEF_URI_H */
+
+/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Lib_NDEF/tagtype5_wrapper.cpp	Wed Jul 27 09:25:33 2016 +0000
@@ -0,0 +1,427 @@
+/**
+  ******************************************************************************
+  * @file    tagtype5_wrapper.c 
+  * @author  MMY Application Team
+  * @version $Revision: 1638 $
+  * @date    $Date: 2016-02-10 16:41:05 +0100 (Wed, 10 Feb 2016) $
+  * @brief   Interface for tagtype5 in order to use NDEF lib
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
+  *
+  * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+  * You may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at:
+  *
+  *        http://www.st.com/myliberty  
+  *
+  * Unless required by applicable law or agreed to in writing, software 
+  * distributed under the License is distributed on an "AS IS" BASIS, 
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+  * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+  * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tagtype5_wrapper.h"
+#include "lib_NDEF.h"
+
+
+/**
+  * @brief  This function read the data stored in NDEF file at defined offset.
+  * @param  Offset : Offset in the NDEF file.
+  * @param  DataSize : Number of byte to read.
+  * @param  pData : pointer on buffer to store read data.
+  * @retval NDEF_ERROR_MEMORY_INTERNAL : Size not compatible with memory.
+  * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported.
+  * @retval NDEF_ERROR : No NDEF in the tag.
+  * @retval NDEF_OK : The operation is completed.
+  */
+uint16_t NFCType5::ReadData( uint16_t Offset , uint16_t DataSize , uint8_t* pData )
+{
+  uint16_t status = NDEF_ERROR;
+  uint8_t atlv_detect[4];
+  uint8_t index = 0;
+  
+  /* Do not include length bytes */
+  DataSize -= FIRST_RECORD_OFFSET;
+  
+  /* If too many data to write return error */
+  if( DataSize > NDEF_MAX_SIZE )
+  {
+    return NDEF_ERROR_MEMORY_INTERNAL;
+  }
+  
+  /* Detect NDEF message in memory */
+  status = NfcType5_NDEFDetection( );
+  if( status != NDEF_OK )
+  {
+    return status;
+  }
+  
+  /* Read TL of Type 5 */
+  status = NFCTAG_ReadData( atlv_detect, CCFileStruct.NDEF_offset, 4 );
+  if( status != NDEF_OK )
+  {
+    return status;
+  }
+  
+  /* Check if L is on 3 or 1 byte and update length in buffer */
+  if( atlv_detect[1] == NFCT5_3_BYTES_L_TLV )
+  {
+    pData[0] = atlv_detect[2];
+    pData[1] = atlv_detect[3];
+    index += 4;
+  }
+  else
+  {
+    pData[0] = 0x00;
+    pData[1] = atlv_detect[1];
+    index += 2;
+  }
+  
+  /* Check CC file is in the correct mode to proceed */
+  if( CCFileStruct.State ==  TT5_INITIALIZED )
+  {
+    return NDEF_ERROR;
+  }
+
+  if( ((Offset == 0) && (DataSize > 0)) || (Offset > 0) )
+  {
+    /* Read NDEF */
+    if( NFCTAG_ReadData( (pData + FIRST_RECORD_OFFSET), CCFileStruct.NDEF_offset + index + Offset, DataSize ) != NFCTAG_OK )
+    {
+      return NDEF_ERROR;
+    }
+  }
+  
+  return NDEF_OK;
+}
+
+/**
+  * @brief  This function writes data in NDEF file at defined offset.
+  * @param  Offset : Offset in the NDEF file.
+  * @param  DataSize : Number of byte to write.
+  * @param  pData : pointer on buffer to copy.
+  * @retval NDEF_ERROR_MEMORY_INTERNAL : Size not compatible with memory.
+  * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported.
+  * @retval NDEF_ERROR : No NDEF in the tag.
+  * @retval NDEF_OK : The operation is completed.
+  */
+uint16_t NFCType5::WriteData( uint16_t Offset , uint32_t DataSize , uint8_t *pData )
+{
+  uint8_t atlv[4];
+  uint8_t index = 0;
+  uint16_t NDEF_Size = 0;
+  NFCTAG_StatusTypeDef status;
+
+  /* Do not include length bytes */
+  DataSize -= FIRST_RECORD_OFFSET;
+  
+  /* If too many data to write return error */
+  if( DataSize > NDEF_MAX_SIZE )
+  {
+    return NDEF_ERROR_MEMORY_INTERNAL;
+  }
+  
+  /* Detect NDEF message in memory */
+  if( NfcType5_NDEFDetection( ) != NDEF_OK )
+  {
+    return NDEF_ERROR;
+  }
+  
+  /* Extract NDEF Size from buffer */
+  NDEF_Size = (uint16_t)(pData[0] << 8);
+  NDEF_Size = NDEF_Size | (uint16_t)(pData[1] );
+  
+  /* If entire NDEF is written, update Length of Type 5 */
+  if( DataSize == NDEF_Size )
+  {
+    /* Check if L is on 3 or 1 byte */
+    if( NDEF_Size >= NFCT5_3_BYTES_L_TLV )
+    {
+      /* First init L with 0, will be updated at the end */
+      atlv[1] = 0x00;
+      atlv[2] = 0x00;
+      atlv[3] = 0x00;
+      
+      status = NFCTAG_WriteData( (atlv + 1), (CCFileStruct.NDEF_offset + 1), 3 );
+      
+      index += 4; 
+    }
+    else
+    {
+      /* First inti L with 0, will be updated at the end */
+      atlv[1] = 0x00;
+      
+      status = NFCTAG_WriteData( (atlv + 1), (CCFileStruct.NDEF_offset + 1), 1 );
+      
+      index += 2;
+    }
+  }
+  
+  /* Start write NDEF message to EEPROM */
+  status = NFCTAG_WriteData( (pData + FIRST_RECORD_OFFSET), CCFileStruct.NDEF_offset + index + Offset, DataSize );
+  if( status != NFCTAG_OK )
+  {
+    return NDEF_ERROR;
+  }
+  
+  /* If entire NDEF is written, update Length of Type 5 */
+  if( DataSize == NDEF_Size )
+  {
+    /* Check if L is on 3 or 1 byte */
+    if( NDEF_Size >= NFCT5_3_BYTES_L_TLV )
+    {
+      /* Update Length value */
+      atlv[1] = NFCT5_3_BYTES_L_TLV;
+      atlv[2] = pData[0];
+      atlv[3] = pData[1];
+      
+      status = NFCTAG_WriteData( (atlv + 1), (CCFileStruct.NDEF_offset + 1), 3 );
+    }
+    else
+    {
+      /* Update Length value */
+      atlv[1] = pData[1];
+      
+      status = NFCTAG_WriteData( (atlv + 1), (CCFileStruct.NDEF_offset + 1), 1 );
+    }
+
+    /* Write Terminator TLV */
+    atlv[0] = NFCT5_TERMINATOR_TLV;
+    status = NFCTAG_WriteData( atlv, CCFileStruct.NDEF_offset + index + NDEF_Size, 1 );
+  }
+  
+  return NDEF_OK;
+}
+
+/**
+  * @brief  This functions writes CCFile in EEPROM.
+  * @Param  pCCBuffer : pointer on the buffer containnig CC file.
+  * @retval NFCTAG status.
+  */
+uint16_t NFCType5::NfcType5_WriteCCFile( const uint8_t * const pCCBuffer )
+{
+  NFCTAG_StatusTypeDef ret_value;
+  
+  /* Write first block of CCFile */
+  ret_value = NFCTAG_WriteData( pCCBuffer, 0x00, 0x4 );
+ 
+  /* If extended memory writes the next 4 bytes */
+  if( (pCCBuffer[2] == 0x00) && (ret_value == NFCTAG_OK) )
+  {
+    ret_value = NFCTAG_WriteData( pCCBuffer + 4, 0x04, 4 );
+  }
+
+  if( ret_value != NFCTAG_OK )
+  {
+    return NDEF_ERROR;
+  }
+  
+    return NDEF_OK;
+}
+
+/**
+  * @brief  This functions reads CCFile in EEPROM.
+  * @Param  pCCBuffer : pointer on the buffer to store CC file.
+  * @retval NFCTAG status.
+  */
+uint16_t NFCType5::NfcType5_ReadCCFile( uint8_t * const pCCBuffer )
+{
+  NFCTAG_StatusTypeDef ret_value;
+  
+  /* Read 4 bytes of CC File */
+  ret_value = NFCTAG_ReadData( pCCBuffer, 0x00, 4 );
+
+  /* If extended memory reads the next 4 bytes */
+  if( (pCCBuffer[2] == 0x00) && (ret_value == NFCTAG_OK) )
+  {
+    ret_value = NFCTAG_ReadData( pCCBuffer + 4, 0x04, 4 );
+  }
+  
+  if( ret_value != NFCTAG_OK )
+  {
+    return NDEF_ERROR;
+  }
+  
+    return NDEF_OK;
+}
+
+/**
+  * @brief  This function initialize memory in Tag Type 5.
+  * @retval NFCTAG status.
+  */
+uint16_t NFCType5::NfcType5_TT5Init( void )
+{
+  NFCTAG_StatusTypeDef ret_value = NFCTAG_OK;
+  uint16_t status;
+  uint8_t accbuffer[8];
+  uint8_t cdata;
+
+  /* Prepare buffer to update CCFile */
+  accbuffer[0] = CCFileStruct.MagicNumber;
+  accbuffer[1] = CCFileStruct.Version;
+  accbuffer[2] = CCFileStruct.MemorySize;
+  accbuffer[3] = CCFileStruct.TT5Tag;
+  CCFileStruct.NDEF_offset = 0x04;
+  
+  /* If extended memory prepare the length bytes */
+  if( CCFileStruct.MemorySize == NFCT5_EXTENDED_CCFILE )
+  {
+    accbuffer[6] = (uint8_t)(CCFileStruct.ExtMemorySize >> 8);
+    accbuffer[7] = (uint8_t)(CCFileStruct.ExtMemorySize & 0xFF);
+    CCFileStruct.NDEF_offset = 0x08;
+  }
+  
+  /* Update CCFile */
+  status = NfcType5_WriteCCFile( accbuffer );
+  if( status != NDEF_OK )
+  {
+    return status;
+  }
+  
+  /* Update NDEF TLV for INITIALIZED state */
+  /* Update T */
+  cdata = NFCT5_NDEF_MSG_TLV;
+  ret_value = NFCTAG_WriteData( &cdata, CCFileStruct.NDEF_offset, 1 );
+  if( ret_value != NFCTAG_OK )
+  {
+    return NDEF_ERROR;
+  }
+
+  /* Update L */
+  cdata = 0x00;
+  ret_value = NFCTAG_WriteData( &cdata, (CCFileStruct.NDEF_offset + 1), 1 );
+  if( ret_value != NFCTAG_OK )
+  {
+    return NDEF_ERROR;
+  }
+  
+  return NDEF_OK;
+}
+
+/**
+  * @brief  This function detects an NDEF message Tag Type 5 in EEPROM.
+  * @retval NDEF_OK : NDEF message Tag Type 5 detected.
+  * @retval NDEF_ERROR_NOT_FORMATED : Device is not an NFC Tag Type 5 Tag.
+  * @retval NDEF_NO_NDEF_DETECTED : No NDEF Detected.
+  */
+uint16_t NFCType5::NfcType5_NDEFDetection( void )
+{
+  uint8_t acc_buffer[8];
+  uint8_t atlv_detect[4];
+  uint16_t status;
+  uint32_t memory_size;
+  
+  CCFileStruct.State = TT5_NO_NDEF;
+  
+  /* Read CCFile */
+  status = NfcType5_ReadCCFile( acc_buffer );
+  if( status != NDEF_OK )
+  {
+    return status;
+  }
+  
+  /* Check Byte 0 is equal to magic number */
+  if( ( acc_buffer[0] != NFCT5_MAGICNUMBER_E1_CCFILE ) && ( acc_buffer[0] != NFCT5_MAGICNUMBER_E2_CCFILE ) )
+  {
+    return NDEF_ERROR_NOT_FORMATED;
+  }
+  /* Check Version number */
+  else if( ( (acc_buffer[1]&0xFC) != 0x40 ) )
+  {
+    return NDEF_ERROR_NOT_FORMATED;
+  }
+  
+  /* Check if CCFile is on 4 Bytes or 8 Bytes */
+  if( acc_buffer[2] == 0x00 )
+  {
+    /* Update CCFIle structure */
+    CCFileStruct.MemorySize = 0x0;
+    CCFileStruct.ExtMemorySize = (uint16_t)acc_buffer[6];
+    CCFileStruct.ExtMemorySize = ( CCFileStruct.ExtMemorySize << 8 ) |  acc_buffer[7];
+    memory_size = CCFileStruct.ExtMemorySize;
+    CCFileStruct.NDEF_offset = 8;
+  }
+  else
+  {
+    /* Update CCFIle structure */
+    CCFileStruct.MemorySize = acc_buffer[2];
+    CCFileStruct.ExtMemorySize = 0x0;
+    memory_size = CCFileStruct.MemorySize;
+    CCFileStruct.NDEF_offset = 4;
+  }
+  
+  /* Update CCFIle structure */
+  CCFileStruct.MagicNumber = acc_buffer[0];
+  CCFileStruct.Version = acc_buffer[1];
+  CCFileStruct.TT5Tag = acc_buffer[3];
+  
+  /* Search for position of NDEF TLV in memory and tag status */
+  while( ( NFCTAG_ReadData( atlv_detect, CCFileStruct.NDEF_offset, 4 ) == NFCTAG_OK ) && ( CCFileStruct.NDEF_offset < memory_size ) )
+  {
+    /* Detect first NDEF Message in memory */
+    if( atlv_detect[0] == NFCT5_NDEF_MSG_TLV )
+    {
+      if( atlv_detect[1] == 0x00 )
+      {
+        CCFileStruct.State = TT5_INITIALIZED;
+      }
+      else
+      {
+        if( CCFileStruct.Version & 0x3 )
+        {
+          CCFileStruct.State = TT5_READ;
+        }
+        else
+        {
+          CCFileStruct.State = TT5_READ_WRITE;
+        }
+      }
+      return NDEF_OK;
+    }
+    /* If Proprietary NDEF jump to end of proprietary message */
+    else if( atlv_detect[0] == NFCT5_PROPRIETARY_TLV )
+    {
+      if( atlv_detect[1] == NFCT5_3_BYTES_L_TLV )
+      {
+        CCFileStruct.NDEF_offset = CCFileStruct.NDEF_offset + ( (uint32_t)atlv_detect[2] << 8 ) + atlv_detect[3];
+        continue;
+      }
+      else
+      {
+        CCFileStruct.NDEF_offset = CCFileStruct.NDEF_offset + atlv_detect[1];
+        continue;
+      }
+    }
+    /* if Terminator no NDEF detected */
+    else if( atlv_detect[0] == NFCT5_TERMINATOR_TLV )
+    {
+      return NDEF_ERROR_NOT_FORMATED;
+    }
+      
+    CCFileStruct.NDEF_offset++;
+  }
+  
+  return NDEF_ERROR_NOT_FORMATED;
+}
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Lib_NDEF/tagtype5_wrapper.h	Wed Jul 27 09:25:33 2016 +0000
@@ -0,0 +1,118 @@
+/**
+  ******************************************************************************
+  * @file    tagtype5_wrapper.h
+  * @author  MMY Application Team
+  * @version $Revision: 1638 $
+  * @date    $Date: 2016-02-10 16:41:05 +0100 (Wed, 10 Feb 2016) $
+  * @brief   Interface for tagtype5 in order to use NDEF lib
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
+  *
+  * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+  * You may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at:
+  *
+  *        http://www.st.com/myliberty  
+  *
+  * Unless required by applicable law or agreed to in writing, software 
+  * distributed under the License is distributed on an "AS IS" BASIS, 
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+  * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+  * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TAGTYPE5_WRAPPER_H
+#define __TAGTYPE5_WRAPPER_H
+
+#include <stdint.h> 
+#include "common.h"
+    
+typedef enum
+{
+  TT5_NO_NDEF = 0,
+  TT5_INITIALIZED,
+  TT5_READ_WRITE,
+  TT5_READ
+} TT5_State;
+
+/**
+  * @brief  CCfile structure
+  */
+typedef struct
+{
+  uint8_t MagicNumber;  /* Magic Number should be E1h or E2h */
+  uint8_t Version;
+  uint8_t MemorySize;
+  uint8_t TT5Tag;
+  uint8_t rsved1;
+  uint8_t rsved2;
+  uint16_t ExtMemorySize;
+  TT5_State State;
+  uint32_t NDEF_offset;
+}sCCFileInfo;
+
+/* Exported constants --------------------------------------------------------*/
+#define NFCT5_MAGICNUMBER_E1_CCFILE       0xE1
+#define NFCT5_MAGICNUMBER_E2_CCFILE       0xE2
+#define NFCT5_EXTENDED_CCFILE             0xFF
+#define NFCT5_VERSION_V1_0                0x40
+#define NFCT5_READ_ACCESS                 0x0C
+#define NFCT5_WRITE_ACCESS                0x03
+
+#define NFCT5_NDEF_MSG_TLV                0x03
+#define NFCT5_PROPRIETARY_TLV             0xFD
+#define NFCT5_TERMINATOR_TLV              0xFE
+#define NFCT5_3_BYTES_L_TLV               0xFF
+
+/* Exported macro ------------------------------------------------------------*/
+/* External variables --------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+//typedef enum
+//{
+//  NFCTAG_OK      = 0,
+//  NFCTAG_ERROR   = 1,
+//  NFCTAG_BUSY    = 2,
+//  NFCTAG_TIMEOUT = 3
+//} NFCTAG_StatusTypeDef;
+class NFCType5 {
+
+  
+ public: 
+sCCFileInfo CCFileStruct;
+
+
+uint16_t NfcType5_WriteCCFile( const uint8_t * const pCCBuffer );
+uint16_t NfcType5_ReadCCFile( uint8_t * const pCCBuffer );
+uint16_t NfcType5_TT5Init( void );
+uint16_t NfcType5_NDEFDetection( void );
+
+
+virtual NFCTAG_StatusTypeDef NFCTAG_ReadData( uint8_t * const pData, const uint16_t TarAddr, const uint16_t Size )=0;
+virtual NFCTAG_StatusTypeDef NFCTAG_WriteData( const uint8_t * const pData, const uint16_t TarAddr, const uint16_t Size )=0;
+
+uint16_t ReadData( uint16_t Offset , uint16_t DataSize , uint8_t* pData );
+uint16_t WriteData( uint16_t Offset , uint32_t DataSize , uint8_t *pData );
+
+};
+#endif /* __TAGTYPE5_WRAPPER_H */
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/X_NUCLEO_NFC02A1/Common/common.h	Wed Jul 27 09:25:33 2016 +0000
@@ -0,0 +1,60 @@
+/**
+ ******************************************************************************
+ * @file    common.h
+ * @author  AST
+ * @version V1.0.0
+ * @date    1 April 2015
+ * @brief   Header file containing generic component definitions
+ *          and I/O functions.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+
+/* Prevent recursive inclusion -----------------------------------------------*/
+
+#ifndef __COMMON_H__
+#define __COMMON_H__
+#include <stdint.h>
+
+/* Types ---------------------------------------------------------------------*/
+
+/**
+ * @brief  NFCTAG status enumerator definition
+ */
+typedef enum
+{
+  NFCTAG_OK      = 0,
+  NFCTAG_ERROR   = 1,
+  NFCTAG_BUSY    = 2,
+  NFCTAG_TIMEOUT = 3
+} NFCTAG_StatusTypeDef;
+typedef NFCTAG_StatusTypeDef (*ReadFnDataPtr)( uint8_t * const, const uint16_t, const uint16_t ) ;
+typedef NFCTAG_StatusTypeDef (*WriteFnDataPtr)( const uint8_t * const, const uint16_t, const uint16_t) ;
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/X_NUCLEO_NFC02A1/Interfaces/X_NUCLEO_NFC02A1.cpp	Wed Jul 27 09:25:33 2016 +0000
@@ -0,0 +1,74 @@
+/**
+  ******************************************************************************
+  * @file       X_NUCLEO_NFC02A1.h
+  * @author  	ST Central Labs
+  * @date       05 Nov 2015
+  * @brief      Singleton class that controls all the electronics inside the 
+  * 			X_NUCLEO_NFC02A1 expansion board
+  ******************************************************************************
+  *
+  * COPYRIGHT(c) 2015 STMicroelectronics
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+#include <X_NUCLEO_NFC02A1.h>
+
+const uint8_t  X_NUCLEO_NFC02A1::M24LR_ADDR= 0xAE; //0xAC; //rp
+const uint8_t  X_NUCLEO_NFC02A1::M24LR_ADDR_DATA = 0xA6;
+const PinName  X_NUCLEO_NFC02A1::DEFAULT_SDA_PIN=D14;
+const PinName  X_NUCLEO_NFC02A1::DEFAULT_SDL_PIN=D15;
+
+
+const PinName X_NUCLEO_NFC02A1::DEFAULT_GPO_PIN=D12;
+const PinName X_NUCLEO_NFC02A1::DEFAULT_RF_DISABLE_PIN=D11;
+const PinName X_NUCLEO_NFC02A1::DEFAULT_LED1_PIN=D5;
+const PinName X_NUCLEO_NFC02A1::DEFAULT_LED2_PIN=D4;
+const PinName X_NUCLEO_NFC02A1::DEFAULT_LED3_PIN=D2;
+
+X_NUCLEO_NFC02A1 *X_NUCLEO_NFC02A1::mInstance = NULL;
+
+X_NUCLEO_NFC02A1* X_NUCLEO_NFC02A1::Instance(DevI2C &devI2C,
+		const PinName &gpoName,
+		const PinName &RFDisableName, const PinName &led1Name,
+		const PinName &led2Name, const PinName &led3Name) {
+	if (mInstance == NULL) { // the first time
+		mInstance = new X_NUCLEO_NFC02A1(devI2C,gpoName,
+				RFDisableName,led1Name,led2Name,led3Name);
+		if (mInstance != NULL) { //allocation ok
+			const int status = mInstance->mM24LR.Initialization();
+			//if (status != NFC_SUCCESS) { //initialization failed
+                        if (status != 0) {
+				delete mInstance;
+				error(
+						"Failed to init X_NUCLEO_NFC02A1 expansion board!\r\nError:0x%X\r\n",
+						status);
+			} //if init
+		} //if instance !=NULL
+	} //if instance
+	return mInstance;
+}
+
+  
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/X_NUCLEO_NFC02A1/Interfaces/X_NUCLEO_NFC02A1.h	Wed Jul 27 09:25:33 2016 +0000
@@ -0,0 +1,153 @@
+/**
+  ******************************************************************************
+  * @file       X_NUCLEO_NFC02A1.cpp
+  * @author  	ST Central Labs
+  * @version 	V1.0.0
+  * @date       05 Nov 2015
+  * @brief      Singleton class that controls all the electronics inside the 
+  * 			X_NUCLEO_NFC02A1 expansion board.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+#ifndef X_NUCLEO_NFC02A1_H_
+#define X_NUCLEO_NFC02A1_H_
+#include <stdint.h>
+
+#include "mbed.h"
+
+#include "m24lr/m24lr.h"
+
+/**
+ * Singleton class that controls all the electronics inside the X_NUCLEO_NFC02A1 expansion board.
+ */
+class X_NUCLEO_NFC02A1 {
+
+public:
+
+private:
+	/**
+	 * Ponter to the singleton instance, NULL if not allocated.
+	 */
+	static X_NUCLEO_NFC02A1 *mInstance;
+	/**
+	 * I2C address of the M24LR chip.
+	 */
+	static const uint8_t M24LR_ADDR;
+        
+        static const uint8_t M24LR_ADDR_DATA;
+
+	/**
+	 * Constructor
+	 * @param devI2C I2C channel used to communicate with the board.
+	 * @param eventCallback Function that will be called when the gpo pin status change.
+	 * @param gpoName Name of the gpio pin of the M24LR chip.
+	 * @param RFDisableName Pin that controls the rf antenna status.
+	 * @param led1Name Pin to control the led1 status.
+	 * @param led2Name Pin to control the led1 status.
+	 * @param led3Name Pin to control the led1 status.
+	 */
+	X_NUCLEO_NFC02A1(DevI2C &devI2C,
+			const PinName &gpoName,	const PinName &RFDisableName,
+			const PinName &led1Name, const PinName &led2Name,
+			const PinName &led3Name):
+ 				mM24LR(M24LR_ADDR, M24LR_ADDR_DATA, devI2C),
+				mNfcLed1(led1Name),mNfcLed2(led2Name),mNfcLed3(led3Name){}
+
+public:
+	static const PinName DEFAULT_SDA_PIN; //!< Default pin used for the M24LR SDA signal.
+	static const PinName DEFAULT_SDL_PIN; //!< Default pin used for the M24LR SDL signal.
+	static const PinName DEFAULT_GPO_PIN; //!< Default pin used for the M24LR GPO signal.
+	static const PinName DEFAULT_RF_DISABLE_PIN; //!< Default pin used for M24LR RF_DISABLE signal.
+	static const PinName DEFAULT_LED1_PIN; //!< Default pin to control the led 1.
+	static const PinName DEFAULT_LED2_PIN; //!< Default pin to control the led 2.
+	static const PinName DEFAULT_LED3_PIN; //!< Default pin to control the led 3.
+
+    /**
+	 * Create or return an instance of X_NUCLEO_NFC02A1.
+	 * @param devI2C I2C channel used to communicate with the board.
+	 * @param eventCallback Function that will be called when the gpo pin status change.
+	 * @param gpoName Name of the gpio pin of the M24LR chip.
+	 * @param RFDisableName Pin that controls the rf antenna status.
+	 * @param led1Name Pin to control the led1 status.
+	 * @param led2Name Pin to control the led1 status.
+	 * @param led3Name Pin to control the led1 status.
+	 */
+	static X_NUCLEO_NFC02A1* Instance(DevI2C &devI2C,
+			const PinName &gpoName = DEFAULT_GPO_PIN,
+ 			const PinName &RFDisableName = DEFAULT_RF_DISABLE_PIN,
+ 			const PinName &led1Name = DEFAULT_LED1_PIN,
+ 			const PinName &led2Name = DEFAULT_LED2_PIN,
+ 			const PinName &led3Name = DEFAULT_LED3_PIN);
+
+	/**
+	 * @return board led1.
+	 */
+	DigitalOut& getLed1() {
+		return mNfcLed1;
+	}
+
+	/**
+	 * @return board led2.
+	 */
+	DigitalOut& getLed2() {
+		return mNfcLed2;
+	}
+
+	/**
+	 * @return board led3.
+	 */
+	DigitalOut& getLed3() {
+		return mNfcLed3;
+	}
+
+	/**
+	 * @return NFC Chip.
+	 */
+	M24LR& getNFCTagM24LR() {
+		return mM24LR;
+	}
+        
+        M24LR* getM24LR() {
+		return &mM24LR;
+	}
+
+	virtual ~X_NUCLEO_NFC02A1() {
+	}
+
+private:
+        M24LR mM24LR;
+
+	DigitalOut mNfcLed1;
+	DigitalOut mNfcLed2;
+	DigitalOut mNfcLed3;
+
+};
+#endif /* X_NUCLEO_NFC02A1_H_ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/X_NUCLEO_NFC02A1/X_NUCLEO_COMMON/DevI2C/DevI2C.h	Wed Jul 27 09:25:33 2016 +0000
@@ -0,0 +1,188 @@
+/**
+ ******************************************************************************
+ * @file    DevI2C.h
+ * @author  AST / EST / AMG-CL
+ * @version V0.0.2
+ * @date    25-July-2016
+ * @brief   Header file for a special I2C class DevI2C which provides some
+ *          helper function for on-board communication
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent from recursive inclusion --------------------------------*/
+#ifndef __DEV_I2C_H
+#define __DEV_I2C_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "mbed.h"
+
+/* Classes -------------------------------------------------------------------*/
+/** Helper class DevI2C providing functions for multi-register I2C communication
+ *  common for a series of I2C devices
+ */
+class DevI2C : public I2C
+{
+ public:
+   
+   /** Create a DevI2C Master interface, connected to the specified pins
+   *
+   *  @param sda I2C data line pin
+   *  @param scl I2C clock line pin
+   */
+   DevI2C(PinName sda, PinName scl) : I2C(sda, scl) {}
+
+   /**
+   * @brief  Writes a buffer towards the I2C peripheral device.
+   * @param  pBuffer pointer to the byte-array data to send
+   * @param  DeviceAddr specifies the peripheral device slave address.
+   * @param  RegisterAddr specifies the internal address register 
+   *         where to start writing to (must be correctly masked).
+   * @param  NumByteToWrite number of bytes to be written.
+   * @retval 0 if ok, 
+   * @retval -1 if an I2C error has occured, or
+   * @retval -2 on temporary buffer overflow (i.e. NumByteToWrite was too high)
+   * @note   On some devices if NumByteToWrite is greater
+   *         than one, the RegisterAddr must be masked correctly!
+   */
+   int i2c_write(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t RegisterAddr, 
+                 uint16_t NumByteToWrite)
+   {
+     int ret;
+     uint8_t tmp[TEMP_BUF_SIZE];
+     
+     if(NumByteToWrite >= TEMP_BUF_SIZE) return -2;
+     
+     /* First, send device address. Then, send data and STOP condition */
+     tmp[0] = RegisterAddr;
+     memcpy(tmp+1, pBuffer, NumByteToWrite);
+     
+     ret = write(DeviceAddr, (const char*)tmp, NumByteToWrite+1, false);
+     
+     if(ret) return -1;
+     return 0;
+   }
+        
+   /**
+   * @brief  Writes a buffer towards the I2C peripheral device.
+   * @param  pBuffer pointer to the byte-array data to send
+   * @param  DeviceAddr specifies the peripheral device slave address.
+   * @param  RegisterAddr specifies the internal address register 
+   *         where to start writing to (must be correctly masked).
+   * @param  NumByteToWrite number of bytes to be written.
+   * @retval 0 if ok, 
+   * @retval -1 if an I2C error has occured, or
+   * @retval -2 on temporary buffer overflow (i.e. NumByteToWrite was too high)
+   * @note   On some devices if NumByteToWrite is greater
+   *         than one, the RegisterAddr must be masked correctly!
+   */
+   int i2c_write(uint8_t* pBuffer, uint8_t DeviceAddr, uint16_t RegisterAddr, 
+                 uint16_t NumByteToWrite)
+   {
+     int ret;
+     uint8_t tmp[TEMP_BUF_SIZE];
+     
+     if(NumByteToWrite >= TEMP_BUF_SIZE) return -2;
+     
+     /* First, send device address. Then, send data and STOP condition */
+     tmp[0] = (RegisterAddr >> 8) & 0xFF;
+     tmp[1] = (RegisterAddr) & 0xFF;
+     memcpy(tmp+2, pBuffer, NumByteToWrite);
+     
+     ret = write(DeviceAddr, (const char*)tmp, NumByteToWrite+2, false);
+     
+     if(ret) return -1;
+     return 0;
+   }
+   /**
+   * @brief  Reads a buffer from the I2C peripheral device.
+   * @param  pBuffer pointer to the byte-array to read data in to
+   * @param  DaviceAddr specifies the peripheral device slave address.
+   * @param  RegisterAddr specifies the internal address register 
+   *         where to start reading from (must be correctly masked).
+   * @param  NumByteToRead number of bytes to be read.
+   * @retval 0 if ok, 
+   * @retval -1 if an I2C error has occured
+   * @note   On some devices if NumByteToWrite is greater
+   *         than one, the RegisterAddr must be masked correctly!
+   */
+   int i2c_read(uint8_t* pBuffer, uint8_t DeviceAddr, uint16_t RegisterAddr, 
+                uint16_t NumByteToRead)
+   {
+     int ret;
+     uint8_t reg_addr[2];
+     reg_addr[0] = (RegisterAddr >> 8) & 0xFF;
+     reg_addr[1] = (RegisterAddr) & 0xFF;
+     /* Send device address, with no STOP condition */
+     ret = write(DeviceAddr, (const char*)reg_addr, 2, true);
+     if(!ret) {
+       /* Read data, with STOP condition  */
+       ret = read(DeviceAddr, (char*)pBuffer, NumByteToRead, false);
+     }
+     
+     if(ret) 
+       return -1;
+     else
+       return 0;
+   }
+   
+   /**
+   * @brief  Reads a buffer from the I2C peripheral device.
+   * @param  pBuffer pointer to the byte-array to read data in to
+   * @param  DaviceAddr specifies the peripheral device slave address.
+   * @param  RegisterAddr specifies the internal address register 
+   *         where to start reading from (must be correctly masked).
+   * @param  NumByteToRead number of bytes to be read.
+   * @retval 0 if ok, 
+   * @retval -1 if an I2C error has occured
+   * @note   On some devices if NumByteToWrite is greater
+   *         than one, the RegisterAddr must be masked correctly!
+   */
+   int i2c_read(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t RegisterAddr, 
+                uint16_t NumByteToRead)
+   {
+     int ret;
+     
+     /* Send device address, with no STOP condition */
+     ret = write(DeviceAddr, (const char*)&RegisterAddr, 1, true);
+     if(!ret) {
+       /* Read data, with STOP condition  */
+       ret = read(DeviceAddr, (char*)pBuffer, NumByteToRead, false);
+     }
+     
+     if(ret) return -1;
+     return 0;
+   }
+   
+private:
+  static const unsigned int TEMP_BUF_SIZE = 32;
+};
+
+#endif /* __DEV_I2C_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/X_NUCLEO_NFC02A1/m24lr/m24lr.cpp	Wed Jul 27 09:25:33 2016 +0000
@@ -0,0 +1,983 @@
+#include "m24lr.h"
+
+uint8_t M24LR::NfctagInitialized = 0; 
+
+
+/**
+  * @brief  This function activate Energy Harvesting mode
+  */
+void M24LR::Enable_EnergyHarvesting( void )
+{
+  /* Initialise M24LR Board */
+  
+    /* Enable Energy Harvesting */
+    i2c_SetEH( );
+
+    /* Store configuration in non Volatile Memory */
+    i2c_Enable_EH_mode();
+    i2c_WriteEH_Cfg( M24LR_EH_Cfg_6MA );
+  
+}
+/**
+  * @brief  Set M24LR nfctag Initialization
+  * @param  None
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::Initialization( void )
+{ 
+  uint8_t nfctag_id = 0;
+  
+  if( NfctagInitialized == 0 )
+  {
+    
+    /* M24LR Init */
+    if( i2c_Init() != NFCTAG_OK )
+    {
+      return NFCTAG_ERROR;
+    }
+    
+    /* Check M24LR driver ID */
+    i2c_ReadID(&nfctag_id);
+    if( (nfctag_id == I_AM_M24LR04) || (nfctag_id == I_AM_M24LR16) || (nfctag_id == I_AM_M24LR64) )
+    {
+      NfctagInitialized = 1;
+     // Nfctag_Drv = &M24lr_i2c_Drv;
+     // Nfctag_Drv->pData = &M24lr_i2c_ExtDrv;
+    }
+    else
+    {
+      NfctagInitialized = 0;
+     // Nfctag_Drv = NULL;
+     // NfctagInitialized = 0;
+      return NFCTAG_ERROR;
+    }
+  }
+  
+  return NFCTAG_OK;
+}
+
+/**
+  * @brief  Set M24LR Initialization
+  * @param  None
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_Init( void )
+{
+  /* Configure the low level interface */
+  return(NFCTAG_OK);
+ // return mM24LR_IO.Init( );
+}
+
+/**
+  * @brief  Read M24LR ID
+  * @param  pICRef : pointer to store ID
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_ReadID( uint8_t * const pData )
+{
+  uint8_t *pBuffer = (uint8_t *)pData;
+  NFCTAG_StatusTypeDef status;
+  /* Read ICRef on device */
+  //return M24LR_i2c_ReadRegister( pICRef, M24LR_ICREF_REG, 1 );
+  /* Before calling this function M24LR must be ready, here is a check to detect an issue */
+   status = i2c_ReadRegister(pBuffer, M24LR_ICREF_REG, 1);
+
+  if (status  == 0)
+    return NFCTAG_OK;
+  return NFCTAG_TIMEOUT;
+ 
+}
+
+/**
+  * @brief  Check M24LR availability
+  * @param  Trials : number of max tentative tried
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_IsDeviceReady( const uint32_t Trials )
+{
+  /* Test i2c with M24LR */
+ // return mM24LR_IO.IsDeviceReady( M24LR_ADDR_DATA_I2C, Trials );
+  uint8_t status = 1;
+  char buffer;
+  while (status != 0) {
+    /* for device is ready address in M24Lr is M24LR_ADDR_DATA_I2C */
+    status = dev_I2C.read(i2c_address_data, &buffer, 1, false);
+  }
+  if ( status == 0 )
+    return NFCTAG_OK;
+  else
+    return NFCTAG_TIMEOUT;
+  
+}
+
+/**
+  * @brief  Configure M24LR GPO
+  * @param  ITConf : 0x01 = RFBUSY, 0x02 = RFWIP
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_ConfigureGPO( const uint16_t ITConf )
+{
+  NFCTAG_StatusTypeDef status = NFCTAG_ERROR;
+  
+  /* Configure GPO function on M24LR */
+  if( (ITConf & M24LR_IT_BUSY_MASK) == M24LR_IT_BUSY_MASK )
+  {
+    status = i2c_SetRFBUSY( );
+  }
+  else if( (ITConf & M24LR_IT_WIP_MASK) == M24LR_IT_WIP_MASK )
+  {
+    status = i2c_SetRFWIP( );
+  }
+  return status;
+}
+
+/**
+  * @brief  Configure GPO as RF WriteInProgress
+  * @param  None
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_SetRFWIP( void )
+{
+  uint8_t reg_value;
+  NFCTAG_StatusTypeDef status;
+  status = i2c_ReadRegister(&reg_value, M24LR_CFG_REG, 1);
+  
+
+  if( status != NFCTAG_OK )
+  {
+    return status;
+  }
+  
+  /* Update register value for WIP configuration */
+  reg_value |= M24LR_CFG_WIPBUSY_MASK;
+  
+  /* Write CFG register */
+  return i2c_WriteRegister( &reg_value, M24LR_CFG_REG, 1 );
+}
+
+
+/**
+  * @brief  Get Configuration of M24LR GPO
+  * @param  GPOStatus : 0x01 = RFBUSY, 0x02 = RFWIP
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_GetGPOStatus( uint16_t * const pGPOStatus )
+{
+  uint8_t reg_value;
+  NFCTAG_StatusTypeDef status;
+  
+  /* Read actual value of CFG register */
+  status = i2c_ReadRegister( &reg_value, M24LR_CFG_REG, 1 );
+  if( status != NFCTAG_OK )
+  {
+    return status;
+  }
+  
+  /* Extract RF WIP/BUSY information */
+  if( (reg_value & M24LR_CFG_WIPBUSY_MASK) == M24LR_CFG_WIPBUSY_MASK )
+  {
+    *pGPOStatus = M24LR_IT_WIP_MASK;
+  }
+  else
+  {
+    *pGPOStatus = M24LR_IT_BUSY_MASK;
+  }
+  
+  return NFCTAG_OK;
+}
+
+/**
+  * @brief  Read N bytes starting from specified I2C address
+  * @param  pData : pointer of the data to store
+  * @param  TarAddr : I2C data memory address to read
+  * @param  NbByte : number of bytes to read
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_ReadData( uint8_t * const pData, const uint16_t TarAddr, const uint16_t NbByte )
+{  
+  int status;
+  /* Before calling this function M24LR must be ready, here is a check to detect an issue */
+  if( i2c_IsDeviceReady( 1 ) != NFCTAG_OK )
+  {
+    return NFCTAG_TIMEOUT;
+  }
+  /* Rosarium : To check M24LR_ADDR_DATA_I2C is this case */
+ /* return M24lr_IO_MemRead( pData, M24LR_ADDR_DATA_I2C, TarAddr, NbByte ); */
+   status = dev_I2C.i2c_read(pData, i2c_address_data, TarAddr, NbByte);
+    if ( status == 0 )
+    return NFCTAG_OK;
+  else
+    return NFCTAG_TIMEOUT;
+}
+
+/**
+  * @brief  Write N data bytes starting from specified I2C Address
+  * @brief  if I2C_Write_Lock bit = 0 or I2C_Password present => ack (modification OK)
+  * @brief  if I2C_Write_Lock bit = 1  and no I2C_Password present => No ack (no modification)
+  * @param  pData : pointer of the data to write
+  * @param  TarAddr : I2C data memory address to write
+  * @param  NbByte : number of bytes to write
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_WriteData( const uint8_t * const pData, const uint16_t TarAddr, const uint16_t NbByte )
+{ 
+  int status;
+  uint8_t align_mem_offset;
+  uint16_t bytes_to_write = NbByte;
+  uint16_t mem_addr = TarAddr;
+  uint8_t *pdata_index = (uint8_t *)pData;
+  
+  /* Before calling this function M24LR must be ready, here is a check to detect an issue */
+  if( i2c_IsDeviceReady( 1 ) != NFCTAG_OK )
+  {
+    return NFCTAG_TIMEOUT;
+  }
+  
+  /* M24LR can write a maximum of 4 bytes in EEPROM per i2c communication */
+  do
+  {
+    /* To write data in M24LR, data must be aligned on the same row in memory */
+    /* align_mem_offset is used to copy only Bytes that are on the same row  in memory */
+    if( bytes_to_write > M24LR_PAGEWRITE_NBBYTE )
+    {
+      /* DataSize higher than max page write, copy data by page */
+      align_mem_offset = M24LR_PAGEWRITE_NBBYTE - (mem_addr % M24LR_PAGEWRITE_NBBYTE);
+    }
+    else
+    {
+      /* DataSize lower or equal to max page write, copy only last bytes */
+      align_mem_offset = bytes_to_write;
+    }
+    /* Write align_mem_offset bytes in memory */
+    /* Rosarium to Check as the address here is 0xA6 rather than 0xAE */
+    /* Rosarium dev_I2C.i2c_write(pdata_index, M24LR_ADDR_DATA_I2C, mem_addr, align_mem_offset); */
+    status = dev_I2C.i2c_write(pdata_index, i2c_address_data, mem_addr, align_mem_offset);
+    
+    /* update index, dest address, size for next write */
+    pdata_index += align_mem_offset;
+    mem_addr += align_mem_offset;
+    bytes_to_write -= align_mem_offset;
+    /* Poll until EEPROM is available */
+    while( i2c_IsDeviceReady( 1 ) != NFCTAG_OK ) {};
+  }
+  while( ( bytes_to_write > 0 ) && ( status == NFCTAG_OK ) );
+  if ( status == 0 )
+    return NFCTAG_OK;
+  else
+    return NFCTAG_ERROR;
+}
+
+/**
+  * @brief  Read N register bytes starting from specified I2C address
+  * @param  pData : pointer of the data to store
+  * @param  TarAddr : I2C memory address to read
+  * @param  NbByte : number of bytes to read
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_ReadRegister( uint8_t * const pData, const uint16_t TarAddr, const uint16_t NbByte )
+{  
+  /* Before calling read function M24LR must be ready, here is a check to detect an issue */
+  int status;
+  
+  /* Before calling any read function M24LR must be ready, here is a check to detect an issue */
+  if( i2c_IsDeviceReady( 1 ) != NFCTAG_OK )
+  {
+    return NFCTAG_TIMEOUT;
+  }
+   /* Read actual value of register */
+  status = dev_I2C.i2c_read(pData, i2c_address_syst, TarAddr, NbByte);
+  
+    if ( status == 0 )
+    return NFCTAG_OK;
+  else
+    return NFCTAG_TIMEOUT;
+}
+
+/**
+  * @brief  Write N bytes to specific register
+  * @param  pData : pointer of the data to write
+  * @param  TarAddr : I2C register address to write
+  * @param  NbByte : number of bytes to write
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_WriteRegister( const uint8_t * const pData, const uint16_t TarAddr, const uint16_t NbByte )
+{ 
+  int status;
+  uint8_t align_mem_offset;
+  uint16_t bytes_to_write = NbByte;
+  uint16_t mem_addr = TarAddr;
+  uint8_t *pdata_index = (uint8_t *)pData;
+  
+  /* Before calling this function M24LR must be ready, here is a check to detect an issue */
+  if( i2c_IsDeviceReady( 1 ) != NFCTAG_OK )
+  {
+    return NFCTAG_TIMEOUT;
+  }
+  
+  /* M24LR can write a maximum of 4 bytes in EEPROM per i2c communication */
+  do
+  {
+    /* To write data in M24LR, data must be aligned on the same row in memory */
+    /* align_mem_offset is used to copy only Bytes that are on the same row  in memory */
+    if( bytes_to_write > M24LR_PAGEWRITE_NBBYTE )
+    {
+      /* DataSize higher than max page write, copy data by page */
+      align_mem_offset = M24LR_PAGEWRITE_NBBYTE - (mem_addr % M24LR_PAGEWRITE_NBBYTE);
+    }
+    else
+    {
+      /* DataSize lower or equal to max page write, copy only last bytes */
+      align_mem_offset = bytes_to_write;
+    }
+    /* Write align_mem_offset bytes in register */
+   // status = M24lr_IO_MemWrite( pdata_index, M24LR_ADDR_SYST_I2C, mem_addr, align_mem_offset );
+    status = dev_I2C.i2c_write(pdata_index, i2c_address_syst, mem_addr, align_mem_offset);
+    /* update index, dest address, size for next write */
+    pdata_index += align_mem_offset;
+    mem_addr += align_mem_offset;
+    bytes_to_write -= align_mem_offset;
+    /* Poll until EEPROM is available */
+    while( i2c_IsDeviceReady( 1 ) != NFCTAG_OK ) {};
+  }
+  while( ( bytes_to_write > 0 ) && ( status == NFCTAG_OK ) );
+  
+    if ( status == 0 )
+    return NFCTAG_OK;
+  else
+    return NFCTAG_ERROR;
+}
+
+/**
+  * @brief  Read M24LR UID
+  * @param  UID : M24LR_UID pointer of the UID to store
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_ReadUID( M24LR_UID * const pUid )
+{
+  uint8_t areg_value[8];
+  uint8_t i;
+  NFCTAG_StatusTypeDef status;
+  
+  /* Read actual value of UID registers */
+  status = i2c_ReadRegister( areg_value, M24LR_UID_REG, 8 );
+  if( status != NFCTAG_OK )
+  {
+    return status;
+  }
+  
+  /* Store information in 2 WORD */
+  pUid->MSB_UID = 0;
+  
+  for( i = 0; i < 4; i++ )
+  {
+    pUid->MSB_UID = (pUid->MSB_UID << 8) | areg_value[7 - i];
+  }
+  
+  pUid->LSB_UID = 0;
+  
+  for( i = 0; i < 4; i++ )
+  {
+    pUid->LSB_UID = (pUid->LSB_UID << 8) | areg_value[3 - i];
+  }
+  
+  return NFCTAG_OK;
+}
+
+/**
+  * @brief  Read DSFID
+  * @param  pData : pointer of the DSFID to store
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_ReadDSFID( uint8_t * const pDsfid )
+{
+  /* Read actual value of DSFID register */
+  return i2c_ReadRegister( pDsfid, M24LR_DSFID_REG, 1 );
+}
+
+/**
+  * @brief  Read AFI
+  * @param  pData : pointer of the AFI to store
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_ReadAFI( uint8_t * const pAfi )
+{
+  /* Read actual value of AFI register */
+  return i2c_ReadRegister( pAfi, M24LR_AFI_REG, 1 );
+}
+
+/**
+  * @brief  Read status of I2C Lock Sectors
+  * @param  Lock_sector : M24LR_Lock_Sectors pointer of the I2c lock sector status to store
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_ReadI2CLockSector( M24LR_Lock_Sectors * const pLock_sector )
+{
+  uint8_t areg_value[8];
+  NFCTAG_StatusTypeDef status;
+
+  /* Read actual value of I2c Write Lock registers */
+  status = i2c_ReadRegister( areg_value, M24LR_LOCK_REG, 8 );
+  if( status != NFCTAG_OK )
+  {
+    return status;
+  }
+  
+  /* Dispatch information to corresponding struct member */
+  pLock_sector->sectors_63_56 = areg_value[7];
+  pLock_sector->sectors_55_48 = areg_value[6];
+  pLock_sector->sectors_47_40 = areg_value[5];
+  pLock_sector->sectors_39_32 = areg_value[4];
+  pLock_sector->sectors_31_24 = areg_value[3];
+  pLock_sector->sectors_23_16 = areg_value[2];
+  pLock_sector->sectors_15_8 = areg_value[1];
+  pLock_sector->sectors_7_0 = areg_value[0];
+  
+  return NFCTAG_OK;
+}
+
+/**
+  * @brief  Lock I2C write on an EEPROM Sectors
+  * @brief  Need a presentation of I2C Password to be effective
+  * @param  Sector : EEPROM Sector number to lock (between 0 to 63)
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_I2CLockSector( const uint8_t Sector )
+{
+  NFCTAG_StatusTypeDef status;
+  uint8_t reg_value = 0;
+  uint16_t sector_write_lock_addr;
+  
+  /* Compute register address */
+  sector_write_lock_addr = M24LR_LOCK_REG | (Sector >> 3);
+  
+  /* Read actual WriteLockStatus */
+  status = i2c_ReadRegister( &reg_value, sector_write_lock_addr, 1 );
+  if( status != NFCTAG_OK )
+  {
+    return status;
+  }
+  
+  /* Compute and update new WriteLockStatus */
+  reg_value |= 1 << ( Sector % 8 );
+
+  /* Write WriteLock register */
+  return i2c_WriteRegister( &reg_value, sector_write_lock_addr, 1 );
+}
+
+/**
+  * @brief  UnLock I2C write on a EEPROM Sector
+  * @brief  Need an presentation of I2C Password to be effective
+  * @param  pSector : EEPROM Sector number to unlock (between 0 to 63)
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_I2CUnlockSector( const uint8_t Sector )
+{
+  NFCTAG_StatusTypeDef status;
+  uint8_t reg_value = 0;
+  uint16_t sector_write_lock_addr;
+  
+  /* Compute register address */
+  sector_write_lock_addr = M24LR_LOCK_REG | (Sector >> 3);
+  
+  /* Read actual WriteLockStatus */
+  status = i2c_ReadRegister( &reg_value, sector_write_lock_addr, 1 );
+  if( status != NFCTAG_OK )
+  {
+    return status;
+  }
+  
+  /* Compute and update new WriteLockStatus */
+  reg_value &= ~( 1 << ( Sector % 8 ) );
+
+  /* Write WriteLock register */
+  return i2c_WriteRegister( &reg_value, sector_write_lock_addr, 1 );
+}
+
+/**
+  * @brief  Present I2C password, authorize I2C write
+  * @param  PassWord : Password value on 32bits
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_PresentI2CPassword( const uint32_t PassWord )
+{
+  uint8_t ai2c_message[9] = {0};
+  uint8_t i;
+  
+  /* Build I2C Message with Password + Validation code 0x09 + Password */
+  ai2c_message[4] = 0x09;
+  i = 0;
+  while( i < 4 )
+  {
+    ai2c_message[i] = ( PassWord >> (i * 8) ) & 0xFF;
+    ai2c_message[i + 5] = ( PassWord >> (i * 8) ) & 0xFF;
+    i++;
+  };
+  
+  /* Present password to M24LR */
+  return i2c_WriteRegister( ai2c_message, M24LR_I2C_PWD_REG, 9 );
+}
+
+/**
+  * @brief  Write new I2C password
+  * @brief  Need to present good I2CPassword before using this function
+  * @param  PassWord : new I2C PassWord value on 32bits
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_WriteI2CPassword( const uint32_t PassWord )
+{
+  uint8_t ai2c_message[9] = {0};
+  uint8_t i;
+  
+  /* Build I2C Message with Password + Validation code 0x07 + Password */
+  ai2c_message[4] = 0x07;
+  i = 0;
+  while( i < 4 ) 
+  {
+    ai2c_message[i] = ( PassWord >> (i * 8) ) & 0xFF;
+    ai2c_message[i + 5] = ( PassWord >> (i * 8) ) & 0xFF;
+    i++;
+  };
+  
+  /* Write Password to register */
+  return i2c_WriteRegister( ai2c_message, M24LR_I2C_PWD_REG, 9 );
+}
+
+/**
+  * @brief  Read SectorSecurityStatus (defining RF access allowed)
+  * @param  SectorNb : Sector number to get RF security status
+  * @param  pData : M24LR_SECTOR_SEC pointer of the data to store
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_ReadSSSx( const uint8_t SectorNb, M24LR_SECTOR_SEC * const pData )
+{
+  uint8_t reg_value;
+  NFCTAG_StatusTypeDef status;
+  uint16_t sector_security_addr;
+  
+  /* Compute Sector Security register address */
+  sector_security_addr = M24LR_SSS_REG | SectorNb;
+  
+  /* Read actual value of SectorSecurityStatus register */
+  status = i2c_ReadRegister( &reg_value, sector_security_addr, 1 );
+  if( status != NFCTAG_OK )
+  {
+    return status;
+  }
+  
+  /* Extract Sector Security Status configuration */
+  pData->SectorLock = reg_value & M24LR_SSS_LOCK_MASK;
+  pData->RW_Protection = (reg_value & M24LR_SSS_RW_MASK) >> 1;
+  pData->PassCtrl = (reg_value & M24LR_SSS_PASSCTRL_MASK) >> 3;
+  
+  return NFCTAG_OK;
+}
+
+/**
+  * @brief  Write SectorSecurityStatus (defining RF access allowed)
+  * @brief  Need an presentation of I2C Password to be effective
+  * @param  SectorNb : Sector number to set RF security
+  * @param  pData : M24LR_SECTOR_SEC pointer of the data to write
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_WriteSSSx( const uint8_t SectorNb, const M24LR_SECTOR_SEC * const pData )
+{
+  uint8_t reg_value;
+  uint16_t sector_security_addr;
+  
+  /* Compute Sector Security register address */
+  sector_security_addr = M24LR_SSS_REG | SectorNb;
+  
+  /* Update Sector Security Status */ 
+  reg_value = (pData->PassCtrl << 3) & M24LR_SSS_PASSCTRL_MASK;
+  reg_value |= ((pData->RW_Protection << 1) & M24LR_SSS_RW_MASK);
+  reg_value |= (pData->SectorLock & M24LR_SSS_LOCK_MASK);
+  
+  /* Write SectorSecurityStatus register */
+  return i2c_WriteRegister( &reg_value, sector_security_addr, 1 );
+}
+
+/**
+  * @brief  Read Memory Size info
+  * @param  SizeInfo : M24LR_Mem_Size pointer of the data to store
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_ReadMemSize( M24LR_Mem_Size * const pSizeInfo )
+{
+  uint8_t areg_value[3];
+  NFCTAG_StatusTypeDef status;
+  
+  /* Read actual value of Mem_Size register */
+  status = i2c_ReadRegister( areg_value, M24LR_MEMSIZE_REG, 3 );
+  if( status != NFCTAG_OK )
+  {
+    return status;
+  }
+  
+  /* Extract Mem information */
+  pSizeInfo->BlockSize = areg_value[2];
+  pSizeInfo->Mem_Size = areg_value[1];
+  pSizeInfo->Mem_Size = (pSizeInfo->Mem_Size << 8) | areg_value[0];
+
+  return NFCTAG_OK;
+}
+
+/**
+  * @brief  Get GPO Configuration status
+  * @param  Rf_Wip_Busy : M24LR_GPO_STATUS pointer of the data to store
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_GetRF_WIP_BUSY( M24LR_GPO_STATUS * const pRf_Wip_Busy )
+{
+  uint8_t reg_value;
+  NFCTAG_StatusTypeDef status;
+  
+  /* Read actual value of CFG register */
+  status = i2c_ReadRegister( &reg_value, M24LR_CFG_REG, 1 );
+  if( status != NFCTAG_OK )
+  {
+    return status;
+  }
+  
+  /* Extract RF WIP/BUSY information */
+  if( (reg_value & M24LR_CFG_WIPBUSY_MASK) == M24LR_CFG_WIPBUSY_MASK )
+  {
+    *pRf_Wip_Busy = M24LR_GPO_WIP;
+  }
+  else
+  {
+    *pRf_Wip_Busy = M24LR_GPO_BUSY;
+  }
+
+  return NFCTAG_OK;
+}
+
+/**
+  * @brief  Configure GPO as RF Busy
+  * @param  None
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_SetRFBUSY( void )
+{
+  uint8_t reg_value;
+  int status;
+  
+  /* Read actual value of CFG register */
+  status = dev_I2C.i2c_read( &reg_value, i2c_address_syst, (uint16_t)M24LR_CFG_REG, 1 );
+  if( status != 0 )
+  {
+    return NFCTAG_TIMEOUT;
+  }
+  
+  /* Update register value for BUSY configuration */
+  reg_value &= !M24LR_CFG_WIPBUSY_MASK;
+  
+  /* Write CFG register */
+  status = i2c_WriteRegister( &reg_value, M24LR_CFG_REG, 1 );
+  if ( status == 0 )
+    return NFCTAG_OK;
+  else
+    return NFCTAG_TIMEOUT;
+}
+
+
+/**
+  * @brief  Get Energy harvesting mode status
+  * @param  EH_mode : M24LR_EH_MODE_STATUS pointer of the data to store
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_Read_EH_mode( M24LR_EH_MODE_STATUS * const pEH_mode )
+{
+  uint8_t reg_value;
+  NFCTAG_StatusTypeDef status;
+  
+  /* Read actual value of CFG register */
+  status = i2c_ReadRegister( &reg_value, M24LR_CFG_REG, 1 );
+  if( status != NFCTAG_OK )
+  {
+    return status;
+  }
+  
+  /* Extract EH_mode configuration */
+  if( (reg_value & M24LR_CFG_EHMODE_MASK) == M24LR_CFG_EHMODE_MASK )
+  {
+    *pEH_mode = M24LR_EH_MODE_DISABLE;
+  }
+  else
+  {
+    *pEH_mode = M24LR_EH_MODE_ENABLE;
+  }
+  
+  return NFCTAG_OK;
+}
+
+/**
+  * @brief  Enable Energy harvesting mode
+  * @param  None
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_Enable_EH_mode( void )
+{
+  uint8_t reg_value;
+  NFCTAG_StatusTypeDef status;
+  
+  /* Read actual value of CFG register */
+  status = i2c_ReadRegister( &reg_value, M24LR_CFG_REG, 1 );
+  if( status != NFCTAG_OK )
+  {
+    return status;
+  }
+  
+  /* Update EH_mode */
+  reg_value &= ~M24LR_CFG_EHMODE_MASK;
+  
+  /* Write CFG register */
+  return i2c_WriteRegister( &reg_value, M24LR_CFG_REG, 1 );
+}
+
+/**
+  * @brief  Disable Energy harvesting mode
+  * @param  None
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_Disable_EH_mode( void )
+{
+  uint8_t reg_value;
+  NFCTAG_StatusTypeDef status;
+  
+  /* Read actual value of CFG register */
+  status = i2c_ReadRegister( &reg_value, M24LR_CFG_REG, 1 );
+  if( status != NFCTAG_OK )
+  {
+    return status;
+  }
+  
+  /* Update EH_mode */
+  reg_value |= M24LR_CFG_EHMODE_MASK;
+  
+  /* Write CFG register */
+  return i2c_WriteRegister( &reg_value, M24LR_CFG_REG, 1 );
+}
+
+/**
+  * @brief  Read Vout sink current configuration status for Energy Harvesting
+  * @param  EH_Cfg : M24LR_EH_CFG_VOUT pointer of the data to store
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_ReadEH_Cfg( M24LR_EH_CFG_VOUT * const pEH_Cfg )
+{
+  uint8_t reg_value;
+  NFCTAG_StatusTypeDef status;
+  
+  /* Read actual value of CFG register */
+  status = i2c_ReadRegister( &reg_value, M24LR_CFG_REG, 1 );
+  if( status != NFCTAG_OK )
+  {
+    return status;
+  }
+  
+  /* Extract Vout configuration for EH information */
+  reg_value &= (M24LR_CFG_EHCFG1_MASK | M24LR_CFG_EHCFG0_MASK);
+  switch( reg_value )
+  {
+    case 0:
+      *pEH_Cfg = M24LR_EH_Cfg_6MA;
+      break;
+    case 1:
+      *pEH_Cfg = M24LR_EH_Cfg_3MA;
+      break;
+    case 2:
+      *pEH_Cfg = M24LR_EH_Cfg_1MA;
+      break;
+    case 3:
+      *pEH_Cfg = M24LR_EH_Cfg_300UA;
+      break;
+    
+    default:
+      *pEH_Cfg = M24LR_EH_Cfg_6MA;
+  } 
+  
+  return NFCTAG_OK;
+}
+
+/**
+  * @brief  Write Vout sink current configuration status for Energy Harvesting
+  * @param  EH_Cfg : M24LR_EH_CFG_VOUT value to configure Vout
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_WriteEH_Cfg( const M24LR_EH_CFG_VOUT EH_Cfg )
+{
+  uint8_t reg_value;
+  NFCTAG_StatusTypeDef status;
+  
+  /* Read actual value of CFG register */
+  status = i2c_ReadRegister( &reg_value, M24LR_CFG_REG, 1 );
+  if( status != NFCTAG_OK )
+  {
+    return status;
+  }
+  
+  /* Update Vout configuration */
+  reg_value &= ~(M24LR_CFG_EHCFG1_MASK | M24LR_CFG_EHCFG0_MASK);
+  reg_value |= EH_Cfg;
+  
+  /* Write CFG register */
+  return i2c_WriteRegister( &reg_value, M24LR_CFG_REG, 1 );
+}
+
+/**
+  * @brief  Get Energy Harvesting status
+  * @param  EH_Val : M24LR_EH_STATUS pointer of the data to store
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_GetEH( M24LR_EH_STATUS * const pEH_Val )
+{
+  uint8_t reg_value;
+  NFCTAG_StatusTypeDef status;
+  
+  /* Read actual value of CTRL register */
+  status = i2c_ReadRegister( &reg_value, M24LR_CTRL_REG, 1 );
+  if( status != NFCTAG_OK )
+  {
+    return status;
+  }
+  
+  /* Extract EH information */
+  if( (reg_value & M24LR_CTRL_EHEN_MASK) == M24LR_CTRL_EHEN_MASK )
+  {
+    *pEH_Val = M24LR_EH_ENABLE;
+  }
+  else
+  {
+    *pEH_Val = M24LR_EH_DISABLE;
+  }
+  
+  return NFCTAG_OK;
+}
+
+/**
+  * @brief  Enable Energy Harvesting
+  * @param  None
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_SetEH( void )
+{
+  uint8_t reg_value;
+  NFCTAG_StatusTypeDef status;
+  
+  /* Read actual value of CTRL register */
+  status = i2c_ReadRegister( &reg_value, M24LR_CTRL_REG, 1 );
+  if( status != NFCTAG_OK )
+  {
+    return status;
+  }
+  
+  /* Update EH configuration */
+  reg_value |= M24LR_CTRL_EHEN_MASK;
+  
+  /* Write CTRL Register */
+  return i2c_WriteRegister( &reg_value, M24LR_CTRL_REG, 1 );
+}
+
+/**
+  * @brief  Disable Energy Harvesting
+  * @param  None
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_ResetEH( void )
+{
+  uint8_t reg_value;
+  NFCTAG_StatusTypeDef status;
+  
+  /* Read actual value of CTRL register */
+  status = i2c_ReadRegister( &reg_value, M24LR_CTRL_REG, 1 );
+  if( status != NFCTAG_OK )
+  {
+    return status;
+  }
+  
+  /* Update EH configuration */
+  reg_value &= ~M24LR_CTRL_EHEN_MASK;
+  
+  /* Write CTRL register */
+  return i2c_WriteRegister( &reg_value, M24LR_CTRL_REG, 1 );
+}
+
+/**
+  * @brief  Check if RF Field is present in front of M24LR
+  * @param  pRF_Field :  M24LR_FIELD_STATUS pointer of the data to store
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_GetRFField( M24LR_FIELD_STATUS * const pRF_Field )
+{
+  NFCTAG_StatusTypeDef status;
+  uint8_t reg_value = 0;
+  
+  /* Read actual value of CTRL register */
+  status = i2c_ReadRegister( &reg_value, M24LR_CTRL_REG, 1 );
+  
+  /* Extract RF Field information */
+  if( status == NFCTAG_OK )
+  {
+    if( (reg_value & M24LR_CTRL_FIELD_MASK) == M24LR_CTRL_FIELD_MASK )
+    {
+      *pRF_Field = M24LR_FIELD_ON;
+    }
+    else
+    {
+      *pRF_Field = M24LR_FIELD_OFF;
+    }
+    
+    return NFCTAG_OK;
+  }
+  
+  return status;
+}
+
+/**
+  * @brief  Check if Write Timing is good
+  * @param  pT_Prog : M24LR_T_PROG_STATUS pointer of the data to store
+  * @retval NFCTAG enum status
+  */
+NFCTAG_StatusTypeDef M24LR::i2c_GetTProg( M24LR_T_PROG_STATUS * const pT_Prog )
+{
+  NFCTAG_StatusTypeDef status;
+  uint8_t reg_value = 0;
+  
+  /* Read actual value of CTRL register */
+  status = i2c_ReadRegister( &reg_value, M24LR_CTRL_REG, 1 );
+  
+  /* Extract T-Prog information */
+  if( status == NFCTAG_OK )
+  {
+    if( (reg_value & M24LR_CTRL_TPROG_MASK) == M24LR_CTRL_TPROG_MASK )
+    {
+      *pT_Prog = M24LR_T_PROG_OK;
+    }
+    else
+    {
+      *pT_Prog = M24LR_T_PROG_NO;
+    }
+
+    return NFCTAG_OK;
+  }
+  else
+    return status;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/X_NUCLEO_NFC02A1/m24lr/m24lr.h	Wed Jul 27 09:25:33 2016 +0000
@@ -0,0 +1,223 @@
+#ifndef __M24LR_H
+#define __M24LR_H
+
+#include "common.h"
+#include "DevI2C.h"
+//#include "lib_NDEF_URI.h"
+  /* Exported constants --------------------------------------------------------*/
+/** @defgroup M24LR_Exported_Constants
+  * @{
+  */
+#define I_AM_M24LR04            0x5A
+#define I_AM_M24LR16            0x4E
+#define I_AM_M24LR64            0x5E
+
+#ifndef NULL
+#define NULL      (void *) 0
+#endif
+
+#define M24LR_PAGEWRITE_NBBYTE  4
+
+#define M24LR_ADDR_DATA_I2C     0xA6
+#define M24LR_ADDR_SYST_I2C     0xAE
+#define M24LR_I2C_TIMEOUT       200 /* I2C Time out (ms), this is the maximum time needed by M24LR to complete any command */
+
+#define M24LR_IT_BUSY_MASK      0x01
+#define M24LR_IT_WIP_MASK       0x02
+
+/* Registers address */
+#define M24LR_SSS_REG           0x0000
+#define M24LR_LOCK_REG          0x0800
+#define M24LR_I2C_PWD_REG       0x0900
+#define M24LR_CFG_REG           0x0910
+#define M24LR_AFI_REG           0x0912
+#define M24LR_DSFID_REG         0x0913
+#define M24LR_UID_REG           0x0914
+#define M24LR_ICREF_REG         0x091C
+#define M24LR_MEMSIZE_REG       0x091D
+#define M24LR_CTRL_REG          0x0920
+
+/* Registers mask */
+#define M24LR_SSS_LOCK_MASK     0x01
+#define M24LR_SSS_RW_MASK       0x06
+#define M24LR_SSS_PASSCTRL_MASK 0x18
+#define M24LR_LOCK_MASK         0x0F
+
+#define M24LR_CFG_EHCFG0_MASK   0x01
+#define M24LR_CFG_EHCFG1_MASK   0x02
+#define M24LR_CFG_EHMODE_MASK   0x04
+#define M24LR_CFG_WIPBUSY_MASK  0x08
+
+#define M24LR_CTRL_EHEN_MASK    0x01
+#define M24LR_CTRL_FIELD_MASK   0x02
+#define M24LR_CTRL_TPROG_MASK   0x80
+  
+ 
+/**
+ * @brief  M24LR VOUT Configuration enumerator definition
+ */
+typedef enum
+{
+  M24LR_EH_Cfg_6MA = 0,
+  M24LR_EH_Cfg_3MA,
+  M24LR_EH_Cfg_1MA,
+  M24LR_EH_Cfg_300UA
+} M24LR_EH_CFG_VOUT;
+
+/**
+ * @brief  M24LR FIELD status enumerator definition
+ */
+typedef enum
+{
+  M24LR_FIELD_OFF = 0,
+  M24LR_FIELD_ON
+} M24LR_FIELD_STATUS;
+
+/**
+ * @brief  M24LR TT-PROG status enumerator definition
+ */
+typedef enum
+{
+  M24LR_T_PROG_NO = 0,
+  M24LR_T_PROG_OK
+} M24LR_T_PROG_STATUS;
+
+/**
+ * @brief  M24LR Energy Harvesting status enumerator definition
+ */
+typedef enum
+{
+  M24LR_EH_DISABLE = 0,
+  M24LR_EH_ENABLE
+} M24LR_EH_STATUS;
+
+/**
+ * @brief  M24LR Energy Harvesting mode enumerator definition
+ */
+typedef enum
+{
+  M24LR_EH_MODE_ENABLE = 0,
+  M24LR_EH_MODE_DISABLE
+} M24LR_EH_MODE_STATUS;
+
+/**
+ * @brief  M24LR GPO status enumerator definition
+ */
+typedef enum
+{
+  M24LR_GPO_BUSY = 0,
+  M24LR_GPO_WIP
+} M24LR_GPO_STATUS;
+
+/**
+ * @brief  M24LR Memory information structure definition
+ */
+typedef struct
+{
+  uint8_t BlockSize;
+  uint16_t Mem_Size;
+} M24LR_Mem_Size;
+
+/**
+ * @brief  M24LR I2C Write Lock register structure definition
+ */
+typedef struct
+{
+  uint8_t sectors_7_0;
+  uint8_t sectors_15_8;
+  uint8_t sectors_23_16;
+  uint8_t sectors_31_24;
+  uint8_t sectors_39_32;
+  uint8_t sectors_47_40;
+  uint8_t sectors_55_48;
+  uint8_t sectors_63_56;
+} M24LR_Lock_Sectors;
+
+/**
+ * @brief  M24LR UID information structure definition
+ */
+typedef struct
+{
+  uint32_t MSB_UID;
+  uint32_t LSB_UID;
+} M24LR_UID;
+
+/**
+ * @brief  M24LR Sector Security register structure definition
+ */
+typedef struct
+{
+  uint8_t SectorLock;
+  uint8_t RW_Protection;
+  uint8_t PassCtrl;
+} M24LR_SECTOR_SEC;
+
+
+  /**
+  * @}
+  */
+  
+class   M24LR {
+public:
+    NFCTAG_StatusTypeDef i2c_Init( void );
+    NFCTAG_StatusTypeDef i2c_ReadID( uint8_t * const pICRef );
+    NFCTAG_StatusTypeDef i2c_IsDeviceReady( const uint32_t Trials );
+    NFCTAG_StatusTypeDef i2c_ConfigureGPO( const uint16_t ITConf );
+    NFCTAG_StatusTypeDef i2c_GetGPOStatus( uint16_t * const pGPOStatus );
+    NFCTAG_StatusTypeDef i2c_ReadData( uint8_t * const pData, const uint16_t TarAddr, const uint16_t NbByte );
+    NFCTAG_StatusTypeDef i2c_WriteData( const uint8_t * const pData, const uint16_t TarAddr, const uint16_t NbByte );
+    NFCTAG_StatusTypeDef i2c_ReadRegister( uint8_t * const pData, const uint16_t TarAddr, const uint16_t NbByte );
+    NFCTAG_StatusTypeDef i2c_WriteRegister( const uint8_t * const pData, const uint16_t TarAddr, const uint16_t NbByte );
+ 
+    
+    /* Extended Functions */
+    NFCTAG_StatusTypeDef i2c_ReadUID( M24LR_UID * const pUid );
+    NFCTAG_StatusTypeDef i2c_ReadDSFID( uint8_t * const pDsfid );
+    NFCTAG_StatusTypeDef i2c_ReadAFI( uint8_t * const pAfi );
+    NFCTAG_StatusTypeDef i2c_ReadI2CLockSector( M24LR_Lock_Sectors * const pLock_sector );
+    NFCTAG_StatusTypeDef i2c_I2CLockSector( const uint8_t Sector );
+    NFCTAG_StatusTypeDef i2c_I2CUnlockSector( const uint8_t Sector );
+    NFCTAG_StatusTypeDef i2c_PresentI2CPassword( const uint32_t PassWord );
+    NFCTAG_StatusTypeDef i2c_WriteI2CPassword( const uint32_t PassWord );
+    NFCTAG_StatusTypeDef i2c_ReadSSSx( const uint8_t SectorNb, M24LR_SECTOR_SEC * const pData );
+    NFCTAG_StatusTypeDef i2c_WriteSSSx( const uint8_t SectorNb, const M24LR_SECTOR_SEC * const pData );
+    NFCTAG_StatusTypeDef i2c_ReadMemSize( M24LR_Mem_Size * const pSizeInfo );
+    NFCTAG_StatusTypeDef i2c_GetRF_WIP_BUSY( M24LR_GPO_STATUS * const pRf_Wip_Busy );
+    NFCTAG_StatusTypeDef i2c_SetRFBUSY( void );
+    NFCTAG_StatusTypeDef i2c_SetRFWIP( void );
+    NFCTAG_StatusTypeDef i2c_Read_EH_mode( M24LR_EH_MODE_STATUS * const pEH_mode );
+    NFCTAG_StatusTypeDef i2c_Enable_EH_mode( void );
+    NFCTAG_StatusTypeDef i2c_Disable_EH_mode( void );
+    NFCTAG_StatusTypeDef i2c_ReadEH_Cfg( M24LR_EH_CFG_VOUT * const pEH_Cfg );
+    NFCTAG_StatusTypeDef i2c_WriteEH_Cfg( const M24LR_EH_CFG_VOUT EH_Cfg );
+    NFCTAG_StatusTypeDef i2c_GetEH( M24LR_EH_STATUS * const pEH_Val );
+    NFCTAG_StatusTypeDef i2c_SetEH( void );
+    NFCTAG_StatusTypeDef i2c_ResetEH( void );
+    NFCTAG_StatusTypeDef i2c_GetRFField( M24LR_FIELD_STATUS * const pRF_Field );
+    NFCTAG_StatusTypeDef i2c_GetTProg( M24LR_T_PROG_STATUS * const pT_Prog );
+    
+    void Enable_EnergyHarvesting( void );
+    NFCTAG_StatusTypeDef Initialization( void );
+    
+    M24LR(uint8_t const address, uint8_t const addressData, DevI2C &devI2C ):
+      i2c_address_syst(address), i2c_address_data(addressData), dev_I2C(devI2C) {}
+    
+   static uint8_t NfctagInitialized;
+  //  M24LR_IO mM24LR_IO;
+   uint8_t i2c_address_syst;
+   
+   uint8_t i2c_address_data;
+   DevI2C dev_I2C;
+   friend class NDEF_URI;
+   //NDEF_URI mM24LR_URI;
+   //M24LR *ptr;
+//   ReadFnDataPtr i2c_ReadData;
+//   WriteFnDataPtr i2c_WriteData;
+                                
+};
+  
+  
+
+  
+#endif /* __M24LR_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Jul 27 09:25:33 2016 +0000
@@ -0,0 +1,95 @@
+/**
+  ******************************************************************************
+  * @file       main.cpp
+  * @author     ST Central Labs
+  * @version    V1.0.0
+  * @date       21 Dic 2015
+  * @brief      This demo writes an ndef message with an url inside.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+#include "mbed.h"
+
+#include "X_NUCLEO_NFC02A1.h"
+#include "DevI2C.h"
+#include "m24lr.h"
+#include "lib_NDEF_URI.h"
+/**
+ * Write a Ndef URI message linking to st.com site.
+ */
+int main(void)
+{
+  
+  sURI_Info URI;
+  NDEF_URI mNDEF_URI;
+  M24LR *mM24LRp;
+  
+  /*use default board pinout*/
+  DevI2C i2cChannel(X_NUCLEO_NFC02A1::DEFAULT_SDA_PIN,X_NUCLEO_NFC02A1::DEFAULT_SDL_PIN);
+  X_NUCLEO_NFC02A1 *nfcNucleo = X_NUCLEO_NFC02A1::Instance(i2cChannel,
+                                                           X_NUCLEO_NFC02A1::DEFAULT_GPO_PIN,X_NUCLEO_NFC02A1::DEFAULT_RF_DISABLE_PIN,
+                                                           X_NUCLEO_NFC02A1::DEFAULT_LED1_PIN,X_NUCLEO_NFC02A1::DEFAULT_LED2_PIN,
+                                                           X_NUCLEO_NFC02A1::DEFAULT_LED3_PIN);
+  
+  mM24LRp = nfcNucleo->getM24LR();
+  mNDEF_URI.setM24LR(mM24LRp);
+  /* Enable Energy Harvesting */
+  mM24LRp->Enable_EnergyHarvesting();
+  
+  printf("System Initialization done: !\n\r");
+  
+  /* Check if no NDEF detected, init mem in Tag Type 5 */
+  if( mNDEF_URI.NfcType5_NDEFDetection() != NDEF_OK)
+  {
+    mNDEF_URI.CCFileStruct.MagicNumber = NFCT5_MAGICNUMBER_E1_CCFILE;
+    mNDEF_URI.CCFileStruct.Version = NFCT5_VERSION_V1_0;
+    mNDEF_URI.CCFileStruct.MemorySize = ( M24LR_MAX_SIZE / 8 ) & 0xFF;
+    mNDEF_URI.CCFileStruct.TT5Tag = 0x05;
+    
+    /* Init of the Type Tag 5 component (M24LR) */
+    while( mNDEF_URI.NfcType5_TT5Init( ) != NFCTAG_OK);
+  }
+  
+  /* Set the LED2 on to indicate Init done */
+  nfcNucleo->getLed2()=1;
+  
+  /* Prepare URI NDEF message content */
+  strcpy( URI.protocol,URI_ID_0x01_STRING );
+  strcpy( URI.URI_Message,"st.com/st25" );
+  strcpy( URI.Information,"\0" );
+  
+  /* Write NDEF to EEPROM */
+  while( mNDEF_URI.NDEF_WriteURI( &URI ) != NDEF_OK);
+  
+  /* Set the LED3 on to indicate Programing done */
+  nfcNucleo->getLed3()=1; 
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Jul 27 09:25:33 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/f9eeca106725
\ No newline at end of file