STMicroelectronics' M24SR NFC Dynamic Tag Library.

Dependencies:   ST_INTERFACES

Dependents:   X_NUCLEO_NFC01A1

Fork of M24SR by ST Expansion SW Team

M24SR series Dynamic NFC Tags

The M24SR series provides an NFC forum tag type 4 RF interface and supports the NFC data exchange format (NDEF). This enables NFC use cases such as simple Bluetooth pairing and other connection handovers, automatic links to URLs, storage of Vcard and other types of information. It can be used in a wide variety of applications, including consumer electronics, computer peripherals, home appliances, industrial automation and healthcare products.

  • NFC forum tag type 4 based on ISO 14443 RF interface
  • 1 MHz I²C serial interface operating from 2.7 to 5.5 V
  • EEPROM memory density from 2 Kbits to 64 Kbits with built-in NDEF message support
  • RF disable pin allowing the application to control RF access from NFC phones
  • 128-bit password protection
  • General-purpose output pin allowing flexibility for the applications (wake up on several types of events)
  • Simple antenna design, backward compatible with M24LR series

For further information and ordering please refer to the ST Page.

HelloWorld application

Import programHelloWorld_Async_M24SR

M24SR NFC example. Simple application to asynchronously write and read an URL from a M24SR tag.

Files at this revision

API Documentation at this revision

Comitter:
nikapov
Date:
Mon Jul 31 12:26:02 2017 +0000
Commit message:
First revision.

Changed in this revision

