Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nrf/nfc: Add basic support for NFC tag 2. #5104

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

glennrub
Copy link
Contributor

This patch adds a new submodule nrfxlib which contains a static
library for NFC on nRF52 devices. Currently, only Tag2 library has
been targeted.

The patch also introduce a basic NFC machine module which expose API for
starting and stopping the NFC library/peripheral and an API to
to set raw payload.

Example:

from machine import NFC
n = NFC()
payload = bytearray([0x03, 0x0F, 0xD1, 0x01, 0x0B, 0x55, 0x02]
payload += [ord(i) for i in "google.com"])
n.payload_raw_set(payload)
n.start()
...
n.stop()

This patch adds a new submodule nrfxlib which contains a static
library for NFC on nRF52 devices. Currently, only Tag2 library has
been targeted.

The patch also introduce a basic NFC machine module which expose API for
starting and stopping the NFC library/peripheral and an API to
to set raw payload.

Example:

from machine import NFC
n = NFC()
payload = bytearray([0x03, 0x0F, 0xD1, 0x01, 0x0B, 0x55, 0x02]
payload += [ord(i) for i in "google.com"])
n.payload_raw_set(payload)
n.start()
...
n.stop()
@rolandvs
Copy link
Sponsor Contributor

Great I will give it a try :-)

@hoihu
Copy link
Sponsor Contributor

hoihu commented Sep 14, 2019

@glennrub Thanks a lot for this!

I wonder.. do you think it would be feasable to leave out the binary blobs ("libnfct2t_nrf52.a" etc) and go for a open source, nrfx based solution - based on nrfx's NFCT driver? I'm unsure about the licencse requirements of this lib and honestly don't like closed source binaries. I'm also not sure if that is going to be accepted by the maintainers.

Would you mind to share some thoughts about it?

As for use cases... our application mainly wanted to have the "tap to pair" functionality.. means OOB bluetooth pairing initated via NFC. But that's an advanced use case and certainly not the first thing to do. I guess a simple NDEF messages with a weblink would be something that a lot of people are waiting for. And your approach is already doing this I suppose (I haven't checked, but the payload given in your example is the header/type of a weblink NDEF message?).

So don't get me wrong, it's great we have something to play with! I'll give it a try perhaps next week. Thanks.

@glennrub
Copy link
Contributor Author

hi @hoihu ,

Thanks for the feedback.

Let me start with the easy one, the sample i provided in the commit message is an NDEF URL to https://google.com. =)

When it comes to the closed source library ("libnfct2t_nrf52.a" etc) i do not find this problematic when targeting nrf-chipset. For more details i'll provide a link to the Nordic 5-clause license summary: https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/introducing-nordics-new-software-licensing-schemes. One important aspect of this license is that there is no need to include the license with binaries.

You triggered me a bit on your question, whether it is feasible to write an open source variant of the library. I'm not an NFC expert, but from what i see in documents online is that it does not look too complex to implement. I'm not sure anymore if the full stack should be the interface for the machine.NFC API (like proposed in this PR), as all other machine APIs are quite low level. And including a full stack is a bit more than that. I have started to think that the machine.NFC should be a pure nrfx NFCT driver wrapper. This should enable the possibility to write a pure micropython .py NFC/NDEF driver or an USER_C_MODULE/separate inbuilt module.

Do you know if there are any requirement of membership in order to provide an implementation?

@rolandvs
Copy link
Sponsor Contributor

rolandvs commented Sep 17, 2019

Just tested the NFC on the EVK_NINA_B1 and works great!

For testing I use the NXP NFC TagInfo App (available for both Android and iOS at the appropriate stores).

@hoihu
Copy link
Sponsor Contributor

hoihu commented Sep 17, 2019

I have started to think that the machine.NFC should be a pure nrfx NFCT driver wrapper. This should enable the possibility to write a pure micropython .py NFC/NDEF driver or an USER_C_MODULE/separate inbuilt module.

yes I'm thinking along the same lines..

