ラベル nfc の投稿を表示しています。 すべての投稿を表示
ラベル nfc の投稿を表示しています。 すべての投稿を表示

2020年4月5日

[golang]NFC-AのUIDを読む

NFC-AのUIDを読むようにした。

https://github.com/hirokuma/go_pasori370/tree/13639388afe725696a6550cab07e760c9f5ce7b4

NFC-FとNFC-Aを順番にInListPassiveTargetして、先に見つかった方を返す。まあ、2つしかないので先も何もないのだが。

UIDの長さが、Single / Double / Trippleのどれかなのを確認すべきなのだろうが、仕様書を引っ張り出すのが面倒だったので4byte以上ならOKとしてしまった。

 

コードがきれいなのかどうかはまだ判断できないけど、そこまで悪くはないんじゃないかなぁ、どうかなぁ。。
他の人のコードなどを見て勉強するところまでやらないと、レベルは上がらんだろうな。

 

ともあれ、golangでNFC R/Wを動かすのはこれでおしまいだ。

2020年4月4日

[golang]ようやくIDmを読む

ようやくgolang + RC-S370でIDmを読むところまでできた。

https://github.com/hirokuma/go_pasori370/tree/fed6133f67075d9dfc065274f71fc84391d38577

$ make
$ make run
2020/04/04 20:49:24 Opened
2020/04/04 20:49:24 write= 0000ff03fdd418011300
2020/04/04 20:49:24 read done: 6(0000ff00ff00)
2020/04/04 20:49:24 read done: 9(0000ff02fed5191200)
2020/04/04 20:49:24 write= 0000ff06fad43202000000f800
2020/04/04 20:49:24 read done: 6(0000ff00ff00)
2020/04/04 20:49:25 read done: 9(0000ff02fed533f800)
2020/04/04 20:49:25 write= 0000ff06fad43205000000f500
2020/04/04 20:49:25 read done: 6(0000ff00ff00)
2020/04/04 20:49:25 read done: 9(0000ff02fed533f800)
2020/04/04 20:49:25 write= 0000ff04fcd43281b7c200
2020/04/04 20:49:25 read done: 6(0000ff00ff00)
2020/04/04 20:49:25 read done: 9(0000ff02fed533f800)
2020/04/04 20:49:25 write= 0000ff09f7d44a010100ffff0101e000
2020/04/04 20:49:25 read done: 6(0000ff00ff00)
2020/04/04 20:49:25 read done: 31(0000ff18e8d54b01011401xxxxxxxxxxxxxxxx100b4b428485d0ff0003e600)
2020/04/04 20:49:25 IDm: xxxxxxxxxxxxxxxx
2020/04/04 20:49:25 PMm: 100b4b428485d0ff
2020/04/04 20:49:25 SystemCode: 0x0003
2020/04/04 20:49:25 Closed

なんとなくIDmは隠してみた。

 

Receiverはポインタ型が良いのかそうでない方が良いのか基準がよくわからなかったのだが、どこかのサイトで「実質は引数に与えられて呼ばれるのと同じ」と説明してあって理解できた。

 

あとは、NFC-AのID読み込みを作って、Pollingで両方実行して先に見つかった方を返す、というところを作ったら終わりかな。
いつもは汎用ライブラリみたいにしてたけど、あれは疲れるからな。

2019年7月15日

[nfc]TNEPというプロトコルができたらしい

NFC Forumの仕様書が有料になったのでスルーしていたのだが、6月くらいにTNEPというプロトコルが追加されたらしい。

https://nfc-forum.org/our-work/specifications-and-application-documents/specifications/nfc-forum-candidate-technical-specifications/

「Tag NDEF Exchange Protocol」の略だそうだ。
それで思いつくのは、SNEP(NFC Simple NDEF Exchange Protocol Technical Specification)だろう。

 

もう数年近くNFCのことをやっていないので間違ってるかもしれんが、NFC Forumとしては3つの柱があったと思う。

  • Reader / Writer
  • Tag(Emulation)
  • P2P

SNEPは、P2PでNDEFを渡してた記憶がある。
渡せるけど、そもそもLLCP自体が負荷が高いよなー、とは思った。
結局のところ、SNEPを使うとしたらスマホくらいしか無いと思う。
そうじゃなかったら、だいたいどっちがどっちの役割になるかが固定されるので、どっちかだけ実装すればよいだろう。
スマホだって、P2Pじゃなくて片方がTag Emulationすればよいだけである。

まあ、P2PだってどっちかがInitiatorでどっちかがTagになって、頻繁に送り合うことで同等に近い関係を持たせようとしているだけだったと思う。


というわけで、まったくTNEPのことはわかっていないのだ。

SNEPが1回だけの通信だったから、TNEPは何度かやりとりできるようになったのかな?
でも、それだったらSNEPを拡張すれば良かっただけのような気もする。

ならば、もっと違った何かがあるのだろうか。
気になりはするが、仕様書を購入してまで読む気にはならんな。

2018年8月19日

[nfc][rpi]最近のOM5578/PN7150S

掃除をしていると、Raspberry Pi2が見つかった。
NXPのプレゼントで当選したOM5578/PN7150Sが載ったままだった。
https://hiro99ma.blogspot.com/2017/01/nfcraspiom5578pn7150s-1.html

当時はkernelにドライバを入れるので苦労したのだが、最近は楽になっているかもしれない。
確かめておこう。


https://github.com/NXPNFCLinux/linux_libnfc-nci

現在の最新リリースは、R2.4。
PDFはAN11697。


0. Raspberry Piのkernelのクロスコンパイル環境

ページの上の方はセルフビルド、下の方はクロスコンパイルの記述になっているので、下を見る。
.bashrcに設定を書くようになっているが、うちは毎回sourceコマンドで読み込むことにする。

echo export PATH=~/Raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin:$PATH > compiler.sh
source ./compiler.sh

1. Raspberry Piのkernelダウンロード

git clone --depth=1 https://github.com/raspberrypi/linux
cd linux

2. ドライバのダウンロード

cd drivers/misc
git clone https://github.com/NXPNFCLinux/nxp-pn5xx.git

3. Makefileの編集

vi Makefile
(obj-がならんでいる一番下に追加)

obj-y               += nxp-pn5xx/

4. Kconfigの変数

vi Kconfig
(sourceがならんでいる一番下に追加)

source "drivers/misc/nxp-pn5xx/Kconfig"

5. Creating the device node

やり方が2種類提示してある。Device treeとPlatform data。
ソースファイルを変更するのは気が進まないので、Device treeにしよう。
と思ったが、どういう設定にすればいいんだ?
ああ、前回と同じ流れじゃないか!

6. ビルド

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
   (Device Drivers ---> Misc devices ---> < > NXP PN5XX based driver)
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs


・・・ここまでやった後で、PDFの「3.2 Alternative to pn5xx_i2c kernel driver」に気付いた。

image

この構成だと、Kernel spaceはI2CとGPIOのドライバで済みそうだ。

https://github.com/NXPNFCLinux/linux_libnfc-nci

src/halimpl/pn54x/tml/i2c/phTmlNfc_alt.h

/* Describe PN71xx connection
  *  0 = Custom configuration
  *  1 = OM557x on Raspberry Pi
  *  2 = OM557x on UdooNeo
  *  3 = OM557x on BeagleBone black
  *
  */

やる気十分じゃないか!
マクロのCONFIGURATIONを変更するだけでよさそうだし、githubに入っているものはデフォルトが1番だから今回は変更しなくて良い。


