Functions for accessing M24SR device.
Dependents: Nucleo_NFC_Example I2C_NFC_Master Print_Entire_Nucleo_NFC01A1_Memory
Fork of lib_M24SR by
Warning: Deprecated!
Supported drivers and applications can be found at this link.
Revision 0:ffc2448b65ef, committed 2014-12-15
- Comitter:
- EnricoG
- Date:
- Mon Dec 15 19:41:52 2014 +0000
- Commit message:
- Initial commit
Changed in this revision
diff -r 000000000000 -r ffc2448b65ef lib_M24SR.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib_M24SR.c Mon Dec 15 19:41:52 2014 +0000 @@ -0,0 +1,598 @@ +/** + ****************************************************************************** + * @file lib_M24SR.c + * @author MMY Application Team + * @version V1.1.0 + * @date 20-October-2014 + * @brief This file help to manage M24SR in a NFC forum context. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + + +/* Includes ------------------------------------------------------------------*/ +#include "lib_M24SR.h" + +/** @addtogroup M24SR_Driver + * @{ + * @brief <b>This folder contains the driver layer of M24SR family (M24SR64, M24SR16, M24SR04, M24SR02)</b> + */ + +/** @addtogroup lib_M24SR + * @{ + * @brief This is the library to interface with the M24SR dynamic tag. + * This layer simplify the use of the M24SR driver by sequencing + * some commands. + */ + +uint8_t I2CPassword[16]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +static uint32_t NDEFSessionOpenID=NDEF_SESSION_CLOSED; + +/* Init NDEF_FileID with bad value in case Init failed */ +static uint16_t NDEF_FileID = 0xDEAD; + +#ifdef __MBED__ + extern void wait_ms(int ms); +#endif + +/** @defgroup libM24SR_Private_Functions + * @{ + */ + +/** + * @} + */ + + +/** @defgroup libM24SR_Public_Functions + * @{ + */ + +/** + * @brief This fonction initialize the M24SR + * @param CCBuffer : pointer on the buffer to store CC file + * @param size : number of byte of data to read + * @retval SUCCESS : Initalization done + * @retval ERROR : Not able to Initialize. + */ +uint16_t M24SR_Initialization ( uint8_t* CCBuffer, uint8_t size ) +{ + uint16_t status = ERROR; + uint16_t trials = 5; /* 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 generaly release the session within the second, but customer can modify this value */ + + /* Perform HW initialization */ + M24SR_Init(); + + /* Read CC file */ + while( status != M24SR_ACTION_COMPLETED && trials) + { + //printf("Calling M24SR_GetSession(), attempts remaining %d\n", trials); + status = M24SR_GetSession(); + //printf("M24SR_GetSession() returned: %d\n", status); + trials--; + } + if (status != M24SR_ACTION_COMPLETED) + { + //printf("M24SR_GetSession() failed\n"); + return ERROR; + } + /*===================================*/ + /* Select the NFC type 4 application */ + /*===================================*/ + errorchk( M24SR_SelectApplication() ); + + /*==================*/ + /* select a CC file */ + /*==================*/ + errorchk (M24SR_SelectCCfile() ); + + /* read the first 15 bytes of the CC file */ + if( M24SR_ReadData ( 0x0000 , 0x0F , CCBuffer )== M24SR_ACTION_COMPLETED) + { + NDEF_FileID = (uint16_t) ((CCBuffer[0x09]<<8) | CCBuffer[0x0A]); + errorchk( M24SR_Deselect () ); + return SUCCESS; + } + else + errorchk( M24SR_Deselect () ); + +Error: + printf("Error in M24SR_Initialization\n"); + return ERROR; + +} + +/** + * @brief This fonction retrieve the NDEF file ID of NDEF file present in M24SR + * @param NDEF_fileID : To store NDEF ID + * @retval SUCCESS : File ID read + * @retval ERROR : Not able to read file ID. + */ +uint16_t M24SR_GetNDEFFileId ( uint16_t *NDEF_fileID ) +{ + if( NDEF_FileID != 0xDEAD) + { + *NDEF_fileID = NDEF_FileID; + return SUCCESS; + } + else + { + return ERROR; + } +} + + +/** + * @brief This fonction configure the M24SR to access NDEF message by I2C + * @param NDEF_fileID : NDEF identification to select NDEF in M24SR + * @param Priority: 2 options: check if M24SR available to open session (no RF session on going) + * Kill RF session and open I2C sesssion. + * @retval SUCCESS : Session is opened + * @retval ERROR : Not able to open session. + */ +uint16_t M24SR_OpenNDEFSession ( uint16_t NDEF_fileID, uint16_t Priority ) +{ + uint16_t status = ERROR; + uint16_t trials = 5; /* 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 generaly release the session within the second, but customer can modify this value */ + + if(NDEFSessionOpenID == NDEF_SESSION_CLOSED) + { + if( Priority == TAKE_SESSION) + { + status = M24SR_KillSession(); + } + else + { + while( status != M24SR_ACTION_COMPLETED && trials) + { + status = M24SR_GetSession(); + trials--; + } + } + if (status != M24SR_ACTION_COMPLETED) + { + /* seems session already open on RF side */ + /* But in case of I2C issue try to init again */ + M24SR_Init(); + return ERROR; + } + + /*===================================*/ + /* Select the NFC type 4 application */ + /*===================================*/ + errorchk( M24SR_SelectApplication() ); + + /*====================*/ + /* select NDEF file */ + /*====================*/ + errorchk( M24SR_SelectNDEFfile(NDEF_fileID) ); + + NDEFSessionOpenID = (uint32_t)(NDEF_fileID); + + return SUCCESS; + } + else if(NDEFSessionOpenID == NDEF_fileID) + { + /* Session already Open not an issue caller can perform access in NDEF file */ + return SUCCESS; + } + +Error: + return ERROR; +} + +/** + * @brief This fonction close the NDEF Session. + * @param NDEF_fileID : NDEF identification to select NDEF in M24SR + * @retval SUCCESS : Session is closed + * @retval ERROR : Not able to close session. + */ +uint16_t M24SR_CloseNDEFSession ( uint16_t NDEF_fileID ) +{ + uint16_t status = ERROR; + + if(NDEFSessionOpenID == (uint32_t)(NDEF_fileID)) + { + errorchk( M24SR_Deselect () ); + NDEFSessionOpenID = NDEF_SESSION_CLOSED; + + return SUCCESS; + } + else if(NDEFSessionOpenID == NDEF_SESSION_CLOSED) + { + /* Not an error as session is already closed */ + return SUCCESS; + } + +Error: + return ERROR; +} + +/** + * @brief This fonction read the data stored in M24SR at defined offset + * @param Offset : Offset in the NDEF file in M24SR + * @param DataSize : Number of byte to read + * @param pData : pointer on buffer to store read data + * @retval Status (SW1&SW2) : Status of the operation. + */ +uint16_t M24SR_ReadData ( uint16_t Offset , uint16_t DataSize , uint8_t* pData) +{ + uint16_t status; + + if( DataSize > M24SR_READ_MAX_NBBYTE) + { + do + { + status = M24SR_ReadBinary ( Offset, M24SR_READ_MAX_NBBYTE , pData); + Offset += M24SR_READ_MAX_NBBYTE; + pData += M24SR_READ_MAX_NBBYTE; + DataSize -= M24SR_READ_MAX_NBBYTE; + }while( DataSize > M24SR_READ_MAX_NBBYTE && status == M24SR_ACTION_COMPLETED); + if( status == M24SR_ACTION_COMPLETED && DataSize) + status = M24SR_ReadBinary ( Offset, (uint8_t)(DataSize) , pData); + } + else + status = M24SR_ReadBinary ( Offset, (uint8_t)(DataSize) , pData); + + return status; +} + +/** + * @brief This fonction read the data stored in M24SR at defined offset without NDEF concideration + * @param Offset : Offset in the NDEF file in M24SR + * @param DataSize : Number of byte to read + * @param pData : pointer on buffer to store read data + * @retval Status (SW1&SW2) : Status of the operation. + */ +uint16_t M24SR_ForceReadData ( uint16_t Offset , uint16_t DataSize , uint8_t* pData) +{ + uint16_t status; + + if( DataSize > M24SR_READ_MAX_NBBYTE) + { + do + { + status = M24SR_STReadBinary ( Offset, M24SR_READ_MAX_NBBYTE , pData); + Offset += M24SR_READ_MAX_NBBYTE; + pData += M24SR_READ_MAX_NBBYTE; + DataSize -= M24SR_READ_MAX_NBBYTE; + }while( DataSize > M24SR_READ_MAX_NBBYTE && status == M24SR_ACTION_COMPLETED); + if( status == M24SR_ACTION_COMPLETED && DataSize) + status = M24SR_STReadBinary ( Offset, (uint8_t)(DataSize) , pData); + } + else + status = M24SR_STReadBinary ( Offset, (uint8_t)(DataSize) , pData); + + return status; +} + +/** + * @brief This fonction write data in M24SR at defined offset + * @param Offset : Offset in the NDEF file in M24SR + * @param DataSize : Number of byte to read + * @param pData : pointer on buffer to copy in M24SR + * @retval Status (SW1&SW2) : Status of the operation. + */ +uint16_t M24SR_WriteData ( uint16_t Offset , uint16_t DataSize , uint8_t* pData) +{ + uint16_t status; + + if( DataSize > M24SR_WRITE_MAX_NBBYTE) + { + do + { + status = M24SR_UpdateBinary ( Offset, M24SR_WRITE_MAX_NBBYTE , pData); + Offset += M24SR_WRITE_MAX_NBBYTE; + pData += M24SR_WRITE_MAX_NBBYTE; + DataSize -= M24SR_WRITE_MAX_NBBYTE; + }while( DataSize > M24SR_WRITE_MAX_NBBYTE && status == M24SR_ACTION_COMPLETED); + if( status == M24SR_ACTION_COMPLETED && DataSize) + status = M24SR_UpdateBinary ( Offset, (uint8_t)(DataSize) , pData); + } + else + status = M24SR_UpdateBinary ( Offset, (uint8_t)(DataSize) , pData); + + return status; +} + +/** + * @brief This fonction activate the need of a password for next read access + * @param pCurrentWritePassword : Write password is needed to have the right to enable Read Password + * @param pNewPassword : The password that will be requiered for next read access + * @retval SUCCESS : Read password is activated + * @retval ERROR : operation does not complete + */ +uint16_t M24SR_EnableReadPassword( uint8_t* pCurrentWritePassword, uint8_t* pNewPassword) +{ + uint16_t status = SUCCESS; + + if(M24SR_Verify( WRITE_PWD ,0x10 ,pCurrentWritePassword ) == M24SR_PWD_CORRECT) + { + /* Set new password */ + M24SR_ChangeReferenceData ( READ_PWD, pNewPassword ); + M24SR_EnableVerificationRequirement( READ_PWD ); + status = SUCCESS; + } + else + { + /* M24SR already lock but password not known */ + status = ERROR; + } + + return status; +} + +/** + * @brief This fonction desactivate the need of a password for next read access + * @param pCurrentWritePassword : Write password is needed to have the right to disable Read Password + * @retval SUCCESS : Read password is desactivated + * @retval ERROR : operation does not complete + */ +uint16_t M24SR_DisableReadPassword( uint8_t* pCurrentWritePassword) +{ + uint16_t status = SUCCESS; + + if(M24SR_Verify( WRITE_PWD ,0x10 ,pCurrentWritePassword ) == M24SR_PWD_CORRECT) + { + /* Set new password */ + M24SR_DisableVerificationRequirement( READ_PWD ); + status = SUCCESS; + } + else + { + /* M24SR already lock but password not known */ + status = ERROR; + } + + return status; +} + +/** + * @brief This fonction activate the need of a password for next write access + * @param pCurrentWritePassword : Write password must be prensented to have the right to modify write Password + * @param pNewPassword : The password that will be requiered for next write access + * @retval SUCCESS : Write password is activated + * @retval ERROR : operation does not complete + */ +uint16_t M24SR_EnableWritePassword( uint8_t* pCurrentWritePassword, uint8_t* pNewPassword) +{ + uint16_t status; + + /* check we have the good password */ + if (M24SR_Verify( WRITE_PWD ,0x10 ,pCurrentWritePassword )== M24SR_PWD_CORRECT) + { + /* Set new password */ + M24SR_ChangeReferenceData ( WRITE_PWD, pNewPassword ); + M24SR_EnableVerificationRequirement( WRITE_PWD ); + status = SUCCESS; + } + else /* we don't have the good password */ + { + status = ERROR; + } + + return status; +} + +/** + * @brief This fonction desactivate the need of a password for next write access + * @param pCurrentWritePassword : Write password must be prensented to have the right to disable it + * @retval SUCCESS : Write password is desactivated + * @retval ERROR : operation does not complete + */ +uint16_t M24SR_DisableWritePassword( uint8_t* pCurrentWritePassword) +{ + uint16_t status = SUCCESS; + + if(M24SR_Verify( WRITE_PWD ,0x10 ,pCurrentWritePassword ) == M24SR_PWD_CORRECT) + { + M24SR_DisableVerificationRequirement( WRITE_PWD ); + status = SUCCESS; + } + else + { + /* M24SR already lock but password not known */ + status = ERROR; + } + + return status; +} + +/** + * @brief This fonction desactivate the need of read and write password for next access + * @param pSuperUserPassword : I2C super user password to overwrite read and write password + * @retval SUCCESS : M24SR access is now free (no password needed) + * @retval ERROR : operation does not complete + */ +uint16_t M24SR_DisableAllPassword( uint8_t* pSuperUserPassword) +{ + uint16_t status = SUCCESS; + + if(M24SR_Verify( I2C_PWD ,0x10 ,pSuperUserPassword ) == M24SR_PWD_CORRECT) + { + M24SR_DisablePermanentState( READ_PWD ); + M24SR_DisablePermanentState( WRITE_PWD ); + + M24SR_DisableVerificationRequirement( READ_PWD ); + M24SR_DisableVerificationRequirement( WRITE_PWD ); + + /* reset password */ + M24SR_ChangeReferenceData ( READ_PWD, pSuperUserPassword ); + M24SR_ChangeReferenceData ( WRITE_PWD, pSuperUserPassword ); + status = SUCCESS; + } + else + { + /* M24SR already lock but password not known */ + status = ERROR; + } + + return status; +} + +/** + * @brief This fonction enable read only mode + * @param pCurrentWritePassword : Write password is needed to have right to enable read only mode + * @retval SUCCESS : M24SR access is now forbidden in write mode + * @retval ERROR : operation does not complete + */ +uint16_t M24SR_EnableReadOnly( uint8_t* pCurrentWritePassword) +{ + uint16_t status = SUCCESS; + + if(M24SR_Verify( WRITE_PWD ,0x10 ,pCurrentWritePassword ) == M24SR_PWD_CORRECT) + { + M24SR_EnablePermanentState( WRITE_PWD ); /* lock write to have read only */ + status = SUCCESS; + } + else + { + /* M24SR already lock but password not known */ + status = ERROR; + } + + return status; +} + +/** + * @brief This fonction disable read only mode + * @param pCurrentWritePassword : Write password is needed to have right to disable read only mode + * @retval SUCCESS : M24SR write access is now allowed + * @retval ERROR : operation does not complete + */ +uint16_t M24SR_DisableReadOnly( uint8_t* pCurrentWritePassword) +{ + uint16_t status = SUCCESS; + + if(M24SR_Verify( I2C_PWD ,0x10 ,I2CPassword ) == M24SR_PWD_CORRECT) + { + M24SR_DisablePermanentState( WRITE_PWD ); /* disable write protection to disable read only mode */ + M24SR_DisableVerificationRequirement( WRITE_PWD ); + status = SUCCESS; + } + else + { + /* we don't have the good I2C password nothing to do anymore */ + status = ERROR; + } + + return status; +} + +/** + * @brief This fonction enable write only mode + * @param pCurrentWritePassword : Write password is needed to have right to enable write only mode + * @retval SUCCESS : M24SR access is now forbidden in read mode + * @retval ERROR : operation does not complete + */ +uint16_t M24SR_EnableWriteOnly( uint8_t* pCurrentWritePassword) +{ + uint16_t status = SUCCESS; + + if(M24SR_Verify( WRITE_PWD ,0x10 ,pCurrentWritePassword ) == M24SR_PWD_CORRECT) + { + M24SR_EnablePermanentState( READ_PWD ); /* disable read access and keep write */ + status = SUCCESS; + } + else + { + /* M24SR already lock but password not known */ + status = ERROR; + } + + return status; +} + +/** + * @brief This fonction disable write only mode + * @param pCurrentWritePassword : Write password is needed to have right to disable write only mode + * @retval SUCCESS : M24SR read access is now allowed + * @retval ERROR : operation does not complete + */ +uint16_t M24SR_DisableWriteOnly( uint8_t* pCurrentWritePassword) +{ + uint16_t status = SUCCESS; + + if(M24SR_Verify( I2C_PWD ,0x10 ,I2CPassword ) == M24SR_PWD_CORRECT) + { + M24SR_DisablePermanentState( READ_PWD ); /* disable write only -> enable write acces */ + M24SR_DisableVerificationRequirement( READ_PWD ); + status = SUCCESS; + } + else + { + /* M24SR already lock but password not known */ + status = ERROR; + } + + return status; +} + +/** + * @brief This function configure GPO purpose for RF session + * @param GPO_config: GPO configuration to set + * @param mode: select RF or I2C, GPO config to update + * @retval Status : Status of the operation. + */ +uint16_t M24SR_ManageGPO( uc8 GPO_config, uc8 mode) +{ + uint16_t status; + + if( mode == RF_GPO) + { + status = M24SR_ManageRFGPO ( GPO_config ); + } + else + { + status = M24SR_ManageI2CGPO ( GPO_config ); + } + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/ + +
diff -r 000000000000 -r ffc2448b65ef lib_M24SR.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib_M24SR.h Mon Dec 15 19:41:52 2014 +0000 @@ -0,0 +1,89 @@ +/** + ****************************************************************************** + * @file lib_M24SR.h + * @author MMY Application Team + * @version V1.0.0 + * @date 20-November-2013 + * @brief This file help to manage Data inside M24SR. + ****************************************************************************** + * @attention + * + * <h2><center>© 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 __LIB_M24SR_H +#define __LIB_M24SR_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "m24sr.h" + +/* ---------------------- M24SR properties -----------------------------------*/ +#define M24SR04_NDEF_MAX_SIZE 0x200 +#define M24SR16_NDEF_MAX_SIZE 0x800 +#define M24SR64_NDEF_MAX_SIZE 0x2000 + + +#define ASK_FOR_SESSION 0x0000 +#define TAKE_SESSION 0xFFFF + +/* M24SR buffer size is 0xF6 can be retrieve dynamicaly in CC file */ +#define M24SR_READ_MAX_NBBYTE 0xF6 +#define M24SR_WRITE_MAX_NBBYTE 0xF6 + + +#define NDEF_SESSION_CLOSED 0xDEADBEEF + +#ifndef errorchk +#define errorchk(fCall) if (status = (fCall), status != M24SR_ACTION_COMPLETED) \ + {goto Error;} else +#endif + +uint16_t M24SR_Initialization (uint8_t* pCCBuffer, uint8_t size ); + +uint16_t M24SR_GetNDEFFileId ( uint16_t *NDEF_fileID ); +uint16_t M24SR_OpenNDEFSession ( uint16_t NDEF_fileID, uint16_t Priority ); +uint16_t M24SR_ReadData ( uint16_t Offset , uint16_t DataSize , uint8_t* pData); +uint16_t M24SR_ForceReadData ( uint16_t Offset , uint16_t DataSize , uint8_t* pData); +uint16_t M24SR_WriteData ( uint16_t Offset , uint16_t DataSize , uint8_t* pData); +uint16_t M24SR_CloseNDEFSession ( uint16_t NDEF_fileID ); + +uint16_t M24SR_EnableReadPassword( uint8_t* pCurrentWritePassword, uint8_t* pNewPassword); +uint16_t M24SR_DisableReadPassword( uint8_t* pCurrentWritePassword ); +uint16_t M24SR_EnableWritePassword( uint8_t* pCurrentWritePassword, uint8_t* pNewPassword); +uint16_t M24SR_DisableWritePassword( uint8_t* pCurrentWritePassword ); +uint16_t M24SR_DisableAllPassword( uint8_t* pSuperUserPassword); + +uint16_t M24SR_EnableReadOnly( uint8_t* pCurrentWritePassword); +uint16_t M24SR_DisableReadOnly( uint8_t* pCurrentWritePassword); +uint16_t M24SR_EnableWriteOnly( uint8_t* pCurrentWritePassword); +uint16_t M24SR_DisableWriteOnly( uint8_t* pCurrentWritePassword); + +uint16_t M24SR_ManageGPO( uc8 GPO_config, uc8 mode); + +#ifdef __cplusplus +} +#endif + + +#endif /* __LIB_M24SR_H */ + +/******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r ffc2448b65ef m24sr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/m24sr.c Mon Dec 15 19:41:52 2014 +0000 @@ -0,0 +1,1205 @@ +/** + ****************************************************************************** + * @file drv_M24SR.c + * @author MMY Application Team + * @version V1.1.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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "m24sr.h" + +/** @addtogroup M24SR_Driver + * @{ + * @brief <b>This folder contains the driver layer of M24SR family (M24SR64, M24SR16, M24SR04, M24SR02)</b> + */ + + +/** @addtogroup drv_M24SR + * @{ + * @brief This file contains the driver which implements all the M24SR commands. + */ + +static C_APDU Command; +//static R_APDU Response; +static uint8_t DataBuffer[0xFF]; +uint8_t uM24SRbuffer [0xFF]; +static uint8_t uDIDbyte =0x00; + + +static uint16_t M24SR_UpdateCrc ( uint8_t ch, uint16_t *lpwCrc); +static uint16_t M24SR_ComputeCrc ( uc8 *Data, uint8_t Length); +static uint16_t M24SR_IsCorrectCRC16Residue ( uc8 *DataIn,uc8 Length); +static void M24SR_InitStructure ( void ); +static void M24SR_BuildIBlockCommand ( uc16 CommandStructure, C_APDU Command, uint16_t *NbByte , uint8_t *pCommand); +static int8_t IsSBlock (uc8 *pBuffer); +#if 0 +static int8_t IsRBlock (uc8 *pBuffer); +static int8_t IsIBlock (uc8 *pBuffer); +#endif +static uint16_t M24SR_FWTExtension ( uint8_t FWTbyte ); + +/** @defgroup drvM24SR_Private_Functions + * @{ + */ + + /** + * @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 byte of the data + * @retval CRC16 + */ +static uint16_t M24SR_ComputeCrc(uc8 *Data, uint8_t Length) +{ + uint8_t chBlock; + uint16_t wCrc; + + 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 +*/ +static uint16_t M24SR_IsCorrectCRC16Residue (uc8 *DataIn,uc8 Length) +{ + uint16_t ResCRC=0; + + /* check the CRC16 Residue */ + if (Length !=0) + ResCRC= M24SR_ComputeCrc (DataIn, Length); + + if ( ResCRC == 0x0000) + { + /* Good CRC, but error status from M24SR */ + return( ((DataIn[Length-UB_STATUS_OFFSET]<<8) & 0xFF00) | (DataIn[Length-LB_STATUS_OFFSET] & 0x00FF) ); + } + else + { + ResCRC=0; + ResCRC= M24SR_ComputeCrc (DataIn, 5); + if ( ResCRC != 0x0000) + { + /* Bad CRC */ + return M24SR_ERROR_CRC; + } + else + { + /* Good CRC, but error status from M24SR */ + return( ((DataIn[1]<<8) & 0xFF00) | (DataIn[2] & 0x00FF) ); + } + } +} + +/** + * @brief Initialize the command and response structure + * @param None + * @retval None + */ +static void M24SR_InitStructure ( 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 = DataBuffer; + // Response.SW1 = 0x00; + // Response.SW2 = 0x00; +} + +/** + * @brief This functions creates an I block command according to the structures CommandStructure and 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 + */ +static void M24SR_BuildIBlockCommand ( uc16 CommandStructure, C_APDU Command, 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 (uc8 *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 (uc8 *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 (uc8 *pBuffer) +{ + + if ((pBuffer[M24SR_OFFSET_PCB] & M24SR_MASK_BLOCK) == M24SR_MASK_SBLOCK) + { + return M24SR_STATUS_SUCCESS; + } + else + { + return M24SR_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. + */ +static uint16_t M24SR_FWTExtension ( uint8_t FWTbyte ) +{ + uint8_t pBuffer[M24SR_STATUSRESPONSE_NBBYTE]; + uint16_t status ; + uint16_t NthByte = 0, + 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_SendI2Ccommand ( NthByte , pBuffer )); + errchk( M24SR_IsAnswerReady ( )); + /* read the response */ + errchk( M24SR_ReceiveI2Cresponse ( M24SR_STATUSRESPONSE_NBBYTE , pBuffer )); + + status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE); + return status; + +Error : + return M24SR_ERROR_I2CTIMEOUT; +} + +/** + * @} + */ + + +/** @defgroup drvM24SR_Public_Functions + * @{ + */ + +/** + * @brief This function initialize the M24SR device + * @retval None + */ +void M24SR_Init( void ) +{ + M24SR_I2CInit(); + // M24SR_GPOInit(); // Empty function + + M24SR_InitStructure(); + +#if defined (I2C_GPO_SYNCHRO_ALLOWED) || defined (I2C_GPO_INTERRUPT_ALLOWED) + if( M24SR_KillSession() == M24SR_ACTION_COMPLETED) + { + M24SR_ManageI2CGPO(I2C_ANSWER_READY); + M24SR_Deselect (); + } +#endif /* I2C_GPO_SYNCHRO_ALLOWED */ +} + +/** + * @brief This function sends the GetSession command to the M24SR device + * @retval M24SR_ACTION_COMPLETED : the function is succesful. + * @retval Status (SW1&SW2) : if operation does not complete. + */ +uint16_t M24SR_GetSession ( void ) +{ + uint8_t Buffer = M24SR_OPENSESSION; + int16_t status; + + errchk(M24SR_SendI2Ccommand ( 0x01 , &Buffer )); + + /* 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_PollI2C ( )); + + return M24SR_ACTION_COMPLETED; +Error : + return M24SR_ERROR_I2CTIMEOUT; +} + + + +/** + * @brief This function sends the KillSession command to the M24SR device + * @param None + * @retval M24SR_ACTION_COMPLETED : the function is succesful. + * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured. + */ +uint16_t M24SR_KillSession ( void ) +{ + uint8_t pBuffer[] = {M24SR_KILLSESSION}; + int8_t status; + + errchk(M24SR_SendI2Ccommand ( 0x01 , pBuffer )); + + /* 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_PollI2C ( )); + + return M24SR_ACTION_COMPLETED; +Error : + return M24SR_ERROR_I2CTIMEOUT; +} + + +/** + * @brief This function sends the Deselect command (S-Block format) + * @retval M24SR_ACTION_COMPLETED : the function is succesful. + * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured. + */ +uint16_t M24SR_Deselect ( void ) +{ + uint8_t pBuffer[] = {0xC2,0xE0,0xB4} ; + int8_t status ; + + /* send the request */ + errchk( M24SR_SendI2Ccommand ( M24SR_DESELECTREQUEST_NBBYTE , pBuffer )); + + errchk( M24SR_IsAnswerReady ( )); + /* flush the M24SR buffer */ + errchk( M24SR_ReceiveI2Cresponse ( M24SR_DESELECTREQUEST_NBBYTE , pBuffer )); + + return M24SR_ACTION_COMPLETED; + +Error : + return M24SR_ERROR_I2CTIMEOUT; +} + + + + +/** + * @brief This function sends the SelectApplication command + * @retval M24SR_ACTION_COMPLETED : the function is succesful. + * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured. + */ +uint16_t M24SR_SelectApplication ( void ) +{ + uint8_t *pBuffer = uM24SRbuffer , + NbByteToRead = M24SR_STATUSRESPONSE_NBBYTE; + uint8_t uLc = 0x07, + pData[] = {0xD2,0x76,0x00,0x00,0x85,0x01,0x01}, + uLe = 0x00; + uint16_t 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 = uLc ; + /* copy the data */ + memcpy(Command.Body.pData, pData, uLc); + /* copy the number of byte to read */ + Command.Body.LE = uLe ; + /* build the IC command */ + M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_SELECTAPPLICATION, Command, &NbByte , pBuffer); + + /* send the request */ + errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer )); + errchk( M24SR_IsAnswerReady ( )); + /* read the response */ + errchk( M24SR_ReceiveI2Cresponse ( NbByteToRead , pBuffer )); + + status = M24SR_IsCorrectCRC16Residue (pBuffer,NbByteToRead); + return status; + +Error : + return M24SR_ERROR_I2CTIMEOUT; +} + +/** + * @brief This function sends the SelectCCFile command + * @retval M24SR_ACTION_COMPLETED : the function is succesful. + * @retval M24SR_ERROR_I2CTIMEOUT : The I2C timeout occured. + * @retval Status (SW1&SW2) : if operation does not complete for another reason. + */ +uint16_t M24SR_SelectCCfile ( void ) +{ + uint8_t *pBuffer = uM24SRbuffer , + NbByteToRead = M24SR_STATUSRESPONSE_NBBYTE; + uint8_t uLc = 0x02; + uint16_t status ; + uint16_t uP1P2 =0x000C, + uNbFileId =CC_FILE_ID, + 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 = uLc ; + /* copy the File Id */ + Command.Body.pData[0] = GETMSB (uNbFileId ) ; + Command.Body.pData[1] = GETLSB (uNbFileId ) ; + /* build the IC command */ + M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_SELECTCCFILE, Command, &NbByte , pBuffer); + + /* send the request */ + errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer )); + errchk( M24SR_IsAnswerReady ( )); + /* read the response */ + errchk( M24SR_ReceiveI2Cresponse ( NbByteToRead , pBuffer )); + + status = M24SR_IsCorrectCRC16Residue (pBuffer,NbByteToRead); + return status; + +Error : + return M24SR_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. + */ +uint16_t M24SR_SelectSystemfile ( void ) +{ + uint8_t *pBuffer = uM24SRbuffer , + NbByteToRead = M24SR_STATUSRESPONSE_NBBYTE; + uint8_t uLc = 0x02; + uint16_t status ; + uint16_t uP1P2 =0x000C, + uNbFileId =SYSTEM_FILE_ID, + 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 = uLc ; + /* copy the File Id */ + Command.Body.pData[0] = GETMSB (uNbFileId ) ; + Command.Body.pData[1] = GETLSB (uNbFileId ) ; + /* build the IC command */ + M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_SELECTCCFILE, Command, &NbByte , pBuffer); + + /* send the request */ + errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer )); + errchk( M24SR_IsAnswerReady ( )); + /* read the response */ + errchk( M24SR_ReceiveI2Cresponse ( NbByteToRead , pBuffer )); + + status = M24SR_IsCorrectCRC16Residue (pBuffer,NbByteToRead); + return status; + +Error : + return M24SR_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. + */ +uint16_t M24SR_SelectNDEFfile ( uc16 NDEFfileId ) +{ + uint8_t *pBuffer = uM24SRbuffer , + NbByteToRead = M24SR_STATUSRESPONSE_NBBYTE; + uint8_t uLc = 0x02; + uint16_t 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 = uLc ; + /* copy the offset */ + Command.Body.pData[0] = GETMSB (NDEFfileId ) ; + Command.Body.pData[1] = GETLSB (NDEFfileId ) ; + /* build the IC command */ + M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_SELECTNDEFFILE, Command, &NbByte , pBuffer); + + /* send the request */ + errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer )); + errchk( M24SR_IsAnswerReady ( )); + /* read the response */ + errchk( M24SR_ReceiveI2Cresponse ( NbByteToRead , pBuffer )); + + status = M24SR_IsCorrectCRC16Residue (pBuffer,NbByteToRead); + return status; + +Error : + return M24SR_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. + */ +uint16_t M24SR_ReadBinary ( uc16 Offset ,uc8 NbByteToRead , uint8_t *pBufferRead ) +{ + uint8_t *pBuffer = uM24SRbuffer ; + uint16_t 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, &NbByte , pBuffer); + + errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer )); + errchk( M24SR_IsAnswerReady ( )); + errchk( M24SR_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 M24SR_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. + */ +uint16_t M24SR_STReadBinary ( uc16 Offset, uc8 NbByteToRead, uint8_t *pBufferRead ) +{ + uint8_t *pBuffer = uM24SRbuffer ; + uint16_t 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, &NbByte , pBuffer); + + errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer )); + errchk( M24SR_IsAnswerReady ( )); + errchk( M24SR_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 M24SR_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. + */ +uint16_t M24SR_UpdateBinary ( uc16 Offset ,uc8 NbByteToWrite,uc8 *pDataToWrite ) +{ + uint8_t *pBuffer = uM24SRbuffer ; + uint16_t 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, &NbByte , pBuffer); + + errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer )); + errchk( M24SR_IsAnswerReady ( )); + errchk( M24SR_ReceiveI2Cresponse ( M24SR_STATUSRESPONSE_NBBYTE , pBuffer )); + /* if the response is a Watiting frame extenstion request */ + if (IsSBlock (pBuffer) == M24SR_STATUS_SUCCESS) + { + /*check the CRC */ + if (M24SR_IsCorrectCRC16Residue (pBuffer , M24SR_WATINGTIMEEXTRESPONSE_NBBYTE) != M24SR_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 M24SR_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. + */ +uint16_t M24SR_Verify ( uc16 uPwdId,uc8 NbPwdByte ,uc8 *pPwd ) +{ + uint8_t *pBuffer = uM24SRbuffer ; + uint16_t status = 0x0000 ; + uint16_t NbByte; + + /*check the parameters */ + if (uPwdId > 0x0003) + { + return M24SR_ERROR_PARAMETER; + } + if ( (NbPwdByte != 0x00) && (NbPwdByte != 0x10)) + { + return M24SR_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 IC command */ + M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_VERIFYBINARYWITHPWD, Command, &NbByte , pBuffer); + } + else + { + /* build the IC command */ + M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_VERIFYBINARYWOPWD, Command, &NbByte , pBuffer); + } + + /* send the request */ + errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer )); + /* wait for answer ready */ + errchk( M24SR_IsAnswerReady ( )); + /* read the response */ + errchk( M24SR_ReceiveI2Cresponse ( M24SR_STATUSRESPONSE_NBBYTE , pBuffer )); + + status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE); + return status; + +Error : + return M24SR_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. + */ +uint16_t M24SR_ChangeReferenceData ( uc16 uPwdId,uc8 *pPwd ) +{ + uint8_t *pBuffer = uM24SRbuffer; + uint16_t status ; + uint16_t NbByte; + + /*check the parameters */ + if (uPwdId > 0x0003) + { + return M24SR_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 IC command */ + M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_CHANGEREFDATA, Command, &NbByte , pBuffer); + + + /* send the request */ + errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer )); + errchk( M24SR_IsAnswerReady ( )); + /* read the response */ + errchk( M24SR_ReceiveI2Cresponse ( M24SR_STATUSRESPONSE_NBBYTE , pBuffer )); + + status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE); + return status; + +Error : + return M24SR_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. + */ +uint16_t M24SR_EnableVerificationRequirement ( uc16 uReadOrWrite ) +{ + uint8_t *pBuffer = uM24SRbuffer; + uint16_t status ; + uint16_t NbByte; + + /*check the parameters */ + if ( (uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002)) + { + return M24SR_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 IC command */ + M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_ENABLEVERIFREQ, Command, &NbByte , pBuffer); + + /* send the request */ + errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer )); + /* The right access to be updated in EEPROM need at least 6ms */ + errchk( M24SR_IsAnswerReady ( )); + /* read the response */ + errchk( M24SR_ReceiveI2Cresponse ( M24SR_STATUSRESPONSE_NBBYTE , pBuffer )); + + status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE); + return status; + +Error : + return M24SR_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. + */ +uint16_t M24SR_DisableVerificationRequirement ( uc16 uReadOrWrite ) +{ + uint8_t *pBuffer = uM24SRbuffer; + uint16_t status ; + uint16_t NbByte; + + /*check the parameters */ + if ( (uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002)) + { + return M24SR_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 IC command */ + M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_DISABLEVERIFREQ, Command, &NbByte , pBuffer); + + /* send the request */ + errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer )); + /* The right access to be updated in EEPROM need at least 6ms */ + errchk( M24SR_IsAnswerReady ( )); + /* read the response */ + errchk( M24SR_ReceiveI2Cresponse ( M24SR_STATUSRESPONSE_NBBYTE , pBuffer )); + + status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE); + return status; + +Error : + return M24SR_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. + */ +uint16_t M24SR_EnablePermanentState ( uc16 uReadOrWrite ) +{ + uint8_t *pBuffer = uM24SRbuffer; + uint16_t status ; + uint16_t NbByte; + + /*check the parameters */ + if ( (uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002)) + { + return M24SR_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 IC command */ + M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_ENABLEVERIFREQ, Command, &NbByte , pBuffer); + + /* send the request */ + errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer )); + errchk( M24SR_IsAnswerReady ( )); + /* read the response */ + errchk( M24SR_ReceiveI2Cresponse ( M24SR_STATUSRESPONSE_NBBYTE , pBuffer )); + + status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE); + return status; + +Error : + return M24SR_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. + */ +uint16_t M24SR_DisablePermanentState ( uc16 uReadOrWrite ) +{ + uint8_t *pBuffer = uM24SRbuffer; + uint16_t status ; + uint16_t NbByte; + + /*check the parameters */ + if ( (uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002)) + { + return M24SR_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 IC command */ + M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_DISABLEVERIFREQ, Command, &NbByte , pBuffer); + + /* send the request */ + errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer )); + errchk( M24SR_IsAnswerReady ( )); + /* read the response */ + errchk( M24SR_ReceiveI2Cresponse ( M24SR_STATUSRESPONSE_NBBYTE , pBuffer )); + + status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE); + return status; + +Error : + return M24SR_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. + */ +uint16_t M24SR_SendInterrupt ( void ) +{ + uint8_t *pBuffer = uM24SRbuffer; + uint16_t uP1P2 =0x001E; + uint16_t status ; + 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 IC command */ + M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_SENDINTERRUPT, Command, &NbByte , pBuffer); + + /* send the request */ + errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer )); + errchk( M24SR_IsAnswerReady ( )); + /* read the response */ + errchk( M24SR_ReceiveI2Cresponse ( M24SR_STATUSRESPONSE_NBBYTE , pBuffer )); + + status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE); + return status; + +Error : + return M24SR_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. + */ +uint16_t M24SR_StateControl ( uc8 uSetOrReset ) +{ + uint8_t *pBuffer = uM24SRbuffer; + uint16_t uP1P2 =0x001F; + uint16_t status ; + uint16_t NbByte; + + /*check the parameters */ + if ( (uSetOrReset != 0x01) && (uSetOrReset != 0x00)) + { + return M24SR_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 IC command */ + M24SR_BuildIBlockCommand ( M24SR_CMDSTRUCT_GPOSTATE, Command, &NbByte , pBuffer); + + /* send the request */ + errchk( M24SR_SendI2Ccommand ( NbByte , pBuffer )); + errchk( M24SR_IsAnswerReady ( )); + /* read the response */ + errchk( M24SR_ReceiveI2Cresponse ( M24SR_STATUSRESPONSE_NBBYTE , pBuffer )); + + status = M24SR_IsCorrectCRC16Residue (pBuffer, M24SR_STATUSRESPONSE_NBBYTE); + return status; + +Error : + return M24SR_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. + */ +uint16_t M24SR_ManageI2CGPO( uc8 GPO_I2Cconfig) +{ + uint16_t 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 M24SR_ERROR_PARAMETER; + } + + /* we must not be in interrupt mode for I2C synchro as we will change GPO purpose */ + M24SR_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) ); + + /* if we have set interrupt mode for I2C synchro we can enable interrupt mode */ + if ( GPO_I2Cconfig == I2C_ANSWER_READY && status == M24SR_ACTION_COMPLETED) +#ifdef I2C_GPO_SYNCHRO_ALLOWED + M24SR_SetI2CSynchroMode(M24SR_WAITINGTIME_GPO); +#else + M24SR_SetI2CSynchroMode(M24SR_INTERRUPT_GPO); +#endif + + 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. + */ +uint16_t M24SR_ManageRFGPO( uc8 GPO_RFconfig) +{ + uint16_t 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 M24SR_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. + */ +void M24SR_RFConfig( uc8 OnOffChoice) +{ + M24SR_RFConfig_Hard(OnOffChoice); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r ffc2448b65ef m24sr.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/m24sr.h Mon Dec 15 19:41:52 2014 +0000 @@ -0,0 +1,233 @@ +/** + ****************************************************************************** + * @file drv_M24SR.h + * @author MMY Application Team + * @version V4.5.0 + * @date 08-May-2013 + * @brief This file provides a set of functions needed to manage M24SR + ****************************************************************************** + * @attention + * + * <h2><center>© 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 + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "drv_I2C_M24SR.h" + + +/* ---------------------- macro function -------------------------------------*/ +#define GETMSB(val) ( (uint8_t) ((val & 0xFF00 )>>8) ) +#define GETLSB(val) ( (uint8_t) (val & 0x00FF )) + +#define TOGGLE(val) ((val != 0x00)? 0x00 : 0x01) + +/* ---------------------- status code ----------------------------------------*/ +#define M24SR_ACTION_COMPLETED 0x9000 +#define UB_STATUS_OFFSET 4 +#define LB_STATUS_OFFSET 3 + +#define M24SR_NBBYTE_INVALID 0xFFFE + +/*-------------------------- File Identifier ---------------------------------*/ +#define SYSTEM_FILE_ID 0xE101 +#define CC_FILE_ID 0xE103 +#define NDEF_FILE_ID 0x0001 + +/*-------------------------- Password Management -----------------------------*/ +#define READ_PWD 0x0001 +#define WRITE_PWD 0x0002 +#define I2C_PWD 0x0003 + +/*-------------------------- Verify command answer ----------------------------*/ +#define M24SR_PWD_NOT_NEEDED 0x9000 +#define M24SR_PWD_NEEDED 0x6300 + +#define M24SR_PWD_CORRECT 0x9000 + + + + +/* special M24SR command ----------------------------------------------------------------------*/ +#define M24SR_OPENSESSION 0x26 +#define M24SR_KILLSESSION 0x52 + +/* Length ----------------------------------------------------------------------------------*/ +#define M24SR_STATUS_NBBYTE 2 +#define M24SR_CRC_NBBYTE 2 +#define M24SR_STATUSRESPONSE_NBBYTE 5 +#define M24SR_DESELECTREQUEST_NBBYTE 3 +#define M24SR_DESELECTRESPONSE_NBBYTE 3 +#define M24SR_WATINGTIMEEXTRESPONSE_NBBYTE 4 +#define M24SR_PASSWORD_NBBYTE 0x10 + +/* 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 + + +/* 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 + + +/* 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; + +/* APDU-Body command structure -----------------------------------------------*/ +typedef struct +{ + uint8_t LC; /* Data field length */ + uint8_t *pData ; /* Command parameters */ + uint8_t LE; /* Expected length of data to be returned */ +} C_APDU_Body; + +/* APDU Command structure ----------------------------------------------------*/ +typedef struct +{ + C_APDU_Header Header; + C_APDU_Body Body; +} C_APDU; + +/* 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; + +/* GPO mode structure -------------------------------------------------------*/ +typedef enum{ + RF_GPO= 0, + I2C_GPO +}M24SR_GPO_MODE; + +/* GPO state structure -------------------------------------------------------*/ +typedef enum{ + HIGH_IMPEDANCE= 0, + SESSION_OPENED, + WIP, + I2C_ANSWER_READY, + INTERRUPT, + STATE_CONTROL +}M24SR_GPO_MGMT; + + +/* public function --------------------------------------------------------------------------*/ + +void M24SR_Init ( void ); +uint16_t M24SR_GetSession ( void ); +uint16_t M24SR_KillSession ( void ); +uint16_t M24SR_Deselect ( void ); +uint16_t M24SR_SelectApplication ( void ); +uint16_t M24SR_SelectCCfile ( void ); +uint16_t M24SR_SelectNDEFfile ( uc16 NDEFfileId ); +uint16_t M24SR_SelectSystemfile ( void ); +uint16_t M24SR_ReadBinary ( uc16 Offset, uc8 NbByteToRead, uint8_t *pBufferRead ); +uint16_t M24SR_STReadBinary ( uc16 Offset, uc8 NbByteToRead, uint8_t *pBufferRead ); +uint16_t M24SR_UpdateBinary ( uc16 Offset, uc8 NbByteToWrite, uc8 *pDataToWrite ); +uint16_t M24SR_Verify ( uc16 uPwdId, uc8 NbPwdByte, uc8 *pPwd ); +uint16_t M24SR_ChangeReferenceData ( uc16 uPwdId, uc8 *pPwd ); +uint16_t M24SR_EnableVerificationRequirement ( uc16 uReadOrWrite ); +uint16_t M24SR_DisableVerificationRequirement ( uc16 uReadOrWrite ); +uint16_t M24SR_EnablePermanentState ( uc16 uReadOrWrite ); +uint16_t M24SR_DisablePermanentState ( uc16 uReadOrWrite ); +uint16_t M24SR_SendInterrupt ( void ); +uint16_t M24SR_StateControl ( uc8 uSetOrReset ); +uint16_t M24SR_ManageI2CGPO ( uc8 GPO_I2Cconfig); +uint16_t M24SR_ManageRFGPO ( uc8 GPO_RFconfig); +void M24SR_RFConfig ( uc8 OnOffChoice); + +#ifdef __cplusplus +} +#endif + +#endif /* __DRV_M24SR_H */ + + + + +/******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/