Demonstration of possible usage of the NFC EEPROM class (including support for ST25DV NFC chip)

Dependencies:   eeprom_driver

Files at this revision

API Documentation at this revision

Comitter:
mbed_official
Date:
Mon Sep 24 17:09:39 2018 +0100
Child:
1:d3ec956b7957
Commit message:
Add mbed deploy into the SmartPoster instructions.
.
Commit copied from https://github.com/ARMmbed/mbed-os-example-nfc

Changed in this revision

.mbed Show annotated file Show diff for this revision Revisions of this file
README.md Show annotated file Show diff for this revision Revisions of this file
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
mbed_app.json Show annotated file Show diff for this revision Revisions of this file
source/EEPROMDriver.h Show annotated file Show diff for this revision Revisions of this file
source/main.cpp Show annotated file Show diff for this revision Revisions of this file
source/target/NfcControllerToEEPROMAdapter.cpp Show annotated file Show diff for this revision Revisions of this file
source/target/NfcControllerToEEPROMAdapter.h Show annotated file Show diff for this revision Revisions of this file
source/target/TARGET_M24SR/EEPROMDriver.cpp Show annotated file Show diff for this revision Revisions of this file
source/target/TARGET_M24SR/eeprom_driver.lib Show annotated file Show diff for this revision Revisions of this file
source/target/TARGET_PN512/EEPROMDriver.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.mbed	Mon Sep 24 17:09:39 2018 +0100
@@ -0,0 +1,1 @@
+ROOT=.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.md	Mon Sep 24 17:09:39 2018 +0100
@@ -0,0 +1,56 @@
+# NFC EEPROM usage example
+
+Demonstration of possible usage of the NFC EEPROM class. 
+
+The application will write an URL to the EEPROM of the NFC tag on your board. This will be able to be read by any NFC device capable of reading NFC tags.
+
+The example needs to supply a driver to the eeprom. This example uses the M24SR driver on the DISCO\_L475VG\_IOT01A and target and the PN512 driver on the NUCLEO\_F401RE target. You may wish to add your own driver or update the configuration if you're using a different board.
+
+# Running the application
+
+## Requirements
+
+Verification of the sample application can be seen on any a smartphone with an NFC reader. After running you will be able to read the tag with an NFC tag reader application.
+
+Information about activity is also printed over the serial connection - please have a client open. You may use:
+
+- [Tera Term](https://ttssh2.osdn.jp/index.html.en)
+
+You will also need to supply the driver for the EEPROM. This example is known to work on DISCO_L475VG_IOT01A which uses M24SR. The driver is downloaded during deployment step (`mbed deploy`). This is based on the contents of the `eeprom_driver.lib` file. The build process will pick up this library and build it as part of the mbed-os build. If you want to use a different driver, please update the contents of `eeprom_driver.lib` to point at the github repository containing the driver.
+
+## Building instructions
+
+Clone the repository containing the collection of examples:
+
+```
+git clone https://github.com/ARMmbed/mbed-os-example-nfc.git
+```
+
+Using a command-line tool, navigate to the exmaple:
+
+```
+cd mbed-os-example-nfc
+cd NFC_EEPROM
+```
+
+Update the source tree:
+
+```
+mbed deploy
+```
+
+If your board is not a DISCO\_L475VG\_IOT01A or a NUCLEO\_F401RE you should indicate in the configuration which driver should be selected by the build system. Edit `mbed_app.json` which contains the configuration. In the `target_overrides` section add your target configuration. The drivers currently supported are `PN512` and `M24SR`.
+
+```json
+    "<TARGET_NAME>": {
+        "target.extra_labels_add": ["<DRIVER_NAME>"]
+    }
+```
+
+
+Run the build:
+
+```
+mbed compile -t <ARM | GCC_ARM> -m <YOUR_TARGET>
+```
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-os.lib	Mon Sep 24 17:09:39 2018 +0100
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/mbed-os/#3fb5781af180c32a6062f050d59cdf93654b3e9f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed_app.json	Mon Sep 24 17:09:39 2018 +0100
@@ -0,0 +1,10 @@
+{
+    "target_overrides": {
+        "DISCO_L475VG_IOT01A": {
+            "target.extra_labels_add": ["M24SR"]
+        },
+        "NUCLEO_F401RE": {
+            "target.extra_labels_add": ["PN512"]
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/EEPROMDriver.h	Mon Sep 24 17:09:39 2018 +0100
@@ -0,0 +1,32 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018-2018 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+#ifndef SOURCE_EEPROMDRIVER_H_
+#define SOURCE_EEPROMDRIVER_H_
+
+#include "nfc/NFCEEPROMDriver.h"
+#include "events/EventQueue.h"
+
+/**
+ * Factory function that returns the NFC EEPROM driver.
+ *
+ * @param[in] queue The event queue that may be used by the driver.
+ *
+ * @return The NFC EEPROM driver to use.
+ */
+mbed::nfc::NFCEEPROMDriver& get_eeprom_driver(events::EventQueue& queue);
+
+#endif /* SOURCE_EEPROMDRIVER_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/main.cpp	Mon Sep 24 17:09:39 2018 +0100
@@ -0,0 +1,118 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018-2018 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+#include "events/EventQueue.h"
+
+#include "nfc/ndef/MessageBuilder.h"
+#include "nfc/ndef/common/URI.h"
+#include "nfc/ndef/common/util.h"
+
+#include "NFCEEPROM.h"
+
+#include "EEPROMDriver.h"
+
+using events::EventQueue;
+
+using mbed::nfc::NFCEEPROM;
+using mbed::nfc::NFCEEPROMDriver;
+using mbed::Span;
+
+using mbed::nfc::ndef::MessageBuilder;
+using mbed::nfc::ndef::common::URI;
+using mbed::nfc::ndef::common::span_from_cstr;
+
+/* URL that will be written into the tag */
+const char url_string[] = "mbed.com";
+
+class EEPROMExample : mbed::nfc::NFCEEPROM::Delegate
+{
+public:
+    EEPROMExample(events::EventQueue& queue, NFCEEPROMDriver& eeprom_driver) :
+        _ndef_buffer(),
+        _eeprom(&eeprom_driver, &queue, _ndef_buffer),
+        _queue(queue)
+    { }
+
+    void run()
+    {
+        if (_eeprom.initialize() != NFC_OK) {
+            printf("failed to initialise\r\n");
+            _queue.break_dispatch();
+        }
+
+        _eeprom.set_delegate(this);
+
+        _queue.call(&_eeprom, &NFCEEPROM::write_ndef_message);
+    }
+
+private:
+    virtual void on_ndef_message_written(nfc_err_t result) {
+        if (result == NFC_OK) {
+            printf("message written successfully\r\n");
+        } else {
+            printf("failed to write (error: %d)\r\n", result);
+        }
+
+        _queue.call(&_eeprom, &NFCEEPROM::read_ndef_message);
+    }
+
+    virtual void on_ndef_message_read(nfc_err_t result) {
+        if (result == NFC_OK) {
+            printf("message read successfully\r\n");
+        } else {
+            printf("failed to read (error: %d)\r\n", result);
+        }
+    }
+
+    virtual void parse_ndef_message(const Span<const uint8_t> &buffer) {
+        printf("Received an ndef message of size %d\r\n", buffer.size());
+    }
+
+    virtual size_t build_ndef_message(const Span<uint8_t> &buffer) {
+        printf("Building an ndef message\r\n");
+
+        /* create a message containing the URL */
+
+        MessageBuilder builder(buffer);
+
+        /* URI expected a non-null terminated string  so we use a helper function that casts
+         * the pointer into a Span of size smaller by one */
+        URI uri(URI::HTTPS_WWW, span_from_cstr(url_string));
+
+        uri.append_as_record(builder, true);
+
+        return builder.get_message().size();
+    }
+
+private:
+    uint8_t _ndef_buffer[1024];
+    NFCEEPROM _eeprom;
+    EventQueue& _queue;
+};
+
+int main()
+{
+    EventQueue queue;
+    NFCEEPROMDriver& eeprom_driver = get_eeprom_driver(queue);
+
+    EEPROMExample example(queue, eeprom_driver);
+
+    example.run();
+    queue.dispatch_forever();
+
+    return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/target/NfcControllerToEEPROMAdapter.cpp	Mon Sep 24 17:09:39 2018 +0100
@@ -0,0 +1,203 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018-2018 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+#include "NfcControllerToEEPROMAdapter.h"
+
+#include <algorithm>
+
+#include "nfc/NFCController.h"
+#include "nfc/NFCEEPROMDriver.h"
+#include "nfc/NFCRemoteInitiator.h"
+
+namespace mbed {
+namespace nfc {
+
+ControllerToEEPROMDriverAdapter::ControllerToEEPROMDriverAdapter(
+    NFCController &controller,
+    const Span<uint8_t> &buffer
+) :
+    _nfc_controller(controller),
+    _eeprom_buffer(buffer),
+    _current_eeprom_size(buffer.size()),
+    _session_opened(false)
+{
+}
+
+ControllerToEEPROMDriverAdapter::~ControllerToEEPROMDriverAdapter()
+{
+    if (_nfc_remote_initiator.get()) {
+        _nfc_remote_initiator->set_delegate(NULL);
+    }
+    _nfc_controller.set_delegate(NULL);
+    _nfc_controller.cancel_discovery();
+}
+
+void ControllerToEEPROMDriverAdapter::reset()
+{
+    _current_eeprom_size = _eeprom_buffer.size();
+    memset(_eeprom_buffer.data(), 0, _eeprom_buffer.size());
+
+    if (_nfc_remote_initiator.get()) {
+        _nfc_remote_initiator->set_delegate(NULL);
+        _nfc_remote_initiator.reset();
+    }
+
+    _nfc_controller.initialize();
+    _nfc_controller.set_delegate(this);
+
+    nfc_rf_protocols_bitmask_t protocols = { 0 };
+    protocols.target_iso_dep = 1;
+    _nfc_controller.configure_rf_protocols(protocols);
+
+    _nfc_controller.start_discovery();
+}
+
+size_t ControllerToEEPROMDriverAdapter::read_max_size()
+{
+    return _eeprom_buffer.size();
+}
+
+void ControllerToEEPROMDriverAdapter::start_session(bool force)
+{
+    _session_opened = true;
+    delegate()->on_session_started(true);
+}
+
+void ControllerToEEPROMDriverAdapter::end_session()
+{
+    _session_opened = false;
+    delegate()->on_session_ended(true);
+}
+
+void ControllerToEEPROMDriverAdapter::read_bytes(
+    uint32_t address, uint8_t *bytes, size_t count
+) {
+    if (address >= _current_eeprom_size) {
+        delegate()->on_bytes_read(0);
+        return;
+    }
+
+    size_t size = std::min(count, (size_t) (_current_eeprom_size - address));
+    memcpy(bytes, _eeprom_buffer.data() + address, size);
+    delegate()->on_bytes_read(size);
+}
+
+void ControllerToEEPROMDriverAdapter::write_bytes(
+    uint32_t address, const uint8_t *bytes, size_t count
+) {
+    if (address >= _current_eeprom_size) {
+        delegate()->on_bytes_written(0);
+        return;
+    }
+
+    size_t size = std::min(count, (size_t) (_current_eeprom_size - address));
+    memcpy(_eeprom_buffer.data() + address, bytes, size);
+    delegate()->on_bytes_written(size);
+}
+
+void ControllerToEEPROMDriverAdapter::read_size()
+{
+    delegate()->on_size_read(true, _current_eeprom_size);
+}
+
+void ControllerToEEPROMDriverAdapter::write_size(size_t count)
+{
+    if (count > (size_t) _eeprom_buffer.size()) {
+        delegate()->on_size_written(false);
+    } else {
+        _current_eeprom_size = count;
+        delegate()->on_size_written(true);
+    }
+}
+
+void ControllerToEEPROMDriverAdapter::erase_bytes(uint32_t address, size_t count)
+{
+    if (address >= _current_eeprom_size) {
+        delegate()->on_bytes_erased(0);
+        return;
+    }
+
+    size_t size = std::min(count, (size_t) (_current_eeprom_size - address));
+    memset(_eeprom_buffer.data() + address, 0, size);
+    delegate()->on_bytes_erased(size);
+}
+
+/* ------------------------------------------------------------------------
+ * Implementation of NFCRemoteInitiator::Delegate
+ */
+void ControllerToEEPROMDriverAdapter::on_connected() { }
+
+void ControllerToEEPROMDriverAdapter::on_disconnected()
+{
+    // reset the state of the remote initiator
+    _nfc_remote_initiator->set_delegate(NULL);
+    _nfc_remote_initiator.reset();
+
+    // restart peer discovery
+    _nfc_controller.start_discovery();
+}
+
+void ControllerToEEPROMDriverAdapter::parse_ndef_message(const Span<const uint8_t> &buffer)
+{
+    if (_session_opened) {
+        return;
+    }
+
+    if (buffer.size() > _eeprom_buffer.size()) {
+        return;
+    }
+
+    _current_eeprom_size = buffer.size();
+    memcpy(_eeprom_buffer.data(), buffer.data(), _current_eeprom_size);
+}
+
+size_t ControllerToEEPROMDriverAdapter::build_ndef_message(const Span<uint8_t> &buffer)
+{
+    if (_session_opened) {
+        return 0;
+    }
+
+    if ((size_t) buffer.size() < _current_eeprom_size) {
+        return 0;
+    }
+
+    memcpy(buffer.data(), _eeprom_buffer.data(), _current_eeprom_size);
+    return _current_eeprom_size;
+}
+
+/* ------------------------------------------------------------------------
+ * Implementation of NFCController::Delegate
+ */
+void ControllerToEEPROMDriverAdapter::on_discovery_terminated(
+    nfc_discovery_terminated_reason_t reason
+) {
+    if(reason != nfc_discovery_terminated_completed) {
+        _nfc_controller.start_discovery();
+    }
+}
+
+void ControllerToEEPROMDriverAdapter::on_nfc_initiator_discovered(
+    const SharedPtr<NFCRemoteInitiator> &nfc_initiator
+) {
+    // setup the local remote initiator
+    _nfc_remote_initiator = nfc_initiator;
+    _nfc_remote_initiator->set_delegate(this);
+    _nfc_remote_initiator->connect();
+}
+
+}  // namespace nfc
+}  // namespace mbed
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/target/NfcControllerToEEPROMAdapter.h	Mon Sep 24 17:09:39 2018 +0100
@@ -0,0 +1,100 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018-2018 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+#ifndef NFCCONTROLLER2EEPROMADAPTER_H_
+#define NFCCONTROLLER2EEPROMADAPTER_H_
+
+#include <algorithm>
+
+#include "nfc/NFCController.h"
+#include "nfc/NFCEEPROMDriver.h"
+#include "nfc/NFCRemoteInitiator.h"
+
+namespace mbed {
+namespace nfc {
+
+/**
+ * Adapt an NFCController into an NFCEEPROMDriver.
+ */
+class ControllerToEEPROMDriverAdapter :
+    public NFCEEPROMDriver,
+    private NFCController::Delegate,
+    private NFCRemoteInitiator::Delegate
+{
+public:
+    ControllerToEEPROMDriverAdapter(
+        NFCController &controller,
+        const Span<uint8_t> &buffer
+    );
+
+    virtual ~ControllerToEEPROMDriverAdapter();
+
+    /* ------------------------------------------------------------------------
+     * Implementation of NFCEEPROMDriver
+     */
+    virtual void reset();
+
+    virtual size_t read_max_size();
+
+    virtual void start_session(bool force);
+
+    virtual void end_session();
+
+    virtual void read_bytes(uint32_t address, uint8_t *bytes, size_t count);
+
+    virtual void write_bytes(uint32_t address, const uint8_t *bytes, size_t count);
+
+    virtual void read_size();
+
+    virtual void write_size(size_t count);
+
+    virtual void erase_bytes(uint32_t address, size_t count);
+
+private:
+    /* ------------------------------------------------------------------------
+     * Implementation of NFCRemoteInitiator::Delegate
+     */
+    virtual void on_connected();
+
+    virtual void on_disconnected();
+
+    virtual void parse_ndef_message(const Span<const uint8_t> &buffer);
+
+    virtual size_t build_ndef_message(const Span<uint8_t> &buffer);
+
+    /* ------------------------------------------------------------------------
+     * Implementation of NFCController::Delegate
+     */
+    virtual void on_discovery_terminated(
+        nfc_discovery_terminated_reason_t reason
+    );
+
+    virtual void on_nfc_initiator_discovered(
+        const SharedPtr<NFCRemoteInitiator> &nfc_initiator
+    );
+
+    NFCController& _nfc_controller;
+    Span<uint8_t> _eeprom_buffer;
+    size_t _current_eeprom_size;
+    bool _session_opened;
+    SharedPtr<NFCRemoteInitiator> _nfc_remote_initiator;
+};
+
+}  // namespace nfc
+}  // namespace mbed
+
+
+#endif /* NFCCONTROLLER2EEPROMADAPTER_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/target/TARGET_M24SR/EEPROMDriver.cpp	Mon Sep 24 17:09:39 2018 +0100
@@ -0,0 +1,24 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018-2018 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+#include "EEPROMDriver.h"
+#include "m24sr_driver.h"
+
+mbed::nfc::NFCEEPROMDriver& get_eeprom_driver(events::EventQueue&)
+{
+    static mbed::nfc::vendor::ST::M24srDriver eeprom_driver;
+    return eeprom_driver;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/target/TARGET_M24SR/eeprom_driver.lib	Mon Sep 24 17:09:39 2018 +0100
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/mbed-nfc-m24sr
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/target/TARGET_PN512/EEPROMDriver.cpp	Mon Sep 24 17:09:39 2018 +0100
@@ -0,0 +1,51 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018-2018 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+#include "EEPROMDriver.h"
+
+#include "nfc/NFCController.h"
+#include "NfcControllerToEEPROMAdapter.h"
+#include "nfc/controllers/PN512Driver.h"
+#include "nfc/controllers/PN512SPITransportDriver.h"
+#include "target/NfcControllerToEEPROMAdapter.h"
+
+using mbed::nfc::NFCController;
+using mbed::nfc::PN512SPITransportDriver;
+using mbed::nfc::PN512Driver;
+using mbed::nfc::ControllerToEEPROMDriverAdapter;
+using mbed::nfc::NFCEEPROMDriver;
+
+NFCEEPROMDriver& get_eeprom_driver(events::EventQueue& queue)
+{
+    static uint8_t ndef_controller_buffer[1024] = { 0 };
+    static uint8_t eeprom_buffer[1024] = { 0 };
+
+    static PN512SPITransportDriver pn512_transport(D11, D12, D13, D10, A1, A0);
+    static PN512Driver pn512_driver(&pn512_transport);
+
+    static NFCController nfc_controller(
+        &pn512_driver,
+        &queue,
+        ndef_controller_buffer
+    );
+
+    static ControllerToEEPROMDriverAdapter eeprom_driver(
+        nfc_controller,
+        eeprom_buffer
+    );
+    return eeprom_driver;
+}
+