M24SR.cpp Show annotated file Show diff for this revision Revisions of this file
M24SR.h Show annotated file Show diff for this revision Revisions of this file
NDefNfcTagM24SR.cpp Show annotated file Show diff for this revision Revisions of this file
NDefNfcTagM24SR.h Show annotated file Show diff for this revision Revisions of this file
ST_INTERFACES.lib Show annotated file Show diff for this revision Revisions of this file
m24sr_def.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 11161008d77a M24SR.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/M24SR.cpp	Mon Jul 31 12:26:02 2017 +0000
@@ -0,0 +1,1582 @@
+/**
+ ******************************************************************************
+ * @file    m24sr_class.cpp
+ * @author  ST Central Labs
+ * @version V2.0.0
+ * @date    28 Apr 2017
+ * @brief   This file provides a set of functions to interface with the M24SR
+ *          device.
+ ******************************************************************************
+ * @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.
+ *
+ ******************************************************************************
+ */
+
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "m24sr_def.h"
+#include "M24SR.h"
+#include "NDefNfcTagM24SR.h"
+
+#ifdef GPIO_PIN_RESET
+	#undef GPIO_PIN_RESET
+#endif
+#define GPIO_PIN_RESET (0)
+
+#ifdef GPIO_PIN_SET
+	#undef GPIO_PIN_SET
+#endif
+#define GPIO_PIN_SET (1)
+
+#define M24SR_MAX_BYTE_OPERATION_LENGHT (246)
+
+/**
+ * default password, also used to enable super user mode through the I2C channel
+ */
+const uint8_t M24SR::DEFAULT_PASSWORD[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+/** @addtogroup M24SR_Driver
+ * @{
+ *	@brief  <b>This folder contains the driver layer of M24SR family (M24SR64, M24SR16, M24SR04, M24SR02)</b> 
+ */
+
+/** @defgroup drv_M24SR
+ * @{
+ *	@brief  This file contains the driver which implements all the M24SR commands.
+ */
+
+#ifndef errchk
+
+/** value returned by the NFC chip when a command is successfully completed */
+#define NFC_COMMAND_SUCCESS 0x9000
+
+/** call the fCall function and check that the return status is M24SR_SUCCESS,
+ *  otherwise return the error status*/
+#define errchk(fCall) {\
+	const int status = (int) (fCall); \
+	if((status!=M24SR_SUCCESS)) { \
+		return (M24SR::StatusTypeDef)status; \
+	}\
+}
+#endif
+
+/**
+ * @brief  This function updates the CRC 
+ * @param  None
+ * @retval None
+ */
+ static uint16_t M24SR_UpdateCrc(uint8_t ch, uint16_t *lpwCrc) {
+	ch = (ch ^ (uint8_t) ((*lpwCrc) & 0x00FF));
+	ch = (ch ^ (ch << 4));
+	*lpwCrc = (*lpwCrc >> 8) ^ ((uint16_t) ch << 8) ^ ((uint16_t) ch << 3) ^ ((uint16_t) ch >> 4);
+
+	return (*lpwCrc);
+}
+
+/**
+ * @brief  This function returns the CRC 16 
+ * @param  Data : pointer on the data used to compute the CRC16
+ * @param  Length : number of bytes of the data
+ * @retval CRC16 
+ */
+ static uint16_t M24SR_ComputeCrc(uint8_t *Data, uint8_t Length) {
+	uint8_t chBlock;
+	uint16_t wCrc = 0x6363; // ITU-V.41
+
+	do {
+		chBlock = *Data++;
+		M24SR_UpdateCrc(chBlock, &wCrc);
+	} while (--Length);
+
+	return wCrc;
+}
+
+/**  
+ * @brief  	This function computes the CRC16 residue as defined by CRC ISO/IEC 13239
+ * @param  	DataIn		:	input data 
+ * @param	Length 		: 	Number of bits of DataIn
+ * @retval 	Status (SW1&SW2)  	:   CRC16 residue is correct	
+ * @retval 	M24SR_ERROR_CRC  	:  CRC16 residue is false
+ */
+ static M24SR::StatusTypeDef M24SR_IsCorrectCRC16Residue(uint8_t *DataIn, uint8_t Length) {
+	uint16_t ResCRC = 0x0000;
+	M24SR::StatusTypeDef status;
+	/* check the CRC16 Residue */
+	if (Length != 0) {
+		ResCRC = M24SR_ComputeCrc(DataIn, Length);
+	}
+
+	if (ResCRC == 0x0000) {
+		/* Good CRC, but error status from M24SR */
+		status = (M24SR::StatusTypeDef) (((DataIn[Length - UB_STATUS_OFFSET] << 8)
+				& 0xFF00) | (DataIn[Length - LB_STATUS_OFFSET] & 0x00FF));
+	} else {
+		ResCRC = 0x0000;
+		ResCRC = M24SR_ComputeCrc(DataIn, 5);
+		if (ResCRC != 0x0000) {
+			/* Bad CRC */
+			return M24SR::M24SR_IO_ERROR_CRC;
+		} else {
+			/* Good CRC, but error status from M24SR */
+			status= (M24SR::StatusTypeDef) (((DataIn[1] << 8) & 0xFF00)
+					| (DataIn[2] & 0x00FF));
+		}
+	}
+	if (status==NFC_COMMAND_SUCCESS) {
+		status =M24SR::M24SR_SUCCESS;
+	}
+
+	return status;
+}
+
+/**
+ * @brief 		This functions creates an I block command according to the structures CommandStructure and Command.
+ * @param	 	Command : structure which contains the field of the different parameters
+ * @param	 	CommandStructure : structure of the command 
+ * @param	 	NbByte : number of bytes of the command
+ * @param	 	pCommand : pointer to the command created
+ */
+static void M24SR_BuildIBlockCommand(uint16_t CommandStructure, C_APDU *Command, uint8_t uDIDbyte, uint16_t *NbByte, uint8_t *pCommand) {
+	uint16_t uCRC16;
+	static uint8_t BlockNumber = 0x01;
+
+	(*NbByte) = 0;
+
+	/* add the PCD byte */
+	if ((CommandStructure & M24SR_PCB_NEEDED) != 0) {
+		/* toggle the block number */
+		BlockNumber = TOGGLE(BlockNumber);
+		/* Add the I block byte */
+		pCommand[(*NbByte)++] = 0x02 | BlockNumber;
+	}
+
+	/* add the DID byte */
+	if ((BlockNumber & M24SR_DID_NEEDED) != 0) {
+		/* Add the I block byte */
+		pCommand[(*NbByte)++] = uDIDbyte;
+	}
+
+	/* add the Class byte */
+	if ((CommandStructure & M24SR_CLA_NEEDED) != 0) {
+		pCommand[(*NbByte)++] = Command->Header.CLA;
+	}
+	/* add the instruction byte byte */
+	if ((CommandStructure & M24SR_INS_NEEDED) != 0) {
+		pCommand[(*NbByte)++] = Command->Header.INS;
+	}
+	/* add the Selection Mode byte */
+	if ((CommandStructure & M24SR_P1_NEEDED) != 0) {
+		pCommand[(*NbByte)++] = Command->Header.P1;
+	}
+	/* add the Selection Mode byte */
+	if ((CommandStructure & M24SR_P2_NEEDED) != 0) {
+		pCommand[(*NbByte)++] = Command->Header.P2;
+	}
+	/* add Data field lengthbyte */
+	if ((CommandStructure & M24SR_LC_NEEDED) != 0) {
+		pCommand[(*NbByte)++] = Command->Body.LC;
+	}
+	/* add Data field  */
+	if ((CommandStructure & M24SR_DATA_NEEDED) != 0) {
+		memcpy(&(pCommand[(*NbByte)]), Command->Body.pData, Command->Body.LC);
+		(*NbByte) += Command->Body.LC;
+	}
+	/* add Le field  */
+	if ((CommandStructure & M24SR_LE_NEEDED) != 0) {
+		pCommand[(*NbByte)++] = Command->Body.LE;
+	}
+	/* add CRC field  */
+	if ((CommandStructure & M24SR_CRC_NEEDED) != 0) {
+		uCRC16 = M24SR_ComputeCrc(pCommand, (uint8_t) (*NbByte));
+		/* append the CRC16 */
+		pCommand[(*NbByte)++] = GETLSB(uCRC16);
+		pCommand[(*NbByte)++] = GETMSB(uCRC16);
+	}
+
+}
+
+
+
+
+/**  
+ * @brief  	This function returns M24SR_STATUS_SUCCESS if the pBuffer is an s-block
+ * @param  	pBuffer		:	pointer to the data
+ * @retval 	M24SR_SUCCESS  :  the data is a S-Block
+ * @retval 	NFC_ERROR  	:  the data is not a S-Block
+ */
+ static M24SR::StatusTypeDef IsSBlock(uint8_t *pBuffer) {
+
+	if ((pBuffer[M24SR_OFFSET_PCB] & M24SR_MASK_BLOCK) == M24SR_MASK_SBLOCK) {
+		return M24SR::M24SR_SUCCESS;
+	} else {
+		return M24SR::M24SR_ERROR;
+	}
+
+}
+
+M24SR::M24SR(const uint8_t address, I2C &I2C,gpoEventCallback eventCallback, const PinName& GPOPinName,
+		const PinName& RFDISPinName) :
+		who_am_i(0),
+		type(0),
+		address(address),
+		dev_I2C(I2C),
+		GPOPin(GPOPinName),
+		RFDisablePin(RFDISPinName),
+		mCommunicationType(SYNC),
+		mLastCommandSend(NONE),
+		mGpoEventInterrupt(GPOPinName),
+		mCallback(&defaultCallback),
+		mComponentCallback(NULL),
+		mNDefTagUtil(new NDefNfcTagM24SR(*this)),
+		mManageGPOCallback(*this),
+		mReadIDCallback(*this){
+		//mNDefTagUtil(NULL){
+	memset(uM24SRbuffer, 0, 0xFF * sizeof(int8_t));
+	uDIDbyte = 0;
+	if (RFDisablePin.is_connected()!=0) {
+		RFDisablePin = 0;
+	}
+	if(GPOPin.is_connected()!=0){
+		if(eventCallback!=NULL)
+			mGpoEventInterrupt.fall(eventCallback);
+		mGpoEventInterrupt.mode(PullUp);
+		mGpoEventInterrupt.disable_irq();
+	}
+}
+
+M24SR::~M24SR(){
+	delete mNDefTagUtil;
+}
+
+/**
+ * @brief  This function sends the FWT extension command (S-Block format)
+ * @param	FWTbyte : FWT value
+ * @return M24SR_SUCCESS if no errors
+ */
+M24SR::StatusTypeDef M24SR::M24SR_SendFWTExtension(uint8_t FWTbyte) {
+	uint8_t pBuffer[M24SR_STATUSRESPONSE_NBBYTE];
+	M24SR::StatusTypeDef status;
+	uint8_t NthByte = 0;
+	uint16_t uCRC16;
+
+	/* create the response */
+	pBuffer[NthByte++] = 0xF2;
+	pBuffer[NthByte++] = FWTbyte;
+	/* compute the CRC */
+	uCRC16 = M24SR_ComputeCrc(pBuffer, 0x02);
+	/* append the CRC16 */
+	pBuffer[NthByte++] = GETLSB(uCRC16);
+	pBuffer[NthByte++] = GETMSB(uCRC16);
+
+	/* send the request */
+	status = M24SR_IO_SendI2Ccommand(NthByte, pBuffer);
+	if (status != M24SR_SUCCESS) {
+		return status;
+	}
+
+	mLastCommandSend=UPDATE;
+
+	if (mCommunicationType==M24SR::SYNC) {
+		status = M24SR_IO_PollI2C();
+		if (status == M24SR_SUCCESS) {
+			return M24SR_ReceiveUpdateBinary();
+		} else {
+			mLastCommandSend = NONE;
+			getCallback()->on_updated_binary(this,status,mLastCommandData.offset, mLastCommandData.data,mLastCommandData.length);
+			return status;
+		}//if-else
+	}//if
+
+	return M24SR_SUCCESS;
+}
+
+/**
+ * @brief  This function initialize the M24SR device
+ * @retval None
+ */
+M24SR::StatusTypeDef M24SR::M24SR_Init(M24SR_InitTypeDef *notUsed) {
+	(void) notUsed;
+	//force to open a i2c session
+	StatusTypeDef status = M24SR_ForceSession();
+	if(status!= M24SR_SUCCESS) {
+		return status;
+	}
+	//leave the gpo always up
+	if(GPOPin.is_connected()!=0) {
+		status = M24SR_ManageI2CGPO(DEFAULT_GPO_STATUS);
+		if(status!= M24SR_SUCCESS)
+			return status;
+	}
+	if(RFDisablePin.is_connected()!=0) {
+		status = M24SR_ManageRFGPO(DEFAULT_GPO_STATUS);
+		if(status!= M24SR_SUCCESS)
+			return status;
+	}
+	//close the session
+	status = M24SR_Deselect();
+	if (status!= M24SR_SUCCESS) {
+		return status;
+	}
+	if(GPOPin.is_connected()!=0) {
+		mGpoEventInterrupt.enable_irq();
+	}
+	return M24SR_SUCCESS;
+}
+
+
+/**
+ * @brief  This function sends the KillSession command to the M24SR device
+ * @param  None
+ * @return M24SR_SUCCESS if no errors
+ */
+M24SR::StatusTypeDef M24SR::M24SR_ForceSession(void) {
+	uint8_t commandBuffer[] = M24SR_KILLSESSION_COMMAND;
+	M24SR::StatusTypeDef status;
+	status = M24SR_IO_SendI2Ccommand(sizeof(commandBuffer), commandBuffer);
+	if(status!=M24SR_SUCCESS) {
+		mCallback->on_session_open(this,status);
+		return status;
+	}
+
+	/* Insure no access will be done just after open session */
+	/* The only way here is to poll I2C to know when M24SR is ready */
+	/* GPO can not be use with KillSession command */
+	status = M24SR_IO_PollI2C();
+
+	getCallback()->on_session_open(this,status);
+	return status;
+
+}
+
+/**
+ * @brief  This function sends the Deselect command (S-Block format)
+ * @return M24SR_SUCCESS if no errors
+ */
+M24SR::StatusTypeDef M24SR::M24SR_Deselect(void) {
+	uint8_t pBuffer[] = M24SR_DESELECTREQUEST_COMMAND;
+	M24SR::StatusTypeDef status;
+	/* send the request */
+	status = M24SR_IO_SendI2Ccommand(sizeof(pBuffer), pBuffer);
+	if(status!=M24SR_SUCCESS) {
+		getCallback()->on_deselect(this,status);
+	}
+
+	mLastCommandSend=DESELECT;
+
+	if (mCommunicationType==M24SR::SYNC) {
+		status = M24SR_IO_PollI2C();
+		if(status == M24SR_SUCCESS) {
+			return M24SR_ReceiveDeselect();
+		} else {
+			mLastCommandSend = NONE;
+			getCallback()->on_selected_application(this,status);
+			return status;
+		}//if-else
+
+	}
+
+	return M24SR_SUCCESS;
+}
+
+M24SR::StatusTypeDef M24SR::M24SR_ReceiveDeselect(void) {
+	uint8_t pBuffer[4];
+	M24SR::StatusTypeDef status;
+	status = M24SR_IO_ReceiveI2Cresponse(sizeof(pBuffer), pBuffer);
+	getCallback()->on_deselect(this,status);
+	return status;
+}
+
+/**
+ * @brief  This function sends the GetSession command to the M24SR device
+ * @retval M24SR_SUCCESS the function is successful.
+ * @retval Status (SW1&SW2) if operation does not complete.
+ */
+M24SR::StatusTypeDef M24SR::M24SR_GetSession(void) {
+	uint8_t commandBuffer[] = M24SR_OPENSESSION_COMMAND;
+
+	M24SR::StatusTypeDef status;
+	status = M24SR_IO_SendI2Ccommand(sizeof(commandBuffer), commandBuffer);
+	if (status!=M24SR_SUCCESS) {
+		getCallback()->on_session_open(this,status);
+		return status;
+	}
+
+	/* Insure no access will be done just after open session */
+	/* The only way here is to poll I2C to know when M24SR is ready */
+	/* GPO can not be use with KillSession command */
+	status = M24SR_IO_PollI2C();
+
+	getCallback()->on_session_open(this,status);
+	return status;
+}
+
+/**
+ * @brief  This function sends the SelectApplication command
+ * @return M24SR_SUCCESS if no errors
+ */
+M24SR::StatusTypeDef M24SR::M24SR_SendSelectApplication(void) {
+
+	C_APDU command;
+	M24SR::StatusTypeDef status;
+	uint8_t *pBuffer = uM24SRbuffer;
+	uint8_t pDataOut[] = M24SR_SELECTAPPLICATION_COMMAND;
+	uint8_t uLe = 0x00;
+	uint16_t uP1P2 =0x0400,	NbByte;
+
+	/* build the command */
+	command.Header.CLA = C_APDU_CLA_DEFAULT;
+	command.Header.INS = C_APDU_SELECT_FILE;
+	/* copy the offset */
+	command.Header.P1 = GETMSB(uP1P2);
+	command.Header.P2 = GETLSB(uP1P2);
+	/* copy the number of byte of the data field */
+	command.Body.LC = sizeof(pDataOut);
+	/* copy the data */
+	command.Body.pData = pDataOut;
+	/* copy the number of byte to read */
+	command.Body.LE = uLe;
+	/* build the I2C command */
+	M24SR_BuildIBlockCommand( M24SR_CMDSTRUCT_SELECTAPPLICATION, &command, uDIDbyte, &NbByte, pBuffer);
+
+	/* send the request */
+	status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
+	if (status != M24SR_SUCCESS) {
+		getCallback()->on_selected_application(this,status);
+		return status;
+	}
+
+	mLastCommandSend=SELECT_APPLICATION;
+
+	if (mCommunicationType==M24SR::SYNC) {
+		status = M24SR_IO_PollI2C();
+		if (status == M24SR_SUCCESS) {
+			return M24SR_ReceiveSelectApplication();
+		} else {
+			mLastCommandSend = NONE;
+			getCallback()->on_selected_application(this,status);
+			return status;
+		}//if-else
+	}//if
+
+	return M24SR_SUCCESS;
+}
+
+M24SR::StatusTypeDef M24SR::M24SR_ReceiveSelectApplication(void) {
+	uint8_t pDataIn[M24SR_STATUSRESPONSE_NBBYTE];
+	M24SR::StatusTypeDef status;
+
+	mLastCommandSend = NONE;
+
+	status = M24SR_IO_ReceiveI2Cresponse(sizeof(pDataIn), pDataIn);
+	if (status!=M24SR_SUCCESS) {
+		getCallback()->on_selected_application(this,status);
+		return status;
+	}//else
+	status = M24SR_IsCorrectCRC16Residue(pDataIn, sizeof(pDataIn));
+	getCallback()->on_selected_application(this,status);
+
+	return status;
+}
+
+M24SR::StatusTypeDef M24SR::M24SR_ReadID(uint8_t *nfc_id) {
+	if (!nfc_id) {
+		return M24SR_ERROR;
+	}
+
+	//enable the callback for change the gpo
+	mComponentCallback = &mReadIDCallback;
+	mReadIDCallback.read_id_on(nfc_id);
+
+	//start the readID procedure
+	return M24SR_SendSelectApplication();
+}
+
+/**
+ * @brief  This function sends the SelectCCFile command
+ * @retval M24SR_SUCCESS the function is successful.
+ * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
+ * @retval Status (SW1&SW2)   if operation does not complete for another reason.
+ */
+M24SR::StatusTypeDef M24SR::M24SR_SendSelectCCfile(void) {
+	C_APDU command;
+	M24SR::StatusTypeDef status;
+	uint8_t *pBuffer = uM24SRbuffer;
+	uint8_t pDataOut[] = CC_FILE_ID_BYTES;
+	uint16_t uP1P2 =0x000C,
+	NbByte;
+
+	/* build the command */
+	command.Header.CLA = C_APDU_CLA_DEFAULT;
+	command.Header.INS = C_APDU_SELECT_FILE;
+	/* copy the offset */
+	command.Header.P1 = GETMSB(uP1P2);
+	command.Header.P2 = GETLSB(uP1P2);
+	/* copy the number of byte of the data field */
+	command.Body.LC = sizeof(pDataOut);
+	command.Body.pData = pDataOut;
+	/* build the I2C command */
+	M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_SELECTCCFILE, &command, uDIDbyte, &NbByte, pBuffer);
+
+	/* send the request */
+	status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
+	if(status!=M24SR_SUCCESS) {
+		getCallback()->on_selected_CC_file(this,status);
+		return status;
+	}//else
+
+	mLastCommandSend=SELECT_CC_FILE;
+
+	if (mCommunicationType==M24SR::SYNC){
+		status = M24SR_IO_PollI2C();
+		if (status==M24SR_SUCCESS) {
+			return M24SR_ReceiveSelectCCfile();
+		} else {
+			mLastCommandSend = NONE;
+			getCallback()->on_selected_CC_file(this,status);
+			return status;
+		}//if-else
+	}//if
+
+	return M24SR_SUCCESS;
+}
+
+M24SR::StatusTypeDef M24SR::M24SR_ReceiveSelectCCfile(void){
+
+	uint8_t pDataIn[M24SR_STATUSRESPONSE_NBBYTE];
+	M24SR::StatusTypeDef status;
+
+	mLastCommandSend = NONE;
+
+	status = M24SR_IO_ReceiveI2Cresponse(sizeof(pDataIn), pDataIn);
+	if (status!=M24SR_SUCCESS) {
+		getCallback()->on_selected_CC_file(this,status);
+		return status;
+	}//else
+	status = M24SR_IsCorrectCRC16Residue(pDataIn, sizeof(pDataIn));
+	getCallback()->on_selected_CC_file(this,status);
+
+	return status;
+}
+
+/**
+ * @brief  This function sends the SelectSystemFile command
+ * @retval Status (SW1&SW2) Status of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
+ */
+M24SR::StatusTypeDef M24SR::M24SR_SendSelectSystemfile(void) {
+	C_APDU command;
+
+	uint8_t *pBuffer = uM24SRbuffer;
+	uint8_t pDataOut[] = SYSTEM_FILE_ID_BYTES;
+	M24SR::StatusTypeDef status;
+	uint16_t uP1P2 =0x000C,	NbByte;
+
+	/* build the command */
+	command.Header.CLA = C_APDU_CLA_DEFAULT;
+	command.Header.INS = C_APDU_SELECT_FILE;
+	/* copy the offset */
+	command.Header.P1 = GETMSB(uP1P2);
+	command.Header.P2 = GETLSB(uP1P2);
+	/* copy the number of byte of the data field */
+	command.Body.LC = sizeof(pDataOut);
+	command.Body.pData = pDataOut;
+	/* build the I²C command */
+	M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_SELECTCCFILE, &command, uDIDbyte, &NbByte, pBuffer);
+
+	/* send the request */
+	status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
+	if (status!=M24SR_SUCCESS) {
+		getCallback()->on_selected_system_file(this,status);
+		return status;
+	}//else
+
+	mLastCommandSend=SELECT_SYSTEM_FILE;
+
+	if (mCommunicationType==M24SR::SYNC) {
+		status = M24SR_IO_PollI2C();
+		if (status == M24SR_SUCCESS) {
+			return M24SR_ReceiveSelectSystemfile();
+		} else {
+			mLastCommandSend = NONE;
+			getCallback()->on_selected_system_file(this,status);
+			return status;
+		}//if-else
+	}//if
+
+	return M24SR_SUCCESS;
+}
+
+M24SR::StatusTypeDef M24SR::M24SR_ReceiveSelectSystemfile() {
+	uint8_t pDataIn[M24SR_STATUSRESPONSE_NBBYTE];
+	M24SR::StatusTypeDef status;
+
+	mLastCommandSend = NONE;
+
+	status = M24SR_IO_ReceiveI2Cresponse(sizeof(pDataIn), pDataIn);
+	if (status!=M24SR_SUCCESS) {
+		getCallback()->on_selected_system_file(this,status);
+		return status;
+	}//else
+	status = M24SR_IsCorrectCRC16Residue(pDataIn, sizeof(pDataIn));
+	getCallback()->on_selected_system_file(this,status);
+
+	return status;
+}
+
+/**
+ * @brief  This function sends the SelectNDEFfile command
+ * @retval Status (SW1&SW2) Status of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
+ */
+M24SR::StatusTypeDef M24SR::M24SR_SendSelectNDEFfile(uint16_t NDEFfileId) {
+	C_APDU command;
+	M24SR::StatusTypeDef status;
+	uint8_t *pBuffer = uM24SRbuffer;
+	uint8_t pDataOut[] = { GETMSB(NDEFfileId), GETLSB(NDEFfileId) };
+	uint16_t uP1P2 = 0x000C, NbByte;
+
+	/* build the command */
+	command.Header.CLA = C_APDU_CLA_DEFAULT;
+	command.Header.INS = C_APDU_SELECT_FILE;
+	/* copy the offset */
+	command.Header.P1 = GETMSB(uP1P2);
+	command.Header.P2 = GETLSB(uP1P2);
+	/* copy the number of byte of the data field */
+	command.Body.LC = sizeof(pDataOut);
+	command.Body.pData = pDataOut;
+	/* copy the offset */
+	/* build the I2C command */
+	M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_SELECTNDEFFILE, &command, uDIDbyte, &NbByte, pBuffer);
+
+	/* send the request */
+	status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
+    if (status!=M24SR_SUCCESS) {
+	    return status;
+    }
+	mLastCommandSend=SELECT_NDEF_FILE;
+
+	if (mCommunicationType==M24SR::SYNC) {
+		status = M24SR_IO_PollI2C();
+		if (status==M24SR_SUCCESS) {
+			return M24SR_ReceiveSelectNDEFfile();
+		} else {
+			mLastCommandSend = NONE;
+			getCallback()->on_selected_NDEF_file(this,status);
+			return status;
+		}
+	}
+
+	return M24SR_SUCCESS;
+
+}
+
+M24SR::StatusTypeDef M24SR::M24SR_ReceiveSelectNDEFfile(){
+
+	uint8_t pDataIn[M24SR_STATUSRESPONSE_NBBYTE];
+	M24SR::StatusTypeDef status;
+
+	mLastCommandSend = NONE;
+
+	status = M24SR_IO_ReceiveI2Cresponse(sizeof(pDataIn), pDataIn);
+	if (status!=M24SR_SUCCESS) {
+		getCallback()->on_selected_NDEF_file(this,status);
+		return status;
+	}//else
+	status= M24SR_IsCorrectCRC16Residue(pDataIn, sizeof(pDataIn));
+	getCallback()->on_selected_NDEF_file(this,status);
+
+	return status;
+}
+
+/**
+ * @brief  This function sends a read binary command
+ * @param	Offset   first byte to read
+ * @param	NbByteToRead   number of bytes to read
+ * @param	pBufferRead   pointer to the buffer read from the M24SR device
+ * @retval Status (SW1&SW2) Status of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
+ */
+M24SR::StatusTypeDef M24SR::M24SR_SendReadBinary(uint16_t Offset, uint8_t NbByteToRead, uint8_t *pBufferRead) {
+	//clamp the buffer to the max size
+	if (NbByteToRead>M24SR_MAX_BYTE_OPERATION_LENGHT) {
+		NbByteToRead=M24SR_MAX_BYTE_OPERATION_LENGHT;
+	}
+
+	C_APDU command;
+	uint8_t *pBuffer = uM24SRbuffer;
+	uint16_t NbByte;
+	M24SR::StatusTypeDef status;
+
+	/* build the command */
+	command.Header.CLA = C_APDU_CLA_DEFAULT;
+	command.Header.INS = C_APDU_READ_BINARY;
+	/* copy the offset */
+	command.Header.P1 = GETMSB(Offset);
+	command.Header.P2 = GETLSB(Offset);
+	/* copy the number of byte to read */
+	command.Body.LE = NbByteToRead;
+
+	M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_READBINARY, &command, uDIDbyte, &NbByte, pBuffer);
+
+	status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
+	if (status!=M24SR_SUCCESS) {
+		getCallback()->on_read_byte(this,status,Offset,pBufferRead,NbByteToRead);
+		return status;
+	}
+
+	mLastCommandSend=READ;
+	mLastCommandData.data=pBufferRead;
+	mLastCommandData.length=NbByteToRead;
+	mLastCommandData.offset=Offset;
+
+	if (mCommunicationType==M24SR::SYNC) {
+		status = M24SR_IO_PollI2C();
+		if (status==M24SR_SUCCESS) {
+			return M24SR_ReceiveReadBinary();
+		} else {
+			mLastCommandSend = NONE;
+			getCallback()->on_read_byte(this,status,Offset,pBufferRead,NbByteToRead);
+			return status;
+		}//if-else
+	}//if
+
+	return M24SR_SUCCESS;
+}
+
+M24SR::StatusTypeDef M24SR::M24SR_ReceiveReadBinary() {
+	M24SR::StatusTypeDef status;
+	const uint16_t length = mLastCommandData.length;
+	const uint16_t offset = mLastCommandData.offset;
+	uint8_t *data = mLastCommandData.data;
+
+	mLastCommandSend = NONE;
+
+	status = M24SR_IO_ReceiveI2Cresponse (length + M24SR_STATUSRESPONSE_NBBYTE , uM24SRbuffer );
+	if (status!=M24SR_SUCCESS) {
+		getCallback()->on_read_byte(this,status,offset,data,length);
+		return status;
+	}
+	status = M24SR_IsCorrectCRC16Residue(uM24SRbuffer, length + M24SR_STATUSRESPONSE_NBBYTE);
+	if (status != M24SR_SUCCESS) {
+		getCallback()->on_read_byte(this,status,offset,data,length);
+	} else{
+		/* retrieve the data without SW1 & SW2 as provided as return value of the function */
+		memcpy(mLastCommandData.data, &uM24SRbuffer[1], length);
+		getCallback()->on_read_byte(this,status,offset,data,length);
+	}
+
+	return status;
+}
+
+/**
+ * @brief  This function sends a ST read binary command (no error if access is not inside NDEF file)
+ * @param	Offset   first byte to read
+ * @param	NbByteToRead number of bytes to read
+ * @param	pBufferRead  pointer to the buffer read from the M24SR device
+ * @retval Status (SW1&SW2) Status of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
+ */
+M24SR::StatusTypeDef M24SR::M24SR_SendSTReadBinary(uint16_t Offset, uint8_t NbByteToRead, uint8_t *pBufferRead) {
+	//clamp the buffer to the max size
+	if (NbByteToRead>M24SR_MAX_BYTE_OPERATION_LENGHT) {
+		NbByteToRead=M24SR_MAX_BYTE_OPERATION_LENGHT;
+	}
+
+	C_APDU command;
+	uint8_t *pBuffer = uM24SRbuffer;
+	uint16_t NbByte;
+	M24SR::StatusTypeDef status;
+
+	/* build the command */
+	command.Header.CLA = C_APDU_CLA_ST;
+	command.Header.INS = C_APDU_READ_BINARY;
+	/* copy the offset */
+	command.Header.P1 = GETMSB(Offset);
+	command.Header.P2 = GETLSB(Offset);
+	/* copy the number of byte to read */
+	command.Body.LE = NbByteToRead;
+
+	M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_READBINARY, &command, uDIDbyte, &NbByte, pBuffer);
+
+	status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
+	if (status!=M24SR_SUCCESS) {
+		getCallback()->on_read_byte(this,status,Offset,pBufferRead,NbByteToRead);
+		return status;
+	}
+
+	mLastCommandSend=READ;
+	mLastCommandData.data=pBufferRead;
+	mLastCommandData.length=NbByteToRead;
+
+	if (mCommunicationType==M24SR::SYNC) {
+		status = M24SR_IO_PollI2C();
+		if (status==M24SR_SUCCESS) {
+			return M24SR_ReceiveReadBinary();
+		} else {
+			mLastCommandSend = NONE;
+			getCallback()->on_read_byte(this,status,Offset,pBufferRead,NbByteToRead);
+			return status;
+		}//if-else
+	}//if
+
+	return M24SR_SUCCESS;
+}
+
+/**
+ * @brief  This function sends a Update binary command
+ * @param	Offset   first byte to read
+ * @param	NbByteToWrite   number of bytes to write
+ * @param	pBufferRead   pointer to the buffer read from the M24SR device
+ * @retval Status (SW1&SW2) Status of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
+ */
+M24SR::StatusTypeDef M24SR::M24SR_SendUpdateBinary(uint16_t Offset, uint8_t NbByteToWrite, uint8_t *pDataToWrite) {
+	//clamp the buffer to the max size
+	if (NbByteToWrite>M24SR_MAX_BYTE_OPERATION_LENGHT) {
+		NbByteToWrite=M24SR_MAX_BYTE_OPERATION_LENGHT;
+	}
+
+	C_APDU command;
+	M24SR::StatusTypeDef status;
+	uint8_t *pBuffer = uM24SRbuffer;
+	uint16_t NbByte;
+
+	/* build the command */
+	command.Header.CLA = C_APDU_CLA_DEFAULT;
+	command.Header.INS = C_APDU_UPDATE_BINARY;
+	/* copy the offset */
+	command.Header.P1 = GETMSB(Offset);
+	command.Header.P2 = GETLSB(Offset);
+	/* copy the number of byte of the data field */
+	command.Body.LC = NbByteToWrite;
+	command.Body.pData = pDataToWrite;
+	/* copy the File Id */
+	//memcpy(command.Body.pData ,pDataToWrite, NbByteToWrite );
+	M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_UPDATEBINARY, &command, uDIDbyte, &NbByte, pBuffer);
+
+	status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
+	if (status!=M24SR_SUCCESS){
+		getCallback()->on_updated_binary(this,status,Offset,pDataToWrite,NbByteToWrite);
+		return status;
+	}
+
+	mLastCommandSend=UPDATE;
+	mLastCommandData.data=pDataToWrite;
+	mLastCommandData.length=NbByteToWrite;
+	mLastCommandData.offset=Offset;
+
+	if (mCommunicationType==M24SR::SYNC) {
+		status = M24SR_IO_PollI2C();
+		if (status==M24SR_SUCCESS) {
+			return M24SR_ReceiveUpdateBinary();
+		} else {
+			mLastCommandSend = NONE;
+			getCallback()->on_updated_binary(this,status,Offset,pDataToWrite,NbByteToWrite);
+			return status;
+		}//if-else
+	}
+
+	return M24SR_SUCCESS;
+}
+
+M24SR::StatusTypeDef M24SR::M24SR_ReceiveUpdateBinary() {
+	uint8_t respBuffer[M24SR_STATUSRESPONSE_NBBYTE];
+	M24SR::StatusTypeDef status;
+	const uint16_t length = mLastCommandData.length;
+	uint8_t *data = mLastCommandData.data;
+	const uint16_t offset = mLastCommandData.offset;
+
+	mLastCommandSend=NONE;
+
+	status= M24SR_IO_ReceiveI2Cresponse (sizeof(respBuffer) , respBuffer);
+	if(status != M24SR_SUCCESS){
+		getCallback()->on_updated_binary(this,status,offset,data,length);
+		return status;
+	}
+
+	if (IsSBlock(respBuffer) == M24SR_SUCCESS) {
+		/*check the CRC */
+		status = M24SR_IsCorrectCRC16Residue(respBuffer, M24SR_WATINGTIMEEXTRESPONSE_NBBYTE);
+		// TODO: why if we check ==NFC_Commandsuccess it fail?
+		if (status != M24SR_IO_ERROR_CRC) {
+			/* send the FrameExension response*/
+			status = M24SR_SendFWTExtension(respBuffer[M24SR_OFFSET_PCB + 1]);
+			if(status!=M24SR_SUCCESS){ //something get wrong -> abort the update
+				getCallback()->on_updated_binary(this,status,offset,data,length);
+			}//status
+		}//if
+	} else { //isSBlock
+		status = M24SR_IsCorrectCRC16Residue(respBuffer, M24SR_STATUSRESPONSE_NBBYTE);
+		getCallback()->on_updated_binary(this,status,offset,data,length);
+	}//if else
+
+	return status;
+}//M24SR_ReceiveUpdateBinary
+
+/**
+ * @brief  This function sends the Verify command
+ * @param	uPwdId   PasswordId ( 0x0001 : Read NDEF pwd or 0x0002 : Write NDEF pwd or 0x0003 : I2C pwd)
+ * @param	NbPwdByte   Number of bytes ( 0x00 or 0x10)
+ * @param	pPwd   pointer to the password
+ * @retval Status (SW1&SW2) Status of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
+ */
+M24SR::StatusTypeDef M24SR::M24SR_SendVerify(uint16_t uPwdId, uint8_t NbPwdByte, const uint8_t *pPwd) {
+	C_APDU command;
+	M24SR::StatusTypeDef status;
+	uint8_t *pBuffer = uM24SRbuffer;
+	uint16_t NbByte;
+
+	/*check the parameters */
+	if ((uPwdId > 0x0003)|| ((NbPwdByte != 0x00) && (NbPwdByte != 0x10))) {
+		getCallback()->on_verified(this,M24SR_IO_ERROR_PARAMETER,constToPasswordType(uPwdId),pPwd);
+		return M24SR_IO_ERROR_PARAMETER;
+	}
+
+	/* build the command */
+	command.Header.CLA = C_APDU_CLA_DEFAULT;
+	command.Header.INS = C_APDU_VERIFY;
+	/* copy the Password Id */
+	command.Header.P1 = GETMSB(uPwdId);
+	command.Header.P2 = GETLSB(uPwdId);
+	/* copy the number of bytes of the data field */
+	command.Body.LC = NbPwdByte;
+
+	if (NbPwdByte == 0x10) {
+		/* copy the password */
+		command.Body.pData = pPwd;
+		/* build the I2C command */
+		M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_VERIFYBINARYWITHPWD, &command, uDIDbyte, &NbByte, pBuffer);
+	} else {
+		command.Body.pData = NULL;
+		/* build the I2C command */
+		M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_VERIFYBINARYWOPWD, &command, uDIDbyte, &NbByte, pBuffer);
+	}
+
+	/* send the request */
+	status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
+	if (status!=M24SR_SUCCESS) {
+		getCallback()->on_verified(this,status,constToPasswordType(uPwdId),pPwd);
+		return status;
+	}
+	mLastCommandSend=VERIFY;
+	mLastCommandData.data=(uint8_t*)pPwd;
+	mLastCommandData.offset=uPwdId;
+
+	if (mCommunicationType==M24SR::SYNC) {
+		status = M24SR_IO_PollI2C();
+		if(status == M24SR_SUCCESS) {
+			return M24SR_ReceiveVerify();
+		} else {
+			mLastCommandSend = NONE;
+			getCallback()->on_verified(this,status,constToPasswordType(uPwdId),pPwd);
+			return status;
+		}
+	}
+
+	return M24SR_SUCCESS;
+}
+
+M24SR::StatusTypeDef M24SR::M24SR_ReceiveVerify() {
+	M24SR::StatusTypeDef status;
+	uint8_t respBuffer[M24SR_STATUSRESPONSE_NBBYTE];
+	mLastCommandSend=NONE;
+
+	const uint8_t *data = mLastCommandData.data;
+	const PasswordType_t type = constToPasswordType(mLastCommandData.offset);
+
+	status=M24SR_IO_ReceiveI2Cresponse (sizeof(respBuffer),respBuffer);
+
+	if (status !=M24SR_SUCCESS) {
+		getCallback()->on_verified(this,status,type,data);
+		return status;
+	}
+
+	status = M24SR_IsCorrectCRC16Residue(respBuffer, M24SR_STATUSRESPONSE_NBBYTE);
+	getCallback()->on_verified(this,status,type,data);
+	return status;
+}
+
+/**
+ * @brief  This function sends the ChangeReferenceData command
+ * @param	uPwdId   PasswordId ( 0x0001 : Read NDEF pwd or 0x0002 : Write NDEF pwd or 0x0003 : I2C pwd)
+ * @param	pPwd   pointer to the passwaord
+ * @retval Status (SW1&SW2) Satus of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
+ */
+M24SR::StatusTypeDef M24SR::M24SR_SendChangeReferenceData(uint16_t uPwdId, uint8_t *pPwd) {
+	C_APDU command;
+	M24SR::StatusTypeDef status;
+	uint8_t *pBuffer = uM24SRbuffer;
+	uint16_t NbByte;
+
+	/*check the parameters */
+	if (uPwdId > 0x0003) {
+		getCallback()->on_change_reference_data(this,M24SR_IO_ERROR_PARAMETER, constToPasswordType(uPwdId), pPwd);
+		return M24SR_IO_ERROR_PARAMETER;
+	}
+
+	/* build the command */
+	command.Header.CLA = C_APDU_CLA_DEFAULT;
+	command.Header.INS = C_APDU_CHANGE;
+	/* copy the Password Id */
+	command.Header.P1 = GETMSB(uPwdId);
+	command.Header.P2 = GETLSB(uPwdId);
+	/* copy the number of byte of the data field */
+	command.Body.LC = M24SR_PASSWORD_NBBYTE;
+	/* copy the password */
+	command.Body.pData = pPwd;
+	/* build the I²C command */
+	M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_CHANGEREFDATA, &command, uDIDbyte, &NbByte, pBuffer);
+
+	/* send the request */
+	status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
+	if (status != M24SR_SUCCESS) {
+		getCallback()->on_change_reference_data(this,status, constToPasswordType(uPwdId), pPwd);
+		return status;
+	}
+
+	mLastCommandSend = CHANGE_REFERENCE_DATA;
+	mLastCommandData.data = pPwd;
+	//use the offset filed for store the pwd id;
+	mLastCommandData.offset = (uint8_t)uPwdId;
+
+	if (mCommunicationType==M24SR::SYNC) {
+		status = M24SR_IO_PollI2C();
+		if (status == M24SR_SUCCESS) {
+			return M24SR_ReceiveChangeReferenceData();
+		} else {
+			mLastCommandSend = NONE;
+			getCallback()->on_change_reference_data(this, status, constToPasswordType(uPwdId), pPwd);
+			return status;
+		}//if-else
+	}//if
+
+	return M24SR_SUCCESS;
+}
+
+M24SR::StatusTypeDef M24SR::M24SR_ReceiveChangeReferenceData(){
+	M24SR::StatusTypeDef status;
+	//TODO the size is 3?
+	uint8_t rensponseBuffer[M24SR_STATUSRESPONSE_NBBYTE];
+
+	PasswordType_t type = constToPasswordType(mLastCommandData.offset);
+	uint8_t *data = mLastCommandData.data;
+
+	status = M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , rensponseBuffer );
+	if (status!=M24SR_SUCCESS) {
+		getCallback()->on_change_reference_data(this,status,type,data);
+		return status;
+	}//else
+
+	status = M24SR_IsCorrectCRC16Residue(rensponseBuffer, M24SR_STATUSRESPONSE_NBBYTE);
+	getCallback()->on_change_reference_data(this,status,type,data);
+	return status;
+}
+
+/**
+ * @brief  This function sends the EnableVerificationRequirement command
+ * @param	uReadOrWrite enable the read or write protection ( 0x0001 : Read or 0x0002 : Write  )
+ * @retval Status (SW1&SW2) Status of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
+ */
+M24SR::StatusTypeDef M24SR::M24SR_SendEnableVerificationRequirement(uint16_t uReadOrWrite) {
+	C_APDU command;
+	M24SR::StatusTypeDef status;
+	uint8_t *pBuffer = uM24SRbuffer;
+	uint16_t NbByte;
+
+	/*check the parameters */
+	if ((uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002)) {
+		getCallback()->on_enable_verification_requirement(this,M24SR_IO_ERROR_PARAMETER, constToPasswordType(uReadOrWrite));
+		return M24SR_IO_ERROR_PARAMETER;
+	}
+
+	/* build the command */
+	command.Header.CLA = C_APDU_CLA_DEFAULT;
+	command.Header.INS = C_APDU_ENABLE;
+	/* copy the Password Id */
+	command.Header.P1 = GETMSB(uReadOrWrite);
+	command.Header.P2 = GETLSB(uReadOrWrite);
+	/* build the I2C command */
+	M24SR_BuildIBlockCommand( M24SR_CMDSTRUCT_ENABLEVERIFREQ, &command, uDIDbyte, &NbByte, pBuffer);
+
+	/* send the request */
+	status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
+	if (status != M24SR_SUCCESS) {
+		getCallback()->on_enable_verification_requirement(this, status, constToPasswordType(uReadOrWrite));
+		return status;
+	}//if
+
+	mLastCommandSend = ENABLE_VERIFICATION_REQUIREMENT;
+	//use the offset filed for store the pwd id;
+	mLastCommandData.offset = (uint8_t)uReadOrWrite;
+
+	if (mCommunicationType==M24SR::SYNC) {
+		status = M24SR_IO_PollI2C();
+		if (status == M24SR_SUCCESS) {
+			return M24SR_ReceiveEnableVerificationRequirement();
+		} else {
+			mLastCommandSend = NONE;
+			getCallback()->on_enable_verification_requirement(this, status, constToPasswordType(uReadOrWrite));
+			return status;
+		}//if-else
+	}//if
+
+	return M24SR_SUCCESS;
+}
+
+M24SR::StatusTypeDef M24SR::M24SR_ReceiveEnableVerificationRequirement(){
+	M24SR::StatusTypeDef status;
+	//TODO the size is 3?
+	uint8_t rensponseBuffer[M24SR_STATUSRESPONSE_NBBYTE];
+
+	const PasswordType_t type = constToPasswordType(mLastCommandData.offset);
+
+	status = M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , rensponseBuffer );
+	if (status!=M24SR_SUCCESS) {
+		getCallback()->on_enable_verification_requirement(this,status,type);
+		return status;
+	}//else
+
+	status = M24SR_IsCorrectCRC16Residue(rensponseBuffer, M24SR_STATUSRESPONSE_NBBYTE);
+	getCallback()->on_enable_verification_requirement(this,status,type);
+	return status;
+}
+
+/**
+ * @brief  This function sends the DisableVerificationRequirement command
+ * @param	uReadOrWrite enable the read or write protection ( 0x0001 : Read or 0x0002 : Write  )
+ * @retval Status (SW1&SW2)   Status of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
+ */
+M24SR::StatusTypeDef M24SR::M24SR_SendDisableVerificationRequirement(uint16_t uReadOrWrite) {
+	C_APDU command;
+	M24SR::StatusTypeDef status;
+	uint8_t *pBuffer = uM24SRbuffer;
+	uint16_t NbByte;
+
+	/*check the parameters */
+	if ((uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002)) {
+		getCallback()->on_disable_verification_requirement(this,M24SR_IO_ERROR_PARAMETER, constToPasswordType(uReadOrWrite));
+		return M24SR_IO_ERROR_PARAMETER;
+	}
+
+	/* build the command */
+	command.Header.CLA = C_APDU_CLA_DEFAULT;
+	command.Header.INS = C_APDU_DISABLE;
+	/* copy the Password Id */
+	command.Header.P1 = GETMSB(uReadOrWrite);
+	command.Header.P2 = GETLSB(uReadOrWrite);
+	/* build the I²C command */
+	M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_DISABLEVERIFREQ, &command, uDIDbyte, &NbByte, pBuffer);
+
+	/* send the request */
+	status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
+	if (status != M24SR_SUCCESS) {
+		getCallback()->on_disable_verification_requirement(this, status, constToPasswordType(uReadOrWrite));
+		return status;
+	}
+
+	mLastCommandSend = DISABLE_VERIFICATION_REQUIREMENT;
+	//use the offset filed for store the pwd id;
+	mLastCommandData.offset = (uint8_t)uReadOrWrite;
+
+	if (mCommunicationType==M24SR::SYNC) {
+		status = M24SR_IO_PollI2C();
+		if (status==M24SR_SUCCESS) {
+			return M24SR_ReceiveDisableVerificationRequirement();
+		} else {
+			mLastCommandSend = NONE;
+			getCallback()->on_disable_verification_requirement(this, status, constToPasswordType(uReadOrWrite));
+			return status;
+		}//if-else
+	}
+
+	return M24SR_SUCCESS;
+}
+
+M24SR::StatusTypeDef M24SR::M24SR_ReceiveDisableVerificationRequirement() {
+	M24SR::StatusTypeDef status;
+	//TODO the size is 3?
+	uint8_t rensponseBuffer[M24SR_STATUSRESPONSE_NBBYTE];
+
+	PasswordType_t type = constToPasswordType(mLastCommandData.offset);
+
+	status = M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , rensponseBuffer );
+	if (status!=M24SR_SUCCESS) {
+		getCallback()->on_disable_verification_requirement(this,status,type);
+		return status;
+	}//else
+
+	status = M24SR_IsCorrectCRC16Residue(rensponseBuffer, M24SR_STATUSRESPONSE_NBBYTE);
+	getCallback()->on_disable_verification_requirement(this,status,type);
+	return status;
+}
+
+/**
+ * @brief  This function sends the EnablePermananentState command
+ * @param	uReadOrWrite   enable the read or write protection ( 0x0001 : Read or 0x0002 : Write  )
+ * @retval Status (SW1&SW2)   Status of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
+ */
+M24SR::StatusTypeDef M24SR::M24SR_SendEnablePermanentState(uint16_t uReadOrWrite) {
+	C_APDU command;
+	M24SR::StatusTypeDef status;
+
+	uint8_t *pBuffer = uM24SRbuffer;
+	uint16_t NbByte;
+
+	/*check the parameters */
+	if ((uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002)) {
+		getCallback()->on_enable_permanent_state(this, M24SR_IO_ERROR_PARAMETER, constToPasswordType(uReadOrWrite));
+		return M24SR_IO_ERROR_PARAMETER;
+	}
+
+	/* build the command */
+	command.Header.CLA = C_APDU_CLA_ST;
+	command.Header.INS = C_APDU_ENABLE;
+	/* copy the Password Id */
+	command.Header.P1 = GETMSB(uReadOrWrite);
+	command.Header.P2 = GETLSB(uReadOrWrite);
+	/* build the I2C command */
+	M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_ENABLEVERIFREQ, &command, uDIDbyte, &NbByte, pBuffer);
+
+	/* send the request */
+	status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
+	if (status != M24SR_SUCCESS) {
+		getCallback()->on_enable_permanent_state(this, status, constToPasswordType(uReadOrWrite));
+		return status;
+	}
+
+	mLastCommandSend = ENABLE_PERMANET_STATE;
+	//use the offset filed for store the pwd id;
+	mLastCommandData.offset = (uint8_t)uReadOrWrite;
+
+	if (mCommunicationType==M24SR::SYNC) {
+		status = M24SR_IO_PollI2C();
+		if (status == M24SR_SUCCESS) {
+			return M24SR_ReceiveEnablePermanentState();
+		} else {
+			mLastCommandSend = NONE;
+			getCallback()->on_enable_permanent_state(this, status, constToPasswordType(uReadOrWrite));
+			return status;
+		}//if-else
+	}
+
+	return M24SR_SUCCESS;
+}
+
+M24SR::StatusTypeDef M24SR::M24SR_ReceiveEnablePermanentState() {
+	M24SR::StatusTypeDef status;
+	//TODO the size is 3?
+	uint8_t rensponseBuffer[M24SR_STATUSRESPONSE_NBBYTE];
+
+	PasswordType_t type = constToPasswordType(mLastCommandData.offset);
+
+	status = M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , rensponseBuffer );
+	if (status!=M24SR_SUCCESS) {
+		getCallback()->on_enable_permanent_state(this,status,type);
+		return status;
+	}//else
+
+	status = M24SR_IsCorrectCRC16Residue(rensponseBuffer, M24SR_STATUSRESPONSE_NBBYTE);
+	getCallback()->on_enable_permanent_state(this,status,type);
+	return status;
+}
+
+/**
+ * @brief  This function sends the DisablePermanentState command
+ * @param	uReadOrWrite enable the read or write protection ( 0x0001 : Read or 0x0002 : Write  )
+ * @retval Status (SW1&SW2)   Status of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
+ */
+M24SR::StatusTypeDef M24SR::M24SR_SendDisablePermanentState(uint16_t uReadOrWrite) {
+	C_APDU command;
+	M24SR::StatusTypeDef status;
+	uint8_t *pBuffer = uM24SRbuffer;
+	uint16_t NbByte;
+
+	/*check the parameters */
+	if ((uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002)) {
+		getCallback()->on_disable_permanent_state(this, M24SR_IO_ERROR_PARAMETER, constToPasswordType(uReadOrWrite));
+		return M24SR_IO_ERROR_PARAMETER;
+	}
+
+	/* build the command */
+	command.Header.CLA = C_APDU_CLA_ST;
+	command.Header.INS = C_APDU_DISABLE;
+	/* copy the Password Id */
+	command.Header.P1 = GETMSB(uReadOrWrite);
+	command.Header.P2 = GETLSB(uReadOrWrite);
+	/* build the I2C command */
+	M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_DISABLEVERIFREQ, &command, uDIDbyte, &NbByte, pBuffer);
+
+	/* send the request */
+	status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
+	if (status != M24SR_SUCCESS) {
+		getCallback()->on_enable_permanent_state(this, status, constToPasswordType(uReadOrWrite));
+		return status;
+	}
+
+	mLastCommandSend = DISABLE_PERMANET_STATE;
+	//use the offset filed for store the pwd id;
+	mLastCommandData.offset = (uint8_t)uReadOrWrite;
+
+	if (mCommunicationType == M24SR::SYNC) {
+		status = M24SR_IO_PollI2C();
+		if (status == M24SR_SUCCESS) {
+			return M24SR_ReceiveDisablePermanentState();
+		} else {
+			mLastCommandSend = NONE;
+			getCallback()->on_disable_permanent_state(this, status, constToPasswordType(uReadOrWrite));
+			return status;
+		}//if-else
+	}
+
+	return M24SR_SUCCESS;
+}
+
+M24SR::StatusTypeDef M24SR::M24SR_ReceiveDisablePermanentState() {
+	M24SR::StatusTypeDef status;
+	//TODO the size is 3?
+	uint8_t rensponseBuffer[M24SR_STATUSRESPONSE_NBBYTE];
+
+	PasswordType_t type = constToPasswordType(mLastCommandData.offset);
+
+	status = M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , rensponseBuffer );
+	if (status!=M24SR_SUCCESS) {
+		getCallback()->on_disable_permanent_state(this,status,type);
+		return status;
+	}//else
+
+	status = M24SR_IsCorrectCRC16Residue(rensponseBuffer, M24SR_STATUSRESPONSE_NBBYTE);
+	getCallback()->on_disable_permanent_state(this,status,type);
+	return status;
+}
+
+/**
+ * @brief  This function generates an interrupt on GPO pin
+ * @param	None
+ * @retval Status (SW1&SW2)   Status of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
+ */
+M24SR::StatusTypeDef M24SR::M24SR_SendInterrupt(void) {
+	C_APDU command;
+
+	uint8_t *pBuffer = uM24SRbuffer;
+	uint16_t uP1P2 = 0x001E;
+	uint16_t NbByte;
+
+
+	StatusTypeDef status = M24SR_ManageI2CGPO(INTERRUPT);
+	if (status!=M24SR_SUCCESS) {
+		return status;
+	}
+
+	/* build the command */
+	command.Header.CLA = C_APDU_CLA_ST;
+	command.Header.INS = C_APDU_INTERRUPT;
+	/* copy the Password Id */
+	command.Header.P1 = GETMSB(uP1P2);
+	command.Header.P2 = GETLSB(uP1P2);
+	command.Body.LC = 0x00;
+	/* build the I2C command */
+	M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_SENDINTERRUPT, &command, uDIDbyte, &NbByte, pBuffer);
+
+	/* send the request */
+	errchk(M24SR_IO_SendI2Ccommand(NbByte, pBuffer));
+	errchk(M24SR_IO_PollI2C());
+	/* read the response */
+	errchk(M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
+
+	return M24SR_IsCorrectCRC16Residue(pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
+
+}
+
+/**
+ * @brief  This function forces GPO pin to low state or high Z
+ * @param	uSetOrReset select if GPO must be low (reset) or HiZ
+ * @retval Status (SW1&SW2) Status of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
+ */
+M24SR::StatusTypeDef M24SR::M24SR_StateControl(uint8_t uSetOrReset) {
+	C_APDU command;
+	uint8_t *pBuffer = uM24SRbuffer;
+	uint16_t uP1P2 = 0x001F;
+	uint16_t NbByte;
+
+	/*check the parameters */
+	if ((uSetOrReset != 0x01) && (uSetOrReset != 0x00)) {
+		return M24SR_IO_ERROR_PARAMETER;
+	}
+
+
+	StatusTypeDef status = M24SR_ManageI2CGPO(STATE_CONTROL);
+	if (status == M24SR_SUCCESS) {
+		return status;
+	}
+
+	/* build the command */
+	command.Header.CLA = C_APDU_CLA_ST;
+	command.Header.INS = C_APDU_INTERRUPT;
+	/* copy the Password Id */
+	command.Header.P1 = GETMSB(uP1P2);
+	command.Header.P2 = GETLSB(uP1P2);
+	command.Body.LC = 0x01;
+	command.Body.pData = &uSetOrReset;
+	/* copy the data */
+	//memcpy(command.Body.pData , &uSetOrReset, 0x01 );
+	//command.Body.LE = 0x00 ;
+	/* build the I2C command */
+	M24SR_BuildIBlockCommand( M24SR_CMDSTRUCT_GPOSTATE, &command, uDIDbyte, &NbByte, pBuffer);
+
+	/* send the request */
+	errchk(M24SR_IO_SendI2Ccommand(NbByte, pBuffer));
+	errchk(M24SR_IO_PollI2C());
+	/* read the response */
+	errchk(M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
+
+	return M24SR_IsCorrectCRC16Residue(pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
+}
+
+M24SR::StatusTypeDef M24SR::M24SR_ManageI2CGPO(NFC_GPO_MGMT GPO_I2Cconfig) {
+
+	if (GPOPin.is_connected() == 0) {
+		return M24SR_IO_PIN_NOT_CONNECTED;
+	}
+	if (GPO_I2Cconfig > STATE_CONTROL) {
+		return M24SR_IO_ERROR_PARAMETER;
+	}
+
+	//enable the callback for change the gpo
+	mComponentCallback = &mManageGPOCallback;
+	mManageGPOCallback.set_new_GPO_config(true,GPO_I2Cconfig);
+
+	//start the manageGPO procedure
+	return M24SR_SendSelectApplication();
+}
+
+M24SR::StatusTypeDef M24SR::M24SR_ManageRFGPO(NFC_GPO_MGMT GPO_I2Cconfig) {
+
+	if(RFDisablePin.is_connected()==0) {
+		return M24SR_IO_PIN_NOT_CONNECTED;
+	}
+	if (GPO_I2Cconfig > STATE_CONTROL) {
+		return M24SR_IO_ERROR_PARAMETER;
+	}
+
+	//enable the callback for change the gpo
+	mComponentCallback = &mManageGPOCallback;
+	mManageGPOCallback.set_new_GPO_config(false,GPO_I2Cconfig);
+
+	//start the manageGPO procedure
+	return M24SR_SendSelectApplication();
+}
+
+M24SR::StatusTypeDef M24SR::M24SR_RFConfig(uint8_t OnOffChoice) {
+	if (RFDisablePin.is_connected()==0) {
+		return M24SR_IO_PIN_NOT_CONNECTED;
+	}
+	/* Disable RF */
+	if (OnOffChoice != 0) {
+		M24SR_IO_RFDIS_WritePin(GPIO_PIN_RESET);
+	} else {
+		M24SR_IO_RFDIS_WritePin(GPIO_PIN_SET);
+	}
+	return M24SR_SUCCESS;
+}
+
+M24SR::StatusTypeDef M24SR::M24SR_IO_SendI2Ccommand(uint8_t NbByte, uint8_t *pBuffer) {
+	int ret = dev_I2C.write(address, (char*) pBuffer, NbByte);
+	if (ret == 0) {
+		return M24SR_SUCCESS;
+	}
+	return M24SR_IO_ERROR_I2CTIMEOUT;
+}
+
+M24SR::StatusTypeDef M24SR::M24SR_IO_ReceiveI2Cresponse(uint8_t NbByte, uint8_t *pBuffer) {
+	int ret = dev_I2C.read(address, (char*) pBuffer, NbByte);
+	if (ret == 0) {
+		return M24SR_SUCCESS;
+	}
+
+	return M24SR_IO_ERROR_I2CTIMEOUT;
+}
+
+M24SR::StatusTypeDef M24SR::M24SR_IO_PollI2C(void) {
+
+    int status = 1;
+    while (status != 0 ) {
+        //send the device address and wait to recevie an ack bit
+        status = dev_I2C.write(address,NULL,0);
+    }
+    return M24SR_SUCCESS;
+}
+
+M24SR::StatusTypeDef M24SR::manage_event(void){
+
+	switch(mLastCommandSend) {
+		case SELECT_APPLICATION:
+			return M24SR_ReceiveSelectApplication();
+		case SELECT_CC_FILE:
+			return M24SR_ReceiveSelectCCfile();
+		case SELECT_NDEF_FILE:
+			return M24SR_ReceiveSelectNDEFfile();
+		case SELECT_SYSTEM_FILE:
+			return M24SR_ReceiveSelectSystemfile();
+		case READ:
+			return M24SR_ReceiveReadBinary();
+		case UPDATE:
+			return M24SR_ReceiveUpdateBinary();
+		case VERIFY:
+			return M24SR_ReceiveVerify();
+		case DESELECT:
+			return M24SR_ReceiveDeselect();
+		case CHANGE_REFERENCE_DATA:
+			return M24SR_ReceiveChangeReferenceData();
+		case ENABLE_VERIFICATION_REQUIREMENT:
+			return M24SR_ReceiveEnableVerificationRequirement();
+		case DISABLE_VERIFICATION_REQUIREMENT:
+			return M24SR_ReceiveDisableVerificationRequirement();
+		case ENABLE_PERMANET_STATE:
+			return M24SR_ReceiveEnablePermanentState();
+		case DISABLE_PERMANET_STATE:
+			return M24SR_ReceiveDisablePermanentState();
+		default:
+			return M24SR_SUCCESS;
+	}//switch
+}//manageInterrupt
+
+NDefLib::NDefNfcTag&M24SR::get_NDef_tag(){
+	return *mNDefTagUtil;
+}
+
+
+/******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 11161008d77a M24SR.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/M24SR.h	Mon Jul 31 12:26:02 2017 +0000
@@ -0,0 +1,1461 @@
+/**
+ ******************************************************************************
+ * @file    m24sr_class.h
+ * @author  ST Central Labs
+ * @version V2.0.0
+ * @date    28 Apr 2017
+ * @brief   This file provides a set of functions to interface with the M24SR
+ *          device.
+ ******************************************************************************
+ * @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.
+ *
+ ******************************************************************************
+ */
+
+/* Revision ------------------------------------------------------------------*/
+/*
+ Based on:         X-CUBE-MEMS1/trunk/Drivers/BSP/Components/m24sr/m24sr.h
+ Revision:         M24SR Driver V1.0.0
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+
+#ifndef __M24SR_CLASS_H
+#define __M24SR_CLASS_H
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "mbed.h"
+#include "I2C.h"
+
+#include "m24sr_def.h"
+#include "Nfc.h"
+
+#include "NDefLib/NDefNfcTag.h"
+class NDefNfcTagM24SR;
+
+/* Classes -------------------------------------------------------------------*/
+
+/**
+* Class representing a M24SR component.
+* This component has two operation modes, sync or async.
+* In sync mode each function call returns only after the command has completed.
+* In async mode each function call returns immediately and the answer will be notified
+* through a callback.
+* The default behavior is sync mode.
+* To enable the async mode ManageI2CGPO(I2C_ANSWER_READY) function must be called.
+* When the component notifies an interrupt user must call  {@link ManageEvent} function.
+* Note that passing a parameter other than I2C_ANSWER_READY to ManageI2CGPO initialize the component in sync mode.
+ */
+class M24SR: public Nfc {
+
+public:
+
+	typedef enum {
+		M24SR_SUCCESS=NFC_SUCCESS,
+		M24SR_ERROR=0x6F00,
+		M24SR_FILE_OVERFLOW_LE = 0x6280,
+		M24SR_EOF = 0x6282,
+		M24SR_PASSWORD_REQUIRED = 0x6300,
+		M24SR_PASSWORD_INCORRECT = 0x63C0,
+		M24SR_PASSWORD_INCORRECT1RETRY = 0x63C1,
+		M24SR_PASSWORD_INCORRECT2RETRY = 0x63C2,
+		M24SR_WRONG_LENGHT = 0x6700,
+		M24SR_UNSUCESSFUL_UPDATING = 0x6581,
+		M24SR_INCOPATIBLE_COMMAND= 0x6981,
+		M24SR_SECURITY_UNSATISFIED = 0x6982,
+		M24SR_REFERENCE_DATA_NOT_USABLE = 0x6984,
+
+		M24SR_INCORRECT_PARAMETER = 0x6a80,
+		M24SR_FILE_NOT_FOUND=0x6a82,
+		M24SR_FILE_OVERFLOW_LC = 0x6A84, //TODO difference with Le??
+
+		M24SR_INCORRECT_P1_OR_P2 = 0x6A86, //TODO better name?
+		M24SR_RF_SESSION_KILLED=0x6500,
+		M24SR_INS_NOT_SUPPORTED=0x6D00,
+		M24SR_CLASS_NOT_SUPPORTED=0x6E00,
+
+		//IOError
+		M24SR_IO_ERROR_I2CTIMEOUT=0x0011,
+		M24SR_IO_ERROR_CRC=0x0012,
+		M24SR_IO_ERROR_NACK=0x0013,
+		M24SR_IO_ERROR_PARAMETER=0x0014,
+		M24SR_IO_ERROR_NBATEMPT=0x0015,
+		M24SR_IO_NOACKNOWLEDGE=0x0016,
+		M24SR_IO_PIN_NOT_CONNECTED=0x0017
+	} StatusTypeDef;
+
+	/**
+	 * @brief  GPO state structure
+	 */
+	typedef enum {
+		HIGH_IMPEDANCE = 0,
+		SESSION_OPENED =1,
+		WIP=2,
+		I2C_ANSWER_READY=3,
+		INTERRUPT=4,
+		STATE_CONTROL=5
+	} NFC_GPO_MGMT;
+
+	/**
+	 * Possible password to set.
+	 */
+	typedef enum{
+		ReadPwd,   //!< Password to use before reading the tag
+		WritePwd,  //!< Password to use before writing the tag
+		I2CPwd,    //!< Root password, used only through nfc
+	}PasswordType_t;
+
+	/**
+	 * Default password used to change the write/read permission
+	 */
+	static const uint8_t DEFAULT_PASSWORD[16];
+
+	/**
+	 * Default gpo status -> the gpo will remain high
+	 */
+	static const NFC_GPO_MGMT DEFAULT_GPO_STATUS=HIGH_IMPEDANCE;
+
+
+	/**
+	 * Function that will be called when an interrupt is fired,
+	 * this function must be set if you want use the component in async mode.
+	 */
+	typedef void(*gpoEventCallback)(void);
+
+	/**
+	 * Object that contains all the callbacks fired by this class, each command has its own callback.
+	 * The callback default implementation is an empty function.
+	 */
+	class Callbacks{
+		public:
+
+			/** called when GetSession or ForceGetSession completes
+			 * @see M24SR#GetSession
+			 * @see M24SR#ForceGetSession */
+			virtual void on_session_open(M24SR *nfc,StatusTypeDef status) {
+				(void)nfc; (void)status;
+			}
+
+			/** called when Deselect completes
+			 * @see M24SR#Deselect */
+			virtual void on_deselect(M24SR *nfc,StatusTypeDef status) {
+				(void)nfc; (void)status;
+			}
+
+			/** called when SelectedApplication completes
+			 * @see M24SR#SelectedApplication */
+			virtual void on_selected_application(M24SR *nfc,StatusTypeDef status) {
+				(void)nfc; (void)status;
+			}
+
+			/** called when SelectedCCFile completes
+			 * @see M24SR#SelectedCCFile */
+			virtual void on_selected_CC_file(M24SR *nfc,StatusTypeDef status) {
+				(void)nfc; (void)status;
+			}
+
+			/** called when SelectedNDEFFile completes
+			 * @see M24SR#SelectedNDEFFile */
+			virtual void on_selected_NDEF_file(M24SR *nfc,StatusTypeDef status) {
+				(void)nfc; (void)status;
+			}
+
+			/** called when SelectedSystemFile completes
+			 * @see M24SR#SelectedSystemFile */
+			virtual void on_selected_system_file(M24SR *nfc,StatusTypeDef status) {
+				(void)nfc; (void)status;
+			}
+
+			/** called when read_binary or STReadBinary completes
+			 * @see M24SR#read_binary
+			 * @see M24SR#STReadBinary */
+			virtual void on_read_byte(M24SR *nfc,StatusTypeDef status,
+					uint16_t offset,uint8_t *readByte, uint16_t nReadByte) {
+				(void)nfc; (void)status;(void)offset; (void)readByte; (void)nReadByte;
+			}
+
+			/** called when UpdatedBinary completes
+			 * @see M24SR#UpdatedBinary */
+			virtual void on_updated_binary(M24SR *nfc,StatusTypeDef status,uint16_t offset,
+					uint8_t *writeByte,uint16_t nWriteByte) {
+				(void)nfc; (void)status; (void)writeByte; (void)nWriteByte; (void)offset;
+			}
+
+			/** called when Verify completes
+			 * @see M24SR#Verify */
+			virtual void on_verified(M24SR *nfc,StatusTypeDef status,PasswordType_t uPwdId,
+					const uint8_t *pwd) {
+				(void)nfc; (void)status;(void)uPwdId;(void)pwd;
+			}
+
+			/** called when ManageI2CGPO completes
+			 * @see M24SR#ManageI2CGPO */
+			virtual void on_manage_I2C_GPO(M24SR *nfc,StatusTypeDef status,NFC_GPO_MGMT newStatus) {
+				(void)nfc; (void)status;(void)newStatus;
+			}
+
+			/** called when ManageRFGPO completes
+			 * @see M24SR#ManageRFGPO */
+			virtual void on_manage_RF_GPO(M24SR *nfc,StatusTypeDef status,NFC_GPO_MGMT newStatus) {
+				(void)nfc; (void)status;(void)newStatus;
+			}
+
+			/** called when ChangeReferenceData completes
+			 * @see M24SR#ChangeReferenceData */
+			virtual void on_change_reference_data(M24SR *nfc ,StatusTypeDef status,PasswordType_t type,
+					uint8_t *data) {
+				(void)nfc; (void)status;(void)type;(void)data;
+			}
+
+			/** called when EnableVerificationRequirement completes
+			 * @see M24SR#EnableVerificationRequirement */
+			virtual void on_enable_verification_requirement(M24SR *nfc ,StatusTypeDef status,PasswordType_t type) {
+				(void)nfc; (void)status;(void)type;
+			}
+
+			/** called when disable_verification_requirement completes
+			 * @see M24SR#disable_verification_requirement */
+			virtual void on_disable_verification_requirement(M24SR *nfc , StatusTypeDef status,PasswordType_t type) {
+				(void)nfc; (void)status;(void)type;
+			}
+
+			/** called when EnablePermanentState completes
+			 * @see M24SR#EnablePermanentState */
+			virtual void on_enable_permanent_state(M24SR *nfc, StatusTypeDef status, PasswordType_t type) {
+				(void)nfc; (void)status;(void)type;
+			}
+
+			/** called when DisablePermanentState completes
+			 * @see M24SR#DisablePermanentState */
+			virtual void on_disable_permanent_state(M24SR *nfc, StatusTypeDef status, PasswordType_t type) {
+				(void)nfc; (void)status;(void)type;
+			}
+
+			/** called when ReadId completes
+			 * @see M24SR#ReadId */
+			virtual void on_read_id(M24SR *nfc, StatusTypeDef status, uint8_t *id) {
+						(void)nfc; (void)status;(void)id;
+			}
+
+			/** called when EnableReadPassword completes
+			 * @see M24SR#EnableReadPassword */
+			virtual void on_enable_read_password(M24SR *nfc, StatusTypeDef status,const uint8_t *newPwd) {
+				(void)nfc; (void)status;(void)newPwd;
+			}
+
+			/** called when EnableWritePassword completes
+			 * @see M24SR#EnableWritePassword */
+			virtual void on_enable_write_password(M24SR *nfc, StatusTypeDef status,const uint8_t *newPwd) {
+				(void)nfc; (void)status;(void)newPwd;
+			}
+
+			/** called when DisableReadPassword completes
+			 * @see M24SR#DisableReadPassword */
+			virtual void on_disable_read_password(M24SR *nfc, StatusTypeDef status) {
+				(void)nfc; (void)status;
+			}
+
+			/** called when DisableWritePassword completes
+			 * @see M24SR#DisableWritePassword */
+			virtual void on_disable_write_password(M24SR *nfc, StatusTypeDef status) {
+				(void)nfc; (void)status;
+			}
+
+			/** called when DisableAllPassword completes
+			 * @see M24SR#DisableAllPassword */
+			virtual void on_disable_all_password(M24SR *nfc, StatusTypeDef status) {
+				(void)nfc; (void)status;
+			}
+
+
+			/** called when EnableReadOnly completes
+			 * @see M24SR#EnableReadOnly */
+			virtual void on_enable_read_only(M24SR *nfc,StatusTypeDef status) {
+				(void)nfc; (void)status;
+			}
+
+			/** called when EnableWriteOnly completes
+			 * @see M24SR#EnableWriteOnly */
+			virtual void on_enable_write_only(M24SR *nfc,StatusTypeDef status) {
+				(void)nfc; (void)status;
+			}
+
+
+			/** called when DisableReadOnly completes
+			 * @see M24SR#DisableReadOnly */
+			virtual void on_disable_read_only(M24SR *nfc,StatusTypeDef status) {
+				(void)nfc; (void)status;
+			}
+
+			/** called when DisableWriteOnly completes
+			 * @see M24SR#DisableWriteOnly */
+			virtual void on_disable_write_only(M24SR *nfc,StatusTypeDef status) {
+				(void)nfc; (void)status;
+			}
+
+			virtual ~Callbacks() {};
+		};
+
+	/*** Constructor and Destructor Methods ***/
+
+	/**
+	 * @brief Constructor.
+	 * @param address I2C address of the component.
+	 * @param I2C     I2C device to be used for communication.
+	 * @param eventCallback Function that will be called when the gpo pin status changes.
+	 * @param GPOPinName Pin used as GPIO.
+	 * @param RFDISPinName Pin used to disable the RF function.
+	 */
+	M24SR(const uint8_t address, I2C &I2C,gpoEventCallback eventCallback, const PinName& GPOPinName,
+			const PinName& RFDISPinName);
+
+	/**
+	 * @brief Destructor.
+	 */
+	virtual ~M24SR(void);
+
+	/*** Public Component Related Methods ***/
+	
+	/**
+	 * @brief  This function initializes the M24SR device.
+	 * @param ptr Configure parameters, not used.
+     * @return M24SR_SUCCESS if no errors
+	 */
+	virtual int init(void *ptr) {
+		return (StatusTypeDef) M24SR_Init((M24SR_InitTypeDef*)ptr);
+	}
+
+	virtual int read_id(uint8_t *id) {
+		return (StatusTypeDef) M24SR_ReadID((uint8_t *) id);
+	}
+
+	/** lock the tag channel */
+	virtual StatusTypeDef get_session(void) {
+		return (StatusTypeDef) M24SR_GetSession();
+	}
+
+	/**
+	 * Force to open an I2C connection , abort the RF connection.
+	 * @return M24SR_SUCCESS if the session is acquired
+	 */
+	StatusTypeDef force_get_session(void) {
+		return (StatusTypeDef) M24SR_ForceSession();
+	}
+
+	virtual StatusTypeDef deselect(void) {
+		return (StatusTypeDef) M24SR_Deselect();
+	}
+
+	////////// tag4 command ////////////////////
+	
+	/**
+	 * Select the application file.
+	 * @return M24SR_SUCCESS if the application is selected
+	 */
+	StatusTypeDef select_application(void) {
+		return M24SR_SendSelectApplication();
+	}
+
+	/**
+	 * Select the CC file.
+	 * @return M24SR_SUCCESS if the CC file is selected.
+	 */
+	StatusTypeDef select_CC_file(void) {
+		return M24SR_SendSelectCCfile();
+	}
+
+	/**
+	 * Select the NDEF file.
+	 * @param NDEFfileId File id to open.
+	 * @return M24SR_SUCCESS if the file is selected
+	 */
+	StatusTypeDef select_NDEF_file(uint16_t NDEFfileId) {
+		return M24SR_SendSelectNDEFfile(NDEFfileId);
+	}
+
+	/**
+	 * Select the system file.
+	 * @return M24SR_SUCCESS if the system file is selected
+	 */
+	StatusTypeDef select_system_file(void) {
+		return M24SR_SendSelectSystemfile();
+	}
+
+	virtual int read_binary(uint16_t Offset, uint8_t NbByteToRead,
+			uint8_t *pBufferRead) {
+		return (StatusTypeDef) M24SR_SendReadBinary((uint16_t) Offset,
+				(uint8_t) NbByteToRead, (uint8_t *) pBufferRead);
+	}
+
+	virtual int update_binary(uint16_t Offset,
+			uint8_t NbByteToWrite,uint8_t *pDataToWrite) {
+		return (StatusTypeDef) M24SR_SendUpdateBinary((uint16_t) Offset,
+				(uint8_t) NbByteToWrite, (uint8_t *) pDataToWrite);
+	}
+
+	/////////////////// iso 7816-4 commands //////////////////////////
+	
+	virtual StatusTypeDef verify(PasswordType_t pwdId, uint8_t NbPwdByte,
+			const uint8_t *pPwd) {
+		return (StatusTypeDef) M24SR_SendVerify(passwordTypeToConst(pwdId),
+				(uint8_t) NbPwdByte, pPwd);
+	}
+
+	virtual StatusTypeDef change_reference_data(PasswordType_t pwdId,
+			const uint8_t *pPwd) {
+		return (StatusTypeDef) M24SR_SendChangeReferenceData(passwordTypeToConst(pwdId),
+				(uint8_t *) pPwd);
+	}
+
+	virtual StatusTypeDef enable_verification_requirement(
+			PasswordType_t uReadOrWrite) {
+		return (StatusTypeDef) M24SR_SendEnableVerificationRequirement(
+				passwordTypeToConst(uReadOrWrite));
+	}
+
+	virtual StatusTypeDef disable_verification_requirement(
+			PasswordType_t uReadOrWrite) {
+		return (StatusTypeDef) M24SR_SendDisableVerificationRequirement(
+				passwordTypeToConst(uReadOrWrite));
+	}
+
+    ////////////////////// ST proprietary //////////////////////////////////
+
+	/**
+	 * Same as {@link NFC#read_binary}, however permitting to read more bytes than available.
+	 * @param Offset read offset.
+	 * @param NbByteToRead Number of bytes to read.
+	 * @param[out] pBufferRead Buffer to store the read data into.
+	 * @return M24SR_SUCCESS if no errors
+	 */
+	StatusTypeDef ST_read_binary(uint16_t Offset,
+			uint8_t NbByteToRead, uint8_t *pBufferRead) {
+		return (StatusTypeDef) M24SR_SendSTReadBinary((uint16_t) Offset,
+				(uint8_t) NbByteToRead, (uint8_t *) pBufferRead);
+	}
+
+	virtual StatusTypeDef enable_permanent_state(PasswordType_t uReadOrWrite) {
+		return (StatusTypeDef) M24SR_SendEnablePermanentState(
+				passwordTypeToConst(uReadOrWrite));
+	}
+
+	virtual StatusTypeDef disable_permanent_state(PasswordType_t uReadOrWrite) {
+		return (StatusTypeDef) M24SR_SendDisablePermanentState(
+				passwordTypeToConst(uReadOrWrite));
+	}
+
+	///////////////////// chip configuration /////////////////////////////////
+	/**
+	 * Set the gpo output pin.
+	 * @param uSetOrReset New pin status.
+ 	 * @return M24SR_SUCCESS if no errors
+	 */
+	StatusTypeDef state_control(uint8_t uSetOrReset) {
+		return (StatusTypeDef) M24SR_StateControl((uint8_t) uSetOrReset);
+	}
+
+	/**
+	 * @brief  This function configures GPO for I2C session.
+	 * @param  GPO_I2Cconfig GPO configuration to set.
+ 	 * @return M24SR_SUCCESS if no errors
+ 	 * @par if the configuration is I2C_ANSWER_READY, the component will start to work
+ 	 * in async mode.
+	 */
+	StatusTypeDef manage_I2C_GPO(NFC_GPO_MGMT GPO_I2Cconfig) {
+		return (StatusTypeDef) M24SR_ManageI2CGPO(GPO_I2Cconfig);
+	}
+
+
+	/**
+ 	* @brief  This function configures GPO for RF session.
+ 	* @param  GPO_RFconfig GPO configuration to set.
+  	* @return M24SR_SUCCESS if no errors
+ 	*/
+	StatusTypeDef manage_RF_GPO(uint8_t GPO_RFconfig) {
+		return (StatusTypeDef) M24SR_ManageRFGPO(
+				(NFC_GPO_MGMT) GPO_RFconfig);
+	}
+
+
+	/**
+	 * @brief  This function enables or disables the RF communication.
+	 * @param  OnOffChoice GPO configuration to set.
+  	 * @return M24SR_SUCCESS if no errors
+	 */
+
+	StatusTypeDef RF_config(uint8_t OnOffChoice) {
+		return (StatusTypeDef) M24SR_RFConfig((uint8_t) OnOffChoice);
+	}
+
+
+	/**
+	 * Generates a negative pulse on the GPO pin.
+	 * Pulse starts immediately after the command is issued and ends at the end of the RF response.
+  	 * @return M24SR_SUCCESS if no errors
+	 */
+	StatusTypeDef send_interrupt(void) {
+		return (StatusTypeDef) M24SR_SendInterrupt();
+	}
+
+
+	/**
+	 * Function to call when the component fire an interrupt.
+	 * @return last operation status
+	 */
+	StatusTypeDef manage_event();
+
+	/**
+	 * Change the function to call when a command ends.
+	 * @param commandCallback Object containing the callback, if NULL it will use empty callback
+	 */
+	void set_callback(Callbacks *commandCallback) {
+		if (commandCallback!=NULL) {
+			mCallback = commandCallback;
+		} else {
+			mCallback = &defaultCallback;
+		}
+	}
+
+
+	/////////////////// hight level/utility function /////////////////////
+
+
+	/**
+	 * Enable the request of a password before reading the tag.
+	 * @param  pCurrentWritePassword Current password
+	 * @param  pNewPassword Password to request before reading the tag.
+	 * @return return M24SR_SUCCESS if no errors
+	 * @par The password must have a length of 16 chars.
+	 */
+	StatusTypeDef enable_read_password(const uint8_t* pCurrentWritePassword, const uint8_t* pNewPassword) {
+
+		//enable the callback for change the gpo
+		mComponentCallback = &mChangePasswordRequestStatusCallback;
+		mChangePasswordRequestStatusCallback.set_task(ReadPwd,pNewPassword);
+
+		return verify(M24SR::WritePwd, 0x10, pCurrentWritePassword);
+	}
+
+	/**
+	 * Disable the request of a password before reading the tag.
+	 * @param  pCurrentWritePassword Current password
+	 * @return return M24SR_SUCCESS if no errors
+	 * @par The password must have a length of 16 chars.
+	 */
+	StatusTypeDef disable_read_password(const uint8_t* pCurrentWritePassword) {
+		mComponentCallback = &mChangePasswordRequestStatusCallback;
+		mChangePasswordRequestStatusCallback.set_task(ReadPwd,NULL);
+
+		return verify(M24SR::WritePwd, 0x10, pCurrentWritePassword);
+	}
+
+	/**
+	 * Enable the request of a password before writing to the tag.
+	 * @param  pCurrentWritePassword Current password
+	 * @param  pNewPassword Password to request before reading the tag.
+	 * @return return M24SR_SUCCESS if no errors
+	 * @par The password must have a length of 16 chars.
+	 */
+	StatusTypeDef enable_write_password(const uint8_t* pCurrentWritePassword, uint8_t* pNewPassword) {
+		//enable the callback for change the gpo
+		mComponentCallback = &mChangePasswordRequestStatusCallback;
+		mChangePasswordRequestStatusCallback.set_task(WritePwd,pNewPassword);
+
+		return verify(M24SR::WritePwd, 0x10, pCurrentWritePassword);
+	}
+
+	/**
+	 * Disable the request of a password before writing the tag.
+	 * @param  pCurrentWritePassword Current password.
+	 * @return return M24SR_SUCCESS if no errors
+	 * @par The password must have a length of 16 chars.
+	 */
+	StatusTypeDef disable_write_password(const uint8_t* pCurrentWritePassword) {
+		mComponentCallback = &mChangePasswordRequestStatusCallback;
+		mChangePasswordRequestStatusCallback.set_task(WritePwd,NULL);
+
+		return verify(M24SR::WritePwd, 0x10, pCurrentWritePassword);
+	}
+
+	/**
+	 * @brief   This function disables both read and write passwords.
+	 * @param	pSuperUserPassword I2C super user password.
+	 * @return  return M24SR_SUCCESS if no errors
+	 * @par The password must have a length of 16 chars.
+	 */
+	StatusTypeDef disable_all_password(const uint8_t* pSuperUserPassword) {
+		mComponentCallback = &mRemoveAllPasswordCallback;
+		return verify(M24SR::I2CPwd, 0x10, pSuperUserPassword);
+	}
+
+	/**
+	 * @brief   This function enables read only mode.
+	 * @param	pCurrentWritePassword Write password is needed to enable read only mode.
+	 * @return  return M24SR_SUCCESS if no errors
+	 * @par The password must have a length of 16 chars.
+	 */
+	StatusTypeDef enable_read_only(const uint8_t* pCurrentWritePassword) {
+		mComponentCallback = &mChangeAccessStateCallback;
+		//disable write = read only
+		mChangeAccessStateCallback.change_access_state(ChangeAccessStateCallback::WRITE,false);
+
+		return verify(M24SR::WritePwd, 0x10, pCurrentWritePassword);
+	}
+
+	/**
+	 * @brief   This function disables read only mode.
+	 * @param	pCurrentWritePassword Write password is needed to disable read only mode.
+	 * @return  return M24SR_SUCCESS if no errors
+	 * @par The password must have a length of 16 chars.
+	 */
+	StatusTypeDef disable_read_only(const uint8_t* pCurrentWritePassword) {
+		mComponentCallback = &mChangeAccessStateCallback;
+		mChangeAccessStateCallback.change_access_state(ChangeAccessStateCallback::WRITE,true);
+
+		return verify(M24SR::I2CPwd, 0x10,pCurrentWritePassword);
+	}
+
+
+	/**
+	 * @brief   This function enables write only mode.
+	 * @param	pCurrentWritePassword Write password is needed to enable write only mode.
+	 * @return  return M24SR_SUCCESS if no errors
+	 * @par The password must have a length of 16 chars.
+	 */
+	StatusTypeDef enable_write_only(const uint8_t* pCurrentWritePassword) {
+		mComponentCallback = &mChangeAccessStateCallback;
+		//disable read = enable write only
+		mChangeAccessStateCallback.change_access_state(ChangeAccessStateCallback::READ,false);
+
+		return verify(M24SR::WritePwd, 0x10, pCurrentWritePassword);
+	}
+
+	/**
+	 * @brief   This function disables write only mode.
+	 * @param	pCurrentWritePassword Write password is needed to disable write only mode.
+	 * @return  return M24SR_SUCCESS if no errors
+	 * @par The password must have a length of 16 chars.
+	 */
+	StatusTypeDef disable_write_only(const uint8_t* pCurrentWritePassword) {
+		mComponentCallback = &mChangeAccessStateCallback;
+		mChangeAccessStateCallback.change_access_state(ChangeAccessStateCallback::READ,true);
+
+		return verify(M24SR::I2CPwd, 0x10, pCurrentWritePassword);
+	}
+
+
+	/**
+	 * Get an implementation of NDefNfcTag to use the library NDefLib.
+	 * @return an object of type NdefNfcTag 
+	 */
+	NDefLib::NDefNfcTag& get_NDef_tag();
+
+
+protected:
+
+	/*** Protected Component Related Methods ***/
+
+	StatusTypeDef M24SR_Init(M24SR_InitTypeDef *);
+	StatusTypeDef M24SR_ReadID(uint8_t *nfc_id);
+	StatusTypeDef M24SR_GetSession(void);
+	StatusTypeDef M24SR_ForceSession(void);
+
+	StatusTypeDef M24SR_Deselect(void);
+	StatusTypeDef M24SR_ReceiveDeselect(void);
+
+	StatusTypeDef M24SR_SendSelectApplication(void);
+	StatusTypeDef M24SR_ReceiveSelectApplication(void);
+
+	StatusTypeDef M24SR_SendSelectCCfile(void);
+	StatusTypeDef M24SR_ReceiveSelectCCfile(void);
+
+	StatusTypeDef M24SR_SendSelectNDEFfile(uint16_t NDEFfileId);
+	StatusTypeDef M24SR_ReceiveSelectNDEFfile();
+
+	StatusTypeDef M24SR_SendSelectSystemfile(void);
+	StatusTypeDef M24SR_ReceiveSelectSystemfile(void);
+
+	StatusTypeDef M24SR_SendReadBinary(uint16_t Offset, uint8_t NbByteToRead,
+			uint8_t *pBufferRead);
+	StatusTypeDef M24SR_SendSTReadBinary(uint16_t Offset, uint8_t NbByteToRead,
+				uint8_t *pBufferRead);
+	StatusTypeDef M24SR_ReceiveReadBinary(void);
+
+	StatusTypeDef M24SR_SendUpdateBinary(uint16_t Offset, uint8_t NbByteToWrite,
+			uint8_t *pDataToWrite);
+	StatusTypeDef M24SR_ReceiveUpdateBinary();
+
+	StatusTypeDef M24SR_SendVerify(uint16_t uPwdId, uint8_t NbPwdByte,
+			const uint8_t *pPwd);
+	StatusTypeDef M24SR_ReceiveVerify();
+
+	StatusTypeDef M24SR_SendChangeReferenceData(uint16_t uPwdId, uint8_t *pPwd);
+	StatusTypeDef M24SR_ReceiveChangeReferenceData();
+
+	StatusTypeDef M24SR_SendEnableVerificationRequirement(
+			uint16_t uReadOrWrite);
+	StatusTypeDef M24SR_ReceiveEnableVerificationRequirement();
+
+	StatusTypeDef M24SR_SendDisableVerificationRequirement(
+			uint16_t uReadOrWrite);
+	StatusTypeDef M24SR_ReceiveDisableVerificationRequirement();
+
+	StatusTypeDef M24SR_SendEnablePermanentState(uint16_t uReadOrWrite);
+	StatusTypeDef M24SR_ReceiveEnablePermanentState();
+
+	StatusTypeDef M24SR_SendDisablePermanentState(uint16_t uReadOrWrite);
+	StatusTypeDef M24SR_ReceiveDisablePermanentState();
+
+	StatusTypeDef M24SR_SendInterrupt(void);
+	StatusTypeDef M24SR_StateControl(uint8_t uSetOrReset);
+
+	StatusTypeDef M24SR_ManageI2CGPO(NFC_GPO_MGMT GPO_I2Cconfig);
+	StatusTypeDef M24SR_ManageRFGPO(NFC_GPO_MGMT GPO_RFconfig);
+
+	StatusTypeDef M24SR_RFConfig(uint8_t OnOffChoice);
+	StatusTypeDef M24SR_SendFWTExtension(uint8_t FWTbyte);
+
+	
+	/**
+	 * Send a command to the component.
+	 * @param NbByte Length of the command.
+	 * @param pBuffer Buffer containing the command.
+	 * @return M24SR_SUCCESS if no errors
+	 */
+	StatusTypeDef M24SR_IO_SendI2Ccommand(uint8_t NbByte, uint8_t *pBuffer);
+	
+	/**
+	 * Read a command response.
+	 * @param NbByte Number of bytes to read.
+	 * @param pBuffer Buffer to store the response into.
+	 * @return M24SR_SUCCESS if no errors
+	 */
+	StatusTypeDef M24SR_IO_ReceiveI2Cresponse(uint8_t NbByte, uint8_t *pBuffer);
+
+	/**
+	 * Do an active polling on the I2C bus until the answer is ready.
+	 * @return M24SR_SUCCESS if no errors
+	 */
+	StatusTypeDef M24SR_IO_PollI2C(void);
+
+	/**
+	 * Read the gpo pin.
+	 * @param[out] pPinState Variable to store the pin state into.
+	 */
+	void M24SR_IO_GPO_ReadPin(uint8_t *pPinState) {
+		*pPinState = GPOPin.read();
+	}
+
+	/**
+	 * Write the gpo pin.
+	 * @param pPinState Pin state to write.
+	 */
+	void M24SR_IO_RFDIS_WritePin(uint8_t PinState) {
+		if (PinState == 0) {
+			RFDisablePin = 0;
+		}
+		else {
+			RFDisablePin = 1;
+		}
+	}
+
+	/*** Component's Instance Variables ***/
+
+	/* Identity */
+	uint8_t who_am_i;
+
+	/* Type */
+	uint8_t type;
+
+	/* I2C address */
+	uint8_t address;
+
+	/* IO Device. */
+	I2C &dev_I2C;
+
+	/* GPIO */
+	DigitalIn GPOPin;
+
+	/**
+	 * Pin used to disable the rf chip functionality.
+	 */
+	DigitalOut RFDisablePin;
+
+	/**
+	 * Buffer used to build the command to send to the chip.
+	 */
+	uint8_t uM24SRbuffer[0xFF];//max command length is 255
+
+	/**
+	 * ???
+	 */
+	uint8_t uDIDbyte;
+
+
+	/**
+	 * Command that the component can accept
+	 */
+	typedef enum{
+		NONE,                            //!< NONE
+		DESELECT,                        //!< DESELECT
+		SELECT_APPLICATION,              //!< SELECT_APPLICATION
+		SELECT_CC_FILE,                  //!< SELECT_CC_FILE
+		SELECT_NDEF_FILE,                //!< SELECT_NDEF_FILE
+		SELECT_SYSTEM_FILE,              //!< SELECT_SYSTEM_FILE
+		READ,                            //!< READ
+		UPDATE,                          //!< UPDATE
+		VERIFY,                          //!< VERIFY
+		MANAGE_I2C_GPO,                  //!< MANAGE_I2C_GPO
+		MANAGE_RF_GPO,                   //!< MANAGE_RF_GPO
+		CHANGE_REFERENCE_DATA,           //!< CHANGE_REFERENCE_DATA
+		ENABLE_VERIFICATION_REQUIREMENT, //!< ENABLE_VERIFICATION_REQUIREMENT
+		DISABLE_VERIFICATION_REQUIREMENT,//!< DISABLE_VERIFICATION_REQUIREMENT
+		ENABLE_PERMANET_STATE,           //!< ENABLE_PERMANET_STATE
+		DISABLE_PERMANET_STATE,          //!< DISABLE_PERMANET_STATE
+	}M24SR_command_t;
+
+	/**
+ 	 * User parameter used to invoke a command,
+ 	 * it is used to provide the data back with the response
+	 */
+	typedef struct{
+		uint8_t *data; //!< data
+		uint16_t length; //!< number of bytes in the data array
+		uint16_t offset; //!< offset parameter used in the read/write command
+	}M24SR_command_data_t;
+
+	/**
+	 * Communication mode used by this device
+	 */
+	typedef enum{
+		SYNC,//!< SYNC wait the command response before returning
+		ASYNC//!< ASYNC use a callback to notify the end of a command
+	}M24SR_communication_t;
+
+	/**
+	 * Type of communication being used
+	 */
+	M24SR_communication_t mCommunicationType;
+
+	/**
+	 * Last pending command
+	 */
+	M24SR_command_t mLastCommandSend;
+
+	/**
+	 * Parameter used to invoke the last command
+	 */
+	M24SR_command_data_t mLastCommandData;
+
+	/**
+	 * Interrupt object fired when the gpo status changes
+	 */
+	InterruptIn mGpoEventInterrupt;
+
+	/** object containing the callbacks to use*/
+	Callbacks *mCallback;
+
+	/**
+	 * Object with private callbacks used to hide high level commands each
+	 * calling multiple low level commands. This callbacks object has
+	 * higher priority comparing to the user callbacks.
+	 */
+	Callbacks *mComponentCallback;
+
+	/**
+	 * Object implementing the interface to use the NDefLib.
+	 */
+	NDefNfcTagM24SR *mNDefTagUtil;
+
+	/**
+	 * get the callback object to use
+	 * @return callback object to use
+	 */
+	Callbacks * getCallback() {
+		if (mComponentCallback != NULL) {
+			return mComponentCallback;
+		}
+		return mCallback;
+	}//getCallback
+
+private:
+	/** object containing empty callback to use in the default case*/
+	Callbacks defaultCallback;
+
+
+	/**
+	 * This class permits to enable/disable the password request to read/write into the tag
+	 * This class is equivalent to calling the methods:
+	 * To enable the request:
+	 * <ul>
+	 *   <li> Verify </li>
+	 *   <li> ChangeReferenceData </li>
+	 *   <li> EnablePermanentState </li>
+	 * </ul>
+	 * To disable the request:
+	 * <ul>
+	 *   <li> Verify </li>
+	 *   <li> disable_verification_requirement </li>
+	 * </ul>
+	 */
+	class ChangePasswordRequestStatusCallback : public Callbacks {
+
+		public:
+
+			/**
+			 * Build the chain of callbacks.
+			 */
+			ChangePasswordRequestStatusCallback():
+				mNewPwd(NULL), mType(I2CPwd),mEnable(false) {}
+
+			/**
+			 * Set the password to enable/disable.
+			 * @param type Type of password to enable/disable.
+			 * @param newPwd Array of 16bytes with the new password, if null the request will be disabled.
+			 */
+			void set_task(PasswordType_t type, const uint8_t *newPwd) {
+				mNewPwd=newPwd;
+				mType=type;
+				mEnable=newPwd!=NULL;
+			}//setTask
+
+			virtual void on_verified(M24SR *nfc, StatusTypeDef status,PasswordType_t ,
+					const uint8_t *) {
+				if (status!=M24SR_SUCCESS) {
+					return onFinishCommand(nfc,status);
+				}
+				if (mEnable) {
+					nfc->change_reference_data(mType,mNewPwd);
+				} else {
+					nfc->disable_verification_requirement(mType);
+				}
+			}
+
+			virtual void on_disable_verification_requirement(M24SR *nfc,
+					StatusTypeDef status, PasswordType_t ) {
+				onFinishCommand(nfc,status);
+			}
+
+			virtual void on_change_reference_data(M24SR *nfc, StatusTypeDef status,
+					PasswordType_t type,
+					uint8_t *) {
+				if (status==M24SR_SUCCESS) {
+					nfc->enable_permanent_state(type);
+				} else {
+					onFinishCommand(nfc,status);
+				}
+			}
+
+			virtual void on_enable_permanent_state(M24SR *nfc, StatusTypeDef status,
+					PasswordType_t ) {
+				onFinishCommand(nfc,status);
+			}
+
+
+		private:
+
+			/**
+			 * Remove the private callbacks and call the user callback.
+			 * @param nfc Object triggering the command.
+			 * @param status Command status.
+			 */
+			void onFinishCommand(M24SR *nfc,StatusTypeDef status) {
+				nfc->mComponentCallback=NULL;
+
+				if (mEnable) {
+					if (mType==ReadPwd) {
+						nfc->getCallback()->on_enable_read_password(nfc,status,mNewPwd);
+					} else {
+						nfc->getCallback()->on_enable_write_password(nfc,status,mNewPwd);
+					}
+				} else {
+					if (mType==ReadPwd) {
+						nfc->getCallback()->on_disable_read_password(nfc,status);
+					} else {
+						nfc->getCallback()->on_disable_write_password(nfc,status);
+					}
+				}//if-else enable
+			}//onFinish
+
+			const uint8_t *mNewPwd;
+			PasswordType_t mType;
+			bool mEnable;
+
+	};
+
+	/**
+	 * Object containing the callback chain needed to change the password request
+	 */
+	ChangePasswordRequestStatusCallback mChangePasswordRequestStatusCallback;
+	friend class ChangePasswordRequestStatusCallback;
+
+	/**
+	 * This class permits to disable all the password requests to read/write into the tag
+	 * This class is equivalent to calling the methods:
+	 * <ul>
+	 *   <li> Verify(i2c) </li>
+	 *   <li> DisablePermanentState(Read) </li>
+	 *   <li> DisablePermanentState(write) </li>
+	 *   <li> disable_verification_requirement(Read) </li>
+	 *   <li> disable_verification_requirement(write) </li>
+	 *   <li> ChangeReferenceData(Read) </li>
+	 *   <li> ChangeReferenceData(write) </li>
+	 * </ul>
+	 */
+	class RemoveAllPasswordCallback : public Callbacks{
+
+		/**
+		 * Store the default password used for open a super user session
+		 * it will be set as default read/write password
+		 */
+		const uint8_t *mI2CPwd;
+
+		public:
+
+			/**
+			 * Build the chain of callbacks.
+			 */
+			RemoveAllPasswordCallback():mI2CPwd(NULL) {}
+
+			virtual void on_verified(M24SR *nfc,StatusTypeDef status,
+					PasswordType_t,const uint8_t* data) {
+				if (status!=M24SR_SUCCESS) {
+					return onFinishCommand(nfc,status);
+				}
+				mI2CPwd = data;
+				nfc->disable_permanent_state(ReadPwd);
+			}
+
+			virtual void on_disable_permanent_state(M24SR *nfc , StatusTypeDef status,
+					PasswordType_t type) {
+				if (status!=M24SR_SUCCESS) {
+					return onFinishCommand(nfc,status);
+				}
+				if (type==ReadPwd) {
+					nfc->disable_permanent_state(WritePwd);
+				} else {
+					nfc->disable_verification_requirement(ReadPwd);
+				}
+			}
+
+			virtual void on_disable_verification_requirement(M24SR *nfc ,
+					StatusTypeDef status,PasswordType_t type) {
+				if (status!=M24SR_SUCCESS) {
+					return onFinishCommand(nfc,status);
+				}
+				if (type==ReadPwd) {
+					nfc->disable_verification_requirement(WritePwd);
+				} else {
+					nfc->change_reference_data(ReadPwd,mI2CPwd);
+				}
+			}
+
+			virtual void on_change_reference_data(M24SR *nfc ,StatusTypeDef status,PasswordType_t type,
+					uint8_t *data) {
+				if (status!=M24SR_SUCCESS) {
+					return onFinishCommand(nfc,status);
+				}
+				if (type==ReadPwd) {
+					nfc->change_reference_data(WritePwd,data);
+				} else {
+					onFinishCommand(nfc,status);
+				}
+			}
+
+		private:
+
+			/**
+			 * Remove the private callback and call the onDisableAllPassword callback.
+			 * @param nfc Object triggering the command.
+			 * @param status Command status.
+			 */
+			void onFinishCommand(M24SR *nfc,StatusTypeDef status) {
+				nfc->mComponentCallback=NULL;
+				mI2CPwd=NULL;
+				nfc->getCallback()->on_disable_all_password(nfc,status);
+			}//onFinish
+
+	};
+
+
+	/**
+	 * Object containing the callback chain needed to remove the password request
+	 */
+	RemoveAllPasswordCallback mRemoveAllPasswordCallback;
+	friend class RemoveAllPasswordCallback;
+
+	/**
+	 * This class permits to set the tag as read/write only
+	 * This class is equivalent to calling the methods:
+	 * <ul>
+	 *   <li> Verify(i2c) </li>
+	 *   <li> EnablePermanentState(Read/write) </li>
+	 * </ul>
+	 * or:
+	 * <ul>
+	 *   <li> Verify(i2c) </li>
+	 *   <li> DisablePermanentState</li>
+	 *   <li> disable_verification_requirement(Read/write) </li>
+	 * </ul>
+	 */
+	class ChangeAccessStateCallback : public Callbacks{
+
+		public:
+
+			typedef enum{
+				WRITE,
+				READ
+			}AccessType_t;
+
+			/**
+			 * Build the chain of callbacks.
+			 */
+			ChangeAccessStateCallback():mType(WRITE),mEnable(false) {}
+
+			/**
+			 * Set the access to enable/disable an access type.
+			 * @param type Access type.
+			 * @param enable True to enable the state, False to disable it.
+			 */
+			void change_access_state(AccessType_t type,bool enable) {
+				mType=type;
+				mEnable=enable;
+			}
+
+			virtual void on_verified(M24SR *nfc,StatusTypeDef status,
+					PasswordType_t,const uint8_t*) {
+				if (status!=M24SR_SUCCESS){
+					return onFinishCommand(nfc,status);
+				}
+
+				if (mEnable) {
+					nfc->disable_permanent_state(mType==WRITE? WritePwd : ReadPwd);
+				} else {
+					nfc->enable_permanent_state(mType==WRITE? WritePwd : ReadPwd);
+				}
+
+			}
+
+			virtual void on_disable_permanent_state(M24SR *nfc, StatusTypeDef status,
+					PasswordType_t type ) {
+				if (status!=M24SR_SUCCESS) {
+					return onFinishCommand(nfc,status);
+				}
+
+				nfc->disable_verification_requirement(type);
+			}
+
+			virtual void on_disable_verification_requirement(M24SR *nfc , StatusTypeDef status, PasswordType_t ) {
+				onFinishCommand(nfc,status);
+			}
+
+			virtual void on_enable_permanent_state(M24SR *nfc ,StatusTypeDef status,PasswordType_t ) {
+				onFinishCommand(nfc,status);
+			}
+
+
+		private:
+
+			/**
+			 * Remove the private callback and call the user callback.
+			 * @param nfc Object triggering the command.
+			 * @param status Command status.
+			 */
+			void onFinishCommand(M24SR *nfc,StatusTypeDef status) {
+				nfc->mComponentCallback=NULL;
+				if (mEnable) {
+					if (mType==READ) {
+						//enable read = disable write only
+						nfc->getCallback()->on_disable_write_only(nfc,status);
+					} else {
+						//enable write = disable read only
+						nfc->getCallback()->on_disable_read_only(nfc,status);
+					}
+				} else {
+					if (mType==WRITE) {
+						//disable write = enable read only
+						nfc->getCallback()->on_enable_read_only(nfc,status);
+					} else {
+						//
+						nfc->getCallback()->on_enable_write_only(nfc,status);
+					}
+				}//if-else enable
+			}//onFinish
+
+			AccessType_t mType;
+			bool mEnable;
+	};
+
+
+	/**
+	 * Object containing the callback chain needed to change the access state
+	 */
+	ChangeAccessStateCallback mChangeAccessStateCallback;
+	friend class ChangeAccessStateCallback;
+
+
+	/**
+	 * Object with the callback used to send a ManageGPO command.
+	 * This class is equivalent to calling the methods:
+	 * <ul>
+	 *   <li> SelectedApplication </li>
+	 *   <li> SelectSystemfile </li>
+	 *   <li> ReadBinar: read the old value </li>
+	 *   <li> onVerified </li>
+	 *   <li> onUpdatedBinary: write the new value</li>
+	 * </ul>
+	 */
+	class ManageGPOCallback : public Callbacks{
+
+	public:
+
+		/**
+		 * Build the chain of callbacks.
+		 * @param parent Parent component to run the command on.
+		 */
+		ManageGPOCallback(M24SR &parent):mParent(parent),
+				mGpoConfig(HIGH_IMPEDANCE),mReadGpoConfig(0),mI2CGpo(true) {}
+
+
+		/**
+		 * Command parameters.
+		 * @param i2cGpo true to change the i2c gpo, false for the rf gpo.
+		 * @param newConfig new gpo function.
+		 */
+		void set_new_GPO_config(bool i2cGpo,NFC_GPO_MGMT newConfig) {
+			mGpoConfig=newConfig;
+			mI2CGpo =i2cGpo;
+		}
+
+		virtual void on_selected_application(M24SR *nfc,StatusTypeDef status) {
+			if (status==M24SR_SUCCESS) {
+				nfc->select_system_file();
+			} else {
+				onFinishCommand(nfc,status);
+			}
+		}
+
+		virtual void on_selected_system_file(M24SR *nfc,StatusTypeDef status) {
+			if (status==M24SR_SUCCESS) {
+				nfc->read_binary(0x0004, 0x01, &mReadGpoConfig);
+			} else {
+				onFinishCommand(nfc,status);
+			}
+		}
+
+		virtual void on_read_byte(M24SR *nfc,StatusTypeDef status,
+				uint16_t,uint8_t*, uint16_t ) {
+			if (status==M24SR_SUCCESS) {
+				nfc->verify(M24SR::I2CPwd, 0x10, M24SR::DEFAULT_PASSWORD);
+			} else {
+				onFinishCommand(nfc,status);
+			}
+		}
+
+		virtual void on_verified(M24SR *nfc,StatusTypeDef status,PasswordType_t, const uint8_t*) {
+			if (status!=M24SR_SUCCESS) {
+				return onFinishCommand(nfc,status);
+			}
+
+			if (mI2CGpo) {
+				mReadGpoConfig = (mReadGpoConfig & 0xF0) | (uint8_t)mGpoConfig;
+			} else {
+				mReadGpoConfig = (mReadGpoConfig & 0x0F) | (((uint8_t)mGpoConfig)<<4);
+			}
+
+			nfc->update_binary(0x0004, 0x01, &mReadGpoConfig);
+		}
+
+		virtual void on_updated_binary(M24SR *nfc,StatusTypeDef status,
+				uint16_t , uint8_t*, uint16_t ) {
+
+			if (status==M24SR_SUCCESS) {
+				if (mGpoConfig == I2C_ANSWER_READY) {
+					mParent.mCommunicationType = ASYNC;
+				} else {
+					mParent.mCommunicationType = SYNC;
+				}//if-else
+			}//status
+			onFinishCommand(nfc,status);
+		}
+
+	private:
+
+		/**
+		 * Remove the private callback and call the user callback.
+		 * @param nfc Object where the command was send to.
+		 * @param status Command status.
+		 */
+		void onFinishCommand(M24SR *nfc,StatusTypeDef status) {
+			mParent.mComponentCallback=NULL;
+			if (mI2CGpo) {
+				mParent.mCallback->on_manage_I2C_GPO(nfc,status,mGpoConfig);
+			} else {
+				mParent.mCallback->on_manage_RF_GPO(nfc,status,mGpoConfig);
+			}//if-else
+		}//onFinishCommand
+
+		/**
+		 * Component where send the commands
+		 */
+		M24SR &mParent;
+
+		/** new gpo function that this class has to write */
+		NFC_GPO_MGMT mGpoConfig;
+
+		/**
+		 * variable where storeing the read gpo configuration
+		 */
+		uint8_t mReadGpoConfig;
+
+		/**
+		 * true to change the i2c gpo, false to change the rf gpo
+		 */
+		bool mI2CGpo;
+
+	};
+
+	/**
+	 * Object containing the callback chain needed to change the gpo function
+	 */
+	ManageGPOCallback mManageGPOCallback;
+
+	/**
+	 * Object with the callback used to read the component ID
+	 * This class is equivalent to calling the methods:
+	 * <ul>
+	 *   <li> SelectedApplication </li>
+	 *   <li> SelectSystemfile </li>
+	 *   <li> read_binary </li>
+	 * </ul>
+	 */
+	class ReadIDCallback : public Callbacks {
+
+		public:
+
+			/**
+			 * Build the chain of callbacks.
+			 * @param parent object where to send the command to.
+			 */
+			ReadIDCallback(M24SR &parent):mParent(parent),mIdPtr(NULL) {}
+
+			/**
+			 * Set the variable containing the result
+			 * @param idPtr
+			 */
+			void read_id_on(uint8_t *idPtr) {
+				mIdPtr = idPtr;
+			}
+
+			virtual void on_selected_application(M24SR *nfc,StatusTypeDef status) {
+				if (status==M24SR_SUCCESS) {
+					nfc->select_system_file();
+				} else {
+					onFinishCommand(nfc,status);
+				}
+
+			}
+
+			virtual void on_selected_system_file(M24SR *nfc,StatusTypeDef status) {
+				if (status==M24SR_SUCCESS) {
+					nfc->read_binary(0x0011, 0x01, mIdPtr);
+				} else {
+					onFinishCommand(nfc,status);
+				}
+			}
+
+			virtual void on_read_byte(M24SR *nfc,StatusTypeDef status,
+				uint16_t ,uint8_t *, uint16_t ) {
+				onFinishCommand(nfc,status);
+			}
+
+		private:
+
+			/**
+			 * Remove the private callback and call the user onReadId function.
+			 * @param nfc Object where the command was send.
+			 * @param status Command status.
+			 */
+			void onFinishCommand(M24SR *nfc,StatusTypeDef status) {
+				mParent.mComponentCallback=NULL;
+				mParent.getCallback()->on_read_id(nfc,status,mIdPtr);
+			}
+
+			M24SR& mParent;
+
+			/**
+			 * pointer to read id
+			 */
+			uint8_t *mIdPtr;
+	};
+
+
+	/**
+	 * Object containing the callback chain needed to read the component id
+	 */
+	ReadIDCallback mReadIDCallback;
+	friend class ReadIDCallback;
+
+	/**
+	 * Convert a generic enum to the value used by the M24SR chip.
+	 * @param type Password type.
+	 * @return equivalent value used inside the m24sr chip */
+	uint16_t passwordTypeToConst(const PasswordType_t &type) const {
+		switch (type) {
+			case ReadPwd:
+				return READ_PWD;
+			case WritePwd:
+				return WRITE_PWD;
+			case I2CPwd:
+			default:
+				return I2C_PWD;
+		}//switch
+	}//passwordTypeToConst
+	
+	/**
+	 * convert  a uint16 into an enum value
+	 * @param type
+	 * @return
+	 */
+	PasswordType_t constToPasswordType(const uint16_t type)const{
+		switch(type) {
+			case READ_PWD:
+				return ReadPwd;
+			case WRITE_PWD:
+				return WritePwd;
+			case I2C_PWD:
+			default:
+				return I2CPwd;
+		}//switch
+	}//passwordTypeToConst
+};
+
+#endif // __M24SR_CLASS_H
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 11161008d77a NDefNfcTagM24SR.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NDefNfcTagM24SR.cpp	Mon Jul 31 12:26:02 2017 +0000
@@ -0,0 +1,185 @@
+/**
+  ******************************************************************************
+  * @file       NdefNfcTagSTM24SR.cpp
+  * @author  	ST Central Labs
+  * @version 	V2.0.0
+  * @date    	28 Apr 2017
+  * @brief      Wrapper class of the NDefLib library to write/read NDEF messages
+  ******************************************************************************
+  * @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 <cmath>
+
+#include "NDefNfcTagM24SR.h"
+
+
+/* wait 1sec, driver is configured to let 200ms for command to complete */
+/* which is enough for all commands except GetSession if RF session is already opened */
+/* Smartphone generally releases the session within the second, anyway the user can modify this value */
+#define OPENSESSION_NTRIALS 5
+
+#define CC_FILE_LENGTH_BYTE 15
+////////////////////////////START  OpenSessionCallBack/////////////////////////
+NDefNfcTagM24SR::OpenSessionCallBack::
+	OpenSessionCallBack(NDefNfcTagM24SR& sender):
+		mSender(sender), mNTrials(OPENSESSION_NTRIALS){}
+
+void NDefNfcTagM24SR::OpenSessionCallBack::on_session_open(M24SR *nfc, M24SR::StatusTypeDef status) {
+	if (status==M24SR::M24SR_SUCCESS) {
+		nfc->select_application();
+	} else {
+		mSender.mCallBack->on_session_open(&mSender,false);
+	}
+}
+
+void NDefNfcTagM24SR::OpenSessionCallBack::on_selected_application(M24SR *nfc, M24SR::StatusTypeDef status) {
+	if (status==M24SR::M24SR_SUCCESS) {
+		nfc->select_CC_file();
+	} else {
+		if (mNTrials==0) {
+			mSender.mCallBack->on_session_open(&mSender,false);
+		} else {
+			mNTrials--;
+			nfc->select_application();
+		}//if-else
+	}//if-else
+}
+
+void NDefNfcTagM24SR::OpenSessionCallBack::on_selected_CC_file(M24SR *nfc, M24SR::StatusTypeDef status) {
+	if (status==M24SR::M24SR_SUCCESS) {
+		nfc->read_binary(0x0000, CC_FILE_LENGTH_BYTE, CCFile);
+	} else {
+		mSender.mCallBack->on_session_open(&mSender,false);
+	}
+}
+
+void NDefNfcTagM24SR::OpenSessionCallBack::on_read_byte(M24SR *nfc, M24SR::StatusTypeDef status, uint16_t offset, uint8_t *readByte, uint16_t nReadByte) {
+	(void)offset;
+	if (status!=M24SR::M24SR_SUCCESS || nReadByte!=CC_FILE_LENGTH_BYTE) {
+		return mSender.mCallBack->on_session_open(&mSender,false);
+	}//else
+	uint16_t NDefFileId = (uint16_t) ((readByte[0x09] << 8) | readByte[0x0A]);
+	mSender.mMaxReadBytes = (uint16_t) ((readByte[0x03] << 8) | readByte[0x04]);
+	mSender.mMaxWriteBytes = (uint16_t) ((readByte[0x05] << 8) | readByte[0x06]);
+	nfc->select_NDEF_file(NDefFileId);
+}
+
+void NDefNfcTagM24SR::OpenSessionCallBack::on_selected_NDEF_file(M24SR *nfc, M24SR::StatusTypeDef status){
+	(void)nfc;
+
+	mSender.mIsSessionOpen = status==M24SR::M24SR_SUCCESS;
+	mSender.mCallBack->on_session_open(&mSender,mSender.mIsSessionOpen);
+}
+////////////////////////////END  OpenSessionCallBack/////////////////////////
+
+bool NDefNfcTagM24SR::open_session(bool force) {
+
+	if (is_session_open()) {
+		mCallBack->on_session_open(this,true);
+		return true;
+	}
+
+	mDevice.set_callback(&mOpenSessionCallback);
+	if (force) {
+		return mDevice.force_get_session() == M24SR::M24SR_SUCCESS;
+	} else {
+		return mDevice.get_session() == M24SR::M24SR_SUCCESS;
+	}
+}
+
+bool NDefNfcTagM24SR::close_session() {
+	mDevice.set_callback(&mCloseSessionCallback);
+	return mDevice.deselect() == M24SR::M24SR_SUCCESS;
+}
+
+void NDefNfcTagM24SR::WriteByteCallback::on_updated_binary(M24SR *nfc,
+	M24SR::StatusTypeDef status,uint16_t startOffset, uint8_t *writeByte,uint16_t nWriteByte){
+
+	if (status!=M24SR::M24SR_SUCCESS){ // error -> finish to write
+		mCallback(mCallbackParam,false,mByteToWrite,mNByteToWrite);
+		return;
+	}//else
+
+	mByteWrote+=nWriteByte;
+	if (mByteWrote==mNByteToWrite) { //write all -> finish
+		mCallback(mCallbackParam,true,mByteToWrite,mNByteToWrite);
+	} else { //else write another slice
+		uint16_t tempLenght = std::min(mSender.mMaxWriteBytes, (uint16_t)(mNByteToWrite-mByteWrote));
+		nfc->update_binary(startOffset+nWriteByte,tempLenght,writeByte+nWriteByte);
+	}//if-else
+}
+
+bool NDefNfcTagM24SR::writeByte(const uint8_t *buffer, uint16_t length,uint16_t offset,
+	byteOperationCallback_t callback,CallbackStatus_t *callbackStatus){
+	if (!is_session_open())
+		callback(callbackStatus,false,buffer,length);
+	//else
+	mWriteByteCallback.set_task(buffer,length,callback,callbackStatus);
+	mDevice.set_callback(&mWriteByteCallback);
+
+	if (length > mMaxWriteBytes) {
+		return mDevice.update_binary(offset, mMaxWriteBytes,(uint8_t*) buffer) == M24SR::M24SR_SUCCESS;
+	} else {
+		return mDevice.update_binary(offset,length,(uint8_t*)buffer) == M24SR::M24SR_SUCCESS;
+	}//if-else
+}
+
+void NDefNfcTagM24SR::ReadByteCallback::on_read_byte(M24SR *nfc,
+	M24SR::StatusTypeDef status,uint16_t startOffset, uint8_t *readBffer,uint16_t nReadByte){
+
+	if (status!=M24SR::M24SR_SUCCESS) { // error -> finish to write
+		mCallback(mCallbackParam,false,mBuffer,mNByteToRead);
+		return;
+	}//else
+
+	mByteRead += nReadByte;
+	if (mByteRead==mNByteToRead) { //read all -> finish
+		mCallback(mCallbackParam,true,mBuffer,mNByteToRead);
+	} else { //else write another slice
+		uint16_t tempLenght = std::min(mSender.mMaxReadBytes, (uint16_t)(mNByteToRead-mByteRead));
+		nfc->read_binary(startOffset+nReadByte,tempLenght,readBffer+nReadByte);
+	}//if-else
+}
+
+bool NDefNfcTagM24SR::readByte(const uint16_t byteOffset, const uint16_t length,
+	uint8_t *buffer, byteOperationCallback_t callback,CallbackStatus_t *callbackStatus) {
+	if (!is_session_open()) {
+		return callback(callbackStatus,false,buffer,length);
+	}
+	//else
+	mReadByteCallback.set_task(buffer,length,callback,callbackStatus);
+	mDevice.set_callback(&mReadByteCallback);
+
+	if (length > mMaxReadBytes) {
+		return mDevice.read_binary(byteOffset, mMaxReadBytes,buffer)== M24SR::M24SR_SUCCESS;;
+	} else {
+		return mDevice.read_binary(byteOffset,length,buffer)== M24SR::M24SR_SUCCESS;;
+	}//if-else
+}
diff -r 000000000000 -r 11161008d77a NDefNfcTagM24SR.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NDefNfcTagM24SR.h	Mon Jul 31 12:26:02 2017 +0000
@@ -0,0 +1,311 @@
+/**
+  ******************************************************************************
+  * @file       Type4NfcTagM24SR.h
+  * @author  	ST Central Labs
+  * @version 	V2.0.0
+  * @date    	28 Apr 2017
+  * @brief      M24SR specific NDefLib derived class
+  ******************************************************************************
+  * @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_NFC01A1_M24SR_NDEFNFCTAGM24SR_H_
+#define X_NUCLEO_NFC01A1_M24SR_NDEFNFCTAGM24SR_H_
+
+#include <cstdlib>
+#include <stdint.h>
+
+#include "NDefLib/NDefNfcTag.h"
+
+#include "M24SR.h"
+
+/**
+ * Helper class to use the NDefLib
+ */
+class NDefNfcTagM24SR: public NDefLib::NDefNfcTag {
+
+public:
+
+	/**
+	 *
+	 * @param device device to use
+	 */
+	NDefNfcTagM24SR(M24SR &device):
+		NDefLib::NDefNfcTag(),
+		mDevice(device),mIsSessionOpen(false),
+		mMaxReadBytes(0xFF), mMaxWriteBytes(0xFF),
+		mOpenSessionCallback(*this),
+		mCloseSessionCallback(*this),
+		mWriteByteCallback(*this),
+		mReadByteCallback(*this){}
+
+	virtual bool open_session(bool force = false);
+
+	virtual bool close_session();
+
+	virtual bool is_session_open(){
+		return mIsSessionOpen;
+	}
+
+	/**
+	* Close the open session.
+	*/
+	virtual ~NDefNfcTagM24SR() {
+		if (is_session_open()) {
+			close_session();
+		}
+	}//~NDefNfcTagM24SR
+
+	protected:
+
+		virtual bool writeByte(const uint8_t *buffer, uint16_t length,uint16_t offset,
+			byteOperationCallback_t callback,CallbackStatus_t *callbackStatus);
+
+		virtual bool readByte(const uint16_t byteOffset, const uint16_t byteLength,
+			uint8_t *buffer, byteOperationCallback_t callback,CallbackStatus_t *callbackStatus);
+
+	private:
+
+		M24SR &mDevice;
+
+		/**
+		 * true if the session is open
+		 */
+		bool mIsSessionOpen;
+
+		/**
+		* Max length for a read operation
+		*/
+		uint16_t mMaxReadBytes;
+
+		/**
+		* Max length for a write operation
+		*/
+		uint16_t mMaxWriteBytes;
+
+		/**
+		 * Class containing the callback needed to open a session and read the max
+		 * read/write size
+		 */
+		class OpenSessionCallBack: public M24SR::Callbacks{
+			public:
+				OpenSessionCallBack(NDefNfcTagM24SR &sender);
+
+				virtual void on_session_open(M24SR *nfc,M24SR::StatusTypeDef status);
+				virtual void on_selected_application(M24SR *nfc,M24SR::StatusTypeDef status);
+				virtual void on_selected_CC_file(M24SR *nfc,M24SR::StatusTypeDef status);
+				virtual void on_read_byte(M24SR *nfc,M24SR::StatusTypeDef status,uint16_t offset,
+						uint8_t *readByte, uint16_t nReadByte);
+				virtual void on_selected_NDEF_file(M24SR *nfc,M24SR::StatusTypeDef status);
+
+			private:
+				/**
+				 * Object that send the open session callback
+				 */
+				NDefNfcTagM24SR &mSender;
+
+				/**
+				 * number of trials done for open the session
+				 */
+				uint32_t mNTrials;
+
+				/**
+				 * buffer where read the CC file
+				 */
+				uint8_t CCFile[15];
+		};
+
+		OpenSessionCallBack mOpenSessionCallback;
+		friend class OpenSessionCallBack;
+
+		/**
+		 * Class containing the callback needed to close a session
+		 */
+		class CloseSessionCallBack : public M24SR::Callbacks{
+			public:
+				CloseSessionCallBack(NDefNfcTagM24SR &sender):
+					mSender(sender){}
+
+				virtual void on_deselect(M24SR *nfc,M24SR::StatusTypeDef status){
+					(void)nfc;
+					if (status==M24SR::M24SR_SUCCESS) {
+						mSender.mIsSessionOpen = false;
+						mSender.mCallBack->on_session_close(&mSender,true);
+					} else {
+						mSender.mCallBack->on_session_close(&mSender,false);
+					}//if-else
+				}
+			private:
+
+				/**
+				 * Object that send the open session callback
+				 */
+				NDefNfcTagM24SR &mSender;
+		};
+
+		CloseSessionCallBack mCloseSessionCallback;
+		friend class OpenSessionCallBack;
+
+		/**
+		 * Class containing the callback needed to write a buffer
+		 */
+		class WriteByteCallback : public M24SR::Callbacks{
+			public:
+
+				/**
+				 *
+				 * @param sender tag where write the buffer
+				 */
+				WriteByteCallback(NDefNfcTagM24SR &sender):
+								  mByteToWrite(NULL),
+								  mNByteToWrite(0),
+								  mByteWrote(0),
+								  mCallback(NULL),
+								  mCallbackParam(NULL),
+								  mSender(sender){}
+
+				/**
+				 * Set the buffer to write and the function to call when finish
+				 * @param buffer Buffer to write.
+				 * @param nByte Number of bytes to write.
+				 * @param callback Function to call when the write ends.
+				 * @param param Parameter to pass to the callback function.
+				 */
+				void set_task(const uint8_t *buffer,uint16_t nByte,
+					byteOperationCallback_t callback,CallbackStatus_t *param) {
+					mByteToWrite=buffer;
+					mNByteToWrite=nByte;
+					mByteWrote=0;
+					mCallback = callback;
+					mCallbackParam = param;
+				}
+
+				virtual void on_updated_binary(M24SR *nfc,M24SR::StatusTypeDef status,
+					uint16_t startOffset,uint8_t *writeByte,uint16_t nWriteByte);
+
+
+			private:
+
+				/** buffer to write */
+				const uint8_t *mByteToWrite;
+				/** length of the buffer */
+				uint16_t mNByteToWrite;
+				/** number of byte already wrote */
+				uint16_t mByteWrote;
+
+				/** function to call when all the bytes are write */
+				byteOperationCallback_t mCallback;
+				/** parameter to pass to the callback function*/
+				CallbackStatus_t* mCallbackParam;
+
+				/** tag where write the buffer*/
+				NDefNfcTagM24SR &mSender;
+		};
+
+		WriteByteCallback mWriteByteCallback;
+		friend class WriteByteCallback;
+
+		/**
+		 * Class containing the callback needed to read a buffer
+		 */
+		class ReadByteCallback : public M24SR::Callbacks{
+			public:
+
+				/**
+				 *
+				 * @param Sender tag where read the buffer
+				 */
+				ReadByteCallback(NDefNfcTagM24SR &sender):
+								 mBuffer(NULL),
+								 mNByteToRead(0),
+								 mByteRead(0),
+								 mCallback(NULL),
+								 mCallbackParam(NULL),
+								 mSender(sender){}
+
+				/**
+				 * Set the buffer where read the data and the function to call when finish
+				 * @param buffer Buffer read
+				 * @param nByte Number of bytes to read
+				 * @param callback Function to call when the read ends
+				 * @param param Parameter to pass to the callback function
+				 */
+				void set_task(uint8_t *buffer,uint16_t nByte,
+					byteOperationCallback_t callback,CallbackStatus_t *param){
+					mBuffer=buffer;
+					mNByteToRead=nByte;
+					mByteRead=0;
+					mCallback = callback;
+					mCallbackParam = param;
+				}
+
+				virtual void on_read_byte(M24SR *nfc,M24SR::StatusTypeDef status,
+					uint16_t offset,uint8_t *readByte, uint16_t nReadByte);
+
+
+			private:
+
+				/**
+				 * Buffer where read the data
+				 */
+				uint8_t *mBuffer;
+
+				/**
+				 * Number of bytes to read
+				 */
+				uint16_t mNByteToRead;
+
+				/**
+				 * Number of bytes already read
+				 */
+				uint16_t mByteRead;
+
+				/**
+				 * Function to call when all the bytes are read
+				 */
+				byteOperationCallback_t mCallback;
+
+				/**
+				 * Parameter to pass to the callback function
+				 */
+				CallbackStatus_t* mCallbackParam;
+
+				/**
+				 * Tag where the data are read
+				 */
+				NDefNfcTagM24SR &mSender;
+		};
+
+		ReadByteCallback mReadByteCallback;
+		friend class ReadByteCallback;
+
+
+};
+
+#endif /* X_NUCLEO_NFC01A1_M24SR_NDEFNFCTAGM24SR_H_ */
diff -r 000000000000 -r 11161008d77a ST_INTERFACES.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ST_INTERFACES.lib	Mon Jul 31 12:26:02 2017 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/ST/code/ST_INTERFACES/#d3c9b33b992c
diff -r 000000000000 -r 11161008d77a m24sr_def.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/m24sr_def.h	Mon Jul 31 12:26:02 2017 +0000
@@ -0,0 +1,282 @@
+/**
+ ******************************************************************************
+ * @file    m24sr.h
+ * @author  MMY Application Team
+ * @version V2.0.0
+ * @date    28 Apr 2017
+ * @brief   This file provides a set of functions needed to manage M24SR
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MMY-ST Liberty SW License Agreement V2, (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/software_license_agreement_liberty_v2
+ *
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __DRV_M24SR_H
+#define __DRV_M24SR_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "Nfc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup M24SR_Driver
+ * @{
+ */
+
+/** @addtogroup drv_M24SR
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief  APDU-Header command structure
+ */
+typedef struct {
+	uint8_t CLA; /* Command class */
+	uint8_t INS; /* Operation code */
+	uint8_t P1; /* Selection Mode */
+	uint8_t P2; /* Selection Option */
+} C_APDU_Header;
+
+/**
+ * @brief  APDU-Body command structure
+ */
+typedef struct {
+	uint8_t LC; /* Data field length */
+	const uint8_t *pData; /* Command parameters */
+	uint8_t LE; /* Expected length of data to be returned */
+} C_APDU_Body;
+
+/**
+ * @brief  APDU Command structure
+ */
+typedef struct {
+	C_APDU_Header Header;
+	C_APDU_Body Body;
+} C_APDU;
+
+/**
+ * @brief  SC response structure
+ */
+typedef struct {
+	uint8_t *pData; /* Data returned from the card */ // pointer on the transceiver buffer = ReaderRecBuf[CR95HF_DATA_OFFSET ];
+	uint8_t SW1; /* Command Processing status */
+	uint8_t SW2; /* Command Processing qualification */
+} R_APDU;
+
+/**
+ * @brief  GPO mode structure
+ */
+typedef enum {
+	RF_GPO = 0, I2C_GPO = 1
+} M24SR_GPO_MODE;
+
+typedef enum {
+	M24SR_WAITINGTIME_POLLING,
+	M24SR_INTERRUPT_GPO
+} M24SR_WAITINGTIME_MGMT;
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup lib_M24SR_Exported_Constants
+ * @{
+ */
+
+/* ---------------------- status code ----------------------------------------*/
+#define UB_STATUS_OFFSET										4
+#define LB_STATUS_OFFSET  									3
+#define I_AM_M24SR                ((uint8_t)0xB4)
+#define I_AM_M24SR_AUTOMOTIVE                ((uint8_t)0xBC)
+
+#define M24SR_NBBYTE_INVALID								0xFFFE
+
+/** @defgroup drv_M24SR_File_Identifier
+ * @{
+ */
+#define SYSTEM_FILE_ID_BYTES {0xE1,0x01}
+#define CC_FILE_ID_BYTES {0xE1,0x03}
+#define NDEF_FILE_ID						0x0001	 
+/**
+ * @}
+ */
+
+/** @defgroup drv_M24SR_Password_Management
+ * @{
+ */
+#define READ_PWD								0x0001
+#define WRITE_PWD								0x0002
+#define I2C_PWD									0x0003
+
+/*-------------------------- Verify command answer ----------------------------*/
+/**
+ * @}
+ */
+
+/** @defgroup drv_M24SR_Command_Management
+ * @{
+ */
+
+/* special M24SR command ----------------------------------------------------------------------*/
+#define M24SR_OPENSESSION_COMMAND {0x26}
+#define M24SR_KILLSESSION_COMMAND {0x52}
+
+/* APDU Command: class list -------------------------------------------*/
+#define C_APDU_CLA_DEFAULT	  0x00
+#define C_APDU_CLA_ST					0xA2
+
+/*------------------------ Data Area Management Commands ---------------------*/
+#define C_APDU_SELECT_FILE     0xA4
+#define C_APDU_GET_RESPONCE    0xC0
+#define C_APDU_STATUS          0xF2
+#define C_APDU_UPDATE_BINARY   0xD6
+#define C_APDU_READ_BINARY     0xB0
+#define C_APDU_WRITE_BINARY    0xD0
+#define C_APDU_UPDATE_RECORD   0xDC
+#define C_APDU_READ_RECORD     0xB2
+
+/*-------------------------- Safety Management Commands ----------------------*/
+#define C_APDU_VERIFY          0x20
+#define C_APDU_CHANGE          0x24
+#define C_APDU_DISABLE         0x26
+#define C_APDU_ENABLE          0x28
+
+/*-------------------------- Gpio Management Commands ------------------------*/
+#define C_APDU_INTERRUPT       0xD6
+
+/*  Length	----------------------------------------------------------------------------------*/
+#define M24SR_STATUS_NBBYTE												2
+#define M24SR_CRC_NBBYTE													2
+#define M24SR_STATUSRESPONSE_NBBYTE								5
+#define M24SR_DESELECTREQUEST_COMMAND	{0xC2,0xE0,0xB4}
+#define M24SR_DESELECTRESPONSE_NBBYTE							3
+#define M24SR_WATINGTIMEEXTRESPONSE_NBBYTE				4
+#define M24SR_PASSWORD_NBBYTE											0x10
+#define M24SR_SELECTAPPLICATION_COMMAND	{0xD2,0x76,0x00,0x00,0x85,0x01,0x01}
+/*  Command structure	------------------------------------------------------------------------*/
+#define M24SR_CMDSTRUCT_SELECTAPPLICATION					0x01FF
+#define M24SR_CMDSTRUCT_SELECTCCFILE							0x017F
+#define M24SR_CMDSTRUCT_SELECTNDEFFILE						0x017F
+#define M24SR_CMDSTRUCT_READBINARY								0x019F
+#define M24SR_CMDSTRUCT_UPDATEBINARY							0x017F
+#define M24SR_CMDSTRUCT_VERIFYBINARYWOPWD					0x013F
+#define M24SR_CMDSTRUCT_VERIFYBINARYWITHPWD				0x017F
+#define M24SR_CMDSTRUCT_CHANGEREFDATA							0x017F
+#define M24SR_CMDSTRUCT_ENABLEVERIFREQ						0x011F
+#define M24SR_CMDSTRUCT_DISABLEVERIFREQ						0x011F
+#define M24SR_CMDSTRUCT_SENDINTERRUPT							0x013F
+#define M24SR_CMDSTRUCT_GPOSTATE									0x017F
+
+/*  Command structure Mask -------------------------------------------------------------------*/
+#define M24SR_PCB_NEEDED				0x0001		/* PCB byte present or not */
+#define M24SR_CLA_NEEDED				0x0002 		/* CLA byte present or not */
+#define M24SR_INS_NEEDED				0x0004 		/* Operation code present or not*/ 
+#define M24SR_P1_NEEDED					0x0008		/* Selection Mode  present or not*/
+#define M24SR_P2_NEEDED					0x0010		/* Selection Option present or not*/
+#define M24SR_LC_NEEDED					0x0020		/* Data field length byte present or not */
+#define M24SR_DATA_NEEDED				0x0040		/* Data present or not */
+#define M24SR_LE_NEEDED					0x0080		/* Expected length present or not */
+#define M24SR_CRC_NEEDED				0x0100		/* 2 CRC bytes present	or not */
+
+#define M24SR_DID_NEEDED				0x08			/* DID byte present or not */
+
+/**
+ * @}
+ */
+
+/*  Offset	----------------------------------------------------------------------------------*/
+#define M24SR_OFFSET_PCB													0
+#define M24SR_OFFSET_CLASS												1
+#define M24SR_OFFSET_INS													2
+#define M24SR_OFFSET_P1														3
+
+/*  mask	------------------------------------------------------------------------------------*/
+#define M24SR_MASK_BLOCK													0xC0
+#define M24SR_MASK_IBLOCK													0x00
+#define M24SR_MASK_RBLOCK													0x80
+#define M24SR_MASK_SBLOCK													0xC0
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+
+/** @brief Get Most Significant Byte
+ * @param  val: number where MSB must be extracted
+ * @retval MSB
+ */
+#define GETMSB(val) 		( (uint8_t) ((val & 0xFF00 )>>8) ) 
+
+/** @brief Get Least Significant Byte
+ * @param  val: number where LSB must be extracted
+ * @retval LSB
+ */
+#define GETLSB(val) 		( (uint8_t) (val & 0x00FF )) 
+
+/** @brief Used to toggle the block number by adding 0 or 1 to default block number value
+ * @param  val: number to know if incrementation is needed
+ * @retval  0 or 1 if incrementation needed
+ */
+#define TOGGLE(val) 		((val != 0x00)? 0x00 : 0x01)
+
+typedef struct {
+	C_APDU command;
+	//static R_APDU 						Response;
+	uint8_t dataBuffer[0xFF];
+	uint8_t uM24SRbuffer[0xFF];
+	uint8_t uDIDbyte;
+} M24SR_DrvDataTypeDef;
+
+typedef void* M24SR_InitTypeDef;
+
+extern NFC_t M24SR_IO_Init(void *handle);
+extern NFC_t M24SR_IO_IsAnswerReady(void *handle);
+extern NFC_t M24SR_IO_SendI2Ccommand(void *handle, uint8_t NbByte,
+		uint8_t *pBuffer);
+extern NFC_t M24SR_IO_ReceiveI2Cresponse(void *handle,
+		uint8_t NbByte, uint8_t *pBuffer);
+extern NFC_t M24SR_IO_PollI2C(void *handle);
+//extern void M24SR_IO_GPO_ReadPin(void *handle, GPIO_PinState *pPinState);
+//extern void M24SR_IO_RFDIS_WritePin(void *handle, GPIO_PinState PinState);
+extern void M24SR_IO_GPO_ReadPin(void *handle, uint8_t *pPinState);
+extern void M24SR_IO_RFDIS_WritePin(void *handle, uint8_t PinState);
+//extern void M24SR_IO_SetI2CSynchroMode(void *handle,
+//		M24SR_WAITINGTIME_MGMT mode);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DRV_M24SR_H */
+
+/******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/