Firmware library for the X-NUCLEO-NFC01A1 Dynamic NFC Tag board.

Dependencies:   M24SR

Dependents:   NFC M2M_2016_STM32 MyongjiElec_capstone1 IDW01M1_Cloud_IBM ... more

Fork of X_NUCLEO_NFC01A1 by ST Expansion SW Team

X-NUCLEO-NFC01A1 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-NFC01A1 Dynamic NFC Tag Expansion Board based on M24SR.

Firmware Library

Class X_NUCLEO_NFC01A1 is intended to represent the Dynamic NFC Tag Expansion Board with the same name.
It provides an API to access to the M24SR component and to the three onboard LEDs.
It is intentionally implemented as a singleton because only one X_NUCLEO_NFC01A1 at a time might be deployed in a HW component stack.
The library also provides an implementation of the NDEF library API for M24SR, providing an simple way to read/write NDEF formatted messages from/to the M24SR dynamic NFC tag.

Example applications

1. Hello World
2. Asynchronous Hello World

Committer:
Davidroid
Date:
Wed Jul 12 14:15:02 2017 +0000
Revision:
33:e6b7e74be1d5
Parent:
29:7a2dfd06cb29
Updated to fit ARM mbed coding style.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
giovannivisentini 6:96389fb79676 1 /**
giovannivisentini 6:96389fb79676 2 ******************************************************************************
giovannivisentini 6:96389fb79676 3 * @file NdefNfcTagSTM24SR.cpp
giovannivisentini 6:96389fb79676 4 * @author ST Central Labs
giovannivisentini 29:7a2dfd06cb29 5 * @version V2.0.0
giovannivisentini 29:7a2dfd06cb29 6 * @date 28 Apr 2017
giovannivisentini 24:9f98eafa2d39 7 * @brief Wrapper class of the NDefLib library to write/read NDEF messages
giovannivisentini 6:96389fb79676 8 ******************************************************************************
giovannivisentini 9:9f2e2e68d695 9 * @attention
giovannivisentini 6:96389fb79676 10 *
giovannivisentini 9:9f2e2e68d695 11 * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
giovannivisentini 6:96389fb79676 12 *
giovannivisentini 6:96389fb79676 13 * Redistribution and use in source and binary forms, with or without modification,
giovannivisentini 6:96389fb79676 14 * are permitted provided that the following conditions are met:
giovannivisentini 6:96389fb79676 15 * 1. Redistributions of source code must retain the above copyright notice,
giovannivisentini 6:96389fb79676 16 * this list of conditions and the following disclaimer.
giovannivisentini 6:96389fb79676 17 * 2. Redistributions in binary form must reproduce the above copyright notice,
giovannivisentini 6:96389fb79676 18 * this list of conditions and the following disclaimer in the documentation
giovannivisentini 6:96389fb79676 19 * and/or other materials provided with the distribution.
giovannivisentini 6:96389fb79676 20 * 3. Neither the name of STMicroelectronics nor the names of its contributors
giovannivisentini 6:96389fb79676 21 * may be used to endorse or promote products derived from this software
giovannivisentini 6:96389fb79676 22 * without specific prior written permission.
giovannivisentini 6:96389fb79676 23 *
giovannivisentini 6:96389fb79676 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
giovannivisentini 6:96389fb79676 25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
giovannivisentini 6:96389fb79676 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
giovannivisentini 6:96389fb79676 27 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
giovannivisentini 6:96389fb79676 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
giovannivisentini 6:96389fb79676 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
giovannivisentini 6:96389fb79676 30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
giovannivisentini 6:96389fb79676 31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
giovannivisentini 6:96389fb79676 32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
giovannivisentini 6:96389fb79676 33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
giovannivisentini 6:96389fb79676 34 *
giovannivisentini 6:96389fb79676 35 ******************************************************************************
giovannivisentini 6:96389fb79676 36 */
giovannivisentini 19:0b65a5813059 37
giovannivisentini 19:0b65a5813059 38 #include <cmath>
giovannivisentini 6:96389fb79676 39
giovannivisentini 6:96389fb79676 40 #include "NDefNfcTagM24SR.h"
giovannivisentini 12:d1f5eaa85deb 41
giovannivisentini 19:0b65a5813059 42
giovannivisentini 6:96389fb79676 43 /* wait 1sec, driver is configured to let 200ms for command to complete */
giovannivisentini 6:96389fb79676 44 /* which is enough for all commands except GetSession if RF session is already opened */
giovannivisentini 9:9f2e2e68d695 45 /* Smartphone generally releases the session within the second, anyway the user can modify this value */
giovannivisentini 6:96389fb79676 46 #define OPENSESSION_NTRIALS 5
giovannivisentini 6:96389fb79676 47
giovannivisentini 6:96389fb79676 48 #define CC_FILE_LENGTH_BYTE 15
giovannivisentini 19:0b65a5813059 49 ////////////////////////////START OpenSessionCallBack/////////////////////////
giovannivisentini 19:0b65a5813059 50 NDefNfcTagM24SR::OpenSessionCallBack::
giovannivisentini 19:0b65a5813059 51 OpenSessionCallBack(NDefNfcTagM24SR& sender):
Davidroid 33:e6b7e74be1d5 52 mSender(sender), mNTrials(OPENSESSION_NTRIALS){}
giovannivisentini 19:0b65a5813059 53
Davidroid 33:e6b7e74be1d5 54 void NDefNfcTagM24SR::OpenSessionCallBack::on_session_open(M24SR *nfc, M24SR::StatusTypeDef status) {
Davidroid 33:e6b7e74be1d5 55 if (status==M24SR::M24SR_SUCCESS) {
giovannivisentini 29:7a2dfd06cb29 56 nfc->select_application();
Davidroid 33:e6b7e74be1d5 57 } else {
giovannivisentini 29:7a2dfd06cb29 58 mSender.mCallBack->on_session_open(&mSender,false);
giovannivisentini 19:0b65a5813059 59 }
giovannivisentini 19:0b65a5813059 60 }
giovannivisentini 19:0b65a5813059 61
Davidroid 33:e6b7e74be1d5 62 void NDefNfcTagM24SR::OpenSessionCallBack::on_selected_application(M24SR *nfc, M24SR::StatusTypeDef status) {
Davidroid 33:e6b7e74be1d5 63 if (status==M24SR::M24SR_SUCCESS) {
giovannivisentini 29:7a2dfd06cb29 64 nfc->select_CC_file();
Davidroid 33:e6b7e74be1d5 65 } else {
Davidroid 33:e6b7e74be1d5 66 if (mNTrials==0) {
giovannivisentini 29:7a2dfd06cb29 67 mSender.mCallBack->on_session_open(&mSender,false);
Davidroid 33:e6b7e74be1d5 68 } else {
giovannivisentini 19:0b65a5813059 69 mNTrials--;
giovannivisentini 29:7a2dfd06cb29 70 nfc->select_application();
giovannivisentini 19:0b65a5813059 71 }//if-else
giovannivisentini 19:0b65a5813059 72 }//if-else
giovannivisentini 19:0b65a5813059 73 }
giovannivisentini 19:0b65a5813059 74
Davidroid 33:e6b7e74be1d5 75 void NDefNfcTagM24SR::OpenSessionCallBack::on_selected_CC_file(M24SR *nfc, M24SR::StatusTypeDef status) {
Davidroid 33:e6b7e74be1d5 76 if (status==M24SR::M24SR_SUCCESS) {
giovannivisentini 29:7a2dfd06cb29 77 nfc->read_binary(0x0000, CC_FILE_LENGTH_BYTE, CCFile);
Davidroid 33:e6b7e74be1d5 78 } else {
giovannivisentini 29:7a2dfd06cb29 79 mSender.mCallBack->on_session_open(&mSender,false);
giovannivisentini 19:0b65a5813059 80 }
giovannivisentini 19:0b65a5813059 81 }
giovannivisentini 19:0b65a5813059 82
Davidroid 33:e6b7e74be1d5 83 void NDefNfcTagM24SR::OpenSessionCallBack::on_read_byte(M24SR *nfc, M24SR::StatusTypeDef status, uint16_t offset, uint8_t *readByte, uint16_t nReadByte) {
giovannivisentini 19:0b65a5813059 84 (void)offset;
Davidroid 33:e6b7e74be1d5 85 if (status!=M24SR::M24SR_SUCCESS || nReadByte!=CC_FILE_LENGTH_BYTE) {
giovannivisentini 29:7a2dfd06cb29 86 return mSender.mCallBack->on_session_open(&mSender,false);
giovannivisentini 19:0b65a5813059 87 }//else
giovannivisentini 19:0b65a5813059 88 uint16_t NDefFileId = (uint16_t) ((readByte[0x09] << 8) | readByte[0x0A]);
giovannivisentini 19:0b65a5813059 89 mSender.mMaxReadBytes = (uint16_t) ((readByte[0x03] << 8) | readByte[0x04]);
giovannivisentini 19:0b65a5813059 90 mSender.mMaxWriteBytes = (uint16_t) ((readByte[0x05] << 8) | readByte[0x06]);
giovannivisentini 29:7a2dfd06cb29 91 nfc->select_NDEF_file(NDefFileId);
giovannivisentini 19:0b65a5813059 92 }
giovannivisentini 19:0b65a5813059 93
Davidroid 33:e6b7e74be1d5 94 void NDefNfcTagM24SR::OpenSessionCallBack::on_selected_NDEF_file(M24SR *nfc, M24SR::StatusTypeDef status){
giovannivisentini 19:0b65a5813059 95 (void)nfc;
giovannivisentini 27:3881985097bb 96
giovannivisentini 27:3881985097bb 97 mSender.mIsSessionOpen = status==M24SR::M24SR_SUCCESS;
giovannivisentini 29:7a2dfd06cb29 98 mSender.mCallBack->on_session_open(&mSender,mSender.mIsSessionOpen);
giovannivisentini 19:0b65a5813059 99 }
giovannivisentini 19:0b65a5813059 100 ////////////////////////////END OpenSessionCallBack/////////////////////////
giovannivisentini 6:96389fb79676 101
giovannivisentini 29:7a2dfd06cb29 102 bool NDefNfcTagM24SR::open_session(bool force) {
giovannivisentini 6:96389fb79676 103
Davidroid 33:e6b7e74be1d5 104 if (is_session_open()) {
giovannivisentini 29:7a2dfd06cb29 105 mCallBack->on_session_open(this,true);
giovannivisentini 6:96389fb79676 106 return true;
giovannivisentini 6:96389fb79676 107 }
giovannivisentini 6:96389fb79676 108
giovannivisentini 29:7a2dfd06cb29 109 mDevice.set_callback(&mOpenSessionCallback);
Davidroid 33:e6b7e74be1d5 110 if (force) {
giovannivisentini 29:7a2dfd06cb29 111 return mDevice.force_get_session() == M24SR::M24SR_SUCCESS;
Davidroid 33:e6b7e74be1d5 112 } else {
giovannivisentini 29:7a2dfd06cb29 113 return mDevice.get_session() == M24SR::M24SR_SUCCESS;
Davidroid 33:e6b7e74be1d5 114 }
giovannivisentini 6:96389fb79676 115 }
giovannivisentini 6:96389fb79676 116
giovannivisentini 29:7a2dfd06cb29 117 bool NDefNfcTagM24SR::close_session() {
giovannivisentini 29:7a2dfd06cb29 118 mDevice.set_callback(&mCloseSessionCallback);
giovannivisentini 29:7a2dfd06cb29 119 return mDevice.deselect() == M24SR::M24SR_SUCCESS;
giovannivisentini 6:96389fb79676 120 }
giovannivisentini 6:96389fb79676 121
giovannivisentini 29:7a2dfd06cb29 122 void NDefNfcTagM24SR::WriteByteCallback::on_updated_binary(M24SR *nfc,
Davidroid 33:e6b7e74be1d5 123 M24SR::StatusTypeDef status,uint16_t startOffset, uint8_t *writeByte,uint16_t nWriteByte){
giovannivisentini 6:96389fb79676 124
Davidroid 33:e6b7e74be1d5 125 if (status!=M24SR::M24SR_SUCCESS){ // error -> finish to write
giovannivisentini 19:0b65a5813059 126 mCallback(mCallbackParam,false,mByteToWrite,mNByteToWrite);
giovannivisentini 19:0b65a5813059 127 return;
giovannivisentini 19:0b65a5813059 128 }//else
giovannivisentini 6:96389fb79676 129
giovannivisentini 19:0b65a5813059 130 mByteWrote+=nWriteByte;
Davidroid 33:e6b7e74be1d5 131 if (mByteWrote==mNByteToWrite) { //write all -> finish
giovannivisentini 19:0b65a5813059 132 mCallback(mCallbackParam,true,mByteToWrite,mNByteToWrite);
Davidroid 33:e6b7e74be1d5 133 } else { //else write another slice
Davidroid 33:e6b7e74be1d5 134 uint16_t tempLenght = std::min(mSender.mMaxWriteBytes, (uint16_t)(mNByteToWrite-mByteWrote));
giovannivisentini 29:7a2dfd06cb29 135 nfc->update_binary(startOffset+nWriteByte,tempLenght,writeByte+nWriteByte);
giovannivisentini 19:0b65a5813059 136 }//if-else
giovannivisentini 19:0b65a5813059 137 }
giovannivisentini 19:0b65a5813059 138
giovannivisentini 19:0b65a5813059 139 bool NDefNfcTagM24SR::writeByte(const uint8_t *buffer, uint16_t length,uint16_t offset,
Davidroid 33:e6b7e74be1d5 140 byteOperationCallback_t callback,CallbackStatus_t *callbackStatus){
Davidroid 33:e6b7e74be1d5 141 if (!is_session_open())
giovannivisentini 19:0b65a5813059 142 callback(callbackStatus,false,buffer,length);
giovannivisentini 19:0b65a5813059 143 //else
giovannivisentini 29:7a2dfd06cb29 144 mWriteByteCallback.set_task(buffer,length,callback,callbackStatus);
giovannivisentini 29:7a2dfd06cb29 145 mDevice.set_callback(&mWriteByteCallback);
giovannivisentini 6:96389fb79676 146
giovannivisentini 6:96389fb79676 147 if (length > mMaxWriteBytes) {
giovannivisentini 29:7a2dfd06cb29 148 return mDevice.update_binary(offset, mMaxWriteBytes,(uint8_t*) buffer) == M24SR::M24SR_SUCCESS;
Davidroid 33:e6b7e74be1d5 149 } else {
giovannivisentini 29:7a2dfd06cb29 150 return mDevice.update_binary(offset,length,(uint8_t*)buffer) == M24SR::M24SR_SUCCESS;
giovannivisentini 19:0b65a5813059 151 }//if-else
giovannivisentini 6:96389fb79676 152 }
giovannivisentini 6:96389fb79676 153
giovannivisentini 29:7a2dfd06cb29 154 void NDefNfcTagM24SR::ReadByteCallback::on_read_byte(M24SR *nfc,
Davidroid 33:e6b7e74be1d5 155 M24SR::StatusTypeDef status,uint16_t startOffset, uint8_t *readBffer,uint16_t nReadByte){
giovannivisentini 19:0b65a5813059 156
Davidroid 33:e6b7e74be1d5 157 if (status!=M24SR::M24SR_SUCCESS) { // error -> finish to write
giovannivisentini 19:0b65a5813059 158 mCallback(mCallbackParam,false,mBuffer,mNByteToRead);
giovannivisentini 19:0b65a5813059 159 return;
giovannivisentini 19:0b65a5813059 160 }//else
giovannivisentini 6:96389fb79676 161
giovannivisentini 19:0b65a5813059 162 mByteRead += nReadByte;
Davidroid 33:e6b7e74be1d5 163 if (mByteRead==mNByteToRead) { //read all -> finish
giovannivisentini 19:0b65a5813059 164 mCallback(mCallbackParam,true,mBuffer,mNByteToRead);
Davidroid 33:e6b7e74be1d5 165 } else { //else write another slice
Davidroid 33:e6b7e74be1d5 166 uint16_t tempLenght = std::min(mSender.mMaxReadBytes, (uint16_t)(mNByteToRead-mByteRead));
giovannivisentini 29:7a2dfd06cb29 167 nfc->read_binary(startOffset+nReadByte,tempLenght,readBffer+nReadByte);
giovannivisentini 19:0b65a5813059 168 }//if-else
giovannivisentini 6:96389fb79676 169 }
giovannivisentini 6:96389fb79676 170
giovannivisentini 19:0b65a5813059 171 bool NDefNfcTagM24SR::readByte(const uint16_t byteOffset, const uint16_t length,
Davidroid 33:e6b7e74be1d5 172 uint8_t *buffer, byteOperationCallback_t callback,CallbackStatus_t *callbackStatus) {
Davidroid 33:e6b7e74be1d5 173 if (!is_session_open()) {
giovannivisentini 19:0b65a5813059 174 return callback(callbackStatus,false,buffer,length);
giovannivisentini 19:0b65a5813059 175 }
giovannivisentini 19:0b65a5813059 176 //else
giovannivisentini 29:7a2dfd06cb29 177 mReadByteCallback.set_task(buffer,length,callback,callbackStatus);
giovannivisentini 29:7a2dfd06cb29 178 mDevice.set_callback(&mReadByteCallback);
giovannivisentini 19:0b65a5813059 179
giovannivisentini 19:0b65a5813059 180 if (length > mMaxReadBytes) {
giovannivisentini 29:7a2dfd06cb29 181 return mDevice.read_binary(byteOffset, mMaxReadBytes,buffer)== M24SR::M24SR_SUCCESS;;
Davidroid 33:e6b7e74be1d5 182 } else {
giovannivisentini 29:7a2dfd06cb29 183 return mDevice.read_binary(byteOffset,length,buffer)== M24SR::M24SR_SUCCESS;;
giovannivisentini 19:0b65a5813059 184 }//if-else
giovannivisentini 19:0b65a5813059 185 }