Raspberry Pi2にセルフビルドさせよう。
Raspbianは2018-06-27のDesktopで、apt update/upgradeも行っておく。
raspi-configなどでI2Cを有効にしておこう。

git clone https://github.com/NXPNFCLinux/linux_libnfc-nci.git
sudo apt install automake autoconf libtool
cd linux_libnfc-nci
./bootstrap
./configure --enable-alt
make
sudo make install

では、デモアプリを動かそう。

nfcDemoApp poll

1回目に実行したときはエラーがたくさん出てしまったが、タグをかざすと読み取っているようだ(エラーによってコンソールが流されて見えん)。
2回目は普通に動いた。
よくわからんが、深追いは止めておこう。


もしかしたら、前回も見逃していただけで、ドライバは何もせずとも動いたのかもしれんな。


私としては、BeagleBone Greenも持っているので、PN7150SとRapberry Pi用のアタッチメントとBeagleBone用のアタッチメントが分かれているとよいのだが、まあ高いものではないから仕方ないのか(Raspiモデルで3500円くらい)。
いつもだとSonyのRC-S620/Sを使うところなのだが、プロトコルを意識せず使用できるというのは強みがある。
まあ、Linuxが載る前提にはなってしまうが。


相手から読まれるだけでよいなら、FeliCa Linkという選択もある。
試作品を作る場合なんかは、Raspberry PiでもFeliCa Linkで済ませていたりする。
ボードにどーん、というのもよいのだが、FeliCa Linkみたいな小ささだと必要なピンだけつなげば良いので、小回りがきくのだ。


image(どーん)


まあ、適材適所ということで。

2018年3月11日

[nfc]Debian9とRC-S370とnfcpy

久々に、PaSoRiを触っている。
BeagleBone Greenに挿して使えるのか、確認しているだけだがね。


http://nfcpy.readthedocs.io/en/latest/topics/get-started.html

せっかくなので、nfcpyを使うことにしよう。
なるべく普通のやり方で使えるに越したことはないのだ。


nfcpyはpython2.xで動くようになっている。
BeagleBone GreenにインストールしたDebianではpython2.7.13が使えるようになっていたので、都合がよい。

$ sudo pip install -U nfcpy

これでインストールできたようなので、下の方に書かれていた「import nfc」の手順を順番にやってみた。
が、open()に失敗する。

不思議に思い、インストール手順にあった「python -m nfc」をやってみると、使用中になっているようだった。

$ python -m nfc
No handlers could be found for logger "nfc.llcp.sec"
This is the 0.13.4 version of nfcpy run in Python 2.7.13
on Linux-4.9.82-ti-r102-armv7l-with-debian-9.4
I'm now searching your system for contactless devices
** found usb:054c:02e1 at usb:001:002 but it's already used
-- scan sysfs entry at '/sys/bus/usb/devices/1-1:1.0/'
-- the device is used by the 'pn533_usb' kernel driver
-- this kernel driver belongs to the linux nfc subsystem
-- you can remove it to free the device for this session
   sudo modprobe -r pn533_usb
-- and blacklist the driver to prevent loading next time
    sudo sh -c 'echo blacklist pn533_usb >> /etc/modprobe.d/blacklist-nfc.conf'
I'm not trying serial devices because you haven't told me
-- add the option '--search-tty' to have me looking
-- but beware that this may break other serial devs
Sorry, but I couldn't find any contactless device

赤文字を実行してやると、openできるようになった。
デバイス関係だからsudoがいるかと思ったが、なくても大丈夫そうだ。


読んでみよう。

>>> import nfc
No handlers could be found for logger "nfc.llcp.sec"
>>> clf=nfc.ContactlessFrontend()
>>> clf.open('usb:054c:02e1')
True
>>> tag=clf.connect(rdwr={'on-connect': lambda tag: False})
>>> print(tag)
Type3Tag 'FeliCa Lite (RC-S965)' ID=0127005D19FE4B78 PMM=00F0000002060300 SYS=88B4

おお、読めた。
SystemCodeが0x88B4になっているから、NDEF用にしていないカードだったのだろう。

Type2のNDEFタグを読ませてみたが、特にそれっぽい表示はしなかった。

>>> tag=clf.connect(rdwr={'on-connect': lambda tag: False})
>>> print(tag)
Type2Tag 'NXP NTAG216' ID=043968D29C3981

>>> for record in tag.ndef.records:
...     print(record)
...
NDEF Uri Record ID '' Resource 'http://www.nxp.com/demoboard/OM5578'

わかりづらいが、printの前にはスペースを入れている。


APIを見て、まねした。


import nfc

def on_connect(tag):
    print('connect: ')
    print(tag)

#def on_discover(tag):
#    print('discover!');
#    return tag;

options = {
        'on-connect': on_connect,
#        'on-discover': on_discover,
        }

while True:
    with nfc.ContactlessFrontend('usb') as clf:
        tag = clf.connect(rdwr=options)
        if tag.ndef:
            print('return:')
            print(tag.ndef.message.pretty())


discoverで検出すると思ったのだが、on-connectでもやれそうだ。
これ、on-connectを指定しないと、tagはboolになるようだった。

whileにしたのは、一度検出すると抜けてしまうからなのだが、これはこれでカードをかざしている間はループし続けてしまう。
on-releaseで離れたのを検知させた方がよさそうだ。

2017年11月3日

[nfc]確定申告でのマイナンバーカード

マイナンバーカードという、個人番号カードをNFC化したものがあるが、そっちで確定申告できるということらしい。

スマホで確定申告可能に 国税庁、iPhone非対応  :日本経済新聞

日経新聞って、技術的なニュースが弱いと思う・・・。
技術系のニュースは的外れな気がするのだが、しょうがないのだろうか。

まあ、私に生活とか法律とかの記事を書けといわれたら、同じようなことを書いてしまうかもしれんので、あしざまに言うことは避けておこう。


いや、タイトルに間違いがあるわけではないのだ。
読んだ範囲では、内容も間違っているわけではない。

ただ「○○自動車が新発売する車では空を飛ぶことができません」みたいな感じで、そもそもそんな機能がないのに「飛べるはずなのに飛べる機能を付けなかった」みたいな感じで読めてしまうのが、よろしくないんじゃなかろうかと思ったのだ。


マイナンバーカードは日本で発行するカードなのだが、その内容は国内規格ではなく、どちらかといえば海外で標準となっているType-Bという形式だ。
パスポートなんかもType-Bだったと思う。

iPhoneが対応していないのは、そういう国際規格のフォーマットは読めなくしているからだ。
読めるのは、NDEFという、NFC Forumが作っている規格のものだけだと思う(持ってないので、よくわからん)。
まあ、iOSはそういうところは攻めないので、Androidで数年かやって問題なさそうだったら採用する、とかじゃなかろうか。
ここら辺は、戦略の違いだろう。


ともかく、今回については、iOSがそういう機能を提供していないから、どうしようもない。
国際規格にすれば大丈夫だろうという目論見だったのかもしれんが、iOSの非公開制に阻まれたのかな。
できるとすれば、日本に限ってそういうiOSにしてしまうとか?


また、読めるだけではダメだろう。
JPKIがあるので、正当性の確認は行うに違いない。
正当性というのは、マイナンバーカードを「うちが発行したものです」と認める作業になろう。

まあ、それくらいやってもらわないと使う方も怖いしね。
普及だけでなく、使い勝手が上がるにもまだまだ時間が必要そうだ。