Perhaps the NDEF TLV memory structure/logic can be separated so that interfacing external NFC chips (e.g. NXP's NTAG chips) can be supported too. I've played with the NTAG chips a couple of years ago and got it working with uPy (it's basically an I2C memory slave and you write the NDEF data to memory segments).

Also I asked again on the nordic repo about the open source driver and got this answer. So at least, the NFCT driver will stay compatible with the binary blob.

On a related note, another user asked for a similar thing and got a bit further.

Do you know if there are any requirement of membership in order to provide an implementation?

I'm sorry but I didn't get this. What kind of membership? For the NFC forum tag specifications? I got my information so far from this site

@glennrub
Copy link
Contributor Author

Hi @hoihu,

I think we both share the same view on what might be more optimal solution here.

However, I want to also play the devil's advocate for a minute:

We have both seen the Tag specifications online. However, that might not grant us license to use what we see there. Looking at the website of NFC Forum on "How to get specification" it states:
"Non-Members: The NFC Forum Technical Specifications are available for purchase after completing the Specification License Agreement." The purchase prices on these specifications are quite costly to my wallet. NFC Forum Specifications

Even if someone of us signs the agreement and someone pays the bill for the specifications, i'm not sure if micropython as a project benefit of having to maintain a NFC stack of its own, when the chip providers already provide solutions for this (I2C, lib.a) and take care of conformance. (Maybe @dpgeorge can fill in here if he has a long term wish for a NFC stack inside microypthon). Redistribution might also be a concern. Can the NFC stack be MIT licensed, or is it bound to the "company"/person signing the license and pay's the bill?

Back as a developer:

I'll do a bit more searching online to see if i can find any open source alternatives. Maybe, by luck there is a tinyNFC somewhere there, like what tinyUSB does for USB.

On the other hand, if we were to implement a hierarchy like "NDEF -> open source driver -> NFCT HAL" for nRF, i would guess that we would end up in higher abstraction level API not to far from NXP I2C or nrf-library as both wants to read and write payloads. This leave us with a common NDEF implementation that can run over multiple ports. Maybe for time being we provide a solution for this? Accepting that NFC on nRF is as closed as NXP I2C? =)

Also to be a bit clear, even if earlier stated that NFC Tag2/4 does not seem to complex it does not mean i will pick the task myself to develop this stack even if purchase and license agreements are signed. I'm basically running a bit short on time these days. Unless someone else would volunteer to do this we will not see NFC support for nRF in a while, unless we use what is available right now.

@rolandvs
Copy link
Sponsor Contributor

Just for the creation of NDEF records and reasonably small... https://pypi.org/project/ndef/

@hoihu
Copy link
Sponsor Contributor

hoihu commented Sep 23, 2019

@glennrub Thanks for your detailed answer.

However, I want to also play the devil's advocate for a minute:

yep - on the other hand - all the informations that's being around in the internet (e.g. @rolandvs link with the python ndef package). Where does the author of this package got his spec's from?

I'm not sure if we are holier than the pope, as we say... ;)

The purchase prices on these specifications are quite costly

ups - sad to see this!

to maintain a NFC stack of its own, when the chip providers already provide solutions for this (I2C, lib.a) and take care of conformance.

This is likely not the intention of this repository, yes. Possibly, a C based low level implementation could be developed in a separate project (ideally just a thin wrapper around NFCT, as you suggested), with some higher level uPy support for NDEF messages? This may then be added to uPy via git submodule?

Accepting that NFC on nRF is as closed as NXP I2C? =)

I guess the main difference is that we are directly linking in a binary blob with unknown content from an external company telit.

What's worse, this binary blob may handle sensitive data (e.g. handover keys, links etc). I'm confused why nordic goes down that way but here we go.

@rolandvs
Copy link
Sponsor Contributor

@glennrub : Interesting enough is the X-CUBE-NFC4 library from STM that contains a middleware library using ndef... A source of inspiration...

@rena2019
Copy link

What's wrong with the code? I cloned the repository and build for BOARD=pca10040. Everythng fine. But if I add
#define MICROPY_PY_MACHINE_NFC (1)
to ports\nrf\boards\particle_xenon\mpconfigboard.h
and build for BOARD=particle_xenon I get the following error:

