2012/05/31

[adk]何かが足りない・・・

前回、PC+libusb-1.0でAcerタブレットのA500をAccessory Modeにすることができたようだった。

 

では、と同じしくみをCQ社のLPC2388基板に組み込んで動かしてみた。
うんうん、VID(Vendor ID)とPID(Product ID)は、ちゃんとAccessory Modeのに切り替わった。
ちゃんとAccessory Modeになると、A500側にダイアログが出てくるのだが・・・出てこん。
待ち時間を増やしたり、PCでうまくいった処理を削っていったりして何が足りないのか調べたが、よくわからん。
「一家に1台のUSBアナライザ」という言葉があるが、こういうことか(いやいや私には不要だ)。。。

 

違いそうな点は、取り除く処理だ。
たとえばWindowsだと、VID/PIDが切り替わるので、デバイスが取り除かれるサウンドと取り付けられるサウンドが鳴動する。
android developerのサイトにあったArduinoサンプルを見ると、AAP(Android Accessory Protocol)の最後でdetach待ちのようなことを行っている。

 

NXPのUsbHostLiteサンプルにはなさそうなところだった。
はて・・・どうしたもんだか。

2012/05/30

[nfc]TargetになるのとCard Emulationするのはちょっと異なる

NFCでターゲットになるのと、カードエミュレーションするのは、ちょっと異なると思う。

ターゲットにならないとカードエミュレーションできないのだが、ターゲットになったからといってカードエミュレーションをする必要はない。

 

カードエミュレーションというのは、文字通り「カードのエミュレーションをする」ことである。
ターゲットというのは、単にイニシエータの対象になる側に回るというだけのことだ。

 

先日、Androidは250msごとにポーリングし、ポーリングし終わったらカードエミュレーションする、と書いたが、それはソースのコメントにそう書いてあっただけだ。
カードエミュレーションするのだったらターゲットになってるからAndroid Beamもやることができるだろうな、というだけであって、Android Beamをするためにカードエミュレーションをする必要はない。

 

NFC Forumの図でも、P2PとCard Emulationが別の柱になっているのはそういうわけである。


しかし、こちらの記事を読んだが、Google Walletってこれじゃいかんよなあ、と思う。
Google Wallet:使ってみました,CNET Brian Bennet氏体験記

なんというか、緊急通報でアプリが落ちる携帯電話、みたいな気分になってしまう。
考えが甘いところがあると、業界全体がだめになったりする。
それでも、できの悪いシステムはもうちょっとつるし上げられないといかんのじゃないか、という気にすらさせられるお話だった。

2012/05/27

ADKの練習

LPC2388基板を使って、ADK(USB Host側)になろうとしている。
しかし、USBもままならないのに、いきなり海に飛び込んでいいものだろうか?
やはり準備運動をしないと、足がつってしまうかもしれない。

 

そんな心配があったので、libusb-1.0を使ってPCをADK化(というのか?)してみた。
cygwinでやったせいかちょっとめんどくさかったが、A500がAccessoryModeになるところまで確認できた。
(Windowsだと、zadig.exeなどを使うことになると思う。説明はこちら。)

https://github.com/hirokuma/libusb_adk

 

さすがlibusbで、Android Accessory Protocolの仕様通りにやったら、動いた。

Accessory Modeになることはできたが、そこから元に戻すプロトコルはなさそうだ。
USBを引っこ抜けば、元に戻るようだった。

 

A500は、以前はAcerのベンダIDのままだったような気がするが、少なくとも今回はAAPの仕様通りに動いた。
Linuxでも動かせると思うが、LinuxだったらAccessoryChatがあるので、そっちをいじった方が確実かも。

Android側のアプリを作ってないので、本業であるバルク通信までは確認できないんだけど、まあなんとかなるだろう。

USBのEnumeration (1)

LPC2388のUSB Host機能を使おうとしている。
USBメモリはサンプル通りにやって使えたのだが、何が行われて動いているのか全然わかっていない。
LPC2388などのUSB Hostサンプルは、NXPが公開している。
私は楽をしたいので、Interface誌の記事をそのまま使った。

Host_EnumDev()を呼んで、MS_Init()を呼んで、FAT_Init()を呼ぶと、USBメモリが使えるようになっている。
MS_Init()は、MassStorageクラスの初期化だろう。
FAT_Init()は、ファイルシステムの初期化だろう。
Host_EnumDev()がUSB Host機能の初期化部分なので、ここだけ把握しておけば何とかなるんじゃなかろうか。



EnumDev、とあるので、これが「USB Enumeration」というやつだろう。
カタカナだと「エニュメレーション」らしい(Googleは、まず入力した通りに検索してくれないものかね)。
確かに、Tech Villageのサイトに書かれている順番でやっているのだけど、もうちょっと詳細が知りたい。
そういうときは、元資料を探さねば。
http://www.usb.org/developers/docs/
USB.orgのドキュメントページから、USB2.0の仕様書をダウンロード。
(仕様書はときどき更新されているのか、私が昔ダウンロードしたものとファイル名が変わっていた。)
この中の「usb_20.pdf」が基本資料になっている。
私が知りたいことは、9章に書かれていた。



まず、Stateという概念がある。
Attached、Powered、Default、Address、ConfiguredとSuspendedの6つ。
9.1.2節が、Bus Enumerationの説明だ。
USB機器を挿すと、AttachedからPoweredになり、Default、Addressを経由して、ConfiguredまでいくとUSB機器として使えるようになる、ということらしい。
このStateを順番に回すから、enumeration、なのかな。

でも・・・Tech Villageに書いてあることとそんなに変わらない。
私が知りたいことは、もうちょっと実装レベルのことだ。
一番わかりやすかったのは、PICでなんか作るばい、というページ。
たしかに、こういう実装になっているのだ。
初回のGET_DESCRIPTORが8byteしか読んでいないので、気になっていたのだが、そういうものらしい。
では、気にせずこのままいくとしよう。

Androidはポーリング周期後にカードエミュレーションするのか

昨日の勉強会で、Androidでは250msごとに搬送波が出ている、というオシロスコープを使った報告があった。

この辺ってどうなってるんだっけ、と思って調べる。


深く追わずに、25、というキーワードで検索。

packages/apps/Nfc/jni/com_android_nfc_NativeNfcManager.cpp

ここに「Polling Loop」というコメントがあり、ひっかかった。
コメント通りなら、250msごとに搬送波を出すが、出し終わったらカードエミュレーションモードになるらしい。

ほほぅ。
確かにこうすれば、Android Beamのためにターゲットにならんといかんという部分が解決できる。

もう少し下のソースに、「Enable CEA detection mechanism」って書いてあるが、これは「Card Emulation A」の略みたいだ。
Type-Aのエミュレーションってことかね。

少し上には「RF Level Detector」って書いてあるので、搬送波検知のRSSIレベルをここで設定して、割込が発生するようになるのかも。

 

しかし1つ疑問が。
同じタイミングで同じ設定のAndroid端末を2台起動すると、同じタイミングでポーリングしてしまって検出できなくなるんじゃないの?と思ったのだ。
ちょっとでも違えば、たぶん搬送波検知機能が動作するんだろうけど、まったく同じタイミングだったらどうしようもあるまい。

なにか手は打ってあるんだろうと思うが、意外と忘れてたりして。

NTAG203は何が違うのだろう?

昨日の勉強会で、勉強会スタンプラリーのスタンプがNFCタグだった。
このタグ、シールタイプのNFCタグだが、NTAG203らしい。
「NFCの性能を全部引き出す」みたいなのが売り文句だったと思うが、はて、何が違うのだろう?


203という数字には意味があり、

2・・・Platform indicator
0・・・Generation number(0はじまり)
3・・・Code number for memory size(3は128~256byte)

となっている。
特徴を見ても、NFC-Aと変わらんように見える。
106kbpsだし、7byte UIDだし。
そもそも「NFC Forum Tag 2 Type compliance」って書いてあるから、大きな違いはないはずだ。

ブロック図も、Ultralight(Cがつかない方)と同じ。


ただ、203Fになると、ちょっと違う。

Fは「Field Detection」、つまり搬送波検知つきなのだ。
カードで検知しても仕方ないが、NTAG203FはHWSON8というパッケージらしい。

Fの方は、データシートの入手にパスワードが必要らしい。
よくわからんが、そこらへんが境目らしい。

2012/05/26

NFC勉強会2はArduino率が高かった

福岡NFC勉強会の2回目から帰ってきた。
(主催者のまどろみさん、おつかれさまです)

 

今回の私は、「FALPとLLCP」というスライドを公開した。
公開、というのか。展示、ではないとおもうが。

私としては、FALPでもLLCPでもなんでもいいから、データを吸い上げたいだけだ。
しかし世の中の事情がそう簡単にはできていないので、うちの環境ではどっちも実現できないもどかしさを墨絵によって表現した。
・・・いや、墨絵ってのは嘘だがね。

 

聞いていた発表は、かなり興味深いところだった。
そこら辺は、他の人の紹介にお任せします。

 

基本的に、私は外に出て行くタイプの人間ではないので、社外勉強会に出ると驚かれる。
一応フォローしておくと、誘われたからでたんですよ! です。
3回目のお誘いはどうなるか、わからんです。
でも、主催者が今年までだし・・・などと悩むところでもあるが、まあそれは私の問題だ。


今回の勉強会に行ってわかったのは、Arduino率が高いということ。
私はArduinoを持ってないので、あー、とか、うー、とか思いながら見てたが、話には入れなかった自分に忸怩たるものがある。
深く恥じ入っているわけではないが、悔しいというところか。
業界とか情勢とか把握してなくて、話を聞くだけになってたところも多いがね。

 

しかしまあ、Arduinoはよくできていると思う。
使ったことはないけど、液晶に画面を出して「1ヶ月くらいしかやってないんですよ」っていわれると、そう思わざるを得ない。
持っている人の割合が非常に高かった。

まあ、こうやって時代に取り残されていくのだろうな、と寂しく笑い、私は天神を去った。

形式手法というものがある

今月のInterface誌が届いていたので、朝から読み始めた。

FM3の説明がたくさんあり、マルチファンクションシリアルで挫折しかけた私にはよさそうだった。

今はLPC2388で遊んでいるので、読むのは後回しにしようかと思ったのだが、OpenOCDの話が載っていたので、そこは読んでおこうと思う。
JTAGデバッガがほしいほしいといってはいるものの、あまり深く考えてなかったのだ。
私は仕事でロータバッハのしか使ったことがないのだが、そういえばJTAG ICEってなんでもいいってわけでもないよなあ、ということに気付いたのだ。

まあ、勉強会が終わってからですな。


今月からの新連載として「Bメソッドによる形式手法」という6回連載の企画が始まった。
仕事が煮詰まっていて忙しいときは、あまりこういう記事を読む気分になれないのだが、今月末は珍しく作業の狭間が来るので、ちょっと(気分に)余裕がある。
そういうときに、こういう勉強をしておかねば。

 

こういう「手法」のようなものは、展示会に行ったりするとあちこちで説明していたりするイメージがある。
なんというか、流行のようなものがあるような気がして、「また来年いくと違うことやってるんだろうな」と思って、不勉強なままになってしまう。
ここ数年、展示会とかいってないので、私の勝手なイメージだがね。

ただ、そうやって見過ごしていると、いつの間にか世の中の潮流から取り残されてしまう、という心配を最近するようになった。
「オオカミが来たぞ-」っていわれても「またか」と無視しているうちに、本当にオオカミが来て村が全滅してしまった、みたいな心配だ。


Bメソッド、というのは、ソフト開発のための形式手法の一つらしい。
そもそも「形式手法」ってなんじゃ?と思ったら、ちょうどいいのがあった。

いまさら聞けない 形式手法入門 (1/3)

そうなのよね・・・ときどき「いまさら」と思って調べないままにしてしまうことがあるのだ。
いかんいかんと心の中では思っているのだが・・・。

と思って読んだけど、やっぱりよくわからん。
もう1つ見てみた。

ディペンダブル・システムのための形式手法の実践ポータル

総称らしい。
たしかに、Bメソッドの記事にも「この辺をカバーします」みたいなことが書かれている。

 

最近、実装していくごとに仕様不明点を質問されたりするので、なんとかしたいところだ。
「こうやってこうやってこうやったときは、どうなるの?」というのが、自分でもよくわからなくなることがあるのだ。

曖昧な点をなくすために長い文章を書くのもメンテナンスが大変になるので、こういった手法で解決できるなら取り入れたいところだ。

2012/05/25

[無駄無駄話]どうでもよさそうなスライドたち

前回の続き。
今度は、今まで作った中でもどうでもよさそうなスライドたちだ。

これはねぇ、うちの電子レンジが今年で18歳になったときに考えたものだ。
私が学校の研究室に入った年に買って(みんなの金で)、私が卒業するときに研究室が解散になったのでもらい、今に至る。



なんだこりゃ?
ああ、これは二日酔いでぼーっとした頭で電車に乗ろうとして切符を買ったが、ぼーっとしすぎて名前が似た遠い駅まで買ったときに書いたものだ。
払った金が悔しくてね。


これはなんか、急に思いついてつくった。
なぜか「メガネって、ずっとつけとるやん」と思ったのがきっかけ。
クリップアートを多用した作りになっているのは、「やっぱり絵があるといいよな」と思っただけである。


これは、あんまりおちゃらけてない。
AndroidでできたNFCアプリをPCから動かせるといいかもな、と思ったのがきっかけ。
バックグラウンドでの定期ポーリングがカードアクセス中に動いてしまうので何らかのブロックを入れたいな、と思ったところで止まっている。
この作りかけから、誰かやってくれんかなあ。
でも、AndroidエミュレータでNFCが使えるようになるという話もあったので、そんなに需要はないのかも。

2012/05/24

[無駄話]最近作ったスライドたち

なぜか、ときどきスライドを作りたくなる。
前回のNFC福岡勉強会を機に作るようになったのだが、どうでもいいことを書きたいときに作るようになってしまった。
今回は初回なので、今まで作ったものをいくつか載せていこう。
といいつつ、slideshareの貼り方練習だったりする。
ページが重たそうだったら、気にくわないので削除しよう。