2017年10月27日

[android][nfc]JPKIのASN.1を読む

OpenSCに入っていた、JPKを読込む部分を参考にして、例のカードの総合認証証明書プロファイルのASN.1ダンプを表示させるアプリをCSharpで作っていたものを、Androidでも動くようにした。

https://github.com/hirokuma/AndroidReadJpk/tree/8b68a801b254368f6a6a884ad843cd965aa5441f


起動させると、アプリのタイトルが「Read JPK PubKey」になっているが、あまり気にしないでおくれ。。。
それと、何が出力されているのかは聞かないでおくれ。。。

内容についてはよく知らんのだ。
暗証番号などを入力せずに読めるから、きっと公開鍵かなんかだろうと思ったんだけど、これはたぶん証明書にあたるものだ。
この中のどこかに、公開鍵が入っているんじゃなかろうかね?


元ネタは、こちらだ。
マイナンバーカードでSSHする - AAA Blog

元ネタの方では、2番目にSELECT FILEするのが0x0018になっているが、暗証番号を打ち込まないと読めないやつは怖いので、認証証明書というやつを読込むことにしたのだった。
データ構造はこれになるのかな?
https://www.jpki.go.jp/ca/pdf/cross_certificate_profile.pdf

このアプリではAPIを使ってダンプさせているため、文字列以外は中身が出てきていないようだ。
応用する方法が思いつけば何か作ろうかと思ったが・・・まあ、そういうのは今回は無しだな。

2017年6月8日

[ios]NFCNDEFPayloadはベタのpayloadなのかな

iPhoneを持ってないし、今のところ買う予定もないのだけど、NFC関連のAPIがiOS11から載りそうだということなので、少し見ておく。
なお、いま(2017/06/08)はまだβ版なので、正式版になる頃には状況が変わっていると思う。

NFCが載ったiOSならどれでもいけるのかと思ったが、iPhone7以降ということで、iPhone6はダメらしい。
なんでだろう、ハード的にそうなってるのかな?


見ておく、といったものの、iOSの挙動を知らないし、Swiftも知らないので、雰囲気だけで読んでいきます。
(間違い多いと思うけど許してね、の別表現。)


https://developer.apple.com/documentation/corenfc

大きく4つに分かれている。

  • Reader Sessions
    • class NFCNDEFReaderSession
    • protocol NFCNDEFReaderSessionDelegate
    • protocol NFCReaderSessionDelegate
    • class NFCReaderSession
  • NFC Tags
    • protocol NFCTag
    • class NFCTagCommandConfiguration
  • NDEF Messages
    • class NFCNDEFMessage
    • class NFCNDEFPayload
    • enum NFCTypeNameFormat
  • Errors
    • struct NFCReaderError


classとprotocolというのが並んでいる。。。
Swiftのprotocolは、Javaのinterfaceみたいなものらしい。

全部羅列したら、何か分かるだろうか?

[Reader Sessions]
  class NFCNDEFReaderSession
    init()
    protocol NFCNDEFReaderSessionDelegate

  protocol NFCNDEFReaderSessionDelegate
    readerSession(didDetectNDEFs)
    readerSession(didInvalidateWithError)

  protocol NFCReaderSessionDelegate
    isReady
    begin()
    invalidate()

  protocol NFCReaderSessionProtocol
    isReady
    begin()
    invalidate()

  class NFCReaderSession
    delegate
    sessionQueue


[NFC Tags]
  protocol NFCTag
    isAvailable
    session
    type
    enum NFCtagType
      ISO15693

  class NFCTagCommandConfiguration
    maximumRetries
    retryInterval


[NDEF Messages]
  class NFCNDEFMessage
    record

  class NFCNDEFPayload
    identifier
    payload
    type
    typeNameFormat

  enum NFCTypeNameFormat
    absoluteURI
    empty
    media
    nfcExternal
    nfcWellKnown
    unchanged
    unknown


[Errors]
  struct NFCReaderError
    省略

わからんわな。

NDEFは、TNFまでは見分けてくれるけど、あとは自分で解析してね、というスタンスのようだ。
なお、NDEFのフォーマットというのはこういう感じだ。

image

まあ、ほぼそのままを渡してくれるので、あとはこれからURIだのTEXTだのSmartPosterだのを自分で解析するのだろう。
自由度が高いが、まあ単なるデータだからね。。。

BLEのペアリングだったり、WiFiのSSIDなんかもタグで読めるだろうけど、iOSってアプリからそういう設定ってできなさそうな気がするから、ありがたみは薄いのかな。
コピー・ペーストができるなら、貼り付けるだけで済むようにできそうだけど、なんとなくそれも許してなさそうな気がする。

2017年6月7日

[ios]Core NFC?

いつかなー、いつかなー、と思っていたiOSでのNFC APIだが、そろそろ使えるようだという話が出ている。

Apple adds support for NFC tags to iPhone 7 and Apple Watch • NFC World


APIはこちら。
まあ、実機を持ってないし、開発環境も無いので、見てみただけだ。

Core NFC | Apple Developer Documentation

Reading NFC NDEF tags is supported on iPhone 7 and iPhone 7 Plus.

だそうだ。


それはともかく、タイトルだけ見る限りはタグの検出とNDEFの読み出しができそうだ。

気になるのは「types 1 through 5」というところ。
えっ、いつの間にType5が出たの??

Type 5 Archives - NFC Forum | NFC Forum
あー、AndroidでいうところのNFC-Vか。


NFCは技術として好きなのだけど、NFC Forumが仕様書を会員以外には販売方式にしてから、どうにもやる気がなくなってしまった。
せめて、NDEFの仕様書とTypeの仕様書は公開してくれてもよいと思うのだが。。

2017年2月2日

[n5]Nexus5から搬送波が出なくなった→復活!

開発関係の話じゃ無くて済まないが、私にとっては緊急事態に等しい。
Nexus5から搬送波が出なくなったのだ。

数日前から発生している。
まったく出ないわけでは無く、弱々しく出るときもあれば、出なくなるときもある。
タグの読込はできないし、SNEPもしない。
うーむ。。。

もう、フルバックアップして、端末リセットするしか無いか。。。
Nexus7もがんばってはくれているのだが、やはりこのサイズでNFCが載っているのはありがたいのだ。
もしリセットで復旧しなかったら、買い直すことになるのだろうか。

 

しかし、nRF52でType4に対応したというのに、何というタイミングか・・・。
New NFC feature on nRF52 series: Read/write capable Type 4 Tag NFC library in nRF5 SDK


2017/02/03

Androidの設定画面から端末リセットを行ったが、復帰せず。。。
搬送波の出方が、相変わらず微妙で、位置がいつもの背面のところよりもかなり下の方でしか確認できない。
落下したことで、なんか部品がずれたりしてるとか?
まさかなぁ。

 

せっかくだから、ファクトリーイメージを焼くところまでやっておこう。
https://developers.google.com/android/images

焼けない?

FAILED (command write failed (No error))

やり方を間違ったのかと思ったが、手順はそんなに変わらんし。
・・・USBハブ経由で挿していたのだが、PCに直接挿すとflash-all.batが動いた。
なんだったんだ。。。

そして、焼き直したけど・・・ダメ。
そうよねぇ、ダメよねぇ。

 

ちょうど今日は日本では節分という行事がある日なので、そういうものにでもすがりつきたい心境だが、買い換えを検討するのが妥当だろうな。


