This application provides a set of demos with X-NUCLEO-NFC01A1 expansion board.
Dependencies: NDefLib X_NUCLEO_NFC01A1 mbed
Fork of X-MBED-NFC1 by
This application provides a set of demos with X-NUCLEO-NFC01A1 expansion board.
The available demos are:
- SAMPLE_WRITE_URL: write a tag with the ST home page URL
- SAMPLE_COUNT_CLICK: create a custom tag to count and report the user button clicks.
- SAMPLE_WRITE_AND_CHANGE_ALL: write a tag with all the supported records and update the tag contents when the user button is pressed.
- SAMPLE_LOCK_TAG_CONTENT: use the M24SR component API to set the NFC tag as read-only.
To enable the different demos comment/uncomment the SAMPLE_* macros provided in main.cpp .
Diff: m24sr/m24sr_class.cpp
- Revision:
- 1:6d202b62ed68
- Parent:
- 0:674813bd5ec9
- Child:
- 2:0648c1561eb2
--- a/m24sr/m24sr_class.cpp Thu Nov 19 08:50:18 2015 +0000
+++ b/m24sr/m24sr_class.cpp Fri Nov 27 15:10:25 2015 +0000
@@ -1,1288 +1,1235 @@
-/**
- ******************************************************************************
- * @file m24sr_class.cpp
- * @author MMY Application Team
- * @version V1.2.0
- * @date 20-October-2014
- * @brief This file provides a set of functions to interface with the M24SR
- * device.
- ******************************************************************************
- * @attention
- *
- * <h2><center>© 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.
- *
- ******************************************************************************
- */
-
-
-/* Generated with Stm32CubeTOO -----------------------------------------------*/
-
-
-/* Revision ------------------------------------------------------------------*/
-/*
- Repository: http://svn.x-nucleodev.codex.cro.st.com/svnroot/X-NucleoDev
- Branch/Trunk/Tag: trunk
- Based on: X-CUBE-MEMS1/trunk/Drivers/BSP/Components/m24sr/m24sr.c
- Revision: :410
-*/
-
-/* Includes ------------------------------------------------------------------*/
-#include "m24sr_class.h"
-#include "m24sr.h"
-
-/** @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
-#define errchk(fCall) if (status = (fCall), status != NFC_IO_SUCCESS) \
- {goto Error;} else
-#endif
-
-
-/**
- * @brief This function updates the CRC
- * @param None
- * @retval None
- */
-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 byte of the data
- * @retval CRC16
- */
-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 to data
-* @param Length : Number of bits of DataIn
-* @retval Status (SW1&SW2) : CRC16 residue is correct
-* @retval M24SR_ERROR_CRC : CRC16 residue is false
-*/
-NFC_StatusTypeDef M24SR_IsCorrectCRC16Residue (uint8_t *DataIn,uint8_t Length)
-{
- uint16_t ResCRC=0x0000;
-
- /* check the CRC16 Residue */
- if (Length !=0)
- ResCRC= M24SR_ComputeCrc (DataIn, Length);
-
- if ( ResCRC == 0x0000)
- {
- /* Good CRC, but error status from M24SR */
- return(NFC_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 NFC_IO_ERROR_CRC;
- }
- else
- {
- /* Good CRC, but error status from M24SR */
- return (NFC_StatusTypeDef)( ((DataIn[1]<<8) & 0xFF00) | (DataIn[2] & 0x00FF) );
- }
- }
-}
-
-/**
- * @brief Initialize the command and response structure
- * @param None
- * @retval None
- */
-void M24SR::M24SR_InitCommandStructure ( void )
-{
-
- /* build the command */
- command.Header.CLA = 0x00;
- command.Header.INS = 0x00;
- /* copy the offset */
- command.Header.P1 = 0x00 ;
- command.Header.P2 = 0x00 ;
- /* copy the number of byte of the data field */
- command.Body.LC = 0x00 ;
- /* copy the number of byte to read */
- command.Body.LE = 0x00 ;
- command.Body.pData = dataBuffer;
-
- // /* initializes the response structure*/
- // Response.pData = contex->DataBuffer;
- // Response.SW1 = 0x00;
- // Response.SW2 = 0x00;
-}
-
-/**
- * @brief This functions creates an I block command according to the structures CommandStructure and data->command.
- * @param Command : structue which contains the field of the different parameter
- * @param CommandStructure : structure that contain the structure of the command (if the different field are presnet or not
- * @param NbByte : number of byte of the command
- * @param pCommand : pointer of the command created
- */
-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 ) ;
- }
-
-}
-
-#if 0
-/**
-* @brief This function return M24SR_STATUS_SUCCESS if the pBuffer is an I-block
-* @param pBuffer : pointer of the data
-* @retval M24SR_STATUS_SUCCESS : the data is a I-Block
-* @retval M24SR_ERROR_DEFAULT : the data is not a I-Block
-*/
-static int8_t IsIBlock (uint8_t *pBuffer)
-{
-
- if ((pBuffer[M24SR_OFFSET_PCB] & M24SR_MASK_BLOCK) == M24SR_MASK_IBLOCK)
- {
- return M24SR_STATUS_SUCCESS;
- }
- else
- {
- return M24SR_ERROR_DEFAULT;
- }
-
-}
-
-/**
-* @brief This function return M24SR_STATUS_SUCCESS if the pBuffer is an R-block
-* @param pBuffer : pointer of the data
-* @retval M24SR_STATUS_SUCCESS : the data is a R-Block
-* @retval M24SR_ERROR_DEFAULT : the data is not a R-Block
-*/
-static int8_t IsRBlock (uint8_t *pBuffer)
-{
-
- if ((pBuffer[M24SR_OFFSET_PCB] & M24SR_MASK_BLOCK) == M24SR_MASK_RBLOCK)
- {
- return M24SR_STATUS_SUCCESS;
- }
- else
- {
- return M24SR_ERROR_DEFAULT;
- }
-
-}
-#endif
-
-/**
-* @brief This function return M24SR_STATUS_SUCCESS if the pBuffer is an s-block
-* @param pBuffer : pointer of the data
-* @retval M24SR_STATUS_SUCCESS : the data is a S-Block
-* @retval M24SR_ERROR_DEFAULT : the data is not a S-Block
-*/
-static int8_t IsSBlock (uint8_t *pBuffer)
-{
-
- if ((pBuffer[M24SR_OFFSET_PCB] & M24SR_MASK_BLOCK) == M24SR_MASK_SBLOCK)
- {
- return NFC_IO_SUCCESS;
- }
- else
- {
- return NFC_IO_ERROR_DEFAULT;
- }
-
-}
-
-/**
- * @brief This function sends the FWT extension command (S-Block format)
- * @param FWTbyte : FWT value
- * @retval Status (SW1&SW2) : Status of the operation to complete.
- * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
- */
-NFC_StatusTypeDef M24SR::M24SR_FWTExtension (uint8_t FWTbyte )
-{
- uint8_t pBuffer[M24SR_STATUSRESPONSE_NBBYTE];
- NFC_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 */
- errchk( M24SR_IO_SendI2Ccommand (NthByte , pBuffer ));
- errchk( M24SR_IO_IsAnswerReady ());
- /* read the response */
- errchk( M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
-
- status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
- return status;
-
-Error :
- return NFC_IO_ERROR_I2CTIMEOUT;
-}
-
-/**
- * @brief This function sends the KillSession command to the M24SR device
- * @param None
- * @retval NFC_OK : the function is succesful.
- * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
- */
-NFC_StatusTypeDef M24SR::M24SR_KillSession ( void )
-{
- uint8_t commandBuffer[] = M24SR_KILLSESSION_COMMAND;
- int8_t status;
-
- errchk(M24SR_IO_SendI2Ccommand (sizeof(commandBuffer) , commandBuffer ));
-
- /* 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 */
- errchk(M24SR_IO_PollI2C ());
-
- return NFC_OK;
-Error :
- return NFC_IO_ERROR_I2CTIMEOUT;
-}
-
-
-/**
- * @brief This function sends the Deselect command (S-Block format)
- * @retval NFC_OK : the function is succesful.
- * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
- */
-NFC_StatusTypeDef M24SR::M24SR_Deselect ( void )
-{
- uint8_t pBuffer[] = M24SR_DESELECTREQUEST_COMMAND ;
- int8_t status ;
-
- /* send the request */
- errchk( M24SR_IO_SendI2Ccommand (sizeof(pBuffer) , pBuffer ));
-
- errchk( M24SR_IO_IsAnswerReady ());
- /* flush the M24SR buffer */
- errchk( M24SR_IO_ReceiveI2Cresponse (sizeof(pBuffer) , pBuffer ));
-
- return NFC_OK;
-
-Error :
- return NFC_IO_ERROR_I2CTIMEOUT;
-}
-
-
-
-
-/**
- * @brief This function sends the SelectApplication command
- * @retval NFC_OK : the function is succesful.
- * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
- */
-NFC_StatusTypeDef M24SR::M24SR_SelectApplication ( void )
-{
-
- C_APDU command;
- uint8_t *pBuffer = uM24SRbuffer;
- uint8_t pDataIn[M24SR_STATUSRESPONSE_NBBYTE];
- uint8_t pDataOut[] = M24SR_SELECTAPPLICATION_COMMAND;
- uint8_t uLe = 0x00;
- NFC_StatusTypeDef status ;
- 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 I²C command */
- M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_SELECTAPPLICATION, &command,uDIDbyte, &NbByte , pBuffer);
-
- /* send the request */
- errchk( M24SR_IO_SendI2Ccommand (NbByte , pBuffer ));
- errchk( M24SR_IO_IsAnswerReady ());
- /* read the response */
- errchk( M24SR_IO_ReceiveI2Cresponse (sizeof(pDataIn) , pDataIn ));
-
- status = M24SR_IsCorrectCRC16Residue (pDataIn,sizeof(pDataIn));
- return status;
-
-Error :
- return NFC_IO_ERROR_I2CTIMEOUT;
-}
-
-
-/**
- * @brief This function initialize the M24SR device
- * @retval None
- */
-NFC_StatusTypeDef M24SR::M24SR_Init(NFC_InitTypeDef *notUsed)
-{
- (void)notUsed;
-
- M24SR_InitCommandStructure();
-
-/*
- if( M24SR_KillSession() == NFC_OK)
- {
- M24SR_ManageI2CGPO(I2C_ANSWER_READY);
- M24SR_Deselect ();
- }
-*/
- return NFC_OK;
-}
-
-NFC_StatusTypeDef M24SR::M24SR_ReadID(uint8_t *nfc_id){
- if(!nfc_id){
- return NFC_ERROR;
- }
- NFC_StatusTypeDef error = M24SR_SelectApplication();
- if(error!=NFC_IO_SUCCESS)
- return error;
-
- return M24SR_ReadBinary(0x0011,1,nfc_id);
-}
-
-
-/**
- * @brief This function sends the GetSession command to the M24SR device
- * @retval NFC_OK : the function is succesful.
- * @retval Status (SW1&SW2) : if operation does not complete.
- */
-NFC_StatusTypeDef M24SR::M24SR_GetSession ( void )
-{
- uint8_t commandBuffer[] = M24SR_OPENSESSION_COMMAND;
- int16_t status;
-
- errchk(M24SR_IO_SendI2Ccommand (sizeof(commandBuffer) , commandBuffer ));
-
- /* 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 GetSession command */
- errchk(M24SR_IO_PollI2C ());
-
- return NFC_OK;
-Error :
- return NFC_IO_ERROR_I2CTIMEOUT;
-}
-
-
-
-
-/**
- * @brief This function sends the SelectCCFile command
- * @retval NFC_OK : the function is succesful.
- * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
- * @retval Status (SW1&SW2) : if operation does not complete for another reason.
- */
-NFC_StatusTypeDef M24SR::M24SR_SelectCCfile ( void )
-{
- C_APDU command;
-
- uint8_t *pBuffer = uM24SRbuffer;
- uint8_t pDataIn[M24SR_STATUSRESPONSE_NBBYTE];
- uint8_t pDataOut[] = CC_FILE_ID_BYTES;
- NFC_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 */
- errchk(M24SR_IO_SendI2Ccommand(NbByte, pBuffer));
- errchk(M24SR_IO_IsAnswerReady());
- /* read the response */
- errchk(M24SR_IO_ReceiveI2Cresponse(sizeof(pDataIn), pDataIn));
-
- status = M24SR_IsCorrectCRC16Residue(pDataIn, sizeof(pDataIn));
- return status;
-
- Error:
- return NFC_IO_ERROR_I2CTIMEOUT;
-}
-
-
-/**
- * @brief This function sends the SelectSystemFile command
- * @retval Status (SW1&SW2) : Status of the operation to complete.
- * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
- */
-NFC_StatusTypeDef M24SR::M24SR_SelectSystemfile ( void )
-{
- C_APDU command;
-
- uint8_t *pBuffer = uM24SRbuffer;
- uint8_t pDataIn[M24SR_STATUSRESPONSE_NBBYTE];
- uint8_t pDataOut[] = SYSTEM_FILE_ID_BYTES;
- NFC_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 */
- errchk( M24SR_IO_SendI2Ccommand (NbByte , pBuffer ));
- errchk( M24SR_IO_IsAnswerReady ());
- /* read the response */
- errchk( M24SR_IO_ReceiveI2Cresponse (sizeof(pDataIn) , pDataIn ));
-
- status = M24SR_IsCorrectCRC16Residue (pDataIn,sizeof(pDataIn));
- return status;
-
-Error :
- return NFC_IO_ERROR_I2CTIMEOUT;
-}
-
-/**
- * @brief This function sends the SelectNDEFfile command
- * @retval Status (SW1&SW2) : Status of the operation to complete.
- * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
- */
-NFC_StatusTypeDef M24SR::M24SR_SelectNDEFfile (uint16_t NDEFfileId )
-{
- C_APDU command;
- uint8_t *pBuffer = uM24SRbuffer;
- uint8_t pDataIn[M24SR_STATUSRESPONSE_NBBYTE];
- uint8_t pDataOut[]={GETMSB(NDEFfileId ), GETLSB(NDEFfileId )};
- NFC_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;
- /* copy the offset */
- /* build the I²C command */
- M24SR_BuildIBlockCommand (M24SR_CMDSTRUCT_SELECTNDEFFILE, &command,uDIDbyte, &NbByte , pBuffer);
-
- /* send the request */
- errchk( M24SR_IO_SendI2Ccommand (NbByte , pBuffer ));
- errchk( M24SR_IO_IsAnswerReady ());
- /* read the response */
- errchk( M24SR_IO_ReceiveI2Cresponse (sizeof(pDataIn) , pDataIn ));
-
- return M24SR_IsCorrectCRC16Residue (pDataIn,sizeof(pDataIn));
-
-Error :
- return NFC_IO_ERROR_I2CTIMEOUT;
-
-}
-
-/**
- * @brief This function sends a read binary command
- * @param Offset : first byte to read
- * @param NbByteToRead : number of byte to read
- * @param pBufferRead : pointer of the buffer read from the M24SR device
- * @retval Status (SW1&SW2) : Status of the operation to complete.
- * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
- */
-NFC_StatusTypeDef M24SR::M24SR_ReadBinary (uint16_t Offset ,uint8_t NbByteToRead , uint8_t *pBufferRead )
-{
- uint8_t *pBuffer = uM24SRbuffer ;
- NFC_StatusTypeDef status ;
- uint16_t NbByte;
-
- /* 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);
-
- errchk( M24SR_IO_SendI2Ccommand (NbByte , pBuffer ));
- errchk( M24SR_IO_IsAnswerReady ());
- errchk( M24SR_IO_ReceiveI2Cresponse (NbByteToRead + M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
-
- status = M24SR_IsCorrectCRC16Residue (pBuffer,NbByteToRead+ M24SR_STATUSRESPONSE_NBBYTE);
- /* retrieve the data without SW1 & SW2 as provided as return value of the function */
- memcpy(pBufferRead ,&pBuffer[1],NbByteToRead);
- return status;
-
-Error :
- return NFC_IO_ERROR_I2CTIMEOUT;
-
-}
-
-
-
-/**
- * @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 byte to read
- * @param pBufferRead : pointer of the buffer read from the M24SR device
- * @retval Status (SW1&SW2) : Status of the operation to complete.
- * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
- */
-NFC_StatusTypeDef M24SR::M24SR_STReadBinary (uint16_t Offset, uint8_t NbByteToRead, uint8_t *pBufferRead )
-{
- uint8_t *pBuffer = uM24SRbuffer ;
- NFC_StatusTypeDef status ;
- uint16_t NbByte;
-
- /* 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);
-
- errchk( M24SR_IO_SendI2Ccommand (NbByte , pBuffer ));
- errchk( M24SR_IO_IsAnswerReady ());
- errchk( M24SR_IO_ReceiveI2Cresponse (NbByteToRead + M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
-
- status = M24SR_IsCorrectCRC16Residue (pBuffer,NbByteToRead+ M24SR_STATUSRESPONSE_NBBYTE);
- /* retrieve the data without SW1 & SW2 as provided as return value of the function */
- memcpy(pBufferRead ,&pBuffer[1],NbByteToRead);
- return status;
-
-Error :
- return NFC_IO_ERROR_I2CTIMEOUT;
-
-}
-
-/**
- * @brief This function sends a Update binary command
- * @param Offset : first byte to read
- * @param NbByteToWrite : number of byte to write
- * @param pBufferRead : pointer of the buffer read from the M24SR device
- * @retval Status (SW1&SW2) : Status of the operation to complete.
- * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
- */
-NFC_StatusTypeDef M24SR::M24SR_UpdateBinary (uint16_t Offset ,uint8_t NbByteToWrite,uint8_t *pDataToWrite )
-{
- //TODO check the length of the data to write
- uint8_t *pBuffer = uM24SRbuffer ;
- NFC_StatusTypeDef status ;
- 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 ;
- /* copy the File Id */
- memcpy(command.Body.pData ,pDataToWrite, NbByteToWrite );
-
- M24SR_BuildIBlockCommand (M24SR_CMDSTRUCT_UPDATEBINARY, &command,uDIDbyte, &NbByte , pBuffer);
-
- errchk( M24SR_IO_SendI2Ccommand (NbByte , pBuffer ));
- errchk( M24SR_IO_IsAnswerReady ());
- errchk( M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
- /* if the response is a Watiting frame extenstion request */
- if (IsSBlock (pBuffer) == NFC_IO_SUCCESS)
- {
- /*check the CRC */
- if (M24SR_IsCorrectCRC16Residue (pBuffer , M24SR_WATINGTIMEEXTRESPONSE_NBBYTE) != NFC_IO_ERROR_CRC)
- {
- /* send the FrameExension response*/
- status = M24SR_FWTExtension (pBuffer [M24SR_OFFSET_PCB+1] );
- }
- }
- else
- {
- status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
- }
-
- return status;
-
-
-Error :
- return NFC_IO_ERROR_I2CTIMEOUT;
-}
-
-
-/**
- * @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 byte ( 0x00 or 0x10)
- * @param pPwd : pointer on the passwaord
- * @retval Status (SW1&SW2) : Status of the operation to complete.
- * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
- */
-NFC_StatusTypeDef M24SR::M24SR_Verify (uint16_t uPwdId,uint8_t NbPwdByte ,uint8_t *pPwd )
-{
- uint8_t *pBuffer = uM24SRbuffer ;
- NFC_StatusTypeDef status = NFC_IO_SUCCESS ;
- uint16_t NbByte;
-
- /*check the parameters */
- if (uPwdId > 0x0003)
- {
- return NFC_IO_ERROR_PARAMETER;
- }
- if ( (NbPwdByte != 0x00) && (NbPwdByte != 0x10))
- {
- return NFC_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 byte of the data field */
- command.Body.LC = NbPwdByte ;
-
- if (NbPwdByte == 0x10)
- {
- /* copy the password */
- memcpy(command.Body.pData, pPwd, NbPwdByte);
- /* build the I²C command */
- M24SR_BuildIBlockCommand (M24SR_CMDSTRUCT_VERIFYBINARYWITHPWD, &command,uDIDbyte, &NbByte , pBuffer);
- }
- else
- {
- /* build the I²C command */
- M24SR_BuildIBlockCommand (M24SR_CMDSTRUCT_VERIFYBINARYWOPWD, &command,uDIDbyte, &NbByte , pBuffer);
- }
-
- /* send the request */
- errchk( M24SR_IO_SendI2Ccommand (NbByte , pBuffer ));
- /* wait for answer ready */
- errchk( M24SR_IO_IsAnswerReady ());
- /* read the response */
- errchk( M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
-
- status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
- return status;
-
-Error :
- return NFC_IO_ERROR_I2CTIMEOUT;
-}
-
-
-/**
- * @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 on the passwaord
- * @retval Status (SW1&SW2) : Status of the operation to complete.
- * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
- */
-NFC_StatusTypeDef M24SR::M24SR_ChangeReferenceData (uint16_t uPwdId,uint8_t *pPwd )
-{
- uint8_t *pBuffer = uM24SRbuffer;
- NFC_StatusTypeDef status ;
- uint16_t NbByte;
-
- /*check the parameters */
- if (uPwdId > 0x0003)
- {
- return NFC_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 */
- memcpy(command.Body.pData, pPwd, M24SR_PASSWORD_NBBYTE);
- /* build the I²C command */
- M24SR_BuildIBlockCommand (M24SR_CMDSTRUCT_CHANGEREFDATA, &command,uDIDbyte, &NbByte , pBuffer);
-
-
- /* send the request */
- errchk( M24SR_IO_SendI2Ccommand (NbByte , pBuffer ));
- errchk( M24SR_IO_IsAnswerReady ());
- /* read the response */
- errchk( M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
-
- status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
- return status;
-
-Error :
- return NFC_IO_ERROR_I2CTIMEOUT;
-}
-
-
-/**
- * @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 : The I2C timeout occured.
- */
-NFC_StatusTypeDef M24SR::M24SR_EnableVerificationRequirement (uint16_t uReadOrWrite )
-{
- uint8_t *pBuffer = uM24SRbuffer;
- NFC_StatusTypeDef status= NFC_IO_SUCCESS ;
- uint16_t NbByte;
-
- /*check the parameters */
- if ( (uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002))
- {
- return NFC_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 I²C command */
- M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_ENABLEVERIFREQ, &command,uDIDbyte, &NbByte , pBuffer);
-
- /* send the request */
- errchk( M24SR_IO_SendI2Ccommand (NbByte , pBuffer ));
- /* The right access to be updated in EEPROM need at least 6ms */
- errchk( M24SR_IO_IsAnswerReady ());
- /* read the response */
- errchk( M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
-
- status = M24SR_IsCorrectCRC16Residue ( pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
- return status;
-
-Error :
- return NFC_IO_ERROR_I2CTIMEOUT;
-}
-
-/**
- * @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 : The I2C timeout occured.
- */
-NFC_StatusTypeDef M24SR::M24SR_DisableVerificationRequirement (uint16_t uReadOrWrite )
-{
- uint8_t *pBuffer = uM24SRbuffer;
- NFC_StatusTypeDef status= NFC_IO_SUCCESS ;
- uint16_t NbByte;
-
- /*check the parameters */
- if ( (uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002))
- {
- return NFC_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 */
- errchk( M24SR_IO_SendI2Ccommand (NbByte , pBuffer ));
- /* The right access to be updated in EEPROM need at least 6ms */
- errchk( M24SR_IO_IsAnswerReady ());
- /* read the response */
- errchk( M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
-
- status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
- return status;
-
-Error :
- return NFC_IO_ERROR_I2CTIMEOUT;
-}
-
-/**
- * @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 : The I2C timeout occured.
- */
-NFC_StatusTypeDef M24SR::M24SR_EnablePermanentState (uint16_t uReadOrWrite )
-{
- uint8_t *pBuffer = uM24SRbuffer;
- NFC_StatusTypeDef status= NFC_IO_SUCCESS ;
- uint16_t NbByte;
-
- /*check the parameters */
- if ( (uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002))
- {
- return NFC_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 I²C command */
- M24SR_BuildIBlockCommand (M24SR_CMDSTRUCT_ENABLEVERIFREQ, &command,uDIDbyte, &NbByte , pBuffer);
-
- /* send the request */
- errchk( M24SR_IO_SendI2Ccommand (NbByte , pBuffer ));
- errchk( M24SR_IO_IsAnswerReady ());
- /* read the response */
- errchk( M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
-
- status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
- return status;
-
-Error :
- return NFC_IO_ERROR_I2CTIMEOUT;
-}
-
-/**
- * @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 : The I2C timeout occured.
- */
-NFC_StatusTypeDef M24SR::M24SR_DisablePermanentState (uint16_t uReadOrWrite )
-{
- uint8_t *pBuffer = uM24SRbuffer;
- NFC_StatusTypeDef status= NFC_IO_SUCCESS ;
- uint16_t NbByte;
-
- /*check the parameters */
- if ( (uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002))
- {
- return NFC_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 I²C command */
- M24SR_BuildIBlockCommand (M24SR_CMDSTRUCT_DISABLEVERIFREQ, &command,uDIDbyte, &NbByte , pBuffer);
-
- /* send the request */
- errchk( M24SR_IO_SendI2Ccommand (NbByte , pBuffer ));
- errchk( M24SR_IO_IsAnswerReady ());
- /* read the response */
- errchk( M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
-
- status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
- return status;
-
-Error :
- return NFC_IO_ERROR_I2CTIMEOUT;
-}
-
-/**
- * @brief This function generates a interrupt on GPO pin
- * @param None
- * @retval Status (SW1&SW2) : Status of the operation to complete.
- * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
- */
-NFC_StatusTypeDef M24SR::M24SR_SendInterrupt ( void )
-{
- uint8_t *pBuffer = uM24SRbuffer;
- uint16_t uP1P2 =0x001E;
- NFC_StatusTypeDef status= NFC_IO_SUCCESS ;
- uint16_t NbByte;
-
- status = M24SR_ManageI2CGPO(INTERRUPT);
-
- /* 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 I²C command */
- M24SR_BuildIBlockCommand (M24SR_CMDSTRUCT_SENDINTERRUPT, &command,uDIDbyte, &NbByte , pBuffer);
-
- /* send the request */
- errchk( M24SR_IO_SendI2Ccommand (NbByte , pBuffer ));
- errchk( M24SR_IO_IsAnswerReady ());
- /* read the response */
- errchk( M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
-
- status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
- return status;
-
-Error :
- return NFC_IO_ERROR_I2CTIMEOUT;
-}
-
-/**
- * @brief This function force 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 : The I2C timeout occured.
- */
-NFC_StatusTypeDef M24SR::M24SR_StateControl (uint8_t uSetOrReset )
-{
- uint8_t *pBuffer = uM24SRbuffer;
- uint16_t uP1P2 =0x001F;
- NFC_StatusTypeDef status= NFC_IO_SUCCESS ;
- uint16_t NbByte;
-
- /*check the parameters */
- if ( (uSetOrReset != 0x01) && (uSetOrReset != 0x00))
- {
- return NFC_IO_ERROR_PARAMETER;
- }
-
- status = M24SR_ManageI2CGPO(STATE_CONTROL);
-
- /* 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 ;
- /* copy the data */
- memcpy(command.Body.pData , &uSetOrReset, 0x01 );
- //command.Body.LE = 0x00 ;
- /* build the I²C command */
- M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_GPOSTATE, &command,uDIDbyte, &NbByte , pBuffer);
-
- /* send the request */
- errchk( M24SR_IO_SendI2Ccommand (NbByte , pBuffer ));
- errchk( M24SR_IO_IsAnswerReady ());
- /* read the response */
- errchk( M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
-
- status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
- return status;
-
-Error :
- return NFC_IO_ERROR_I2CTIMEOUT;
-}
-
-
-
-/**
- * @brief This function configure GPO purpose for I2C session
- * @param GPO_I2Cconfig: GPO configuration to set
- * @retval Status (SW1&SW2) : Status of the operation to complete.
- */
-NFC_StatusTypeDef M24SR::M24SR_ManageI2CGPO( uint8_t GPO_I2Cconfig)
-{
- NFC_StatusTypeDef status;
- uint8_t GPO_config;
- uint8_t DefaultPassword[16]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
- if( GPO_I2Cconfig > STATE_CONTROL)
- {
- return NFC_IO_ERROR_PARAMETER;
- }
-
- /* we must not be in interrupt mode for I2C synchro as we will change GPO purpose */
- M24SR_IO_SetI2CSynchroMode(M24SR_WAITINGTIME_POLLING);
-
- M24SR_SelectApplication();
- M24SR_SelectSystemfile();
- M24SR_ReadBinary (0x0004 , 0x01 , &GPO_config );
-
- /* Update only GPO purpose for I2C */
- GPO_config = (GPO_config & 0xF0) | GPO_I2Cconfig;
- M24SR_SelectSystemfile();
- M24SR_Verify(I2C_PWD ,0x10 ,DefaultPassword );
- status = M24SR_UpdateBinary (0x0004 ,0x01, &(GPO_config) );
-
- M24SR_Deselect();
-
- /* if we have set interrupt mode for I2C synchro we can enable interrupt mode */
- if ( GPO_I2Cconfig == I2C_ANSWER_READY && status == NFC_OK)
- M24SR_IO_SetI2CSynchroMode(M24SR_INTERRUPT_GPO);
-
- return status;
-}
-
-/**
- * @brief This function configure GPO purpose for RF session
- * @param GPO_RFconfig: GPO configuration to set
- * @retval Status (SW1&SW2) : Status of the operation to complete.
- */
-NFC_StatusTypeDef M24SR::M24SR_ManageRFGPO(uint8_t GPO_RFconfig)
-{
- NFC_StatusTypeDef status;
- uint8_t GPO_config;
- uint8_t DefaultPassword[16]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
- if( GPO_RFconfig > STATE_CONTROL)
- {
- return NFC_IO_ERROR_PARAMETER;
- }
-
- M24SR_SelectApplication();
- M24SR_SelectSystemfile();
- M24SR_ReadBinary (0x0004 , 0x01 , &GPO_config );
-
- /* Update only GPO purpose for I2C */
- GPO_config = (GPO_config & 0x0F) | (GPO_RFconfig<<4);
- M24SR_SelectSystemfile();
- M24SR_Verify(I2C_PWD ,0x10 ,DefaultPassword );
- status = M24SR_UpdateBinary (0x0004 ,0x01, &(GPO_config) );
-
- return status;
-}
-
-
-/**
- * @brief This function enable or disable RF communication
- * @param OnOffChoice: GPO configuration to set
- * @retval Status (SW1&SW2) : Status of the operation to complete.
- */
-NFC_StatusTypeDef M24SR::M24SR_RFConfig(uint8_t OnOffChoice)
-{
- /* Disable RF */
- if ( OnOffChoice != 0 )
- {
- M24SR_IO_RFDIS_WritePin(GPIO_PIN_RESET);
- }
- else
- {
- M24SR_IO_RFDIS_WritePin(GPIO_PIN_SET);
- }
- return NFC_OK;
-}
-
-
-
-NFC_StatusTypeDef M24SR::M24SR_IO_SendI2Ccommand(uint8_t NbByte , uint8_t *pBuffer){
- int ret = dev_i2c.write(address,(char*)pBuffer,NbByte);
- if(ret==0)
- return NFC_IO_SUCCESS;
- return NFC_IO_ERROR_I2CTIMEOUT;
-}
-
-NFC_StatusTypeDef M24SR::M24SR_IO_ReceiveI2Cresponse(uint8_t NbByte , uint8_t *pBuffer){
- int ret = dev_i2c.read(address,(char*)pBuffer,NbByte);
- if(ret==0)
- return NFC_IO_SUCCESS;
- return NFC_IO_ERROR_I2CTIMEOUT;
-}
-
-
-#define M24SR_POLL_DELAY 10
-#define M24SR_I2C_POLLING 1 /* In case M24SR will reply ACK failed allow to perform retry before returning error (HAL option not used) */
-
-
-NFC_StatusTypeDef M24SR::M24SR_IO_PollI2C(void)
-{
- int status = 1;
- uint32_t nbTry = 0;
- char buffer;
- //
- wait_ms(M24SR_POLL_DELAY);
- while (status != 0 && nbTry < M24SR_I2C_POLLING)
- {
- status = dev_i2c.read(address, &buffer, 1, false);
- nbTry++;
- }
- if (status == 0)
- return NFC_IO_SUCCESS;
- //else
- return NFC_IO_ERROR_I2CTIMEOUT;
-}
-
-NFC_StatusTypeDef M24SR::M24SR_IO_IsAnswerReady(void){
- uint32_t retry = 0xFFFFF;
- int8_t stable = 0;
- GPIO_PinState PinState;
-
- switch (syncMode){
- case M24SR_WAITINGTIME_POLLING :
- return M24SR_IO_PollI2C ();
-
- case M24SR_WAITINGTIME_TIMEOUT :
- // M24SR FWI=5 => (256*16/fc)*2^5=9.6ms but M24SR ask for extended time to program up to 246Bytes.
- // can be improved by
- wait_ms(80);
- return NFC_IO_SUCCESS;
-
- case M24SR_WAITINGTIME_GPO :
- do{
- M24SR_IO_GPO_ReadPin(&PinState);
- if( PinState == GPIO_PIN_RESET){
- stable ++;
- }
- retry --;
- }
- while(stable <5 && retry>0);
- if(!retry)
- goto Error;
- return NFC_IO_SUCCESS;
-
- case M24SR_INTERRUPT_GPO :
-
- /* Check if the GPIO is not already low before calling this function */
- M24SR_IO_GPO_ReadPin(&PinState);
- answerReadyInterrupt.enable_irq();
- if(PinState == GPIO_PIN_SET){
- while (!interruptIsFired)
- __WFE();
- }
- interruptIsFired=false;
- answerReadyInterrupt.disable_irq();
- return NFC_IO_SUCCESS;
-
- default :
- return NFC_IO_ERROR_DEFAULT;
- }
-
- Error :
- return NFC_IO_ERROR_DEFAULT;
-}
-
-
-/******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/
+/**
+ ******************************************************************************
+ * @file m24sr_class.cpp
+ * @author MMY Application Team
+ * @version V1.2.0
+ * @date 20-October-2014
+ * @brief This file provides a set of functions to interface with the M24SR
+ * device.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© 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.
+ *
+ ******************************************************************************
+ */
+
+/* Generated with Stm32CubeTOO -----------------------------------------------*/
+
+/* Revision ------------------------------------------------------------------*/
+/*
+ Repository: http://svn.x-nucleodev.codex.cro.st.com/svnroot/X-NucleoDev
+ Branch/Trunk/Tag: trunk
+ Based on: X-CUBE-MEMS1/trunk/Drivers/BSP/Components/m24sr/m24sr.c
+ Revision: :410
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "m24sr_class.h"
+#include "m24sr.h"
+
+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
+#define NFC_COMMAND_SUCCESS 0x9000
+#define errchk(fCall) {\
+ const NFC_StatusTypeDef status = (fCall); \
+ if((status!=NFC_SUCCESS)) \
+ return status; \
+ }\
+
+#endif
+
+/**
+ * @brief This function updates the CRC
+ * @param None
+ * @retval None
+ */
+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 byte of the data
+ * @retval CRC16
+ */
+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 to data
+ * @param Length : Number of bits of DataIn
+ * @retval Status (SW1&SW2) : CRC16 residue is correct
+ * @retval M24SR_ERROR_CRC : CRC16 residue is false
+ */
+NFC_StatusTypeDef M24SR_IsCorrectCRC16Residue(uint8_t *DataIn, uint8_t Length) {
+ uint16_t ResCRC = 0x0000;
+
+ /* check the CRC16 Residue */
+ if (Length != 0)
+ ResCRC = M24SR_ComputeCrc(DataIn, Length);
+
+ if (ResCRC == 0x0000) {
+ /* Good CRC, but error status from M24SR */
+ return (NFC_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 NFC_IO_ERROR_CRC;
+ } else {
+ /* Good CRC, but error status from M24SR */
+ return (NFC_StatusTypeDef) (((DataIn[1] << 8) & 0xFF00)
+ | (DataIn[2] & 0x00FF));
+ }
+ }
+}
+
+/**
+ * @brief This functions creates an I block command according to the structures CommandStructure and data->command.
+ * @param Command : structue which contains the field of the different parameter
+ * @param CommandStructure : structure that contain the structure of the command (if the different field are presnet or not
+ * @param NbByte : number of byte of the command
+ * @param pCommand : pointer of the command created
+ */
+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);
+ }
+
+}
+
+#if 0
+/**
+ * @brief This function return M24SR_STATUS_SUCCESS if the pBuffer is an I-block
+ * @param pBuffer : pointer of the data
+ * @retval M24SR_STATUS_SUCCESS : the data is a I-Block
+ * @retval M24SR_ERROR_DEFAULT : the data is not a I-Block
+ */
+static int8_t IsIBlock (uint8_t *pBuffer)
+{
+
+ if ((pBuffer[M24SR_OFFSET_PCB] & M24SR_MASK_BLOCK) == M24SR_MASK_IBLOCK)
+ {
+ return M24SR_STATUS_SUCCESS;
+ }
+ else
+ {
+ return M24SR_ERROR_DEFAULT;
+ }
+
+}
+
+/**
+ * @brief This function return M24SR_STATUS_SUCCESS if the pBuffer is an R-block
+ * @param pBuffer : pointer of the data
+ * @retval M24SR_STATUS_SUCCESS : the data is a R-Block
+ * @retval M24SR_ERROR_DEFAULT : the data is not a R-Block
+ */
+static int8_t IsRBlock (uint8_t *pBuffer)
+{
+
+ if ((pBuffer[M24SR_OFFSET_PCB] & M24SR_MASK_BLOCK) == M24SR_MASK_RBLOCK)
+ {
+ return M24SR_STATUS_SUCCESS;
+ }
+ else
+ {
+ return M24SR_ERROR_DEFAULT;
+ }
+
+}
+#endif
+
+/**
+ * @brief This function return M24SR_STATUS_SUCCESS if the pBuffer is an s-block
+ * @param pBuffer : pointer of the data
+ * @retval M24SR_STATUS_SUCCESS : the data is a S-Block
+ * @retval M24SR_ERROR_DEFAULT : the data is not a S-Block
+ */
+static NFC_StatusTypeDef IsSBlock(uint8_t *pBuffer) {
+
+ if ((pBuffer[M24SR_OFFSET_PCB] & M24SR_MASK_BLOCK) == M24SR_MASK_SBLOCK) {
+ return NFC_SUCCESS;
+ } else {
+ return NFC_ERROR;
+ }
+
+}
+
+/**
+ * @brief This function sends the FWT extension command (S-Block format)
+ * @param FWTbyte : FWT value
+ * @retval Status (SW1&SW2) : Status of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
+ */
+NFC_StatusTypeDef M24SR::M24SR_FWTExtension(uint8_t FWTbyte) {
+ uint8_t pBuffer[M24SR_STATUSRESPONSE_NBBYTE];
+ NFC_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 */
+ errchk(M24SR_IO_SendI2Ccommand(NthByte, pBuffer));
+ errchk(M24SR_IO_IsAnswerReady());
+ /* read the response */
+ errchk(
+ M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
+
+ status = M24SR_IsCorrectCRC16Residue(pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
+
+ if(status == NFC_COMMAND_SUCCESS)
+ return NFC_SUCCESS;
+ else
+ return status;
+}
+
+/**
+ * @brief This function sends the KillSession command to the M24SR device
+ * @param None
+ * @retval NFC_OK : the function is succesful.
+ * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
+ */
+NFC_StatusTypeDef M24SR::M24SR_KillSession(void) {
+ uint8_t commandBuffer[] = M24SR_KILLSESSION_COMMAND;
+
+ errchk(M24SR_IO_SendI2Ccommand(sizeof(commandBuffer), commandBuffer));
+
+ /* 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 */
+ errchk(M24SR_IO_PollI2C());
+
+ return NFC_SUCCESS;
+}
+
+/**
+ * @brief This function sends the Deselect command (S-Block format)
+ * @retval NFC_OK : the function is succesful.
+ * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
+ */
+NFC_StatusTypeDef M24SR::M24SR_Deselect(void) {
+ uint8_t pBuffer[] = M24SR_DESELECTREQUEST_COMMAND;
+
+ /* send the request */
+ errchk(M24SR_IO_SendI2Ccommand(sizeof(pBuffer), pBuffer));
+
+ errchk(M24SR_IO_IsAnswerReady());
+ /* flush the M24SR buffer */
+ errchk(M24SR_IO_ReceiveI2Cresponse(sizeof(pBuffer), pBuffer));
+
+ return NFC_SUCCESS;
+}
+
+/**
+ * @brief This function sends the SelectApplication command
+ * @retval NFC_OK : the function is succesful.
+ * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
+ */
+NFC_StatusTypeDef M24SR::M24SR_SelectApplication(void) {
+
+ C_APDU command;
+ uint8_t *pBuffer = uM24SRbuffer;
+ uint8_t pDataIn[M24SR_STATUSRESPONSE_NBBYTE];
+ uint8_t pDataOut[] = M24SR_SELECTAPPLICATION_COMMAND;
+ uint8_t uLe = 0x00;
+ NFC_StatusTypeDef status;
+ 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 I²C command */
+ M24SR_BuildIBlockCommand( M24SR_CMDSTRUCT_SELECTAPPLICATION, &command,
+ uDIDbyte, &NbByte, pBuffer);
+
+ /* send the request */
+ errchk(M24SR_IO_SendI2Ccommand(NbByte, pBuffer));
+ errchk(M24SR_IO_IsAnswerReady());
+ /* read the response */
+ errchk(M24SR_IO_ReceiveI2Cresponse(sizeof(pDataIn), pDataIn));
+
+ status= M24SR_IsCorrectCRC16Residue(pDataIn, sizeof(pDataIn));
+
+ if(status == NFC_COMMAND_SUCCESS)
+ return NFC_SUCCESS;
+ else
+ return status;
+
+}
+
+/**
+ * @brief This function initialize the M24SR device
+ * @retval None
+ */
+NFC_StatusTypeDef M24SR::M24SR_Init(NFC_InitTypeDef *notUsed) {
+ (void) notUsed;
+
+ errchk(M24SR_KillSession())
+ errchk(M24SR_ManageI2CGPO(I2C_ANSWER_READY))
+ errchk(M24SR_Deselect())
+
+ return NFC_SUCCESS;
+}
+
+NFC_StatusTypeDef M24SR::M24SR_ReadID(uint8_t *nfc_id) {
+ if (!nfc_id) {
+ return NFC_ERROR;
+ }
+
+ errchk(M24SR_SelectApplication())
+
+ return M24SR_ReadBinary(0x0011, 1, nfc_id);
+}
+
+/**
+ * @brief This function sends the GetSession command to the M24SR device
+ * @retval NFC_OK : the function is succesful.
+ * @retval Status (SW1&SW2) : if operation does not complete.
+ */
+NFC_StatusTypeDef M24SR::M24SR_GetSession(void) {
+ uint8_t commandBuffer[] = M24SR_OPENSESSION_COMMAND;
+
+ errchk(M24SR_IO_SendI2Ccommand(sizeof(commandBuffer), commandBuffer));
+
+ /* 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 GetSession command */
+ errchk(M24SR_IO_PollI2C());
+
+ return NFC_SUCCESS;
+
+}
+
+/**
+ * @brief This function sends the SelectCCFile command
+ * @retval NFC_OK : the function is succesful.
+ * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
+ * @retval Status (SW1&SW2) : if operation does not complete for another reason.
+ */
+NFC_StatusTypeDef M24SR::M24SR_SelectCCfile(void) {
+ C_APDU command;
+
+ uint8_t *pBuffer = uM24SRbuffer;
+ uint8_t pDataIn[M24SR_STATUSRESPONSE_NBBYTE];
+ uint8_t pDataOut[] = CC_FILE_ID_BYTES;
+ NFC_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 */
+ errchk(M24SR_IO_SendI2Ccommand(NbByte, pBuffer));
+ errchk(M24SR_IO_IsAnswerReady());
+ /* read the response */
+ errchk(M24SR_IO_ReceiveI2Cresponse(sizeof(pDataIn), pDataIn));
+
+ status = M24SR_IsCorrectCRC16Residue(pDataIn, sizeof(pDataIn));
+
+ if(status == NFC_COMMAND_SUCCESS)
+ return NFC_SUCCESS;
+ else
+ return status;
+}
+
+/**
+ * @brief This function sends the SelectSystemFile command
+ * @retval Status (SW1&SW2) : Status of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
+ */
+NFC_StatusTypeDef M24SR::M24SR_SelectSystemfile(void) {
+ C_APDU command;
+
+ uint8_t *pBuffer = uM24SRbuffer;
+ uint8_t pDataIn[M24SR_STATUSRESPONSE_NBBYTE];
+ uint8_t pDataOut[] = SYSTEM_FILE_ID_BYTES;
+ NFC_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 */
+ errchk(M24SR_IO_SendI2Ccommand(NbByte, pBuffer));
+ errchk(M24SR_IO_IsAnswerReady());
+ /* read the response */
+ errchk(M24SR_IO_ReceiveI2Cresponse(sizeof(pDataIn), pDataIn));
+
+ status = M24SR_IsCorrectCRC16Residue(pDataIn, sizeof(pDataIn));
+
+ if(status == NFC_COMMAND_SUCCESS)
+ return NFC_SUCCESS;
+ else
+ return status;
+}
+
+/**
+ * @brief This function sends the SelectNDEFfile command
+ * @retval Status (SW1&SW2) : Status of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
+ */
+NFC_StatusTypeDef M24SR::M24SR_SelectNDEFfile(uint16_t NDEFfileId) {
+ C_APDU command;
+ uint8_t *pBuffer = uM24SRbuffer;
+ uint8_t pDataIn[M24SR_STATUSRESPONSE_NBBYTE];
+ uint8_t pDataOut[] = { GETMSB(NDEFfileId), GETLSB(NDEFfileId) };
+ NFC_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;
+ /* copy the offset */
+ /* build the I²C command */
+ M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_SELECTNDEFFILE, &command, uDIDbyte,
+ &NbByte, pBuffer);
+
+ /* send the request */
+ errchk(M24SR_IO_SendI2Ccommand(NbByte, pBuffer));
+ errchk(M24SR_IO_IsAnswerReady());
+ /* read the response */
+ errchk(M24SR_IO_ReceiveI2Cresponse(sizeof(pDataIn), pDataIn));
+
+ status = M24SR_IsCorrectCRC16Residue(pDataIn, sizeof(pDataIn));
+ if(status == NFC_COMMAND_SUCCESS)
+ return NFC_SUCCESS;
+ else
+ return status;
+
+}
+
+/**
+ * @brief This function sends a read binary command
+ * @param Offset : first byte to read
+ * @param NbByteToRead : number of byte to read
+ * @param pBufferRead : pointer of the buffer read from the M24SR device
+ * @retval Status (SW1&SW2) : Status of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
+ */
+NFC_StatusTypeDef M24SR::M24SR_ReadBinary(uint16_t Offset, uint8_t NbByteToRead,
+ uint8_t *pBufferRead) {
+ C_APDU command;
+ uint8_t *pBuffer = uM24SRbuffer;
+ NFC_StatusTypeDef status;
+ uint16_t NbByte;
+
+ /* 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);
+
+ errchk(M24SR_IO_SendI2Ccommand(NbByte, pBuffer));
+ errchk(M24SR_IO_IsAnswerReady());
+ errchk(
+ M24SR_IO_ReceiveI2Cresponse (NbByteToRead + M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
+
+ status = M24SR_IsCorrectCRC16Residue(pBuffer,
+ NbByteToRead + M24SR_STATUSRESPONSE_NBBYTE);
+ if(status != NFC_COMMAND_SUCCESS)
+ return status;
+ /* retrieve the data without SW1 & SW2 as provided as return value of the function */
+ memcpy(pBufferRead, &pBuffer[1], NbByteToRead);
+ return NFC_SUCCESS;
+
+}
+
+/**
+ * @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 byte to read
+ * @param pBufferRead : pointer of the buffer read from the M24SR device
+ * @retval Status (SW1&SW2) : Status of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
+ */
+NFC_StatusTypeDef M24SR::M24SR_STReadBinary(uint16_t Offset,
+ uint8_t NbByteToRead, uint8_t *pBufferRead) {
+ C_APDU command;
+ uint8_t *pBuffer = uM24SRbuffer;
+ NFC_StatusTypeDef status;
+ uint16_t NbByte;
+ /* 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);
+
+ errchk(M24SR_IO_SendI2Ccommand(NbByte, pBuffer));
+ errchk(M24SR_IO_IsAnswerReady());
+ errchk(
+ M24SR_IO_ReceiveI2Cresponse (NbByteToRead + M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
+
+ status = M24SR_IsCorrectCRC16Residue(pBuffer,
+ NbByteToRead + M24SR_STATUSRESPONSE_NBBYTE);
+
+ if(status != NFC_COMMAND_SUCCESS)
+ return status;
+ /* retrieve the data without SW1 & SW2 as provided as return value of the function */
+ memcpy(pBufferRead, &pBuffer[1], NbByteToRead);
+ return NFC_SUCCESS;
+}
+
+/**
+ * @brief This function sends a Update binary command
+ * @param Offset : first byte to read
+ * @param NbByteToWrite : number of byte to write
+ * @param pBufferRead : pointer of the buffer read from the M24SR device
+ * @retval Status (SW1&SW2) : Status of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
+ */
+NFC_StatusTypeDef M24SR::M24SR_UpdateBinary(uint16_t Offset,
+ uint8_t NbByteToWrite, uint8_t *pDataToWrite) {
+ //TODO check the length of the data to write
+ C_APDU command;
+
+ uint8_t *pBuffer = uM24SRbuffer;
+ NFC_StatusTypeDef status;
+ 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);
+
+ errchk(M24SR_IO_SendI2Ccommand(NbByte, pBuffer));
+ errchk(M24SR_IO_IsAnswerReady());
+ errchk(
+ M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
+ /* if the response is a Watiting frame extenstion request */
+
+ if (IsSBlock(pBuffer) == NFC_SUCCESS) {
+ /*check the CRC */
+ status =M24SR_IsCorrectCRC16Residue(pBuffer,
+ M24SR_WATINGTIMEEXTRESPONSE_NBBYTE);
+ // TODO: why if we check ==NFC_Commandsuccess it fail?
+ if (status != NFC_IO_ERROR_CRC) {
+ /* send the FrameExension response*/
+ errchk(M24SR_FWTExtension(pBuffer[M24SR_OFFSET_PCB + 1]));
+ }else
+ return status;
+ } else {
+ status = M24SR_IsCorrectCRC16Residue(pBuffer,
+ M24SR_STATUSRESPONSE_NBBYTE);
+ if(status!=NFC_COMMAND_SUCCESS)
+ return status;
+ }
+
+ return NFC_SUCCESS;
+
+}
+
+/**
+ * @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 byte ( 0x00 or 0x10)
+ * @param pPwd : pointer on the passwaord
+ * @retval Status (SW1&SW2) : Status of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
+ */
+NFC_StatusTypeDef M24SR::M24SR_Verify(uint16_t uPwdId, uint8_t NbPwdByte,
+ const uint8_t *pPwd) {
+ C_APDU command;
+
+ uint8_t *pBuffer = uM24SRbuffer;
+ NFC_StatusTypeDef status = NFC_SUCCESS;
+ uint16_t NbByte;
+
+ /*check the parameters */
+ if (uPwdId > 0x0003) {
+ return NFC_IO_ERROR_PARAMETER;
+ }
+ if ((NbPwdByte != 0x00) && (NbPwdByte != 0x10)) {
+ return NFC_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 byte 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 */
+ errchk(M24SR_IO_SendI2Ccommand(NbByte, pBuffer));
+ /* wait for answer ready */
+ errchk(M24SR_IO_IsAnswerReady());
+ /* read the response */
+ errchk(
+ M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
+
+ status = M24SR_IsCorrectCRC16Residue(pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
+ if(status == NFC_COMMAND_SUCCESS)
+ return NFC_SUCCESS;
+ else
+ 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 on the passwaord
+ * @retval Status (SW1&SW2) : Status of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
+ */
+NFC_StatusTypeDef M24SR::M24SR_ChangeReferenceData(uint16_t uPwdId,
+ uint8_t *pPwd) {
+ C_APDU command;
+ uint8_t *pBuffer = uM24SRbuffer;
+ NFC_StatusTypeDef status;
+ uint16_t NbByte;
+
+ /*check the parameters */
+ if (uPwdId > 0x0003) {
+ return NFC_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 */
+ errchk(M24SR_IO_SendI2Ccommand(NbByte, pBuffer));
+ errchk(M24SR_IO_IsAnswerReady());
+ /* read the response */
+ errchk(
+ M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
+
+ status = M24SR_IsCorrectCRC16Residue(pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
+
+ if(status == NFC_COMMAND_SUCCESS)
+ return NFC_SUCCESS;
+ else
+ 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 : The I2C timeout occured.
+ */
+NFC_StatusTypeDef M24SR::M24SR_EnableVerificationRequirement(
+ uint16_t uReadOrWrite) {
+ C_APDU command;
+ uint8_t *pBuffer = uM24SRbuffer;
+ NFC_StatusTypeDef status = NFC_SUCCESS;
+ uint16_t NbByte;
+
+ /*check the parameters */
+ if ((uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002)) {
+ return NFC_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 I²C command */
+ M24SR_BuildIBlockCommand( M24SR_CMDSTRUCT_ENABLEVERIFREQ, &command,
+ uDIDbyte, &NbByte, pBuffer);
+
+ /* send the request */
+ errchk(M24SR_IO_SendI2Ccommand(NbByte, pBuffer));
+ /* The right access to be updated in EEPROM need at least 6ms */
+ errchk(M24SR_IO_IsAnswerReady());
+ /* read the response */
+ errchk(
+ M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
+
+ status = M24SR_IsCorrectCRC16Residue(pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
+ if(status == NFC_COMMAND_SUCCESS)
+ return NFC_SUCCESS;
+ else
+ 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 : The I2C timeout occured.
+ */
+NFC_StatusTypeDef M24SR::M24SR_DisableVerificationRequirement(
+ uint16_t uReadOrWrite) {
+ C_APDU command;
+ uint8_t *pBuffer = uM24SRbuffer;
+ NFC_StatusTypeDef status = NFC_SUCCESS;
+ uint16_t NbByte;
+
+ /*check the parameters */
+ if ((uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002)) {
+ return NFC_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 */
+ errchk(M24SR_IO_SendI2Ccommand(NbByte, pBuffer));
+ /* The right access to be updated in EEPROM need at least 6ms */
+ errchk(M24SR_IO_IsAnswerReady());
+ /* read the response */
+ errchk(
+ M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
+
+ status = M24SR_IsCorrectCRC16Residue(pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
+
+ if(status == NFC_COMMAND_SUCCESS)
+ return NFC_SUCCESS;
+ else
+ 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 : The I2C timeout occured.
+ */
+NFC_StatusTypeDef M24SR::M24SR_EnablePermanentState(uint16_t uReadOrWrite) {
+ C_APDU command;
+
+ uint8_t *pBuffer = uM24SRbuffer;
+ NFC_StatusTypeDef status = NFC_SUCCESS;
+ uint16_t NbByte;
+
+ /*check the parameters */
+ if ((uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002)) {
+ return NFC_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 I²C command */
+ M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_ENABLEVERIFREQ, &command, uDIDbyte,
+ &NbByte, pBuffer);
+
+ /* send the request */
+ errchk(M24SR_IO_SendI2Ccommand(NbByte, pBuffer));
+ errchk(M24SR_IO_IsAnswerReady());
+ /* read the response */
+ errchk(
+ M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
+
+ status = M24SR_IsCorrectCRC16Residue(pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
+ if(status == NFC_COMMAND_SUCCESS)
+ return NFC_SUCCESS;
+ else
+ 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 : The I2C timeout occured.
+ */
+NFC_StatusTypeDef M24SR::M24SR_DisablePermanentState(uint16_t uReadOrWrite) {
+ C_APDU command;
+
+ uint8_t *pBuffer = uM24SRbuffer;
+ NFC_StatusTypeDef status = NFC_SUCCESS;
+ uint16_t NbByte;
+
+ /*check the parameters */
+ if ((uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002)) {
+ return NFC_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 I²C command */
+ M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_DISABLEVERIFREQ, &command,
+ uDIDbyte, &NbByte, pBuffer);
+
+ /* send the request */
+ errchk(M24SR_IO_SendI2Ccommand(NbByte, pBuffer));
+ errchk(M24SR_IO_IsAnswerReady());
+ /* read the response */
+ errchk(
+ M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
+
+ status = M24SR_IsCorrectCRC16Residue(pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
+
+ if(status == NFC_COMMAND_SUCCESS)
+ return NFC_SUCCESS;
+ else
+ return status;
+}
+
+/**
+ * @brief This function generates a interrupt on GPO pin
+ * @param None
+ * @retval Status (SW1&SW2) : Status of the operation to complete.
+ * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured.
+ */
+NFC_StatusTypeDef M24SR::M24SR_SendInterrupt(void) {
+ C_APDU command;
+
+ uint8_t *pBuffer = uM24SRbuffer;
+ uint16_t uP1P2 = 0x001E;
+ NFC_StatusTypeDef status = NFC_SUCCESS;
+ uint16_t NbByte;
+
+ status = M24SR_ManageI2CGPO(INTERRUPT);
+
+ /* 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 I²C command */
+ M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_SENDINTERRUPT, &command, uDIDbyte,
+ &NbByte, pBuffer);
+
+ /* send the request */
+ errchk(M24SR_IO_SendI2Ccommand(NbByte, pBuffer));
+ errchk(M24SR_IO_IsAnswerReady());
+ /* read the response */
+ errchk(
+ M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
+
+ status = M24SR_IsCorrectCRC16Residue(pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
+
+ if(status == NFC_COMMAND_SUCCESS)
+ return NFC_SUCCESS;
+ else
+ return status;
+
+}
+
+/**
+ * @brief This function force 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 : The I2C timeout occured.
+ */
+NFC_StatusTypeDef M24SR::M24SR_StateControl(uint8_t uSetOrReset) {
+ C_APDU command;
+ uint8_t *pBuffer = uM24SRbuffer;
+ uint16_t uP1P2 = 0x001F;
+ NFC_StatusTypeDef status = NFC_SUCCESS;
+ uint16_t NbByte;
+
+ /*check the parameters */
+ if ((uSetOrReset != 0x01) && (uSetOrReset != 0x00)) {
+ return NFC_IO_ERROR_PARAMETER;
+ }
+
+ status = M24SR_ManageI2CGPO(STATE_CONTROL);
+
+ /* 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 I²C command */
+ M24SR_BuildIBlockCommand( M24SR_CMDSTRUCT_GPOSTATE, &command, uDIDbyte,
+ &NbByte, pBuffer);
+
+ /* send the request */
+ errchk(M24SR_IO_SendI2Ccommand(NbByte, pBuffer));
+ errchk(M24SR_IO_IsAnswerReady());
+ /* read the response */
+ errchk(
+ M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
+
+ status = M24SR_IsCorrectCRC16Residue(pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
+
+ if(status == NFC_COMMAND_SUCCESS)
+ return NFC_SUCCESS;
+ else
+ return status;
+}
+
+/**
+ * @brief This function configure GPO purpose for I2C session
+ * @param GPO_I2Cconfig: GPO configuration to set
+ * @retval Status (SW1&SW2) : Status of the operation to complete.
+ */
+NFC_StatusTypeDef M24SR::M24SR_ManageI2CGPO(M24SR_GPO_MGMT GPO_I2Cconfig) {
+ uint8_t GPO_config = 0;
+
+ if (GPO_I2Cconfig > STATE_CONTROL) {
+ return NFC_IO_ERROR_PARAMETER;
+ }
+
+ /* we must not be in interrupt mode for I2C synchro as we will change GPO purpose */
+ M24SR_IO_SetI2CSynchroMode(M24SR_WAITINGTIME_POLLING);
+
+ errchk(M24SR_SelectApplication());
+
+ errchk(M24SR_SelectSystemfile());
+
+ errchk(M24SR_ReadBinary(0x0004, 0x01, &GPO_config))
+
+ /* Update only GPO purpose for I2C */
+ GPO_config = (GPO_config & 0xF0) | GPO_I2Cconfig;
+
+ errchk(M24SR_Verify(I2C_PWD, 0x10, DEFAULT_PASSWORD));
+
+ errchk(M24SR_UpdateBinary(0x0004, 0x01, &(GPO_config)));
+
+ /* if we have set interrupt mode for I2C synchro we can enable interrupt mode */
+ if (GPO_I2Cconfig == I2C_ANSWER_READY)
+ M24SR_IO_SetI2CSynchroMode(M24SR_INTERRUPT_GPO);
+
+ return NFC_SUCCESS;
+}
+
+/**
+ * @brief This function configure GPO purpose for RF session
+ *
+ * @param GPO_RFconfig: GPO configuration to set
+ * @retval Status (SW1&SW2) : Status of the operation to complete.
+ */
+NFC_StatusTypeDef M24SR::M24SR_ManageRFGPO(M24SR_GPO_MGMT GPO_RFconfig) {
+ uint8_t GPO_config;
+
+ if (GPO_RFconfig > STATE_CONTROL) {
+ return NFC_IO_ERROR_PARAMETER;
+ }
+
+ errchk(M24SR_SelectApplication())
+ errchk(M24SR_SelectSystemfile())
+ errchk(M24SR_ReadBinary(0x0004, 0x01, &GPO_config))
+
+ /* Update only GPO purpose for I2C */
+ GPO_config = (GPO_config & 0x0F) | (GPO_RFconfig << 4);
+
+ errchk(M24SR_SelectSystemfile())
+ errchk(M24SR_Verify(I2C_PWD, 0x10, DEFAULT_PASSWORD))
+ errchk(M24SR_UpdateBinary(0x0004, 0x01, &(GPO_config)))
+
+ return NFC_SUCCESS;
+}
+
+/**
+ * @brief This function enable or disable RF communication
+ * @param OnOffChoice: GPO configuration to set
+ * @retval Status (SW1&SW2) : Status of the operation to complete.
+ */
+NFC_StatusTypeDef M24SR::M24SR_RFConfig(uint8_t OnOffChoice) {
+ /* Disable RF */
+ if (OnOffChoice != 0) {
+ M24SR_IO_RFDIS_WritePin(GPIO_PIN_RESET);
+ } else {
+ M24SR_IO_RFDIS_WritePin(GPIO_PIN_SET);
+ }
+ return NFC_SUCCESS;
+}
+
+NFC_StatusTypeDef M24SR::M24SR_IO_SendI2Ccommand(uint8_t NbByte,
+ uint8_t *pBuffer) {
+ int ret = dev_i2c.write(address, (char*) pBuffer, NbByte);
+ if (ret == 0)
+ return NFC_SUCCESS;
+ return NFC_IO_ERROR_I2CTIMEOUT;
+}
+
+NFC_StatusTypeDef M24SR::M24SR_IO_ReceiveI2Cresponse(uint8_t NbByte,
+ uint8_t *pBuffer) {
+ int ret = dev_i2c.read(address, (char*) pBuffer, NbByte);
+ if (ret == 0)
+ return NFC_SUCCESS;
+
+ return NFC_IO_ERROR_I2CTIMEOUT;
+}
+
+#define M24SR_POLL_DELAY 10
+#define M24SR_I2C_POLLING 200 /* In case M24SR will reply ACK failed allow to perform retry before returning error (HAL option not used) */
+
+NFC_StatusTypeDef M24SR::M24SR_IO_PollI2C(void) {
+
+ int status = 1;
+ uint32_t nbTry = 0;
+ char buffer;
+ //
+ wait_ms(M24SR_POLL_DELAY);
+ while (status != 0 && nbTry < M24SR_I2C_POLLING) {
+ status = dev_i2c.read(address, &buffer, 1, false);
+ nbTry++;
+ }
+
+ if (status == 0)
+ return NFC_SUCCESS;
+ //else
+ return NFC_IO_ERROR_I2CTIMEOUT;
+}
+
+NFC_StatusTypeDef M24SR::M24SR_IO_IsAnswerReady(void) {
+ uint32_t retry = 0xFFFFF;
+ int8_t stable = 0;
+ GPIO_PinState PinState;
+
+ switch (syncMode) {
+ case M24SR_WAITINGTIME_POLLING:
+ return M24SR_IO_PollI2C();
+
+ case M24SR_WAITINGTIME_TIMEOUT:
+ // M24SR FWI=5 => (256*16/fc)*2^5=9.6ms but M24SR ask for extended time to program up to 246Bytes.
+ // can be improved by
+ wait_ms(80);
+ return NFC_SUCCESS;
+
+ case M24SR_WAITINGTIME_GPO:
+ do {
+ M24SR_IO_GPO_ReadPin(&PinState);
+ if (PinState == GPIO_PIN_RESET) {
+ stable++;
+ }
+ retry--;
+ } while (stable < 5 && retry > 0);
+ if (!retry)
+ goto Error;
+ return NFC_SUCCESS;
+
+ case M24SR_INTERRUPT_GPO:
+
+ /* Check if the GPIO is not already low before calling this function */
+ M24SR_IO_GPO_ReadPin(&PinState);
+ answerReadyInterrupt.enable_irq();
+ if (PinState == GPIO_PIN_SET) {
+ while (!interruptIsFired)
+ __WFE();
+ }
+ //the interrupt is disable insde the interrupt callback
+ //answerReadyInterrupt.disable_irq();
+ interruptIsFired = false;
+ return NFC_SUCCESS;
+
+ default:
+ return NFC_IO_ERROR_I2CTIMEOUT;
+ }
+
+ Error: return NFC_IO_ERROR_I2CTIMEOUT;
+}
+
+/******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/