記念すべき?初回作品。
自分の過去を振り返っただけなので、ちと恥ずかしい気もするが、まあいいや。

これは勉強会で発表したもの。
背景が青っぽいのは、昔からの癖だ。
暗い部屋だと、白背景は画面がまぶしすぎる、というのもあるし、医学学会などでは青背景のスライドが多かったので、見慣れたということもある。
まあ、最近はそこまで暗い部屋でやることもなくなったので、そうでもないのかな。
きっとプロジェクターの性能が上がって、明るい部屋でも見やすくなったのだろう。
技術の進歩は、スライドの背景色も変える。

Aboutものが2つ。

どっちも、よく使っているものなので、自分のまとめとして作ったものだ。
FeliCa Plugは、私も話を聞いてもピンとこなかったので、イメージがつかめると嬉しいところだ。

基礎っぽい資料もいくつかある。

基礎は大切なので、資料を作っておきたい。
といいつつ、私自身は「NFCとは・・」みたいなのがあんまりわかっていない。
「ああ、nimocaとかあんなのね」とか「PaSoRiでアクセスできるやつね」で済ませるようにしている。
詳しい人も多いので、あまり細かいところまで気を遣いたくないだけだ。



さて、こんなところだろうか。
あとは、どうでもいいスライドたちが残っている。
個人的にはそっちの方に対する思い入れが強いのだが、忘れてるしなあ。

2012/05/23

nfc-smart-tagに実装が追加されたようだ

連休とか法事とかやってるあいだに、nfc-smart-tagのターゲット実装が追加されたようだ。
やはり、間に合わなかったか(私が)。

まあ、まだ見ていないのだがね。

 

ちょっとだけdiffを見ていて、気になったというか、どうなんだったっけ、というのがあった。
NFCとはまったく関係ない箇所だ。

 

static const。
TgInitTarget (As、はない)の実装らしき関数があるのだが、固定パラメータをstatic constで定義していたのだ。
うーん、私だったらconstだなあ、と思いましてね。

static変数であれば、ヒープの方に置かれるだろう。
初期値があるなら、初期値ありヒープへ。

const変数であれば、constなのでROM領域へ置かれるだろう。
値が変更されないので、プログラムと同じ扱いにすることが多いと思う。

プログラムは、プログラム領域だろう。
constと一緒で、ROMなりFLASHなり、基本的に書き換えられない領域だと思う。
私が使ってきた環境で、ROMよりもRAMの方が多い、という環境はなかったのでそう思っているが、RAMの方が広ければそっちに展開するのかもしれん(MMUがなくてもやるのかしら)。
Linuxのinitramfsみたいな展開の仕方や、kernelの展開もあるだろうが、まあそれは別扱いだ。

 

nfc-smart-tagでstatic constがあったのは、関数の中。
constはわかるのだけど、staticはなくてもなあ・・・。
と思ったが、コンパイラによって色々あるのかもしれん。

私は、むかし関数内にstatic変数を使ってたらコンパイラが展開するときに失敗するという現象でかなりはまり込んだことがあるので、やらなくなった。

なのでまあ、そういう書き方がいいこともあるのかもしれん、と記憶にだけとどめておこう。

2012/05/21

周波数とアンテナの長さ

都内で、NFC勉強会が行われるらしいが、趣向が凝っている。
NFCタグを作ってみよう、というものだ。
なんと、コイルを巻くところからやるらしい。
普通の人だと作ったりできないんだろうな、と思い込んでいただけに興味深い。
(まあ、遠いからいったりしないのだが。)



さて、どうやって作るのだろうか?

周波数でアンテナの長さは決まる、という。
Wikipediaのダイポールアンテナについての説明があった。
4分の1波長らしい。
NFCだと13.56MHz。
速度と波長の関係は高校の授業で出てきた、v=fλ。vは速度、fは周波数、λが波長。
速度はと同じだろうから、v=c=3.0x10^8 [m/s]。
周波数は、f=13.56x10^6[Hz]。
λ=v/f=(3.0x10^8) / (13.56x10^6) = (3.0/13.56) x 10^2 = 22.124[m]。
これの4分の1だから、5.53[m]・・・でいいのかな?

MIFARE Ultralight Cのシールを持っているのだが、これを見ると直径2.5cmの外周を8周くらいしている線が見える。
内側に行くほど短くなるが、無視して計算すると・・・62.8cm。
全然足りないじゃないか!
やはり計算が違うのか・・・。
通信ソサイエティマガジンという季刊誌の論文賞ページの2009年受賞RFIDタグ用アンテナ技術[pdf]に詳細に書かれている。
読んでも、正直なところよくわからなかったが、周波数だけでなく通信距離なども含めていろいろ考慮して考えられていることはわかった。
やっぱり、ちゃんとやってる人にはかなわんな、と思った次第である。

まあ、短くする技術はあるのだろうが、そうしない方法であれば5.53メートルでもいいんじゃないだろうか。
うちには長い線がないのでできないんだけどね。

2012/05/20

勉強会用の資料を作る

半分くらい忘れかけていたが、今週の土曜日はNFC勉強会のようだ。
最近、週と曜日がはっきりせん。

SDK for NFC Starter Kitの使い方資料を作ろうと思ったのだが、サンプルが付いているのであまりやることがない。
なので、以前つくったライブラリを使う説明になってしまった。
よく考えると、タイトルに偽りありなのかもしれんが・・・他に思いつかなかったので許しておくれ。
http://www.slideshare.net/hiro99ma/sdk-for-nfc-starter-kit1
http://www.slideshare.net/hiro99ma/sdk-for-nfc-starter-kit2

文字が見えにくいかもしれないので、原本も置いておく。
資料1
資料2

さて、勉強会の場所はGuildCafe Costaさん(日曜日は、うぐいすカフェ、のようですが勉強会は土曜日です)。
前回と同じなので、さすがに大丈夫だと思う。

2012/05/19

[pasori]FeliCaランチャーはUを認識してくれなさそうだ

なんのこっちゃ、というタイトルになってしまったが、NDEFの話だ。

LPC2388基板でFeliCa Plugが動くようになり、USBメモリからもファイルが読めるようになった。
ならば、とNDEF対応したのだが、とりあえず簡単だったURI(Type番号0x55 'U')をやってみた。

 

こういうのの動作確認は、FeliCaランチャーが良かろう、と動かしてみたが、ただのFeliCa Liteをかざしたときと同じ動作になった。
しかし、実装上間違ってそうなところがないので、携帯電話のP906iからiCタグリーダーで読んでみると、URLとして読んでくれた。

 

ということで、FeliCaランチャーはUを認識しなさそうだ。
「U」に限定したのは、スマートポスター「Sp」は認識していそうだからだ。
Spの中にはUがあるので、Spを見分けているようだ。

2012/05/16

[felicaplug]ブロックリストの説明がよくわからない

2012/05/19追記あり

NFC-Fでは、データアクセスにブロックリストというデータが使われる。
FeliCa Liteだけを使っていると気にしないが、FeliCaにはいろいろなアクセスの方法がある。
ブロックごとに指定できるので、このような方式になっているのだろう(もう忘れた)。
詳細は、PDFにもあるし、黒本もあるので読まれるとよかろう。

 

FeliCa Plugは、ブロックリストを受信しても処理せず、そのままマイコンに送ってくる。
ただそれは受信側のしくみだというだけで、R/Wから送信する場合にはその限りではない。
簡単にいえば、R/Wの仕様が厳しくて、ありえなさそうなブロックリストを受け付けない、ということもありうるということだ。

 

まあ、それはいい。
しかし続けて書かれている、アクセスモードとサービスコードリスト順番。
これが「FeliCa Plugでは常に○○を指定します」と書かれている。

私の基準からすると、これは「FeliCa Plugはブロックリストを評価しない」という説明とは矛盾している。
「評価しない」のであれば、「常に○○を指定します」ではだめなのだ。
この書き方では、MUST、になってしまう。
他の製品では評価しているのでなるべくそうしてほしい、というところで、MAY、であればわかるのだが。


RFC-2119でMUSTだのMAYだのは規定があるので、Sonyさんのドキュメントもそうなっているといいのだが、といつも思う。

作業チーム内で議論になるのも、お客さんともめるのも、FeliCaドキュメントの解釈についてということがしばしばで「ドキュメントチームは一体なにやってんだか」ってことが多かった。

技術文書は、曖昧な箇所があってはいけない(自分の書いたものは棚に上げるが…)。
ブルックス氏の本にあったが、こんな感じだ。

海に持っていくクロノメーターは2個ではいけない。1個か、そうでなければ3個以上にすること。

文章の内容はよくわからないけど、私はこれを書き方の説明と思っている。
2個ではいけない理由はさておき、「2個ではいけない」ということと「1個 or 3個以上」という説明の仕方にしないとわかりにくい、ということ。
(古い格言、って書いてあるけど、なんだろうね?)

 

FeliCaドキュメントは、「2個ではいけない」か「1個か3個以上」のどちらかしか書かれていないことが多い。
そのせいで、他のドキュメントとの整合や、似たような製品、過去の知識などと比べてしまい、変な推測を生んでしまうのだ。

「2個ではいけない、と書いているので、念のために3個にしておいた方がいいのでは・・・」
「いや、これは1個だけが可能で、2個ではだめだ、といっているのかもしれない・・・」

とか。

FeliCa実装をしている人の大半はドキュメントで泣いていると思うので、改善されると嬉しい。
今は改善されているのだったらいいんだけどね。
「当時言えばよかったやん」って思うかもしれんけど、まあ、いろいろ、あるんでね。


昔の愚痴はこの辺りにして。

「ブロックリストは評価しない」のだから、ブロックリストの説明にある「常に○○を指定」は無視しよう。

無視するけど、NDEF対応するんだからマイコン側で評価するんだけどね。
今回書いたのは、誰がどこまで責任を持つか、というところなのだ。


2012/05/19追記

傘を盗まれた日に書いてたので、感情的になっていたような気がする。
すまん。
もうちょっと冷静にドキュメントを読んでみよう。

 

まず念頭に置いておかないといかんのは、FeliCa PlugのドキュメントはNFC-Fに配慮したものになっている、というところだ。

例えば「FB転送時にはシステムコードを12fchにしないでください」などだ。
FB転送は、FT転送のようなランダムアクセス(とはちょっと違うけど、イメージ的にそんなやつ)ができないので、Type3 Tagっぽく実装したとしてもR/W側の実装によってはアクセスできないことがある。

もしそういう機器が出回ってしまうと、その機器のみならずType3 Tag、ひいてはNFC-F機器自体の信頼性を揺るがすことにもなりかねない。
NFC関係の部品があまり一般で使えるようになっていなかったのも、このあたりの事情があるんじゃないかと勝手に思っている。

 

ブロックリストについても、Type3 Tagのドキュメントで

[RQ_T3T_CSE_027]アクセスモードは「000b」 (SHALL)
[RQ_T3T_CSE_028]サービスコードリストの先頭のサービスは「0000b」

と書かれている。
サービスについては、

[RQ_T3T_MEM_001]R/Wは「001001b」、ReadOnlyは「001011b」

となっていて、FeliCa Plugでは「0009hを推奨」となっている。
つまり、サービスは1つだけを推奨していて、サービスリストにも1つしか記載しない前提なので、そのサービスコード順番は「0000b」となる。

ということなのだろう。

いろいろと資料を見ていくとわかるのだが、やっぱり大変だなあ、と思った。
まあ、私も誤解していたところがあるので、これで許していただきたいところだ。

2012/05/15

[lpc2388]USBメモリが読めた(ただしFAT16)

ようやく、LPC2388をUSB Hostとして動かし、USBメモリのファイルを読むことができた。
といっても・・・全然自分でがんばったところはない。
動くことが確認できているファイルを、自分の環境に突っ込んだだけだ。

 

動かずにいたのは、割込を許可していないためだった。
LPC2388のVICは許可していたのだが、ARMの割込は一番最後に許可していて、その許可前にUSBメモリにアクセスしていたのだ。
まあ、動いたからいいや。

 

実は使用するピンを変更したのだ。
LPC2388基板は、USB Hostとしてポート1という場所を使っている。
ピンの名前に「USB_xxx_1」のようになっているのがそれ。
FeliCa Plugの制御に使っているピンが、USBとしては使っていなかったけど重なっててね。
USBもFeliCa Plugも動かなくなっていたので「きっとこのピンが悪さをしているに違いない!」と夜中に半田付けし直したのだ。

結果的に、全然関係なかった。
単に「ブレッドボードへの差しが甘い」というだけのことだったみたいだ。
ブレッドボード用のジャンパピンを買った方がいいのかもしれん。

 

FAT16限定なのは、サンプルがそうだったから。
FAT32に対応するといいんだろうけど、しゃあらしいっちゃんね。


やったのは、テキストファイルに16byteの文字を書いて、Read w/o Encしたらその中身を返すというだけのもの。
これができるのだから、ファイルのサイズを大きくして、複数ブロックにしてもできそうだ。

FeliCa Plugは、1回に12ブロックまでしかアクセスできない。
ST-1020は、2bit画像のような比較的大きなデータをするのに複数回アクセスするようになっているが、それはこの12ブロック制限があるためだ。
無線で巨大なデータを一度に送るってのはいろいろと難しそうだが、うまいことやればファイル転送くらいはできそうだ(我慢がいるけど)。

 

私が今回やりたかったのはそうではなく、単にURLが入ったテキストファイルをUSBメモリの中に入れておいて、FeliCa PlugをUかSpで読めるようにしてみよう、というだけのものだ。
まだNDEFには手を出していなかったが、そろそろそんな季節になったということか。

2012/05/13

[lpc2388]USBメモリを挿すとソフトが動かなくなる

Interface誌のLPC2388基板を使っている。
gccからUSB Hostを使うサンプルがあり、USBメモリにファイル書き込みができることは確認した。

では、と以前作成していたFeliCa Plugのソフトに混ぜ込んだ。
困ったことに、USBメモリを挿すと動かなくなる。


やっているのは、USB Host機能の初期化だけだ。
初期化の先で何をやっているかは把握していない・・・。

まず、初期化とUSBメモリの読み込みをすると、動かなくなった。
では初期化だけならいいだろう、と読み込みを外すと、動作した。
そこまではいい。
問題は、その動いた状態でUSBメモリを挿すと動作がどこかで固まってしまうということだ。

アプリ側では何もしていないので、USBの割り込みハンドラが何かやっているせいだろう、とハンドラの中身をまるまる消したが、それでもだめ。
USBの初期化も消すと、問題なく動くようになる。
だから、初期化することによってUSB挿抜を検知するようになったということだ。
FIQも使ってないのに・・・なんだろう・・・

 

デバッガがやはりほしくなってきた今日この頃である。


さて、続きだ。

いろいろ削った結果、HcInterruptEnableに設定をしなければ、USBメモリを挿しても抜いても影響がないことがわかった。
やはり割込関係か。

しかし、なぜ割り込みハンドラを空にしてもだめなんだろうか?
別の割り込みハンドラが動作しているのだろうか。

 

そう思って、HcInterruptEnableレジスタの仕様を調べようとしたのだが…載ってない。
なぜだ?と思ったら、これはOHCIの仕様[pdf]らしい。
やっぱりUSBは大変だなあ、と思った次第である。

なるべく既にあるものを使って、わからんとこだけ調べようかね。

[rcs620s]TgInitTargetの動き

「ひどいw」といわれたので、もうちょっと説明することにしよう。
RC-S620/SのTgInitTargetがどういう動きをするかについてだ。


うちではRC-S620/Sをパソコンのシリアルポートに接続しているので、その前提で話をしよう。

ソフトを作ると面倒だから、バイナリファイルを作った。

https://sites.google.com/site/hiro99ma/home/files/other/TgInitTarget.zip?attredirects=0&d=1

RC-S620/Sをパソコンにつなぎ、適当なシリアル通信ツールで開く。
私はAcknowrichを使った。
バイナリファイルの転送ができて、バイナリで受信データが見られれば良い。

通信設定をあわせて、RfConfig1~3.txtを順に送信すると、RC-S620/Sを使う準備ができる。
続けてTgInitTarget.txtを送信。

すると、ACKだけが返ってくるのがわかるだろう。
他のコマンドは、ACKに続けてレスポンスが返ってくるのだが、TgInitTargetはそうではない。

ではいつレスポンスが返ってくるかというと、R/Wからコマンドを受信したときになる。
ポーリングはコマンドとして処理しないので、それではレスポンスが返ってこない。

待ち状態をキャンセルしたい場合は、TgInitTargetの【注意事項】に書かれている通りにやればいいのだろう(やったことがない)。


この状態で、PaSoRiからRead w/o Encとかすると受信待ちが解除され、そのコマンドがそのままレスポンスとして返ってくる。
NFC-DEPをする場合は、ATR_REQでないことを調べ、再度TgInitTargetコマンドを発行することになるだろう。

2012/05/12

[rcs620s]TgInitTarget

RC-S620/Sの簡易コマンドリファレンスが更新されて、Targetになるコマンドが公開された。

公開されたといっても、この手順はNFC-DEPとして使うためのものである。
なぜかというと、SetParametersコマンドにて自動的にATR_RESを返さない手順で書かれているからだ。
ATR_REQを受信したことを確認してからATR_RESを返しましょう、という説明になっていると思う。


では、ATR_REQ以外を受信したらどうなるか。
同じである。
ATR_REQを受信したらATR_REQがまるまるレスポンスとして返されるように、それ以外のコマンドを受信したとしたら、そのコマンドがまるまるレスポンスとして返ってくる。

 

しかし、1つ覚えておこう。
Pollingは、コマンド扱いではない、ということだ。
あれは脊髄反射的な応答をRWがするので、Hostまで返ってこない。

まあ、PollingのたびにHostへ確認が来ていたら、時間が間に合わないだろうがね。


ちなみにNXPのPN533では、TgInitAsTargetというコマンドがある。
私はこれを見ながら、NFC-DEPの実装をしていた。

主な違いは、historical byte。
何かの歴史的に残してあるパラメータらしいのだが、TgInitTargetにはこれがない。
そのため、パケットを作るときに妙な動きをしていたことがあった。
いろいろと試していって、RC-S620/SのTgInitAsTargetにはhistorical byteはない、と推測したのだった。

解析のいいところは、答え合わせして正解だったときに喜びを得ることができるというところだろうか。
まあ、答え合わせできないということの方が多いんだがね。


まあ、自分でやっていてなんだが、DEP目的以外でTargetになるのは控えた方がよいな。
李下に冠を正さず、といいますか。

やってみたらわかるけど、Targetを実装するのはかなりめんどうだ。
アトリエのどかさんも取り組まれているようだが、動かすところよりも動いてからの方で考え込まれているようだ。

 

ふはははは、悩め悩め(ひどい…)!

 

NFC QUESTの魔王は紳士的(というよりも業界人的?)なのだが、私は人が悪いので、ちゃかすくらいしかしない。

私もけっこうなおじさんなので、技術を若い人に追い抜かれるのは時間の問題だろう。
かといって、楽々と追い抜かせるのは気にくわない。

まあ、ここらへんはもうちょっと酔っぱらったら書くことにしようかね。

2012/05/09

ATR_REQについて

RC-S620/Sのコマンドリファレンスを読んでいる。
これはじっくり読むものだ。
特にTargetになる部分なんかは、慎重に進めていかねば。

 

さて、このTargetに関する箇所だが、ATR_REQとかATR_RESとかいう言葉がしばしば出てくる。
なんじゃこりゃ?と思った人のために、ちょっと書いてみようと思った次第だ。

といっても、私もぱっとみてなんだったかおぼえてなかったんだけどね。


私のNFC個人資料(非公開)を読むと、ATR_REQはNFC-DEPコマンドに分類されている。

簡単に書くなら、ATtRibute REQuest、つまり「貴様は何者だ!」というところか。
博多弁だと「きさーん、なにもんじゃ」とかか。
一般的には「属性要求」と呼ばれている。
JIS X5211の「12.5.1.1 属性要求 (ATR_REQ)」を参照されたし。

ATR_REQは、NFCID3iと呼ばれるInitiator側のNFCID3(10byte。こちらも参照)を始め、いくつかの情報を送ってくる。

それに対してTargetは、ATR_RESを返す。ATtRibute RESonseだ。
だいたい同じようなパラメータを返すことになる。
もちろんこのときは、NFCID3tと呼ばれるTarget側のNFCID3である。


さあ、道案内まではできたと思う。
あとは実践あるのみだ。

コマンドリファレンスに書いてある内容は、私が今までやっていたDEPのやり方ではなかったので、試したことがないのだな。
でもこれでやれるのだろうから、その方が簡単だろうと思う。

今度の土日にやってみました、という報告がたくさん出てくるといいな、と思う私であった。

nfc-smart-tag、というプロジェクト

nfc-smart-tag、というcode.googleのプロジェクトがあるとつぶやきがあった。

http://code.google.com/p/nfc-smart-tag/

 

これより先にLLCPの実装をして、「へへん私の方が早かったよ」という紹介をしたかったのだが、間に合わなかった。
まあ、LLCPのシーケンスを焦ったのはこのせいだったのだがね。

 

このプロジェクト、ソフトだけじゃなくてハードから作っている。
RC-S620/Sと同じくらいの基板で、いろいろとできるようにしている。
ここら辺の図を見ると、なんとなくイメージがわかるだろうか。

基板は、こういうの
青がきれいですな。

実現するサービスは、こういうの
これを見るまでは、てっきりRC-S620/Sを動かすだけのハード作成だと思ってたので、驚いたのだ。
ごめん、実はよくわかってないんです・・・。サービス苦手。

 

ショックに近いのが、LLCPのシーケンス
私があーだこーだ線を引っ張っていたのに、こんなに軽やかに引けるものだなんて・・・。
このシーケンスは、実装するときの参考にさせてもらおう。


このプロジェクト、ソースも公開されている。
それがなにか?と思うかもしれないが、これは公開されたRC-S620/Sのコマンドリファレンスを見ながら参考にできるということなのだ。

コマンドリファレンスだけあっても、実際にどう使えばいいんだよー、という解決策の一つになるのだ。
そう簡単にはわからないかもしれないが、参考にできるものがあるのとないのとでは大違いだ。

 

私もちょっと停滞気味で、Interface誌ボードでFeliCa Plugだけ動かしてもなあ、と思っていたので、ちょうどいい刺激になりそうだ。
Interface誌のボード、汎用で使える半田付けできるスペースがあるといいのにな。
それがあると、空中配線したりしなくていいんだけど、まあ付録で買えるのだから文句は言えんな。

RC-S620/Sコマンドリファレンスの更新!

いつもは冷静(?)な私も、今回は興奮を隠せなかった。
RC-S620/Sコマンドリファレンスマニュアルが更新されたのだ!
Version 2.0である。


Version 1.0が出たとき、私はこんなことを書いていた。2011年7月12日だ。

[rcs620s]RFConfiguration
[rcs620s]InListPassiveTarget
[rcs620s]Reset
[felica]CommunicateThruEXを考える

たぶん、この4つのコマンドが説明されていたのだ。
このコマンドがあれば、カードへのアクセスはできる。

できるのだが、まだ能力の半分も出せていない、といえよう。


そしてVersion 2.0。
ページ数は36ページも増えている。

なにが増えたかというと、@SDK4FeliCaさんの書かれているように、NFCIP-1のP2P、流行りの言葉で言えばNFC-DEPに関するコマンドが追記されたのだ。
いやあ、待ってました。

 

今眺めているが・・・やはり、私はわからないままコマンドを使ってたんだな-、とわかる。
無知の知、といいましょうか。
RTOXってどうやって渡すんだろう、と悩んでいたのが解決したり、あのコマンドのパラメータは推測通りだった、と喜んだり。

まだちょっとしか読んでないけど、これはなくていいの?と思ったものが2つ。

1つは、GGS(頭文字)コマンドだ。
私はこれを使って、今のモードを取得していたのだけど、なくてもいけるってことなのかな。

もう1つは、WRとRR(頭文字)とかのコマンドだ。
よくわからないけどおまじないのように書いていたので、意味がわかるといいな、と思っていたのだ。
残念ながらコマンドの説明はなかったが、呪文としてはちゃんと記載があったので、悩まなくていいや。

 

あれ、IJFDコマンドがないぞ??
もしかして、CommunicateThruEXで全部できるのか?
まったく想像してなかったので、これは試してみなくてはならん。


しかしまあ、ここまで仕様が公開されるとはまったく思ってなかった。
嬉しい驚きだ。

 

ちょっと昔話をさせてもらおう。

私がRC-S620/Sを購入したのは、2010年11月26日だ。
当時のブログ(のメモ)を見ると「あれ、このピン配置ってどうなってるの??」とある。
そう、当時はピンの配置すらわからなかったのだ。
買ったものの、配線もできずに困り果て、購入したスイッチサイエンスさんに問い合わせたのだ。
部品って、データシートがネットでダウンロードできることが多い。
NFC関係はセキュリティが絡むから、購入した人にだけ配られるのかな、などと気軽に考えていたのだが、そうは問屋が卸さなかった。
「製品仕様書」のPDFをもらえたのは、2010年12月10日のことだった。
このとき「ネットなどに公開しないこと」といわれたので、このドキュメントに書いてあることは書かないように気を配っている(つもり)。

 

しかし・・・配線はわかったけれども、コマンドがわからない。
そう、コマンドリファレンスは別で、どうも一般人には公開されないようだったのだ。
とはいえ、FeliCa Developers' Blogの記事に、Arduinoで動かす記事が載っていた。
いや、この記事を見たからRC-S620/Sを買ったのだ。
Arduinoのサンプルソースを読むと、だいたい何をやっているかわかったので、コマンドを作って、三者間通信させることは簡単そうだった。

まずはUSB-シリアル変換チップに半田付けしてパソコンからアクセスできるようにし、バイナリエディタでコマンドをいくつか打ち込み、TeraTermで流し込む、ということをやった。
動いたので、当時よく使っていたBeagleBoardに接続し、UARTのポートをたたいて三者間通信できるようにしたのだ。
Androidのいいところは、文字入力するような部分が簡単にできるのと、NDKで好き勝手出来るというところだ(特に自前でビルドした場合は)。
あとはJNIつくって、適当にJavaから呼び出せるようにした。

その年のまとめに「三者間通信までできたが、達成感が少ない」と書いている。
そう、三者間通信以外のサンプルがなかったので、先に進めなかったのだ。

 

そこから、NFC Forumの仕様書があることを知って読み始め、Android2.3が出てNFC APIが増えたのを知り、PollingとSENSF_REQが同じものだ、ということがわかったのだ。

前のブログはそこで終わっている。。。


つまりまあ、RC-S620/Sを買って2ヶ月も経ったのに、三者間通信くらいしかできなかったという情報量だったのだ、当時は。

今でこそRC-S620/Sを比較的自由に扱えるようになったものの、これはNXPのドキュメントを読んで参考にできたからだ。
あれがなかったら、きっと私はNFCを続けてなかっただろう。
そのくらい、情報が絶望的になかったのだ。

 

個人がNFCをパソコンで開発する環境も整ってきたし、組込みとして開発する環境も整ってきたので、いい時代になったと思う。
あまりにほいほいと開発できてしまって張り合いがないかもしれないが、昔は大変だったんだよ、と年寄りめいたことを書いて今回は終わろう。

2012/05/04

[無駄話]RX62Nはコードフラッシュへの書き込み回数制限が1000回

タイトル通りだ。ユーザーズマニュアル(ハードウェア編)を読んで、気付いた。
1000回・・・。
開発中だと、すぐに終わってしまうんじゃなかろうか。
あるいは、デバッガを使っているとそうならないようにがんばっているとか。
いや、この回数が保証回数であることはわかっている。
とはいえ、不慣れな人にとっては不安な回数だ。
うーむ。
素人には、ある程度の高性能なマイコンの方が整っているからやりよい、ということになるのかなあ。
それなら、LPC-2388かSTM32が手元にあるマイコンでは使いやすそうだ。
あるいはV850か。
いやいや、わかっている、わかっているんだ。
やることも決まっていないのにマイコンだけ決めようなんてのが、あまり意味がないってことは。
でも、今くらいしかこういうまねごとができないのだ。
仕事だと、決められる暇がないまま作業に突入することが多いし。
あー、またLPC-2388に戻りますかね。
gccだし、なんとなく慣れた気がするし。

2012/05/03

[無駄話]マイコンがオーバースペックだったようだ

LPC-2388基板やFM3基板でもFeliCa Plugは動いた。
が・・・ちょっとやりすぎではないか、と思ったのだ。
機能が多いとかではなく、機能に対してマイコンがすごすぎやしないか、ということだ。

CQ出版の付録になった基板たちは、だいたいなんでもできるようにスペックのよいマイコンが載っている。
これが、FeliCa Plugのように省電力をぎりぎりまで突き詰めるような用途に対してはオーバースペックなんじゃなかろうか、と思ったのだ。
もちろん、例えばFM3マイコンにしても、スペックの下がったマイコンはある。
あるのはわかっているのだが、私は自分でマイコンから基板を起こしたりできない・・・。
そこら辺が哀しいところだ。

気を取り直して、うちにある基板たちを見ていこう。
どれかほどほどのものがあるかもしれない。
こんなにあったのか・・・。
ざーっと動いていないときの消費電力を調べたところ、ColdFireが一番小さかった。
その次が、V850とRX62Nだった。
SH-2Aが予想以上に大きかったのだけど、マニュアルの見方が悪いのかな?
78K0S/KA1+というマイコンも持っている。
これは私にしては珍しく、チップ本体だけだ。
このくらいなら、ハードが苦手な私でも扱えるかも・・・という期待で買ったものだ。
残念なことに、SPIがない・・・。
UARTならあるのでRC-S620/Sなら制御できそうだが、いかんせんRAMが256byteだ。
software-SPI、なんてこともできなくはないのだろうが・・・どうなんだろうね。

そんなわけで、V850基板を使ってみようかと考えている。
いきおいで購入したMINICUBE2もあるし、デバッグが楽そう・・・あれ?
検索してみると、V850基板はMINICUBE対応で、MINICUBE2対応するにはごにょごにょやらんといかん、とある。
そんな!
ちょっとやさぐれそうである。

FeliCa Plugでできそうなこと (FB転送)

「できそうなこと」という妙な表現になったが、それは試していないからだ。
FeliCa Plugのユーザーズマニュアルを読んで、FB転送というものでできそうなことを書いておこう。


FeliCa Plugでできる転送方法は、2種類ある。

  • FeliCa Through転送(FT転送)
  • FeliCa Buffering転送(FB転送)

今まで試したのは、FT転送。
これは、普通のFeliCa Liteにやるようなアクセスができる。
この「アクセスができる」は、リーダライタ側の話だ。

 

それに対して、FB転送はそうではない。
リーダライタ側は、Write Without Encryption→Read Without Encryptionの順でしかアクセスできないようになっている。

そのような制約の何がいいのかというと、これによって機器側の「FeliCaプロトコル時間制約」がほぼなくなるのだ。
私はお遊びでしかFeliCaのソフトを作っていないので気にしてなかったけれども、プロトコルに時間の制約が存在するのだ。
○○時間以内に応答を返さないといけないとか、そんなの。

FB転送すると、こうなるらしい。

  1. [RW側]Write Without Encryptionを送信
  2. [FP側]受信データをRAMに溜め、とりあえずRWに返信
  3. [FP側]FeliCa Plugはデータ受信をHostマイコンに通知
  4. [FP側]HostマイコンはSPIでRAMから受信データを吸い込む
  5. [FP側]HostマイコンはSPIでRAMへ送信データを書き込む
  6. [FP側]Hostマイコンは送信データ転送完了をFeliCa Plugへ通知
  7. [RW側]Read Without Encryptionを送信
  8. [FP側]RAMデータから送信データを作ってRWに返信

上記の3~6の間、FeliCa Plugはリーダライタに応答しないらしい。
しかし、どんなに時間が経っていたとしても、7で返信できるように見える。

Read w/o Enc時、IDmが一致していればRAMに入っているデータを指定したブロック数だけ転送してくれるようだ。
(RAM転送前は不定な値が取得される、とある。)

RAMがどのくらい保持しているかはまだ読み切れていないが、おそらくFeliCa Plugを眠らせるまで(SW=Hを維持している間)だろう。


こんな使い方ができるかもしれん。

 

伝言板(制限付き)

  • 書き込みたい人は、Write w/o Encで書き込める(ただし、1件しか書き込めない)
  • 読み込みたい人は、Read w/o Encで読み込める。
    次の人が書き込むまでは同じ内容が読み取れる。

制限ありすぎ・・・。

実装側の利点としては、Write w/o Enc後にRAMへデータを転送するとき以外はHostマイコンを眠らせておいてもよいということ。
FeliCa Plugがデータをバッファリングしてくれているので、Host側はRead w/o Encに関与しなくても済むのだ(たぶん)。

FeliCa Plugが起きているときの消費電流は、最大で1.0mA~1.2mAくらい。
あまり調べてないけど、ここまで小さくするのはマイコンでは無理そうな気がする。

 

FT転送で同じことをやろうとしたら、どうなるだろうか?
Write w/o EncでEEPROMみたいなものにデータを保存し、Read w/o Encでそのデータを返す。
搬送波検知まではHostマイコンもFeliCa Plugも寝ていられるので、実はそっちの方が消費電力が小さく済むような気がした(FeliCa Plugが寝ると、0.1uA~1.0uA)。

Write w/o Encする回数が極端に少なく、Read w/o Encする回数が非常に多いのであれば、つまりRF通信による読み込み時間が圧倒的に長いのであれば、上記のような使い方はできなくもないのかもしれない。

でも、mAとuAって単位が違うくらいだから、素直にFT転送を使った方がよさそうな気はする。


やはりここは、Write w/o EncとRead w/o Encの間に時間が空くようなシステムで使うべきなのだろうか。
いくつか考えてみたけど、データ交換する目的ならば、プロトコルを作ってしまってFT転送でやりとり、ということもできるはず。

Read w/o Encが来るまでの間はどんなに短時間でもHostマイコンを眠らせてできるだけ消費電力を抑えたい、というときに使えばいいのかな。

他の人の例が見たいものだ。

2012/05/01

[fm3]FM3基板でもFeliCa Plugが動いた

ごにょごにょと文句を言っていたが、結果としてはCQ-FM3基板でもFeliCa Plugが動作した。
動きは、CQ-LPC2388基板と同じである。

githubにも置いた。


どっちもARMではあるが、いろいろと違いがあった。

だが、今回はKeil uVision4という統合開発環境を使ったおかげで、楽だった。
だって、スタートアップルーチンはあるし、コンパイラはあるし。
SPI(SIO)ドライバのサンプルもそのまま使えたので、悩んだのはGPIOの設定くらいだ。

MOSIとMISO(SOTとSIN)を直結しているところは、やはり回避しなくてはならなかった。
PZRレジスタが使えるブロックに機能を動かし、ホストからの送信時にはSINをHiZに、受信時はSOTをHiZにしてやった。


では、最後に波形集を。

 

初期化パラメータの転送