毒くらわば皿まで、という言葉が日本にはあります。
あきらめろ?
中途半端で終わらせるな?
そんな意味合いなのでしょうか。

ここまでやったので、裏蓋を開けてみました。

image

爪で開けようとして失敗したので、ビックカメラのカード(10年くらい前に作ったやつなので、今は違うかも)が薄かったので、それを電源ボタン辺りに差し込んで、ぐいっとひねったところ、ようやく1箇所だけ開いた。
あとは、Tポイントカード(これも10年くらい前)が厚めだったので、使い分けながらやっていくと、なんとか開いた。

左側の黒いやつが、NFCアンテナなのかな?
ということは、その上にある4つの接点で本体と接しているのか。

アンテナの右上にある丸いのは、ボタン電池かと思ったが、たぶんセンサだろう。
なんだろう、磁気とかか?

蓋を外した状態で立ち上げ、搬送波を確認したがまったく出ていなかった。
やはり、蓋の裏にあるやつがNFCアンテナか。
運が良ければ、この接点の接触が悪いために出ていない、というだけかもしれん。
アルコールで拭いて、カッターの先っちょで本体側の接点をもう少し持ち上げて、蓋を閉じる。

そして端末を起動すると・・・搬送波復活!
タグも読めるし、SNEPもする!
よかった。。。。


そのあと、しばらくすると、また読めなくなった。
が、接点の辺りを蓋の上から押すと、読めた。

うちの場合は、黄色の丸で囲んだところ辺りに、NFCアンテナの接点があった。
ここが離れているとき、指で軽く押すと、カチッと接触するような音が聞こえた。

image

押すといっても、力を入れるか入れないか、という程度のものだ。
カチッという音も、ちょうど音が鳴るような距離が開いていたから聞こえたのだろう。
だから、押すとちょうど接触して読めたのだろう。

そういう状態であれば、蓋の外から押さえつけるか、蓋を変形してしまえば接触すると思う。
今回は、遠くからライターの火で炙って、少し温めてから少し曲げてみた。
今のところ、それで接触するようになったけど、湾曲しやすいところに接点を持ってくるというのは、あまりよくなかったんじゃなかろうか。
せめて、もう少し縁の方になっていれば、そういう影響はなかったんじゃなかろうか。
実際、NFC以外のアンテナは、縁の方に接点があったし。

2017年1月29日

[android][nfc]Beamアプリを作る

HCE, Reader modeと来たら、P2Pをやらねばならぬのぅ。
というわけで、Android Beamの、NDEFを投げたり取ったりするだけのアプリを作る。
大きいファイルのやりとりをするサンプルもあるが、今回はNDEFだけだ。
Sharing Files with NFC | Android Developers


Androidで使えるO2O技術まとめ解説(終):AndroidビームとPush通知で最強のO2Oアプリを作る (3/3) - @IT
ここら辺にサンプルがあるので、見れば分かるだろう。
あと、NFC Hacksも読みながらやっている。

createNdefMessage()が呼ばれるタイミングは、端末を向かい合わせて、星が流れる画面になったところだ。
LLCPのデータ交換が行われるようになったところ、といえば良いだろうか。
この状態で小さく表示されているアプリをタップすると、相手にデータが送られる。
タップというよりは、相手の方に押すというイメージだろうか。
そして、相手にPUSHされるとonNdefPushComplete()が呼ばれる。

 

まずは、ここまでをコミットしておく。
EditTextに文字を入れ、別のAndroid端末と向かい合わせ、星が流れる画面になったらサムネイル画面をタップする。
そうすると、相手に送られるであろう。
https://github.com/hirokuma/AndroidBeamSample/tree/ca064f1c87acfd396e4ca6eef4832ef847911087

ButtonやTextViewは使っていないので、気にしないでおくれ。


受信する方は、NDEFタグの読み取りと同じだそうだ。

今回はNDEF Textを送受信している。
Textのところは、こちらからお借りした。
なっぴーさんもともきーさんも、お二人とも元気だろうか。。。
ReadRTDText/HomeActivity.java at master · bs-nfc/ReadRTDText

 

Textの送受信まで取り付けたのが、こちら。
https://github.com/hirokuma/AndroidBeamSample/tree/69b3c0eca2016386cb30a5d1a86a987c4d245281

NDEFなんだけど、IntentではactionがTECH_DISCOVEREDでやってくるのよねぇ。

NDEF Textで文字列を送ったが、バイナリデータを送りたい場合はcreateExternal()がよいのだろうか?
気になるところだが、今回はおしまい。

[android][nfc]Reader modeアプリを作る (2)

私も、AndroidのNFC reader modeサンプルを作った。
hirokuma/AndroidReaderSample

まねしたつもりはないのだが、前回参考にしたサイトと同じような内容になってしまった。
androhi/NFCReaderModeSample: NdefAdapter.ReaderCallbackのサンプル

まあ、API呼んで、コールバックされるだけなので、IDを取得するだけであれば、そんなに差が出ないだろう。

 

Nexus5で動かしているのだが、普通のタグ(HCEじゃないやつ)は読めるのだが、Android BeamしているNexus7をかざすとNFC機能自体がおかしくなるのか、普通のタグも読めなくなってしまう。
時間が経てばよくなるわけでも無く、一度Reader modeをdisable-->enableさせないと動かないようだった。
うーん・・・・・・・。

 

ただ、AndroidのCardReaderサンプルは、そういうことが起きていないような気がする。
私のアプリだと、AndroidのCardEmulationサンプルにかざすとNFCタグが読めなくなるのだが、CardReaderサンプルでは何かしているのだ。

面倒だが、サンプルが何をしているか調べるか。


まずは、CardEmulationから。

AndroidManifest.xmlの<service>で、HOST_APDU_SErVICEやxmlでAIDリストの指定をしている。
Activityでは、AccountUpdateというクラスが文字入力の監視と、変更時にHCEが返す値の更新なんかをやっているのだろう。

CardServiceがHCE動作をしている。
processCommandApdu()が入り口になっていて、SELECT FILEで自分のAIDが指定されていれば処理して、そうでなければ処理しない、というだけのようだ。

 

では、CardReaderを見ていく。

AndroidManifest.xmlで<intent-filter>が設定されている。
「Filtering for NFC Intents」によると、NFCタグをかざされたときに自アプリを起動される対象として選んでほしいときにつけるようだ。
優先度を読み解く図があったように思うが、今回は関係ないのでよかろう。

ActivityでReader modeを有効にしているのは、ここ。
対象はNFC-Aで、NDEFチェックをしないようにしている。
処理本体は、LoyaltyCardReader。

 

うーん?
私のReader modeサンプルがAndroid Beamを受けると動かなくなるというほどの違いはなさそうだが。。。


あ、CardReaderサンプルでenableReaderMode()に与えるフラグにNfcAdapter.FLAG_READER_NFC_Fを追加したら同じ動作になった!
これって、何らかのバグじゃなかろうか。。。

HCEしている方には、こういうログが出た。

E/BrcmNfcNfa: llcp_link_activate (): Failed to parse general bytes

そのあとで「--------- beginning of system」と出ている。
Reader側はかざしたときのログは出ないが「beginning of system」のログは出ている。
確か、このログはserviceが起動しているときに出るような気がするので、もしかしたらNfcServiceなどが再起動しているのかもしれない。

FLAG_READER_NFC_Fを追加しても、ちゃんとNFC-Fのタグは読めるのだ。
単に、LLCPを受けるとうまくいかない、というだけである。
そういえば、AndroidのLLCPはNFC-Fでやっていたような気がするので、そこら辺が影響しているのかも。

 

うちにはNexus5と7しか端末がないが、どちらもBroadcomのチップだったように思う。
だから、Android側なのかドライバ側なのかは切り分けができんな。

とりあえずの回避策は、HCEのタグを読みたくてenableReaderMode()を使うのであれば、相手がNFC-Fになることは(Android6までは)ないので、FLAG_READER_NFC_Fは付けないようにする、だろう。

Android7ではHCE-Fがあるらしいから、さすがに直っているのかもしれんが、じゃあReader modeになる方もAndroid 7じゃないといけないのか?という疑問が出てくる。
が、うちにはAndroid7が使える端末がないので、確認できんな。

ひとまず、githubに置いておくサンプルからは、NFC-Fを外しておこう。
https://github.com/hirokuma/AndroidReaderSample

2017年1月28日

[android][nfc]Reader modeアプリを作る (1)

HCEは動いているようだが、Reader Modeになるアプリを作ったことがないことに気付いた。
ならば、やらねばならぬのぅ。

 

Android 4.4で追加されたNFC reader mode - Qiita
「盛り上がっているのか盛り上がっていないのか」で始まるこの記事は、だいたい3年前のようだ。
当時からそうだったのだけど、未だによくわからないですな。。。
私も、バスや電車に乗るときはnimocaを使っているけど、買い物をするときは現金だし。

ただ、技術者にできる特権として、技術を提供できる、というものがある。
それが、たとえマイナーだったとしても。。。
まあ、私はNFCという技術がけっこう気に入っているので、なるべく使っているというしだいだ。

 

さて、脱線はここまでにして、Reader modeを見ていこう。
ActivityがReader modeになって、Android Beamなどに対応しなくなるという動作らしい。


このBeamを止める動作は、HCE側が同じことできないだろうか。。。
HCEしても、Windowsにかざすと、こちらはP2Pされたと思ってSNEPしてしまうのだ。
Reader modeとHCEが両立できるなら、Windowsでもタグとして認識してくれそうな気がする。
設定画面でAndroid Beamを止める設定はあるのだが、これは下回りとしては止まっていなさそうなのだ。
SNEPはしないものの、LLCPの何もしないやりとり(BLEでいえば、Empty PDUだけのやりとり)はしていそうな気配がある。

 

こういうときは、PN7150だ!
AndroidのCardReaderサンプルを起動させて、nfcDemoApp pollしたPN7150にかざすと、Android Beam(LLCP)を検知していない。
しかし、同じくAndroidのCardEmulationサンプルを起動させてかざすと、LLCPしているログが出続けている。

設定画面でAndroid Beamを無効にしてもLLCPしているログは出た。
NFC自体を無効にすると、出なくなる。
しかし、そこからNFCを有効にすると、私のHCE Sampleタグが読めた。
Android Beamを有効にしても、まだ読めている。
そして、何かをトリガにしてAndroid Beamが有効になるようなのだが、トリガが何かは分からなかった。
けっこう放置したけどHCEタグしか読めず、Google Mapアプリを立ち上げたらLLCPログが出始めた。
ポイントは、NFCを無効にする前にAndroid Beamだけを無効→NFC無効→NFC有効→Android Beam有効、の順番だ。
Android Beamだけを有効にしてもLLCPは始まらず、NFC有効時にBeamが有効なら同時に動かすし、SNEPするアプリが起動すればそれはそれで動かす、という動作か。
まあ、ホーム画面をBeamしてもうれしくはないしな。

私が作ったHCESampleサービスも入っているのだが、これはロック画面以外では読み取れなかった。
これは、作り方がよろしくないだけかもしれないので、また考えるとしよう。


軽くLLCP/SNEP/Android Beamの動作を書いておこう。

NFCは、R/WであるInitiatorがTagであるTargetにリクエストを送り、Targetがレスポンスを返す、という通信になっている。
TargetがInitiatorに対して自発的に送信することができないのだ。
しかし、P2Pのようなデータ交換ではどちらがデータを送りたくなるか分からないので、通信している間は常にInitiatorがTargetに何かを送信し、TargetがInitiatorに何かを返信する、ということをやっている。

InitiatorがR/Wとして動作するのか、P2Pの親として動作するのかは、ISO/IEC 18092に書いてあったと思う。
Targetを捕捉してすぐにその判断が行われ、動作分岐するのだ。
RC-S620/SのリファレンスマニュアルではP2Pになるときの動作が書かれているのだが、違う分岐に行くとHCEすることができるだろう。

SNEPは、LLCPでNDEFのタグを投げる、Simple NDEF Exchange Protocolのことだ、。
Android BeamはSNEPでアプリの情報(AAR)を送信していたはず(昔は、Android Pushというプロトコルもあった)。

 

だから、P2Pとして動作せずにR/Wとして動きたいときは、どちらかがLLCPしないようにすればよいのだけど、HCEはバックグラウンドで動くから、いつLLCPをやめる/戻すのタイミングがわからないということで、R/W側がやらざるを得なくなったというところか。
だって、他のアプリがAndroid Beamするつもりで動いているのに、裏で動いているHCEのせいで動作しなかったら「なんで??」ってなるよねぇ。

じゃあ、HCEがサービスじゃなくてアプリの一部として動作するのであればBeamはしなくていいやん、と思ったのだが、このAndroidサンプルはタグを読んでReaderアプリが起動していなかったら起動させる、ということをやっているようなのだ。
ただ、Google Playアプリが起動するだけなのでよくわからないのだが。。。
HCEするアプリの方に数字を打ち込むようになっているから、それがGoogle Playのアプリに関連づけられているのかもしれん。

すまん、サンプルがどういう動きをするのかは読んでいないのだ。。。
しかし、相手のアプリを起動させるためにBeamをしているだけであれば、HCE側もなんとかできるかもしれない。
希望だけ持っておこう。


サンプルを作ろうと思ったが、Qiitaの記事を書かれた人のサンプルがシンプルなので、それを見るのがよいだろう。
とはいえ、私も自分で実装しておかねば、今後使うときに困るので、自分なりに作っておこう。

 

機能として必要なのは、NfcAdapter.enableReaderMode()と、その引数で指定するNfcAdapter.ReaderCallbackクラスの派生クラスのインスタンスだ。
NfcAdapter.ReaderCallbackには、onTagDiscovered()だけがあればよさそうだ。

こちらのサンプルも、AndroidのサンプルもenableReaderMode()の最後の引数がnullだった。
何かと思ったら、reader modeの追加設定などができるみたい。
なんだろう、onTagDiscovered()が呼ばれたときに渡すデータを設定できるのかな?

また、APIの説明文に「disabling any peer-to-peer and card-emulation modes」と書いてあるので、HCEしているときにBeamを止める、というのは、少なくともこれではできないということになる。。。
この辺りは、やはりどうしようもないな。
やりたいなら、利害関係が発生しないように専用端末を作るしかないだろうか。
HCEする自アプリが起動していたせいで、他のアプリがSNEPする機会を失った、などと訴えられても困るものだ。

2017年1月24日

[nfc]Android HCEとWindows10(PC)

前回、AndroidでHCEして動かした。
いずれはきれいに書き直したいのだが、とりあえずNexus5とNexus7(Android 6.0.1)では動いている。

 

ただ、これを読み取る相手がうまくいかない。
NXPのPN7150では、正しく読み取れている。
Androidの画面が表示されていれば、ロック画面でも読み取れるようだ。

ロック画面では搬送波が出ていないので、これであればWindows10でも読めるかと思ったが、今日は動かない。。
AndroidのNXP TagInfoアプリでは1回だけ読めた(Nexus5のHCEをNexus7で読んだ)。
2回目は読めなかったが、普通のNFCタグも読めなくなっていたので、NfcService自体が再起動したんじゃなかろうか。

 

PN7150を使ってみていると、Nexus5のロック画面ではHCEでのタグが、ロック解除するとLLCPが読み取れている。
これはNexus7でも同じようだ。
だから、普通の画面だとHCEが動いていないかもしれんが、ロック画面では動いていそうなのだ。
だったら、Windows10で読めてもおかしくない気が。。。

Androidのログを見ても、アクセスしに来たという形跡がない。
FeliCa Plugで搬送波検知タイミングをLEDで表示させてみたが、読み取れるタグをかざしたときと、HCEしているロック画面をかざしたときの点灯具合が明らかに異なる。
通常は間欠送信で、タグがあると出しっ放しになるのだが、ロック画面をかざしても間欠送信しかしていない。
Windows10に読み取れるタグをかざして搬送波を長めに出させ、ささっとロック画面にしたAndroidをかざすと読み取ってくれた。

 

ということは、うまくHCEのタグを読んでくれないのは、Windows10の粘りが足りないということか。
RC-S380を使っているのだが、NFCポートソフトウェアがインストールされていないせいかもしれないが、もうちょっと長めに出さないとHCEしている端末では間に合っていないのかもしれない。

[nfc]HCEサンプルを久々に動かす

お仕事用にNFCタグを作っていたのだが、そういえばAndroidにはHCEがあったことを思い出した。
HCE...Host Card Emulation。
モバイルFeliCaチップやPN544のようにチップがカードエミュレーションするのではなく、ソフトウェアが制御するカードエミュレーションだ。

 

3年くらい前に作ったものがあった。
hiro99ma blog: [nfc]HCEのサンプルを作った
SDK19だったらしい。
まだAndroid Studioではなかったのでimportして、SDKを22くらいに変更(最新すぎない程度に新しくした)。
PC/SCも少しやったので、当時よりは内容を理解できるかもしれんが、まずは動かそう。

。。。動かん。
そもそも、ActivityがないServiceだけのアプリだから、動いていてもいなくても、よくわからん。
当時はFeliCaランチャーを使ったようだけど、どうせなら普通のR/Wで読込ませたいではないか。

 

そうだ、こういうときにPN7150を使えばよいのだ!
nfcDemoApp pollを起動して、かざすと・・・

Found

Type :          'Type A'
NFCID1 :        '08 20 79 C5 '
Record Found :
                NDEF Content Max size :         '48 bytes'
                NDEF Actual Content size :      '27 bytes'
                ReadOnly :                      'FALSE'
                Type :                          'URI'
                URI :                           'http://hiro99ma.blogspot.com/'

ふん、動いているじゃあないか。

そして、うまく動いてくれなかったWindows10 + RC-S380や、Nexus7のNXP Tag Infoアプリでも読めるようになった。
なんだったんだ。。。

うっとうしいことに、Nexus7にかざすと、Nexus5(HCEアプリはNexus5で動かしていた)の方にAndroid Payの画面が立ち上がってしまう。
対応するクレジットカードを持っていないので、出てきても困るし、そもそもそんなの期待していない。

まあ、動くには動いたので、Android Studio + SDK22版をコミットしておこう。
ランチャーがないので、設定アプリから削除するなりアンインストールするなりになります。
hirokuma/HceSample at 6419f2ad21e4654f7b084e64744eb2b2fc7fc521


GoogleのHCEサンプルを動かしてみたのだが、こっちはSNEPというか、Android Beamっぽく動いてしまう。
googlesamples/android-CardEmulation

 

うーん、便利にしようとしすぎて、よくわからない動きになってしまっている気がしている。
かといって、iOSみたいに何もできないのも困るので、もうちょっと自由度がありつつ、抑えもきかせたいという。。。
もう、専用のハードボタンがあってもよいんじゃないかとすら思ってしまう。

2017年1月23日

[nfc]OM5578/PN7150S来たる - おまけ

今さらだが、OM5578/PN7150S Raspberry Pi版の回路図があった。
http://www.nxp.com/documents/software/HW3561.zip

PN7150やOM5578でばかり調べていたけど、直接Raspberry Piに挿すのはOM29110だから、その図面を探さないといけなかったのだな。。。

 

こちらが、OM5578(PN7150が載っているボード)のピン(I2C側は省略)。

image

こちらが、Raspberry Piに挿す方。

image

 

基板のシルクを見ると、GPIO_0がIRQ、GPIO_1がVEN、残りは印刷されていない。
そして、GPIO_0はRaspberry Piの16ピン、GPIO_1は18ピンにつながっている。

 

で、前回のDTSファイル。

&i2c1{
	status = "okay";
	pn547: pn547@28 {
		compatible = "nxp,pn547";
		reg = <0x28>;
		clock-frequency = <400000>;
		interrupt-parent = <&gpio>;
		interrupts = <23 0x0>;
		interrupt-gpios = <&gpio 23 0>;
		enable-gpios = <&gpio 24 0>;
		firmware-gpios = <&gpio 25 0>;
	};
};

あー、interruptsやinterrut-gpiosが23なのは、PN7150のIRQピンがRaspberry Piの16ピンで、それがGPIO23だからか。
VENも、18ピンがGPIO24だから、enable-gpiosも24なのだね。

firmware-gpiosはGPIO25の予定だけど、回路図に書いていないから意味が無いのかもしれない。
OM5578の回路図はこうなっていたので、うん、意味が無いな。

image

 

ドライバのソースを読むと、IRQは必須だけど、VENやFIRMはオプショナルのようだ。
FIRMは、ファームウェアのダウンロード制御に使うようである。

 

LinuxのDevice-Treeのことはわかっていないが、今回の数字がRaspberry PiのGPIOピンと関連していることが分かったので、少しすっきりした。

2017年1月22日

[nfc]OM5578/PN7150S来たる (5)

前回、dmesgを確認して、何かエラーになっているところまで分かった。
どうしたものか。。。

01: (irq_create_of_mapping) from [<80498ba8>] (of_irq_get+0x4c/0x5c)
02: (of_irq_get) from [<8044af78>] (i2c_device_probe+0x208/0x224)
03: (i2c_device_probe) from [<8039d008>] (driver_probe_device+0x204/0x2d0)
04: (driver_probe_device) from [<8039d170>] (__driver_attach+0x9c/0xa0)
05: (__driver_attach) from [<8039b1b0>] (bus_for_each_dev+0x74/0xa4)
06: (bus_for_each_dev) from [<8039ca30>] (driver_attach+0x28/0x30)
07: (driver_attach) from [<8039c640>] (bus_add_driver+0x19c/0x224)
08: (bus_add_driver) from [<8039d830>] (driver_register+0x88/0x108)
09: (driver_register) from [<8044c278>] (i2c_register_driver+0x48/0x8c)
10: (i2c_register_driver) from [<7f0e9024>] (pn54x_dev_init+0x24/0x38 [pn5xx_i2c])
11: (pn54x_dev_init [pn5xx_i2c]) from [<80009754>] (do_one_initcall+0x90/0x1f0)

バックトレースまで出ていて、この辺がポイントなんじゃなかろうかとは思うのだが、見方がさっぱりわからん。

pn54x_dev_initはgithubから落としてきたソースに入っている。
また、このログの後にこう出ている。

01: pn54x_probe
02: /soc/i2c@7e804000/pn547@28: could not get #gpio-cells for /soc/cprman@7e101000
03: pn544 1-0028: VEN GPIO error getting from OF node
04: pn544: probe of 1-0028 failed with error -22

よくわからんが、OF nodeとかいうやつが関係しているらしいから、of_irq_getがうまくいかないとか、そんなことだろうか。
検索してみた。

Raspberry Pi • View topic - AR1021 Touch Controller Overlay/Driver Issues

この人も、同じようにエラー-22で、I2Cで、of_irq_getのログが出ている。
アドバイスで「"interrupt-parent"を正しくせよ」と書かれている。

今使っているDTSの設定は、NXPが提供しているDTBファイルから持ってきたものだ。
kernelが違うので、interrupt-parentを変更しないといけないということかもしれない。
<0xf>という値は、動いているDTSファイルを検索すると、bcm2835-gpioのphandleというものと同じ値のような気がする。
今のDTSファイルでは、bcm2835-gpioのphandleは<0xb>になっていた。

では、と、pn7150のDTSファイルで<0xf>を<0xb>に変えてみた。

01: pn54x_dev_init
02: pn54x_probe
03: pn544 1-0028: CLKREQ GPIO  error getting from OF node
04: pn54x_probe: request irq_gpio 23
05: pn54x_probe: request ven_gpio 24
06: pn54x_probe: request firm_gpio 25
07: pn54x_probe : requesting IRQ 189

おお、バックトレースが出なくなった!
出なくなったが、OF nodeのエラーは出ている。。。
nfcDemoAppを動かしても、コールバック関数登録のエラーが出て動かない。

エラーは、ここだろう。
https://github.com/NXPNFCLinux/nxp-pn5xx/blob/master/pn5xx_i2c.c#L460

OPTIONALと書いてあるから、もしかしたらオリジナルでもエラーになっているかも・・・出てた。
ということは、それ以外の原因で動いていないのか。。。


NXPのkernelでnfcDemoApp pollするとpn54_dev_open()が呼ばれているログがdmesgに出るのだが、私のkernelでは出てない。
lsmodでpn5xx_i2cは出てるし、/dev/pn544はあるし、何が不満なのだ?

 

出ているのは、このエラーだろう。
https://github.com/NXPNFCLinux/linux_libnfc-nci/blob/master/demoapp/main.c#L665
たどると、nativeNfcSnep_registerClientCallback()だとは思うが、エラーログすら出てないので、さっぱりわからん。
トレースログはsrc/halimpl/pn54x/log/phNxpLog.hのマクロをTRUEに変更せんといかんようなので、リビルド。

NxpFunc:    nativeNfcManager_doInitialize: enter; NCI_VERSION=0x10
NxpFunc:    nativeNfcManager_doInitialize: can't find libnfc-nxp.conf file
NxpFunc:    nativeNfcSnep_registerClientCallback:
NxpFunc:    nativeNfcSnep_registerClientCallback: Nfc not initialized.
SNEP Client Register Callback Failed

意外ッ! それは設定ファイル!!
どうも、/etc/libnfc-nxp.confを読みに行っているようである。
ファイル自体はこれを置けばよいのか。
make installしてもコピーされないので、わからんよ。。。
https://github.com/NXPNFCLinux/linux_libnfc-nci/blob/master/conf/PN7150/libnfc-nxp.conf

ファイルを置いて、ついでにLD_LIBRARY_PATHに/usr/local/libを追加した。
今度実行すると、先に進んだが、I2Cのオープンに失敗しているようだ。

NxpTml:     Opening port=/dev/pn544
NxpTml:     _i2c_open() Failed: retval ffffffff

I2Cは/dev/i2c-1だと思うが、/dev/pn544とつながっているのかな?
試しに

$ cat /dev/pn544

とすると、Permission deniedで怒られた。
ということは・・・

$ sudo ./nfcDemoApp poll

おー、動いた!
ログが大量に出てわからんが、搬送波も出ているし、かざすとログが出るので、読んでいるのだろう。


では、Raspberry Pi2の自分のkernelをビルドし、OM5578/PN7150Sを動かすようにするまでの手順を残しておこう。
もっとスマートなやり方があるとは思うのだが、今の私ではこれが限界だ。

  • Raspberry PiのKernel buildingを見ながら、ビルドする環境を作る。
    うちは、Bash on Windowsでやった。
  • AN11697のPDFの3章を見ながら環境を作る。
  • 3.2.3章のデバイスノードは、Device treeの方にする。
    私はこの内容をnxp-pn5xx.dtsという名前で、arch/arm/boot/dts/に置いた。
    数字は、NXPのkernelからDTBファイルをDTSに変換して持ってきた。
&i2c1{
	status = "okay";
	pn547: pn547@28 {
		compatible = "nxp,pn547";
		reg = <0x28>;
		clock-frequency = <400000>;
		interrupt-parent = <&gpio>;
		interrupts = <23 0x0>;
		interrupt-gpios = <&gpio 23 0>;
		enable-gpios = <&gpio 24 0>;
		firmware-gpios = <&gpio 25 0>;
	};
};
  • arch/arm/boot/dts/bcm2709.dtsiファイルに、「#include "nxp-pn5xx.dts"」を追加。
    これだと、Raspberry Pi2のDTSファイルにしか読み込まれないので、bcm2708_common.dtsiに追加した方がよいかもしれない。
    また、nxp-pn5xx.dtsにしたものの、includeするから拡張子はdtsiの方が良いのかも。
    ルールがよくわかってない。
  • Raspberry Piのサイトを見ながらkernelをビルドする。
    DTBファイルを作るだけなら、make ~ dtbsだけ実行するとarch/arm/boot/dts/にDTBファイルができるので、それでよいだろう。
  • ビルドしたものをRaspberry Piのサイトを見ながらSDカードに展開する。
    DTBファイルだけなら、SDカードにコピーするか、動いている環境から/boot/にコピーする、でよいだろう。
  • ここまででよいはずなので、Raspberry Piを起動し、dmesgを見る。
    "dmesg | less"などとして、"pn"を検索するのがよいだろう。
    エラーになっていないなら、たぶん大丈夫。

次は、デモアプリ。
Raspberry Piでビルドする前提。

  • githubからlinux_libnfc-nciをgitで取ってくる。
  • ./bootstrap
  • ./configure --enable-pn7150
  • make -j4 (jの数はてきとう)
  • sudo make install
  • conf/PN7150/libnfc-nxp.confを/etc/にコピー
  • LD_LIBRARY_PATHに/usr/local/libを追加
  • sudo ./nfcDemoApp pollなど

たぶん、こんなもんじゃなかろうか。
つかれたー。

2017年1月21日

[nfc]OM5578/PN7150S来たる (4)

PDFに従い、make defconfigして.configを作った。
menuconfigするのが面倒だったので、.configをPNで検索して書き換えた。

CONFIG_NFC_NXP_PN5XX=m

そして、zImage, modules dtbsする。
時間がかかってビルドできたので、書いてあるようにSDカードにコピーする。
私はBash on Windowsでやったので、適当にtgzに固めて、scpでコピーしてRaspi上で書き換えた。