D:\msys64\tmp\cchwcWvg.ltrans3.ltrans.o: In function nfc_platform_event_handler': D:\msys64\home\rena2019\micropython.nrf52_nfc\ports\nrf/modules/machine/nfc.c:52: undefined reference to nrfx_nfct_state_force'
../../lib/nrfxlib/nfc/lib/cortex-m4/hard-float/\libnfct2t_nrf52.a(nfc_t2t_lib_al.c.o): In function nrfx_nfct_evt_handler': C:\nfc_repo\nfc-library\private\nfc_t2t_lib\armgcc/../nfc_t2t_lib_al.c:308: undefined reference to nrfx_nfct_rx'
C:\nfc_repo\nfc-library\private\nfc_t2t_lib\armgcc/../nfc_t2t_lib_al.c:317: undefined reference to nrfx_nfct_rx' ../../lib/nrfxlib/nfc/lib/cortex-m4/hard-float/\libnfct2t_nrf52.a(nfc_t2t_lib_al.c.o): In function nrf_nfct_rx_frameend_handle':
C:\nfc_repo\nfc-library\private\nfc_t2t_lib\armgcc/../nfc_t2t_lib_al.c:252: undefined reference to nrfx_nfct_init_substate_force' C:\nfc_repo\nfc-library\private\nfc_t2t_lib\armgcc/../nfc_t2t_lib_al.c:278: undefined reference to nrfx_nfct_rx'
C:\nfc_repo\nfc-library\private\nfc_t2t_lib\armgcc/../nfc_t2t_lib_al.c:286: undefined reference to nrfx_nfct_init_substate_force' ../../lib/nrfxlib/nfc/lib/cortex-m4/hard-float/\libnfct2t_nrf52.a(nfc_t2t_lib_al.c.o): In function nfc_t2t_lib_al_setup':
C:\nfc_repo\nfc-library\private\nfc_t2t_lib\armgcc/../nfc_t2t_lib_al.c:115: undefined reference to nrfx_nfct_nfcid1_default_bytes_get' C:\nfc_repo\nfc-library\private\nfc_t2t_lib\armgcc/../nfc_t2t_lib_al.c:129: undefined reference to nrfx_nfct_init'
../../lib/nrfxlib/nfc/lib/cortex-m4/hard-float/\libnfct2t_nrf52.a(nfc_t2t_lib_al.c.o): In function nfc_t2t_lib_al_parameter_set': C:\nfc_repo\nfc-library\private\nfc_t2t_lib\armgcc/../nfc_t2t_lib_al.c:177: undefined reference to nrfx_nfct_parameter_set'
C:\nfc_repo\nfc-library\private\nfc_t2t_lib\armgcc/../nfc_t2t_lib_al.c:151: undefined reference to nrfx_nfct_nfcid1_default_bytes_get' ../../lib/nrfxlib/nfc/lib/cortex-m4/hard-float/\libnfct2t_nrf52.a(nfc_t2t_lib_al.c.o): In function nfc_t2t_lib_al_parameter_get':
C:\nfc_repo\nfc-library\private\nfc_t2t_lib\armgcc/../nfc_t2t_lib_al.c:200: undefined reference to nrfx_nfct_nfcid1_default_bytes_get' ../../lib/nrfxlib/nfc/lib/cortex-m4/hard-float/\libnfct2t_nrf52.a(nfc_t2t_lib_al.c.o): In function nfc_t2t_lib_al_start':
C:\nfc_repo\nfc-library\private\nfc_t2t_lib\armgcc/../nfc_t2t_lib_al.c:223: undefined reference to nrfx_nfct_enable' ../../lib/nrfxlib/nfc/lib/cortex-m4/hard-float/\libnfct2t_nrf52.a(nfc_t2t_lib_al.c.o): In function nfc_t2t_lib_al_send':
C:\nfc_repo\nfc-library\private\nfc_t2t_lib\armgcc/../nfc_t2t_lib_al.c:234: undefined reference to nrfx_nfct_tx' ../../lib/nrfxlib/nfc/lib/cortex-m4/hard-float/\libnfct2t_nrf52.a(nfc_t2t_lib_al.c.o): In function nfc_t2t_lib_al_stop':
C:\nfc_repo\nfc-library\private\nfc_t2t_lib\armgcc/../nfc_t2t_lib_al.c:239: undefined reference to `nrfx_nfct_disable'
collect2.exe: error: ld returned 1 exit status
make: *** [Makefile:359: build-particle_xenon-s140/firmware.elf] Error 1

@projectgus
Copy link
Contributor

This is an automated heads-up that we've just merged a Pull Request
that removes the STATIC macro from MicroPython's C API.

See #13763

A search suggests this PR might apply the STATIC macro to some C code. If it
does, then next time you rebase the PR (or merge from master) then you should
please replace all the STATIC keywords with static.

Although this is an automated message, feel free to @-reply to me directly if
you have any questions about this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants