Complete mbed library/workspace for HelloWorld_NFC02A1

Dependencies:   NDefLib X_NUCLEO_NFC02A1 mbed

Fork of HelloWorld_NFC02A1 by ST Expansion SW Team

X-NUCLEO-NFC02A1 Dynamic NFC Tag Expansion Board Firmware Package

Introduction

This firmware package includes Components Device Drivers, Board Support Package and example applications for STMicroelectronics X-NUCLEO-NFC02A1 Dynamic NFC Tag Expansion Board based on M24LR.

Example Application

This is just a simple "hello world" style program for the X-NUCLEO-NFC02A1 Dynamic NFC Tag Expansion Board. The program writes a URI link to the M24LR dynamic tag using the synchronous programming model. It then reads back the URI from the tag to display it on terminal. The URI can also be retrieved from an NFC enabled smartphone/tablet.

Lib_NDEF/tagtype5_wrapper.cpp

Committer:
rosarium
Date:
2016-07-27
Revision:
0:892175366555

File content as of revision 0:892175366555:

/**
  ******************************************************************************
  * @file    tagtype5_wrapper.c 
  * @author  MMY Application Team
  * @version $Revision: 1638 $
  * @date    $Date: 2016-02-10 16:41:05 +0100 (Wed, 10 Feb 2016) $
  * @brief   Interface for tagtype5 in order to use NDEF lib
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
  *
  * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
  * You may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
  *
  *        http://www.st.com/myliberty  
  *
  * Unless required by applicable law or agreed to in writing, software 
  * distributed under the License is distributed on an "AS IS" BASIS, 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
  * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "tagtype5_wrapper.h"
#include "lib_NDEF.h"


/**
  * @brief  This function read the data stored in NDEF file at defined offset.
  * @param  Offset : Offset in the NDEF file.
  * @param  DataSize : Number of byte to read.
  * @param  pData : pointer on buffer to store read data.
  * @retval NDEF_ERROR_MEMORY_INTERNAL : Size not compatible with memory.
  * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported.
  * @retval NDEF_ERROR : No NDEF in the tag.
  * @retval NDEF_OK : The operation is completed.
  */
uint16_t NFCType5::ReadData( uint16_t Offset , uint16_t DataSize , uint8_t* pData )
{
  uint16_t status = NDEF_ERROR;
  uint8_t atlv_detect[4];
  uint8_t index = 0;
  
  /* Do not include length bytes */
  DataSize -= FIRST_RECORD_OFFSET;
  
  /* If too many data to write return error */
  if( DataSize > NDEF_MAX_SIZE )
  {
    return NDEF_ERROR_MEMORY_INTERNAL;
  }
  
  /* Detect NDEF message in memory */
  status = NfcType5_NDEFDetection( );
  if( status != NDEF_OK )
  {
    return status;
  }
  
  /* Read TL of Type 5 */
  status = NFCTAG_ReadData( atlv_detect, CCFileStruct.NDEF_offset, 4 );
  if( status != NDEF_OK )
  {
    return status;
  }
  
  /* Check if L is on 3 or 1 byte and update length in buffer */
  if( atlv_detect[1] == NFCT5_3_BYTES_L_TLV )
  {
    pData[0] = atlv_detect[2];
    pData[1] = atlv_detect[3];
    index += 4;
  }
  else
  {
    pData[0] = 0x00;
    pData[1] = atlv_detect[1];
    index += 2;
  }
  
  /* Check CC file is in the correct mode to proceed */
  if( CCFileStruct.State ==  TT5_INITIALIZED )
  {
    return NDEF_ERROR;
  }

  if( ((Offset == 0) && (DataSize > 0)) || (Offset > 0) )
  {
    /* Read NDEF */
    if( NFCTAG_ReadData( (pData + FIRST_RECORD_OFFSET), CCFileStruct.NDEF_offset + index + Offset, DataSize ) != NFCTAG_OK )
    {
      return NDEF_ERROR;
    }
  }
  
  return NDEF_OK;
}

/**
  * @brief  This function writes data in NDEF file at defined offset.
  * @param  Offset : Offset in the NDEF file.
  * @param  DataSize : Number of byte to write.
  * @param  pData : pointer on buffer to copy.
  * @retval NDEF_ERROR_MEMORY_INTERNAL : Size not compatible with memory.
  * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported.
  * @retval NDEF_ERROR : No NDEF in the tag.
  * @retval NDEF_OK : The operation is completed.
  */
uint16_t NFCType5::WriteData( uint16_t Offset , uint32_t DataSize , uint8_t *pData )
{
  uint8_t atlv[4];
  uint8_t index = 0;
  uint16_t NDEF_Size = 0;
  NFCTAG_StatusTypeDef status;

  /* Do not include length bytes */
  DataSize -= FIRST_RECORD_OFFSET;
  
  /* If too many data to write return error */
  if( DataSize > NDEF_MAX_SIZE )
  {
    return NDEF_ERROR_MEMORY_INTERNAL;
  }
  
  /* Detect NDEF message in memory */
  if( NfcType5_NDEFDetection( ) != NDEF_OK )
  {
    return NDEF_ERROR;
  }
  
  /* Extract NDEF Size from buffer */
  NDEF_Size = (uint16_t)(pData[0] << 8);
  NDEF_Size = NDEF_Size | (uint16_t)(pData[1] );
  
  /* If entire NDEF is written, update Length of Type 5 */
  if( DataSize == NDEF_Size )
  {
    /* Check if L is on 3 or 1 byte */
    if( NDEF_Size >= NFCT5_3_BYTES_L_TLV )
    {
      /* First init L with 0, will be updated at the end */
      atlv[1] = 0x00;
      atlv[2] = 0x00;
      atlv[3] = 0x00;
      
      status = NFCTAG_WriteData( (atlv + 1), (CCFileStruct.NDEF_offset + 1), 3 );
      
      index += 4; 
    }
    else
    {
      /* First inti L with 0, will be updated at the end */
      atlv[1] = 0x00;
      
      status = NFCTAG_WriteData( (atlv + 1), (CCFileStruct.NDEF_offset + 1), 1 );
      
      index += 2;
    }
  }
  
  /* Start write NDEF message to EEPROM */
  status = NFCTAG_WriteData( (pData + FIRST_RECORD_OFFSET), CCFileStruct.NDEF_offset + index + Offset, DataSize );
  if( status != NFCTAG_OK )
  {
    return NDEF_ERROR;
  }
  
  /* If entire NDEF is written, update Length of Type 5 */
  if( DataSize == NDEF_Size )
  {
    /* Check if L is on 3 or 1 byte */
    if( NDEF_Size >= NFCT5_3_BYTES_L_TLV )
    {
      /* Update Length value */
      atlv[1] = NFCT5_3_BYTES_L_TLV;
      atlv[2] = pData[0];
      atlv[3] = pData[1];
      
      status = NFCTAG_WriteData( (atlv + 1), (CCFileStruct.NDEF_offset + 1), 3 );
    }
    else
    {
      /* Update Length value */
      atlv[1] = pData[1];
      
      status = NFCTAG_WriteData( (atlv + 1), (CCFileStruct.NDEF_offset + 1), 1 );
    }

    /* Write Terminator TLV */
    atlv[0] = NFCT5_TERMINATOR_TLV;
    status = NFCTAG_WriteData( atlv, CCFileStruct.NDEF_offset + index + NDEF_Size, 1 );
  }
  
  return NDEF_OK;
}

/**
  * @brief  This functions writes CCFile in EEPROM.
  * @Param  pCCBuffer : pointer on the buffer containnig CC file.
  * @retval NFCTAG status.
  */
uint16_t NFCType5::NfcType5_WriteCCFile( const uint8_t * const pCCBuffer )
{
  NFCTAG_StatusTypeDef ret_value;
  
  /* Write first block of CCFile */
  ret_value = NFCTAG_WriteData( pCCBuffer, 0x00, 0x4 );
 
  /* If extended memory writes the next 4 bytes */
  if( (pCCBuffer[2] == 0x00) && (ret_value == NFCTAG_OK) )
  {
    ret_value = NFCTAG_WriteData( pCCBuffer + 4, 0x04, 4 );
  }

  if( ret_value != NFCTAG_OK )
  {
    return NDEF_ERROR;
  }
  
    return NDEF_OK;
}

/**
  * @brief  This functions reads CCFile in EEPROM.
  * @Param  pCCBuffer : pointer on the buffer to store CC file.
  * @retval NFCTAG status.
  */
uint16_t NFCType5::NfcType5_ReadCCFile( uint8_t * const pCCBuffer )
{
  NFCTAG_StatusTypeDef ret_value;
  
  /* Read 4 bytes of CC File */
  ret_value = NFCTAG_ReadData( pCCBuffer, 0x00, 4 );

  /* If extended memory reads the next 4 bytes */
  if( (pCCBuffer[2] == 0x00) && (ret_value == NFCTAG_OK) )
  {
    ret_value = NFCTAG_ReadData( pCCBuffer + 4, 0x04, 4 );
  }
  
  if( ret_value != NFCTAG_OK )
  {
    return NDEF_ERROR;
  }
  
    return NDEF_OK;
}

/**
  * @brief  This function initialize memory in Tag Type 5.
  * @retval NFCTAG status.
  */
uint16_t NFCType5::NfcType5_TT5Init( void )
{
  NFCTAG_StatusTypeDef ret_value = NFCTAG_OK;
  uint16_t status;
  uint8_t accbuffer[8];
  uint8_t cdata;

  /* Prepare buffer to update CCFile */
  accbuffer[0] = CCFileStruct.MagicNumber;
  accbuffer[1] = CCFileStruct.Version;
  accbuffer[2] = CCFileStruct.MemorySize;
  accbuffer[3] = CCFileStruct.TT5Tag;
  CCFileStruct.NDEF_offset = 0x04;
  
  /* If extended memory prepare the length bytes */
  if( CCFileStruct.MemorySize == NFCT5_EXTENDED_CCFILE )
  {
    accbuffer[6] = (uint8_t)(CCFileStruct.ExtMemorySize >> 8);
    accbuffer[7] = (uint8_t)(CCFileStruct.ExtMemorySize & 0xFF);
    CCFileStruct.NDEF_offset = 0x08;
  }
  
  /* Update CCFile */
  status = NfcType5_WriteCCFile( accbuffer );
  if( status != NDEF_OK )
  {
    return status;
  }
  
  /* Update NDEF TLV for INITIALIZED state */
  /* Update T */
  cdata = NFCT5_NDEF_MSG_TLV;
  ret_value = NFCTAG_WriteData( &cdata, CCFileStruct.NDEF_offset, 1 );
  if( ret_value != NFCTAG_OK )
  {
    return NDEF_ERROR;
  }

  /* Update L */
  cdata = 0x00;
  ret_value = NFCTAG_WriteData( &cdata, (CCFileStruct.NDEF_offset + 1), 1 );
  if( ret_value != NFCTAG_OK )
  {
    return NDEF_ERROR;
  }
  
  return NDEF_OK;
}

/**
  * @brief  This function detects an NDEF message Tag Type 5 in EEPROM.
  * @retval NDEF_OK : NDEF message Tag Type 5 detected.
  * @retval NDEF_ERROR_NOT_FORMATED : Device is not an NFC Tag Type 5 Tag.
  * @retval NDEF_NO_NDEF_DETECTED : No NDEF Detected.
  */
uint16_t NFCType5::NfcType5_NDEFDetection( void )
{
  uint8_t acc_buffer[8];
  uint8_t atlv_detect[4];
  uint16_t status;
  uint32_t memory_size;
  
  CCFileStruct.State = TT5_NO_NDEF;
  
  /* Read CCFile */
  status = NfcType5_ReadCCFile( acc_buffer );
  if( status != NDEF_OK )
  {
    return status;
  }
  
  /* Check Byte 0 is equal to magic number */
  if( ( acc_buffer[0] != NFCT5_MAGICNUMBER_E1_CCFILE ) && ( acc_buffer[0] != NFCT5_MAGICNUMBER_E2_CCFILE ) )
  {
    return NDEF_ERROR_NOT_FORMATED;
  }
  /* Check Version number */
  else if( ( (acc_buffer[1]&0xFC) != 0x40 ) )
  {
    return NDEF_ERROR_NOT_FORMATED;
  }
  
  /* Check if CCFile is on 4 Bytes or 8 Bytes */
  if( acc_buffer[2] == 0x00 )
  {
    /* Update CCFIle structure */
    CCFileStruct.MemorySize = 0x0;
    CCFileStruct.ExtMemorySize = (uint16_t)acc_buffer[6];
    CCFileStruct.ExtMemorySize = ( CCFileStruct.ExtMemorySize << 8 ) |  acc_buffer[7];
    memory_size = CCFileStruct.ExtMemorySize;
    CCFileStruct.NDEF_offset = 8;
  }
  else
  {
    /* Update CCFIle structure */
    CCFileStruct.MemorySize = acc_buffer[2];
    CCFileStruct.ExtMemorySize = 0x0;
    memory_size = CCFileStruct.MemorySize;
    CCFileStruct.NDEF_offset = 4;
  }
  
  /* Update CCFIle structure */
  CCFileStruct.MagicNumber = acc_buffer[0];
  CCFileStruct.Version = acc_buffer[1];
  CCFileStruct.TT5Tag = acc_buffer[3];
  
  /* Search for position of NDEF TLV in memory and tag status */
  while( ( NFCTAG_ReadData( atlv_detect, CCFileStruct.NDEF_offset, 4 ) == NFCTAG_OK ) && ( CCFileStruct.NDEF_offset < memory_size ) )
  {
    /* Detect first NDEF Message in memory */
    if( atlv_detect[0] == NFCT5_NDEF_MSG_TLV )
    {
      if( atlv_detect[1] == 0x00 )
      {
        CCFileStruct.State = TT5_INITIALIZED;
      }
      else
      {
        if( CCFileStruct.Version & 0x3 )
        {
          CCFileStruct.State = TT5_READ;
        }
        else
        {
          CCFileStruct.State = TT5_READ_WRITE;
        }
      }
      return NDEF_OK;
    }
    /* If Proprietary NDEF jump to end of proprietary message */
    else if( atlv_detect[0] == NFCT5_PROPRIETARY_TLV )
    {
      if( atlv_detect[1] == NFCT5_3_BYTES_L_TLV )
      {
        CCFileStruct.NDEF_offset = CCFileStruct.NDEF_offset + ( (uint32_t)atlv_detect[2] << 8 ) + atlv_detect[3];
        continue;
      }
      else
      {
        CCFileStruct.NDEF_offset = CCFileStruct.NDEF_offset + atlv_detect[1];
        continue;
      }
    }
    /* if Terminator no NDEF detected */
    else if( atlv_detect[0] == NFCT5_TERMINATOR_TLV )
    {
      return NDEF_ERROR_NOT_FORMATED;
    }
      
    CCFileStruct.NDEF_offset++;
  }
  
  return NDEF_ERROR_NOT_FORMATED;
}

/**
  * @}
  */ 

/**
  * @}
  */ 

/**
  * @}
  */ 

/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/