SPICLKが連続しているが、FeliCa Plugは問題ないようだ。
ギャップがない分、転送が早く終わる。

image

 

Read Without Encryption

image

 

Write Without Encryption

image

[fm3]CSIOのノーマル転送とSPI転送の違いは、SCKに対する転送のタイミングだけか

FM3基板で、あきらめてSPIドライバを実装しようとしている。
できるだけ楽をしようとしたのだが、APIから戻ってこないのではどうしようもない。
ああ、デバッガがあれば・・・。


FM3(正確には、MB9BF618T)では、SPI機能をCSIOというクロック同期シリアルインターフェースで実現するようだ。
そもそもシリアル通信自体が「マルチファンクションシリアルインターフェース」という汎用シリアル機能で実現するようになっている。

なので、UARTやI2Cなども含めて扱えるようなのだが、その分、設定するレジスタも多いように思う。
それはいいとして、SPIだ。
SPIについて「SPI転送(I)」と「SPI転送(II)」しかないのだ。
いや、SPIってモードが4つあるのに、なんで2つなんだ??

 

そう思って「ノーマル転送(I)」の説明を見ると、SPI転送とほぼレジスタもタイミングも一緒。
違うのは、レジスタでは「SPI」というビットを立てるかどうかと、タイミングではSCKの立ち上がりで転送するか立ち下がりで転送するかというところ。

あれ・・・ここの違いがSPIのモードじゃないっけ・・・。


古いInterface誌を引っ張り出した。

モード0:クロックはL。立ち上がりエッジでデータ取得
モード1:クロックはH。立ち下がりエッジでデータ取得
モード2:クロックはL。立ち下がりエッジでデータ取得
モード3:クロックはH。立ち上がりエッジでデータ取得

ホストがFeliCa Plugを使うときは、モード1で送信(FeliCa Plugはモード3で受信)、モード3で受信(FeliCa Plugはモード1で受信)、ということになるようだ。

 

では、FM3の場合。

ノーマル転送(I) :クロックはH。立ち下がりエッジで送信。立ち上がりエッジで受信。
ノーマル転送(II):クロックはL。立ち上がりエッジで送信。立ち下がりエッジで受信。
SPI転送(I):クロックはH。立ち上がりエッジで送信。立ち下がりエッジで受信。
SPI転送(II):クロックはL。立ち下がりエッジで送信。立ち上がりエッジで受信。

送信と受信でタイミングが違うのは、同じ設定で送受信できるようにするためだろう。
FeliCa Plugでいえば、ノーマル転送(I)を使えばよさそうだ。

 

こういうのは人口に膾炙している用語を使った方がいいと思うなあ。

[fm3]なんかいろいろ期待の波形と違う

ようやくSPIの送信ができるようになった。
なんか、使いづらい。
Cortex-M3のせいというわけでもないように思う。
機能が多くなって、ドキュメントが読みづらいのかなあ。


目下の悩みは、SPIだ。
サンプルドライバがあったので、そのまま使っている。
送信ができるようになったと書いたが、出てきた波形はこんなのだ。

image

SPIって、1byte送信したら、少し間が空くものじゃないの?
1Mbpsで9byte送信していて、時間は72us。だから転送に間違いはなさそうなのだが。。。

まあ、それ以上に困っているのは、送信関数から戻ってこないってことだけどね。
SPIが動かないということはないだろうから間違ってるんだろうけど、何が間違ってるのだろうか。。。。

[fm3]GPIOアクセス速度がよくわからん

久しぶりにわからんシリーズだ。

FM3基板のサンプルソースは144MHzで動作しているらしい。
動作クロックをなんとなくで調べてみよう。

GPIOを、HI→LO→HI→LO→HI、とさせた。

image

うーん?? 10MHzくらいしか出てないぞ?

説明を読むと、マスタークロックが144MHzで、GPIOがつながっているAPB2は分周して72MHzになっているらしい。
しかしそれでも、この速度は遅いような。

うちのロジアナはサンプリングが100MHzなので、確かに72MHzはうまく取れないかもしれない。
しかしエイリアシングを起こしているなら、もっとぼろぼろの波形になってもいいような気がする。

うーむ。


GPIOアクセスには、こんなコードを書いた。

FM3_GPIO->PDORF_f.P2 = 1;        /* HI */
FM3_GPIO->PDORF_f.P2 = 0;        /* LO */
FM3_GPIO->PDORF_f.P2 = 1;        /* HI */
FM3_GPIO->PDORF_f.P2 = 0;        /* LO */
FM3_GPIO->PDORF_f.P2 = 1;        /* HI */

そういえば、これってビットフィールドだった・・・。

よく考えると、私が仕事で使っているマイコンはビットアクセス命令があって、1クロックで制御できるようになっているのだ。
上記のソースだと、値を取得して、特定のビットにAND/ORして、書き込む、というステップを踏んでいるはずだ。
そりゃ遅くなるだろう。

 

よく読むと「ビット・バンド・エイリアス」というしくみがある。
これはWORDアクセスしてもビットアクセスと同じ効果が得られるようになっているらしい。
ほほぅ。

mb9b610t.hには、このマクロ定義がずらーーーっとある。
このヘッダファイルは大きいのだけれど、ファイルの半分はビットバンドエイリアスの定義になっている。

私が今回アクセスしたいのは、ポートFのbit2。
bFM3_GPIO_PDORF_P2、という定義名のようだ。
やってみよう。

bFM3_GPIO_PDORF_P2 = 1;
bFM3_GPIO_PDORF_P2 = 0;
bFM3_GPIO_PDORF_P2 = 1;
bFM3_GPIO_PDORF_P2 = 0;
bFM3_GPIO_PDORF_P2 = 1;

計測すると・・・80ns。。。
変わらんなあ。

最適化が必要なのか?
とりあえずコンパイルした結果で確認を・・・。

Keilの評価版ではアセンブルリストを出力してくれないらしい。
CodeSourceryが入っているので、AXFファイルをobjdumpすればいいようだ(BINARY HACKSを読みながら)。

$ arm-none-eabi-objdump -d cqfm3_felicaplug.axf  > asm.lst

402:    4911          ldr    r1, [pc, #68]    ; (448 <_init+0x9c>)
404:    2201          movs    r2, #1
406:    600a          str    r2, [r1, #0]
408:    2300          movs    r3, #0
40a:    600b          str    r3, [r1, #0]
40c:    600a          str    r2, [r1, #0]
40e:    600b          str    r3, [r1, #0]
410:    600a          str    r2, [r1, #0]

STR命令でアクセスしているな。
Interface誌の説明だと、これでよさそうだ。
STR命令が遅いのか?とも思ったけど、ここには1サイクルと書かれている。

なんか間違ってるのか、こういうものなのかなんだけど、ようわからんですわ。

とりあえずビットバンドエイリアスを使うようにしておこう。
GPIOの出力なら、こんなマクロで済みそうだ。

#define GPIO_PDOR(p,b)    bFM3_GPIO_PDOR##p##_P##b

いや、いっそのことこうか。

#define GPIO_BBA_BIT(r,p,b)        bFM3_GPIO_##r##p##_P##b

GPIO_BBA_BIT(PDOR, F, 2) = 1;