起動!
・・・だめだ、koファイルはできているのだが、読込んでくれる気配がない。。。

 

問題は、DTSファイルの方ではないだろうか?

試しに、arch/arm/boot/dts/に、"Hello!"と書いたaaaaa.dtsファイルを置いて、make dtbsしてみた。
エラーにも何もならない。。。
読んでくれてすらいないということか。


じゃあ、今動いているkernelはどうやってるんだろうか。
もしかして、=mじゃなくて、=yしてkernelに入れ込んでるんじゃなかろうか?
だからといってDTSファイルが不要だとは思わないけど、kernelに組み込んでいるからdtbに入っている、とかか?
それだったらoverlaysに入っているのかもしれんが、そういう訳でもない。
DTSがわかってないのに、適当にやろうとするのが間違いなのか。。。

 

まあいい。
まずは、動いているkernelと同じconfig設定にしよう。

Raspberry Pi 2で現在のカーネルのコンフィグを確認する - 組み込みの人。

これでconfig.gzを取り出して、見てみた。

CONFIG_NFC_NXP_PN5XX=y

ビルドし直して動かしたが、そういう話ではなさそうだ。


動いている環境のdtbを見直したが、pn7120の部分はi2c@7e804000というところの中に入っているのだ。
入れ子になっているから、includeとかしてるんじゃないだろうか?

適当の書き換えて、raspi2のdtsにincludeしたら、それっぽいdtbファイルになった。


とにかく、アプリを動かさないと分からない。

https://github.com/NXPNFCLinux/linux_libnfc-nci

git-coreをapt installし、上記をgit cloneして、./bootstrapして足りないものをapt installして、

$ sudo apt install git-core bc automake autoconf libtool
$ ./configure --enable-pn7150
$ make
$ ./nfcDemoApp

立ち上がりはするのだが、SNEPのコールバック関数登録ができないというログが出るし、なによりタグをかざしても反応がない。

失敗だ!

 

/dev/を見ると、/dev/pn544がない。
lsmodではpn5xx_i2cが見えるのだが、あればよいというわけではないのか。
configを見比べたが、動いている方でもNFCは有効<m>になっているものの、CONFIG_NFC_NCIなどは未設定になっている。
CONFIG_NFC_PN533は<m>だけど、これは関係ないよなぁ。
CONFIG_BCM2708_GPIOが今回のconfigにないのがあやしい気もするのだけど、そもそもPDFではkernelの設定については触れられていないので、さっぱりわからん。。。

$ dmesg
....
pn544: probe of 1-0028 failed with error -22
...

あー、ドライバでエラーが出てるんだ。

2017年1月20日

[nfc]OM5578/PN7150S来たる (3)

では、Raspberry Piのkernelをビルドして、一緒にnxp-pn5xxもビルドしよう。

 

ここからが、いろいろ分からなかった。。。

Raspberry Piのkernelビルド自体は、説明ページもあり、クロスコンパイルのことも書かれているので、よい。
Kernel building - Raspberry Pi Documentation

nxp-pn5xxをkernelのソースに組み込む方法も、こちらのPDFに書かれていた。
https://github.com/NXPNFCLinux/linux_libnfc-nci/blob/master/doc/AN11697%20-%20PN71x0%20Linux%20Software%20Stack%20Integration%20Guidelines.pdf

じゃあいいやん、と思ったのだが、デバイスの情報がいるではないか。
上記PDFの、"3.2.3 Creating the device node"のところだ。
サンプルもあるくらいだから、Device treeを使うのだろう。
nxp-pn5xx/sample_devicetree.txt at master · NXPNFCLinux/nxp-pn5xx

regはI2Cアドレスだろうから0x28でよいだろうし、clock-frequencyもI2Cだからこのままでよいだろう。
問題は、interrupt-gpiosとenable-gpiosだ。
ドキュメントに、どう設定すべきか書いてある箇所を見つけられなかったのだ。
テスターで当たってみると、たぶんVENが18ピン、IRQが16ピンになっているのだと思う。
が、どう書いてよいのかがわからん。。。

/bootにdtbファイルがあることが分かったので、これを変換してdtsファイルにした。
[Linux][kernel] Device Tree についてのまとめ – Qiita

pn7120@28 {
        compatible = "nxp,pn547";
        reg = <0x28>;
        clock-frequency = <0x61a80>;
        interrupt-parent = <0xf>;
        interrupts = <0x17 0x0>;
        interrupt-gpios = <0xf 0x17 0x0>;
        enable-gpios = <0xf 0x18 0x0>;
        firmware-gpios = <0xf 0x19 0x0>;
        linux,phandle = <0x29>;
        phandle = <0x29>;
};

Raspberry Pi2っぽいdtbファイルを選んだのだけど、たぶんどれも同じよね。。。
githubのサンプルより項目が多いのだけど、全部書いた方がよいのだろうか?
あるいは、自動で埋めてくれるから書かない方がよいというタイプだろうか。。。

悩むねぇ。

2017年1月19日

[nfc]OM5578/PN7150S来たる (2)

PN7150は、これだ。
PN7150|High Performance Plug'n Play NFC for OS|NXP

NCI1.0互換というところが売りのようだ。
NFC Controller Interfaceの略なのだが、NCIの仕様書はNFC Forumの有料会員になるか購入するかしないと入手できなくなってしまった。

が、NCI1.0のときはまだダウンロードできたので、手元にある。
以前ダウンロードできたものが有償になったときって、ダウンロードしたものの扱いはどうなるんだろう?
まあ、捨てないけどさ。


PN7150に戻ろう。
PDFを見ると、PCD(R/Wね)にもなれるし、PICC(タグね)にもなれるようだ。
PN53xみたいなチップなのかもしれない。
PN54系は使ったことが無いが、モバイルFeliCaチップみたいに電源だけ入れておけばCardEmulationしてくれるのだろうか。
まあ、私には手に入れられないチップだから、気にすまい。。。

ブロック図を見ると、Cortex-M0が載っていた。
へー。
CODE側とDATA側にそれぞれEEPROMが載ってるのは何でだろう?
ホストとはI2Cで通信するようだ。


そういえば、今のLinuxはNCI対応しているということだ。
I2Cはどうやってるのだろう、などと思っていたが、kernelのビルド時に決まっているのだろうか?

このPDFを見ると、kernel spaceのドライバと、user spaceのHALで何とかしているように見える。
linux_libnfc-nci/doc at master · NXPNFCLinux/linux_libnfc-nci

image

 

lsmodすると、pn5xx_i2cというモジュールが読み込まれていた。
PN7150だけど、pn5xxで扱えるようになっているのだろう。

ソースはこれか。
ちょっと見たけど、よくわからん。
NXPNFCLinux/nxp-pn5xx: NXP's NFC Open Source Kernel mode driver

$ cat /sys/bus/i2c/devices/1-0028/name
pn547

この0028が、0x28というI2Cアドレスということだろうか?

UM10936によると、PN7150のI2Cアドレスは0x28~0x2Bで、アドレスピン2本で決定されるようになっている。
OM5578/PN7150Sの回路図ではどちらのピンもGNDにプルダウンされているから、0x28でよいはずだ。

しかし、これは機器を接続するまで分からないはずだ。
モジュールのビルド時に決定しているのだろうか?
今回使ったRaspberry PiのSDカードはPN7150用だから、そうなのかもしれない。

 

いくらモジュールやアプリが提供されていても、使うまでの方法が分からねば意味が無いのだ。。。
次はそこら辺を見ていこう。