2012/04/30

[fm3]レジスタ名は大切ね

富士通のFM3を搭載したCQ基板で遊んでいる。
まだ遊ばれているというところではあるが・・・。

 

LPC-2388は、まだなんかわかったような気がしている。
しかし、Cortex-M3になって複雑になったのか、FM3はなんかよくわかっていない。
ドキュメントは日本語があるのだ。
これは大きい!

でも・・なんかわかりにくい。
なんでだろう?
富士通マイコンのドキュメントを読むのが久しぶりなせいか、なんかわかりにくい。

ドキュメントの構成のせいなのか、Cortex-M3が複雑なのか、他に要素があるのか、そこらへんがわかっていない。


ただ、1つだけ。
1つだけ気になったことがあった。
外部割り込みのレジスタ名だ。
いや、レジスタをCソースで扱うためにビットフィールド定義したmb9b610t.hのフィールド名だ。

今回、FeliCa Plugからの割込を受け付けるために、FM3から2つの外部割り込みピンを使おうとしている。
FM3のつくりかCortex-M3のつくりかしらないけど、外部割り込みは0~7chと8~31chの2つに分かれている(アプリケーションノートには8~15chとあったけど、違うチップかしら?)。
0~7chはIRQ4に、8~31chはIRQ5に割り当てられている。

そこまではいい。
気になるのは、C定義だ。

 

IRQ4

typedef struct stc_intreq_irq04mon_field
{
  __IO uint32_t EXTINT0    : 1;
  __IO uint32_t EXTINT1    : 1;
  __IO uint32_t EXTINT2    : 1;
  __IO uint32_t EXTINT3    : 1;
  __IO uint32_t EXTINT4    : 1;
  __IO uint32_t EXTINT5    : 1;
  __IO uint32_t EXTINT6    : 1;
  __IO uint32_t EXTINT7    : 1;
} stc_intreq_irq04mon_field_t;

 

IRQ5

typedef struct stc_intreq_irq05mon_field
{
  __IO uint32_t EXTINT0    : 1;
  __IO uint32_t EXTINT1    : 1;
  __IO uint32_t EXTINT2    : 1;
  __IO uint32_t EXTINT3    : 1;
  __IO uint32_t EXTINT4    : 1;
  __IO uint32_t EXTINT5    : 1;
  __IO uint32_t EXTINT6    : 1;
  __IO uint32_t EXTINT7    : 1;
  __IO uint32_t EXTINT8    : 1;
  __IO uint32_t EXTINT9    : 1;
  __IO uint32_t EXTINT10   : 1;
  __IO uint32_t EXTINT11   : 1;
  __IO uint32_t EXTINT12   : 1;
  __IO uint32_t EXTINT13   : 1;
  __IO uint32_t EXTINT14   : 1;
  __IO uint32_t EXTINT15   : 1;
  __IO uint32_t EXTINT16   : 1;
  __IO uint32_t EXTINT17   : 1;
  __IO uint32_t EXTINT18   : 1;
  __IO uint32_t EXTINT19   : 1;
  __IO uint32_t EXTINT20   : 1;
  __IO uint32_t EXTINT21   : 1;
  __IO uint32_t EXTINT22   : 1;
  __IO uint32_t EXTINT23   : 1;
} stc_intreq_irq05mon_field_t;

 

どっちもEXTINT0からはじまるんかい!!

せめて、IRQ5はEXTINT8から始まるべきだろう。
そうしないと、私みたいにあまりよく見ずに「EXTINT0は1つしかないはずだから、間違ってたらコンパイルエラーになるだろう」と期待している人が馬鹿を見るではないか。

ああ、馬鹿を見たさ・・・。
You look a foolish guy in this site (?).

EXTINTという外部割り込みの先頭は0から始まるべきだろう、という思想なのかもしれないけど、わかりにくい。
(他にも、同じ名前のレジスタがよくある)
ここはビット番号ではなく、機能として表した方がいろいろとよかったんじゃなかろうかね。

なるべく安くFeliCa Plugで搬送波検知させてみよう

4月も今日で終わりだ。
しかし、私は明日も休みだ!
そのうれしさを、この記事に昇華させよう(意味不明)。

今月のInterface誌は、ARMコア搭載のFM3という富士通のチップが載った基板が付録になっている。
それとFeliCa Plugを使って搬送波検知をさせてみよう、というお話だ。

「NFC-Fカードとして動作させるんじゃないのかー」と言われそうだが、まだやってないのだ。
LPC-2388ではやったので、やってみたい人はやってみよう。


いるもの

今月のInterface誌。2012年6月号だ。
大きめの本屋さんだったら、あると思う。

20120430_1

 

こんな基板が入ってる。
なお、これは私がいくつか半田付けしたあとのものだ。
基板を動かすだけならば、左上と中央上の2つのジャンパをつければいい。
「ジャンパ(jumper)」というのは、2点間をショート(短絡)させたり切り離したりするときに使うものだ。
なので、別に特定の部品を使う必要はないのだけど、プログラムを焼き込むときにはショートさせないといかんので、ジャンパを使っている。
私はピンヘッダというやつを買って、ニッパで切り離しながら使っている。
(さすが秋月、安いな・・・。)

あまり気にしていなかったのだが、「ジャンパーピン」というと、ピンヘッダをショートさせるやつのことを指すようだ。
ピンヘッダはあまり売っていないけど、ジャンパーピンは自作パソコンのお店で売られているかもしれない。

20120430_3

赤と黒のよりよりした線は、リセット用スイッチだ。
写真には収まっていないが、先っちょにスイッチが付いている。
これも、別にスイッチじゃなくてジャンパピンでも問題ない。

私はInterface誌を購読していて、年に2回くらいこういう基板が付録で入ってきている。
最初は近所(といっても、まあまあ遠い)まで部品を買いにいっていたのだが、めんどくさくなって何度か「付録用セット」を購入したのだ。
そのときに、スイッチが付いてきたという次第である。
当時は「1つ1つの基板用に買わないと」と思ってたけど、リセットするスイッチなんて使い回せるよなあ、と今になって思う。
まあ、買って損をしたって感じはしないので、それはそれでよし、だ。

中央下のmini-Bコネクタは、最初から実装済み。
その左にあるAコネクタは、何となく接続。今回とは関係ない。


主役とも言えるFeliCa Plugは、こちら。
リセットスイッチの先端も見えているが、まあ気にしないでくれ。

PaSoRiに載っているのが、FeliCa Plug。これは小さい方のRC-S802だ。
そこからフラットケーブルが延びて、ブレッドボードにつながっているのはスイッチサイエンスさんのピッチ変換基板

ちょっと注意が必要なのは、1ピンがこの向きで見て左側にある、ということ。
変換基板を見ると右側が1ピンぽく見えるけど、そうではないのだ。

私はFeliCa Plugとピッチ変換基板を同時に購入したけど、FeliCa Plug単品ではフラットケーブルがないかもしれない。

20120430_4


全体を見ると、こんな感じだ。
ハヤトのブレッドボードを使っているが、FM3基板はブレッドボードに刺さっているわけではなく、這い回した線がブレッドボードに刺さっているだけだ。

image

なお、右側にいるのはロジアナだ。
オプティマイズさんのカメレオンUSBを使ったものである

ソフト屋さんの聴診器、とも言われるロジアナ。
デバッガを持っていれば何とかなるものだけど、持っていないのでこれに頼っている。
内部の動作は追えないけれども、ソフトさえ動けば外に出すことができる。
まあ、ソフトが動かないとどうしようもないのだが、リアルタイムに確認しないといけないものはロジアナが強い。

ただ、ロジアナ専用機を使ったことがある人間としては、長時間記録ができないのがつらいことがある。
データを圧縮する機能があれば、変化の少ない波形であれば比較的長時間の記録ができそうだ。
購入する場合は、そんなことも気にしておいた方がよいだろう。

image


配線は、こんな感じ。
といっても、まだ動いているのは一部だ。
/RFDET、SW、SEL、SPICLK(HIにするだけ)。

image

ソフトは、githubに置いた。
開発環境は、Keilを使っている。
ビルドした後は、USBを使って基板にソフトを焼いている
焼くソフトに電話番号まで記入してダウンロードせんといかんのかー、と思わないでもないが、やさぐれた大人なのであまり気にしない。
個人的には、Interface誌を買った人はCQ出版の名前でダウンロードできる、とかがよかったな。


で、このソフトを動かしてみたのだが、あんまり速くない。
ポートをHI/LOWさせてロジアナで時間を計測したのだが、10MHzくらいだった。
うーん、72MHzで動作すると書いてあったけど、何か抜けてるのか? あるいはポート出力している分の時差があるのか。

 

いや、10MHzが遅いというわけではないのだ。
指定した速度になっていない、ということが問題なだけである。
Cortex-M3 / FM3のドキュメントをほとんど読んでないので、まだ何を間違えていてもおかしくないところだ。


あ、いるものとして、搬送波を出してくれるもの、を書き忘れてた。

PaSoRiみたいなR/Wとか、Android端末でもNFC対応しているなら出してくれそうだ。
うちは、PaSoRiで試している。
ちゃんとそれっぽくLEDが明るく点滅しているので、まあいいのだろう。

 

以上、連休中にFeliCa Plugを何となく買ってみたけど使っていない人向けの記事でした。

SPIのマスター受信

FM3基板とは関係ないが、ちょっと思い出したので書いておこう。
SPIでマスターが受信するときのことだ。

 

SPIは、マスターがクロックを出す。
送信も受信もだ。

自分が送信するときは、送信レジスタに値を書き込むと、SPI処理部がクロックを出しながら送信してくれる。
それはいい。

では受信。
受信は、マスターがクロックを出すとスレーブがデータを送ってくる。
何も考えなければ、クロック送信→受信レジスタを読む、という処理でよさそうだ。
しかし、私の知っている範囲では「クロック送信」というレジスタはない。
じゃあ受信レジスタだけ読めばいいかというと、もちろんそんなことしてもデータは入っていない。

どうしたらいい?

答は簡単で「ダミーデータを送信する」だ。
最初に書いたが、送信レジスタに値を書き込むと、クロックを出す。
スレーブはそのクロックに合わせてデータを送信する。
だから、ダミーデータの送信が終わると、受信レジスタに値が入っていることになる。

つまりまあ、送信と受信は同時に行われるのだな。
UARTやI2Cと違った動きなので、それはそれで面白い。

 

個人的には、SPIが一番手間のかからんシリアル通信だという印象を持っている。
UARTはパソコンとかとやりとりしやすいけど、調歩同期ってのが苦手だ(私が)。
I2Cは線が2本でいいしアドレスごとにやりとりできるからよさそうだけど、デバッグすると誰が悪さをしているのかさっぱりわからない。

RC-S620/SもSPI対応したものがあると手軽なんだけどなー、とは思うが、今はUSB-シリアル変換チップを使ってPCから簡単に制御できることを考えると、UARTも捨てがたいとは思う。
悩ましい限りだ。

[fm3+fp]搬送波検出まで

すんなり動くかと思ったが、やはり初めてのマイコンは勝手がよくわからん。
とりあえず搬送波検出までできた。

https://github.com/hirokuma/cqfm3_rfdetect

[fm3]まず半田付けから始めよ

CQ出版のInterface誌付録LPC-2388基板でFeliCa Plugを動かすことができた。

せっかくなので、先月発売されたInterface誌のFM3基板でも動かしてみようではないか。
・・・と思ってしばらくぼやぼやと考えていたが、考えるよりもやってしまうことにした。

FM3というのは富士通のマイコンで、ARMのCortex-M3コアだそうだ。
見た目は、でかい。
仕事で使ってるマイコンの4倍くらいある。
まあ、ピン数が176本もあるから仕方ないか。


前回の反省から、SPI接続については事前に調べることにした。
LPC-2388は偶然にも、MOSIをHiZにすることができたのでなんとかなったが、全部のマイコンがそんなわけでもない。

私が調べたところでは「PZRレジスタ制御可能」となっている端子だけがHiZにできる。
ハードウェアマニュアルp.56の「入出力回路形式 分類I」というものだけがHiZにできるようだ。

FM3はSPIのMOSI/MISO/SCKという名称ではなく、SOT/SIN/SCKという名称になっているようだ。
そもそもSPI専用というわけではなく、マルチファンクションシリアル、というもののようだ。

SOTピンで入出力形式が分類Iになっているものを探すと・・・SOT1_2とSOT6_2だけみたいだ。
アンダーバーの左側がチャネル、右側がリロケーションポート番号。
リロケーションポート番号というのは、同じ機能を別のポートに割り振ることができますよ、ということらしい。
ここでいえば、例えばシリアルのチャネル1出力はSOT1_0, SOT1_1, SOT1_2の3つがあって、ここから好きなピンを使えば良いのだろう。


予想で図面を引っ張った。
さて、今回もちゃんと動いてくれるだろうか?

image

2012/04/29

FeliCa Plugでできること (FT転送)

ようやくFeliCa PlugのFT転送ができたので、できたことを書いておこう。
初期化まででできることは「FeliCa Plugでできること(初期化まで)」を参照のこと。


できること

Read Without Encryptionに応答する

Read Without Encryptionを受信すると、ブロック数とブロックリストが取得できる。
それを元に、ステータスコードと返信したいデータをブロック数×16byteだけ返すと、FeliCa PlugがRead Without Encryptionの応答として返してくれる。

 

Write Without Encryptionに応答する

Write Without Encryptionを受信すると、ブロック数、ブロックリストおよびブロックデータが取得できる。
それを元にステータスコードを返すと、FeliCa PlugがWrite Without Encryptionの応答として返してくれる。


NFC-Fカードとして振る舞うというのはこういうことなのだな。

FeliCa Plug自体は、Read w/o EncやWrite w/o Encのフォーマットさえ正しければ、そのまま返してくれるようだ。
だから、ブロックリストやステータスコードを含めてかなり自由にデータを使うことができる。

比較すんなり行ったような気がするが、実は最後になって詰まるところがあった。
搬送波が未検出状態になったあと、なぜかHost側がデータ受信を開始してしまうのだ。

調べてみると、SW=LOWにするとIRQがHIになり、受信開始割込が入っていた。
ドキュメントを読むと、SW=LOWにするとIRQはHiZになるようだった。
消費電力を気にするならば、プルアップ/プルダウンするなり、GPIOにして出力を固定にするなりしないといかんだろう。

まあ、あまりその手のことには詳しくないのだが、ソフトについてはIRQ割込を先に止めてからSW=LOWにする、ということですな。

それがわかってからも時間がかかったのは、ARMのVICについて解釈を間違っていたレジスタがあったためだった。
ああ、デバッガさえあれば・・・。


ここまでのところを、githubに置いた。
作った資料などもあるので、お役に立てば幸いである。

[felicaplug]ようやくFeliCa Plugが応答した

ようやくFeliCa PlugがRead Without EncryptionとWrite Without Encryptionに応答した。
明治時代なら、開通おめでたう、というところだ。

 

Read Without Encryptionのとき。
前半の4個がR/Wからの受信で、後半の18個がFeliCa Plugからの送信。
ステータスフラグ2つと、1ブロック分の16byte。
データは0~15だ。

image

 

Write Without Encryptionのとき。
前半の20個がR/Wからの受信、後半の2個がFeliCa Plugからの送信。
ステータスフラグ2つだけだ。

image

 

感想としては「デバッガを持っていればもう少し早くできただろう」ということだ。
負け惜しみではない!
コーディングレベルのミスがいくつかあって、全然違うところで悩んだりしていたのだ。

まあ、動いてしまえばいい思い出だ。

2012/04/28

[felicaplug]MISOとMOSIは直結したらだめだったので、MOSIをHiZにした

FeliCa Plugのドキュメントを見ながらやっている。
まずはデータ受信だ。
SPICLKを出せばいいらしいので、やってみた。

image

あれ・・・DATAが0のままだ。
IRQは、最初のSPICLKでLOになると書いてあるので、この動きは正しい。
しかしDATAが0というのはおかしい。
一瞬、受信データがないのでは、と思ったが、IRQはデータ受信要求なので、ないことはないのだ。

ということは、データがうまく読めてないということか。。。

 

まさか、MOSIとMISOを接続しているから、MOSIの影響を受けているのでは。。。。
受信したいときはMOSIをハイインピーダンスにできればいいのだが、そんなことできるのか?

うーん、うーん・・・。


できるようだ。

PINSEL1を変更してMOSIだけをGPIOに戻し、PINMODE1でHiZにしてやるとよさそうだ。

image

いやあ、あせったあせった。

さて、Host側はSPICLKの立ち上がりで読めばいいらしい。
ロジアナ波形を目視しよう。

06 01 80 82

おお、それっぽい。
Read Without Encryptionで、ブロック数1,ブロックリストは8082。
ブロック番号0x82を読みにきているということか。
システムコードで0x12FCを返しているので、きっとFeliCa Liteだと思っているのだろう。
FeliCa Liteのブロック番号0x82はIDブロックで、IDd、DFCなどが入っている。
うん、データ的にも正しそうだ。

 

では、LPC2388がそういうデータと思ってくれているかUARTに掃き出させてみよう。

9F F0

・・・なんじゃこりゃ・・・・・。
UART処理を手抜きしているので、データは正しいのにUARTが失敗しているだけなのかもしれない、という可能性が捨てられない。
ああ、デバッガがほしい。。。

 

あ、受信バッファの初期化をしていなかった。
もう一度。

06 01 80 82

やれやれだぜ・・・。

[nfc]通信速度について勘違いをしている(私が)

NFCの通信速度について自分の考え方に勘違いがあるような気がしている。

たとえばNFC-Fの場合、212kbps / 424kbpsとなっている。
私はこう考えていたのだ。

NFC-Fはマンチェスター符号化しているから、1bitの転送には01か10の2つデータが必要になる。
だから、実通信速度はこの半分の106kbps / 212kbpsになるだろう。

しかし、それは間違った考えではなかろうか。
だって「こういう通信をしますよ」とあらかじめ言っておきながら、その通信速度が記載してある値の半分ということはあり得ないだろう。

 

そんなわけで、過去に通信速度について何回か書いたような気がするが、あれは全部間違っていたんじゃないか、というお話でした。

うーん、誰かおしえてくれー!

2012/04/27

FeliCa Plugでできること (初期化まで)

SonyさんのFeliCa Plugで最近遊んでいる。
いや、まだ遊ばれているというところか・・・。

ようやく初期化までできたので、そこまででできることを書いておこう。
なお、購入する場合はスイッチサイエンスさんが一番手軽だと思う。


できること

最終的にはNFC-Fカードとして振る舞うことができるのだが、今回は初期化が済んだまでにできること、だ。

 

搬送波検知

これが、一番大きな機能かな。
そしてこれだけなら、実はソフト的なことをしなくても使うことができる。

搬送波というのは、NFCでいえばリーダライタ(イニシエータ)が出す電波(データの有無は関係ない)のことで、NFCカードは搬送波を使って電力を起こし、自分を起動させることになる。
うちの携帯電話(P906i)は、リーダライタに近づけるだけでLEDが点滅するようになっている。

FeliCa Plugは搬送波で動作することはできないのだが、搬送波が検知できたらポートを変化させて通知してくれるようになっている。
なので、FeliCa Plugに電源を挿し、搬送波検出ポートにLEDを接続するだけで、リーダライタが近づいたらLEDが光る、というしくみをつくることができる。

 

これを何に使うかというと、だいたいは「省電力」だろう。
FeliCa Plugを搬送波が検知できるだけの状態にしておくと、あまり電力を使わない。
用事があるのはリーダライタの相手をするときだけだから、それまでは寝ていていいのだ。

もしこのしくみがなくてリーダライタが近づいてきたことを知ろうとするなら、搬送波を受信しなくてはならない。
これが、かなり電力を使う。携帯電話の電池が一ヶ月持ったりしないのは、そのためだ。
NFCならではの利点と言えよう。

 

そんなわけで、もしNFCリーダライタ動作をする携帯電話などが近づいたことを知りたい、と思った場合には、FeliCa Plugを視野に入れてもよいだろう。
FeliCa Plug自体はNFC-Fで動作するものだけど、搬送波は13.56MHzという周波数だけしか見ないので、たぶんMIFAREなんかでも大丈夫だろう。

 

リーダライタにNFC-Fカードとして検知させる

NFC-Fカードとして動作する手前の段階だ。
相手にNFC-Fカードとして検知させることができる。
わかりやすくいえば、ポーリングに反応する、ということだ。

・・・と思う。
実はまだ、あまり確認していない。
PaSoRiで使えるソフトに「FeliCaランチャー」というものがあり、そのソフトはNFC-Fカードを検出するとポップアップを表示するようになっている。
そのツールが、搬送波検知後に初期化してやると反応してポップアップを表示したのだ。
だから、おそらくポーリングに反応したのだろうと思っている。

初期化のパラメータでIDmやPMmを一部指定することができるのだが、その値が取れたかどうかまでは確認していない。


ここまでだ。

ここまでくるのに、かなり時間がかかった。
主な原因は、

  • ARM7系で一からソフトを書くのが初めてだった
  • NXPのLPC2388のドキュメントを読むのが面倒だった(読めよ)
  • 初めてのくせに、JTAG ICEなどのデバッグ道具がなかった

というところか。

自宅だと開発環境にそこまでお金をかけられないので、デバッグ環境にしわ寄せが来てしまう。
ロータバッハのICEしか見たことがなく、高いんだろうな-、と思っていたのだが、探してみるとけっこう安いものもある。
今月のInterface誌付録が、Cortex-M3ボードだったことも考えると、ARMのJTAG ICEは1つくらいあってもいいのかもしれん。

・・・と無理やり思い込もうとしているので、もうちょっとこのままがんばってみよう。

2012/04/25

[felicaplug]FeliCaランチャーに認めてもらう

SPIができてしまえば、あとは比較的楽だった。

image

RF検出してからSWをHにして50us以上待ち、初期パラメータという値をFeliCa Plugに転送する。
転送後、SEL=Hにして相手からのデータ転送割り込み(IRQ)を待つ。

 

このロジアナ波形は、RFDET=Lから初期パラメータ転送後のSEL=Hまでだ。
RFを出しているのはPaSoRiで、ソフトはFeliCaランチャー。
しばらくすると、FeliCaランチャーがカードを認識したときの動作をしてくれた。

ようやく、NFC仲間と認めてもらえたようだ。
よかったよかった。


今までの作業を見ていると、FeliCa Plugがどうのこうのではなく、単にLPC-2388というマイコンの動かし方がわからずに時間がかかっていた、ということだと思う。
既にドライバが整っているマイコンであれば、もう少し簡単じゃないだろうか。

残るは、読み書き対応だ!

[arm]SPIにもてこずりつつも、実はポーリングタイマのせい

土日と、ARM LPC-2388を使った通信に苦労していた。
UARTはまだしも、SPIはそんなに設定も多くないので軽く考えていた。
そして動かずに困った、という話である。

 

途中を省略すると、ポーリングタイマのせいだった。
タイマというと、割り込みで動作させるものの代表格、という扱いになっていることも多い。
しかし、ほんの短い時間だけだったり、割り込み要因発生から処理が呼び出されるまでの時間差が無視できない環境では、タイマをポーリングして使うことも多い。

今回も「1.1us以上待つ」のような制約がいくつかあるので、ポーリングタイマを作っていた。
なにせ、LPC-2388は最高で72MHz動作が可能だ。
1clk=14nsくらいだから、100くらい待てばいいのか・・・。

かもしれないが、動作クロックはあとで変更するかもしれないのでループによるタイマはやめておきたい。
やはり、タイマ機能を使ってポーリングタイマを作りたいものだ。

 

と力強く書いてみたが、最初はうまく行かなかった。
SPIがうまくいかないいかないと長い時間悩んでいたのだが、その前に置いていたポーリングタイマがタイムアウトしてくれず、SPI処理まで進まずに動いていなかっただけだった。

最終的には、こんなタイマになった。

void Tmr_Init(void)
{
    /* TMR0 */
    T0PR  = 18 - 1;            /* 18MHz/18 --> 1MHz */
    T0MCR = 0x00000006;        /* Match時に停止 */
    T0TCR = 0x00000000;
}
 
void Tmr0_Wait(uint32_t waitus)
{
    T0MR0 = waitus;
    T0TCR = 0x00000001;
    while(T0TCR & 0x00000001) {
        ;
    }
}

 

シンプルだ。
動かなかった理由は・・・最初に呼び出していると思い込んでいたTmr_Init()を呼び出していなかったので、タイムアウトしてもT0TCRの最下位ビットがクリアされていなかった、というだけのことだった。

あー、職場でやってなくて良かった。


ここ最近はNFCのことを書いていないので、そろそろ普通の人扱いになってきたんじゃなかろうか。
この調子でがんばりたい。

最近、ホームページの設定で「検索に引っかからないようにする」というのも見つけた。
ふふふ、これでいつでも痕跡を消せるぞ。

2012/04/22

[arm]UARTにてこずる

SPIよりも先に、デバッグ環境を整えねばならぬ。
JTAGを買うこともなさそうなので、printfデバッグにしよう。

といっても、本物のprintfは重たいので、単にUARTに掃き出すだけでいい。
そう思ってさっさと終わらせたかったのだが、なかなか動かなかった。


原因の一つは、実装ミス(それしかないけど)。

UARTの通信速度を決めるレジスタがあり、LPC-2388ではNXP提供のExcelファイルで計算したレジスタ値を設定するのがよさそうだった。
その通りに設定した(つもり)だったけど、なんかデータが化ける。
2時間くらいやって、ようやく得られたレジスタ値のdefine名を間違っていただけ、ということに気付いた。

 

もう1つは、実装漏れのようなもの。
UART出力のためにリングバッファを用意していたのだが、なんかでたらめなデータが出力されていたのだ。
ようやく、WriteポインタとReadポインタの初期値が設定されていないことに気付く。
この2つはstatic変数として定義していたので、0初期化されるつもりだったのだ。
しかし、よくよく考えるとResetベクタからスタックを初期化した後、すぐにmain()を呼び出していて、CRT0みたいな処理をまったくやってなかったのだ。

newlibを組み込めばいいみたいだけど、今回はそんなに大きなシステムでもないし、標準ライブラリも使わなくて済むと思うので、初期化関数で初期化するルールにした。

 

最後まで手こずったのが、リングバッファ。
デバッガがあれば簡単なのかもしれないけど、私はこういうのが苦手なのだ。

しかしよく読むと、LPC-2388のUARTには16byteもFIFOが積まれていることがわかった。
なら、リングバッファを用意してやるまでもない。
今回は115200bps/8bit/non-parity/stop bit 1なので、1byteが86usくらいで送信できる。
16byteなら1.4ms程度か。
バッファを持たせるとSPIでの受信データを出力できそうだけど、まあ、それはそのときに考えよう。

 

現状のソースをそろそろgithubで管理しておこう。

https://github.com/hirokuma/felica_plug

2012/04/21

私の知ってる無線パケット

私が知っている無線のことを書いておく。
以前、同じようなことを書いたかもしれないが、気にしない・・・。

NFCって分類にしたけど、あんまり関係がない。
が、NFC Forumの「Digital Protocol」を読みながら書くと、ちょっとは関係しそうだ。


だいたいの無線パケットは、こんな構成になっている。
・・・というほど無線を扱ったことがないのだけど、まあいいや。

image

 

エンコード(encode)

パケットの前に、データの表現方法について書いておかないといかんことがわかった。

NFC-Fでいえば「6.1.1 Modulation」のところだ。
英語で書いてあるが「Manchester coding」という言葉が1行目に書いてある。

無線の世界だけじゃなく、デジタルデータのやりとりの際、同じビットのデータが連続するのは好まれない(らしい)。
NFCだけでなく、USBやデジタル放送など、8b10bやマンチェスターのようなデータ変換をして、あまり0000…とか1111…のようなデータが連続しないように裏でがんばっている。

NFC-Fではマンチェスターと呼ばれる変換を行っている。
こんなのだ。
http://japan.maxim-ic.com/app-notes/index.mvp/id/3435
「0」を0→1、「1」を1→0、という信号の変化で表現する。
こうすると、どうやっても同じデータが2bit分までしか連続できない。

ただ、データの量が倍になってしまうのが残念だが、仕方ないところだ。

 

プリアンブル(pre-amble)

「こんなタイミングでデータを送信するから、うまく捉まえてね」という同期タイミングを表す。

送信する方と受信する方で通信速度を合わせていたとしても、それをどのタイミングで取得したらいいのか、というのはなかなかわからない。
電子回路であれば、クロックマスターみたいにクロックを出す人がいて、それにあわせてデータを送信/受信すればいいのだけど、無線の場合はおのおののクロックでやらないといけない。

それに、無線の周波数をお互いで決めていたとしても、ノイズなどでいろんなデータが取得できてしまう。
決まった信号(ビットで0101を繰り返すだけ、など)を最初に送信することで、受信する人はその信号にがんばって同期するのだ。

と書いたものの、ISO18092によると、Pollingコマンドのプリアンブルは48bitのゼロ値らしい。
ほほぅ、そういうのもあるんだな、と納得しかけたが、ちょっと違った。
デジタルなゼロ値は、マンチェスター符号に置き換えると「010101…」となるのだった。

DigitalProtocolの「6.1.2 Synchronization」に同期の取り方が書いてあるが、なんか難しそうなので読んでない。
Figure 20に2つ信号の図があるが、これはビットの正転と反転を表している。
無線だけかどうか知らないけれども、データ転送ではビット反転もよく行われるように思う(なんでだろう?)。
この図のSoSがプリアンブルの部分だと思う。その下に「has a value of 48bd」とあるので、たぶんそうだろう。
続くSoFが、SYNCコードということになる。

 

SYNCコード(sync code)

同期が取れただけでは、どこからデータが始まるのかわからない。
また、同期を取ったと思ったけれども、実はそれが偶然ノイズだったり別の人の無線パケットだったりすることもしばしばある。

それを解決するために、プリアンブルの後に送信側と受信側で取り決めた特定のデータを載せ、「プリアンブルの後にこのデータが来たら、それはうちの無線パケットですよ。次はデータが来ますよ」という取り決めをする。
それがSYNCコードとかユニークワードとか呼ばれているものだ。

受信する人は、プリアンブルをビット単位で処理しながらSYNCコードが来るのを待ちわびることになる。

DigitalProtocolの「6.3.1.2」に、SoFは0xB24D、と書かれている。
「もし受信側が0x4DB2と読んだら、それはビット反転しているからそう解釈してね」というようなことも書かれている。

そういうことからもわかるように、SYNCコードはどういう値でもよいわけではなく、見分けやすいような値になっている。

 

データ(data)

ここにようやく、送りたいデータが載せられる。
ただ無線の場合、よそからの電波やノイズなどでデータが一部壊れることがしばしばある。
壊れていないことは受信側で確認しないとわからないので、だいたいCRCみたいな確認用のデータが最後にひっつけるようにすることが多い。
チェックサムだとビット化けしていても気付かないことがあるので、CRCを使うことが多いようだ。

ネットでのダウンロードだとMD5なんかがよく使われていると思うが、サイズが大きいので16bitくらいのCRCがよく使われるようだ。
DigitalProtocolの「6.4 Data and Payload Format」のEoDに、CRC_F1, CRC_F2となっていて、ここも16bitになっていることがわかる。

長いデータを送信すると、それだけデータが化ける確率も高くなるので短めにしたいんだろう、という気がする。
それに、無線の送受信というのはけっこう電力を使うので、短めにしてさっさと終わらせたいというのもあるだろう。
また、無線というのが共用のものであるため、長い時間送信したりしないように法律で規制されていることが多いからかもしれない。

 

ポストアンブル(post-amble)

データのおしまい。
なくてもいいような気がするけど、「俺がまだ送信しているから待てよ」というキャリアセンスさせるためにやってるのかもしれん(勝手な予想)。


あと、キャリアセンス、というものがある。
情報処理の試験で「CSMA/CD」とか「CSMA/CA」とか出てくる、あれだ。

無線というのは、他の人によって妨害されやすい。
周波数が違えばだいたいいいんだけど、同じ種類の機器は同じ周波数を使うことが多いので、悪意がなくても妨害してしまうことがある。
それを避けるために、無線の衝突を避けるためのしくみをがんばって考えなくてはならない。

 

基本は「誰かが送信している間は自分は送信しない」だ。
送信しているかどうかは、受信しないとわからない。
LBT(Listen-before-Talk)、などと呼ばれることもある。無線を話す前に聞く、ということ。

しかし、無線を壊すのは「同じ周波数」という条件なので、上記のような無線パケットだけでなく、他の知らない機器が送信していることも考えんといかん。

なので、だいたいは「RSSI値」(受信信号強度)という、データの中身ではなく特定の周波数の無線電力を見て、一定レベルよりも大きかったら「誰かが送信している」とみなすことが多い。
電波法では、周波数ごとにこの辺も取り決められている(はず)。


FeliCa Liteなんかの「Without Encryption」ってのはここら辺のはなしだろう。
「無線パケットは暗号化してないので、受信機がいたらそのまま読み取られますよ」ということだ。
これはMIFARE ClassicやUltralightも同じだろう(NFC-Bはよく知らない・・・)。

NFC Forumでは無線に関する規格を決めているので、それにあわせて受信機を作るだけでいいのだ。
WireSharkでイーサネット上のデータを拾ってくるのと一緒だ。

 

FeliCa StandardやMIFAREの製品版には、NFC Forum外のプロトコルがおそらく存在し、そこではパケットデータ自体を暗号化してやりとりするような取り決めがあると思う。
考えつく方法は・・・

  • 暗号化用のコマンドを作り、コマンド以降を暗号化する。
    まあ、これが普通なのかな。
  • SYNCコードを変えて送信する。受信する方はがんばって複数のSYNCコードを読み分けられるように作っておき、このSYNCコードなら暗号無し、このSYNCコードなら暗号有り、みたいにする。
    これだと、データ部全体を暗号化できるけど、受信機が大変かも。
  • 周波数自体を変える。
    これだと、その周波数帯を知らない限りは受信できないのでさらに安全。
    しかし、リーダライタは複数の周波数帯を使い分けないといかんので、さらに大変。

 

とにかく、無線である以上は傍受から逃れられない、というお話でした。

2012/04/18

[arm]LPC-2388のIRQからVICVectAddrXを使う

FeliCa PlugをARM LPC-2388から操作するには、SPIを使うことになる。
しかし、その前にやりたいことがあった。

割り込みハンドラの整理だ。
FIQを使っていたのだけど、ハンドラに飛んでからswitch-caseなどで分岐するのはあまり効率が良くない。
せっかくのFIQなのだから、そういうのはもっと高速な用途のために空けておき、そこまで速度がいらないものはIRQでやってしまうといいんではなかろうか。

 

と思ったことにしたいが、実は少し違う。
ARMの割り込み処理をネットで探していたら、VICVectAddr0などを使う例があったのだ。

VICが使えるARMの場合、VICVectAddrX(Xは該当する番号)に値を入れておくと、該当する割り込みが発生したときにVICVectAddrレジスタにVICVectAddrXの値が入っている、というようになっているらしい。

これを使うときは、こういうのが多い。

  • 割り込みハンドラが呼び出されてからVICVectAddrレジスタを読み取り、そこへ関数ジャンプする。
  • 割り込みハンドラとしてVICVectAddrレジスタの値を使う

どっちかを選べといわれたら、後者の方が手間が少なくてよさそうだろう?
私はそう思ったのだ。


しばらく試してわかったのは、VICVectAddrレジスタを使うしくみはFIQではなくIRQでのみ有効、ということ。

 

最後までわからなかったのは、割り込みハンドラ呼び出し前のPCとVICVectAddrの関係。
最初に見たサンプルをそのまま使っていたのだが、IRQのベクタが

LDR     PC, [PC, #-0x0FF0]

となっていたのだ。
でも、-0x0FF0では大きすぎたのだな・・・。

2012/04/15

[FeliCaPlug]やっと搬送波検出ができた

CQ出版のARMボードで、ようやくFeliCa Plugからの搬送波検出割り込みによってLEDを光らせる、という基本の部分ができた。

なかなか動かなかったのは・・・数値の書き間違え。

PINSEL4 = 0x01400000;
EXTINT = 0x0000000f;        /* EINT割り込みクリア */
EXTMODE |= 0x00000006;        /* エッジ割り込み */
EXTPOLAR |= 0x00000004;        /* EINT1 : low-active */

というコードを書きたかったのだが、

PINSEL4 = 0x014000000;
EXTINT = 0x0000000f;        /* EINT割り込みクリア */
EXTMODE |= 0x00000006;        /* エッジ割り込み */
EXTPOLAR |= 0x00000004;        /* EINT1 : low-active */

と、0を1つ多くしてしまっていたのだ・・・。

 

気付いたときは「なんで桁数が多いのにコンパイラが警告を出さんのだ!」と怒ったのだが、先頭が0だったから1桁多くても問題なかったのだった。

うーん、なんか悔しい。


とりあえず、EINT1割り込みという外部割り込みは動作できた。

やはり最後は、SPIが残った。
プロトコルがいるものは、後回しにしてしまいたくなるから困ったもんだ。

[arm]配線

Interface誌2009年5月の付録ボードと、FeliCa Plugをつなごう。

Erattaにも書いてあったが、雑誌に書かれているCN2の+5Vと+3.3Vが逆だ。
今回は使ってないけど、使おうとしている人はご注意を(いるのか?)。

 

想定ではこんな配線でいいはず。

lpc2388

 

配線だけやってみた。

Clipboard01

見た目がきれいではないが・・・技がないので仕方ない。
こういうボードとブレッドボードをうまくつなぐ方法があるのかわからないので、いつもこんな感じだ。

あー、柔らかくてメス-オスのタイプもあるんですな。
これを持ってたら、CQボードは普通にピンを出しさえすれば、半田付け不要かつしっかりフィットだったんだなぁ。

まあ、技がないってのはこの辺も含めてのことなので仕方ない。


まだソフトが出来てないけど、半田付け作業は休日くらいしか暇がないのでね。
いつ動くようになるか、楽しみだ。

そういえばこのCQボードってUSBホストにもなることができる。
ちゃんと作れば、ADKにもなりそうだが、はてさてそんな気力が湧くかどうか。

[arm]カレントプログラムステータスレジスタ(CPSR)

LPC2388のサンプルソースを見ていると、やたらとインラインアセンブラが出てくる。
そのほとんどが、CPSRって書いてある。
何だろう?

Current Program Status Registerの略で、レジスタだからCから直接触れない。
ARM用のコンパイラとかだったらわからないけど、gccにはできん。
なので、インラインアセンブラで直接触らんといかん。
まあ、専用コンパイラじゃないから仕方ないか。

これの下位5bitが、モードビットと呼ばれている。
ARMにはいくつか動作モードがあって、そのうちのどれで動作しているかがわかるし、設定できるようだ。
この資料が、LPC2388のドキュメントにはなさそうだ。
ARMのレジスタなので、ARMのドキュメントから探さねばならん。
ということに、なかなか気付かなかった。
#    CPRSのモードビット(M[4:0])
#        1_0000(0x10) : ユーザ
#        1_0001(0x11) : FIQ
#        1_0010(0x12) : IRQ
#        1_0011(0x13) : スーパバイザ
#        1_0111(0x17) : アボート
#        1_1011(0x1b) : 未定義
#        1_1111(0x1f) : システム


なんでこんなのを調べているかというと、単にFIQを使いたいからだ。
Interface誌のサンプルでは、startup.sの中にあるアセンブラが呼ばれて、そこからCソースが呼ばれて、戻ってきてから復帰処理、という流れになっている。
が、まだるっこしい。
Cソースで関数が割り込みハンドラになっていれば、直接ジャンプしてもいけるはず。
探すと、Cソースでこんな感じにしておけばFIQハンドラとみなされるようだ。
void isr_FIQ(void) __attribute__ ((interrupt("FIQ")));
ARMはベクタテーブルは固定のようで、ここにはジャンプ先が書いてあるのではなく、ジャンプした後の処理を書くようだ。
「LDR PC, 処理先アドレス」のようになっている。
ここの処理先アドレスにさっきのCソースの関数を書けるかというと、そうはなってない。
一度別の場所に飛び、そこからCソースの関数へジャンプしている。
たぶん、ベクタテーブルが4byteごとなので、ここには4byte分の処理しか書けない。
ジャンプ命令は32bitアドレスどこへでもいけるようなので、4byte以上の命令長になるから一端中継する必要があるのだろう。
ただ、Interface誌のサンプルでは中継点で割り込みからの復帰処理を書く必要があったのだけど、__attribute__を使うとそこまでコンパイラがやってくれるようなので、ジャンプ命令だけで済んでいる。

あと、ARMの動作モードごとにスタックポインタ(R13)があるので、必要なモードだけスタックを設定しなくてはならんようだ。
これが、
  1. CPSRのモードビットに書き込んでモード遷移する
  2. R13にスタックポインタをLDRで設定する
ということをやるようなのだ。
いやあ、めんどくさい。
一度作ってしまえばいいんだろうけど、初回はめんどくさいな。
(まねするだけだけど。)

サンプルでは、スタックポインタをmemory.defの中で決めている。
0x4000_F000~0x4000_FFFFまで取っている。
4KBか・・・今使っているマイコンの全メモリと同じじゃないか・・・。



サンプルソースでは、IRQを使っているようだったが、私はFIQを使ってみたい。
IRQに比べて何が「F」なのかというと、専用のレジスタが多いためのようだ。
ARMの汎用レジスタは、
  • R0~R15
  • CPSR
  • (SPSR_xxx)
らしい。
IRQモードになると、R13、R14、SPSR_irqだけがIRQ用になり、それ以外は共通。
FIQモードでは、R8~R14とSPSR_fiqがFIQ用になる。
違いはR8~R12で、レジスタをいろいろ使い分ける必要があるなら、IRQでは一度現在のレジスタ値をどこかに退避させ、処理が終わったら戻してやらないといかんのだろう。
FIQは専用なので、そこら辺を気にしなくていいのが「F」ってことのようだ。

では、FIQを発生させるにはどう変更すれば良いだろうか。
ブロック図を見ると、IRQとFIQはVIC(Vector Interrupt Controller)から入力される。
サンプルはタイマ割り込みを発生させているので、そのままだとVICがIRQを出すのだろう。
割り込みの選択は、Interrupt Select Register(VICIntSelect)で行われている。
割り込み要因ごとに、IRQにするかFIQにするかが選択できる。
デフォルトは、全部IRQ。
割り込み要因を有効にするかどうかは、Interrupt Enable Register(VICIntEnable)で行う。
デフォルトは、全部割り込み無効。
そして、IRQやFIQ自体の有効/無効は、ARM側のレジスタになる。
これまたCPSRだ。
割り込み禁止/許可の専用命令はないらしい。
VICはメモリにマップされているのでCソースからも扱いやすいのだが、CPSRはアセンブラじゃないといかん。
頻繁に使うので、こちらをそのまま採用したマクロにした。
R12ってレジスタをハードコーディングしているけど、いいのかな?
コンパイラがうまいことやってくれるような風に書かれているけど、「In general」ってあるよなあ。
clobber listってのに書いておくからよい、という解釈でいいのかな。

2012/04/14

[arm]gccバージョンの違い

雑誌InterfaceのARM基板(2009年5月)。
IAR社は制限付きながらも統合開発環境がある。
それもいいのだけど、うちではデバッガがないのでそんなに利点がない。
ならば、制限無しのgccがいいんじゃなかろうか。
そんなわけで、gccを使うことにしている。

CQ出版の特設サイトを見ながら環境構築。
gcc環境の説明はここにあった。
ここではcygwinを使うようになっていた。
別にそれでもいいのだけど、フリーのARMコンパイル環境は何となくCodeSourceryかな、と思っている。
(いつの間にかMentorになってる…知らんかった…。)

当時のgccと、今のCodeSourcery gccを比べてみよう。

arm-elf-gcc (GCC) 4.3.1
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


arm-none-eabi-gcc.exe (Sourcery CodeBench Lite 2011.09-69) 4.6.1
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


4.3.1から4.6.1に上がっている。
では、ビルド結果はどうだろう。サンプルソースをそのままビルド。
最適化指定はしてない。。。ので、-O0扱いと同じようだ。

4.3.1
.text          0x0000005c      0x1f0 gcc_sample.o
               0x0000008c                CPU_DisableInterrupt
               0x000000bc                CPU_IRQInterrupt
               0x0000012c                main
               0x0000005c                CPU_EnableInterrupt
               0x0000024c                _etext = .

CPU_EnableInterrupt : 48byte
CPU_DisableInterrupt : 48byte
CPU_IRQInterrupt : 112byte
main : 288byte

4.6.1
*(.text)
.text          0x0000005c      0x1cc gcc_sample.o
               0x0000005c                CPU_EnableInterrupt
               0x00000090                CPU_DisableInterrupt
               0x000000c4                CPU_IRQInterrupt
               0x00000134                main
               0x00000228                _etext = .

CPU_EnableInterrupt : 52byte
CPU_DisableInterrupt : 52byte
CPU_IRQInterrupt : 112byte
main : 244byte

4.6.1の方が小さくなっている。
が、main以外は4.3.1の方が小さめだ。
何が違うんだろう?

比較しようかと思ったが、めんどくさくなってやめた。
最適化の有無だけ見ようかと-O3すると、4.6.1ではmain自体がなくなったので、やっぱりやめた(4.3.1には残ってた)。
本職でこういう作業をしなくなったときに見直そう。
見直すとき用に、-O3時の結果だけ置いておく。


Cソース
void CPU_EnableInterrupt()

{

  volatile unsigned int CPSR_val;

  asm ("MRS %0, CPSR": "=r" (CPSR_val):);

  CPSR_val &= ~0x80;

  asm ("MSR CPSR, %0": :"r" (CPSR_val));

}
4.3.1
sub    sp, sp, #4

MRS r3, CPSR

str    r3, [sp, #0]

ldr    r2, [sp, #0]

bic    r2, r2, #128

str    r2, [sp, #0]

ldr    r3, [sp, #0]

MSR CPSR, r3

add    sp, sp, #4

bx    lr
4.6.1
sub    sp, sp, #8

MRS r2, CPSR

str    r2, [sp, #4]

ldr    r1, [sp, #4]

bic    r0, r1, #128

str    r0, [sp, #4]

ldr    r3, [sp, #4]

MSR CPSR, r3

add    sp, sp, #8

bx    lr

フレームのために、4.3.1は4byte、4.6.1は8byte使っているように見える。
でも、実際に使っているのは4byte分だけ・・・?
そういえば、gcc4って中間コードを吐いた後でも最適化する段があったような。
なんかもう、感覚的にわかりにくくなってきたな。

CodeSourcery用にサンプルを書き換えた。

オリジナルは、Interface誌の付録。
  • LPC23xx.hを使うようにした
  • 割り込み禁止/許可をマクロにした(参考サイト)
まーだ、よくわかってないです。

[arm]LPC23xx.hの最新はどれだ?

雑誌Interface誌の付録ボードを使おうとしている。
マイコンは、NXPのLPC2388。
コンパイラは、CodeSourceryのLite版にしようかと考えている。

 

コンパイラをインストールしたのはいいが、レジスタのアドレスがわからん。
Inteface誌のgccサンプルを見ると、ソースの頭に自分で定義していた。
こ、これは私には無理だ・・・。

自分のほしいアドレスだけ登録する気力がないので、ネットで調べてみた。
LPC23xx.hというものがそれらしい。
最初に出てくるのは、NXP社ではなくKeil社(コンパイラの提供などしている)。
ここの中程に、ヘッダファイルがある。

ヘッダファイルのファイルヘッダ(紛らわしいな)のバージョンは、1.01。
果たしてこれは最新版なのだろうか?


きっとNXPに最新版があるはず、とドキュメントをダウンロード(zip。大きいので注意)。
アプリケーションノートとサンプルがあったので、探していった。

私の見たところでは、これが最新版。

*   2009.03.13  ver 1.07    FIO1MASK1,FIO1SET1,FIO1CLR1 value corrected

AN11008_Flash_based_non-volatile_storage_with_software.zip(zip)の中にあった。
ヘッダファイルだけ置いてくれるとありがたいんだけどなあ。

[arm]AHBバスってなんだろう

LPC2388というNXPのチップを使おうとしている。
ARM7ベースということだが、そもそもARMに詳しくない・・・。

ハードに詳しくないので、よくわからん用語を自分なりに解釈しよう。


AHBバス、という用語が出てきた。

ARM7自体は入出力をARM7固有のバスでやるらしいが、LPC2388はAHBバスに変換する、と雑誌に書かれている(めんどくさいので、自分では調べない…)。
さらに、AHBバスを2つ使っているらしい(デュアルAHB)。

 

では、AHBバスってのはなんだろう?
AMBA、という標準バス仕様らしいが、元はARM社らしい。
ここの記事がわかりやすかった。
http://www.atmarkit.co.jp/fsys/zunouhoudan/038zunou/arm_amba.html

説明のところにタイミングチャートが書いてあるものの、私にとってはあまり影響がない(と思う)。
だいたいバスってのはデバイスとやりとりするための通路みたいなもので、そこまでソフト的に意識しなくていいものだと思っている。
初期設定で気にしておけばいい、くらいがありがたい。


まずは、AHBバスにどういうデバイスが載っているか見ていこう。
ユーザーズマニュアルを見て、それっぽいところだけ抜き出した。

image

うーん。。。やっぱり図を見てもよくわからないな。

データシートのメモリマップにはAHB用のアドレスがあるのだが、詳細がわからない。
やはり、ユーザーズマニュアルを読まないとわからんようだ。


http://jp-origin.rd2011.nxp.com/products/microcontrollers/arm7/lpc2300/LPC2388FBD144.html

ここがLPC2388のページらしい。
jpって付いているが、だいたい英語だ。
ここからドキュメントをダウンロードできる。

 

2章にメモリアドレッシングがある。
見た感じだけだが、AHB上にあるデバイス用になっているだけで、AHB自体は何もしなくてもいいような気がする。

いや・・・AHBの設定をAHB周辺機器のメモリでやるわけはないか。
3章で見つけることができた。
AHBCFG1とAHBCFG2だ。


この2レジスタは構成がほぼ同じになっているようだ。

説明書きによると、デフォルトではラウンドロビンになっていて、以下の順で見て回るとのこと。

  • AHB1 : CPU, DMA, AHB1, USB
  • AHB2 : Ethernet, CPU

この順番を入れ替えることができる。
できるようだが、私が使う範囲では気にしなくてもよさそうだ。
どうりで、どのサンプルソースを見ても変更してないわけだ。

 

 

というような決定をいちいちしていかないといかん。
めんどうなので使い慣れたマイコンにしたいところだが、どれもあまり変わらん。
あきらめて調べ続けますかね。

PaSoRi RC-S380/S

日本でも、RC-S380/Sが発表された。

http://www.sony.co.jp/Products/felica/business/products/RC-S380.html

 

ん、「/S」??
私のイメージでは、「/S」はUARTモデルで、「/U」がUSBモデルだったのだ。
まあ、これはRC-S620/SとRC-S620/Uだけなのかもしれんが。
もちろん、PaSoRiはUSBです。

「業務用途専用モデル」とあるので、RC-S330/Sと同じ扱いのようだ。
(これも「/S」がついてるので、別の意味があるのかな。)
RC-S330は白パソリだと思ってたけど、写真は黒パソリになってた。
白パソリは、搬送波が出てるとLEDが点灯してて好きだったのだ。


RC-S380/Sの特長は、NFC Forum認定プログラムで認定されたリーダライタというところだろう。
これは認定第1号である。
おお! すごい!!

 

・・・と驚いてみたものの、NFC Forum認証プログラム自体がなんだかわからない。
サイトは、こちら
認証した場合の利点が列挙されている。

  1. NFC ForumのWEBサイトに認証されたデバイスが載ります(RC-S380の場合)
  2. 他のNFC Forum認証済みデバイス達によって、あなたのデバイスの信頼性が増します
  3. 他社アプリがあなたのデバイスを信頼したり推奨する割合が増えます
  4. NFC ForumのN-Markをタッチポイントに配置することができます
  5. NFC Forum認証マークをパッケージなどに表示できます

うーん、訳が今ひとつなのは申し訳ない・・・。
なんとなく雰囲気を読み取ってもらえれば幸いだ。

わかりやすいのは、1,4,5だ。
WEBサイトにはRC-S380が載っているし、今までのおサイフケータイマーク(NFCカードを左手で持ってかざしているイメージ?)の代わりにNマークが載っている。
PaSoRiの商品サイトにも「CERTIFIED」というNFC Forumのマークが表示されている。

 

2と3は、今後の話だろうが、影響が大きいと思う。

自社製のNFCデバイスを動かすメーカーは別だろうが、そういうところは多くあるまい。
だいたいはNFCサービスだけを運用したいだろうから、対応するデバイスが多い方がありがたい。
しかし対応するデバイスを増やすためには、そのデバイス向けソフトを作って、テストせんといかん。
このテスト工数が馬鹿にならないと思っている。

サービスを売るときも「リーダライタは○○社の××に対応」などとデバイスを指定せざるを得なかったし、他に方法がなかった。

 

これからは「NFC Forumが認証したデバイス」という見方ができるようになる。
動作確認はやらないといけないだろうけど、NFC Forumの規格にあわせてアプリを作っておけば、NFC Forumが認証したデバイスであれば動くはず、ということになるのかな。

2は「NFC Forum認証されたデバイスはこんなにあるんだ」とか「このデバイスも認証されているなら、他社のこのデバイスも同じことができるんだ」みたいな効果が得られるということだと思う。

3は「このアプリはNFC Forum認証されたデバイスで動作します」というものが増えてくると認証されたデバイスを購入することが多くなるとか…そういうことでいいのかな。

一般的な「標準化」の利点というのはだいたいそういうものだと思っている。


PC/SC 2.0対応、というのも大きいだろうと思う。
「だろう」がつくのは、私がPC/SCに詳しくないからだ。
雑誌Interfaceの特集があったので、そこから知識を得よう。

以前までのPaSoRiは、Type-BのみがPC/SC対応だった。
今回は、MIFAREもFeliCaも対応したとのこと。

Type-Bのみ対応だったのは、e-Taxという納税システムに対応するためだと思う。
やったことはないのだが、日本ではType-Bの住基カードというものを使って納税だか納税の資料作成だかをやることができるようなのだ。
それ以外の用途はあまりないだろう、ということだったのかな。

 

今のところ、NFC Forumでリーダライタを取り扱うための手段は規定されていない(NCIがそうなるのかな、と思ってるけど、よくわからん)。
なので、PC/SCが唯一の共通手段になっているのだろう。
さっき「このアプリはNFC Forum認証されたデバイスで動作します」と書いたが、アプリがデバイスを操作する手段も共通化されないと、意味がない。
「いやあ、無線レベルではNFC Forum認証されたんですけど、デバイスを操作する方法は認証がないんですよ、はっはっは」では、ちょっと困るところだ。

なので、

  • 無線部の標準化:NFC Forum
  • APIの標準化:PC/SC

というのが現状ではないかと思う(リーダライタの場合)。


私のレベルで気になるのは、PC/SCはどうやって実現しているのか?というところ。

私が今持っているRC-S620/Sなんかを操作するときは、RC-S620/Sのコマンドを使っている。
それしかないと思い込んでいるのだが、実はPC/SCコマンドというものがあって、それを直接デバイスとやりとりできたりするんだろうか?

 

雑誌Interfaceの記事を読む限り、PC/SCはドライバレベルの対応であると思う。
リーダライタへのAPIだけを規定し、そこからリーダライタ間の制御はドライバ依存というしくみだ。
ってことは、手持ちのPaSoRiもドライバが新しくなればPC/SCでFeliCaにアクセスできたりするのだろうか?とも思ったが、そんな簡単なものじゃないのかもしれない。

 

まあ、Windowsでソフト作ることはほとんどないので影響はないのだが、今後何があるかわからんので選択肢として覚えておくことにしよう。

2012/04/13

SmartMXの情報はあまり集まらなかった

久しぶりに早く帰ってきたので(今日だけ)、SmartMXについて調べたことを書き残しておく。
あまり細かいことはわからなかったのだが、何も書かないよりいいだろう。


SmartMXはたくさん種類があった。
それは、NXPのホームページから調べることができたのでわかった。
めんどうだったので、一番最初にあったPDFを読んだ。


まず、SmartMXは「マイコン」だということ。
マイコン(micro computer)の定義はいろいろありそうだが、CPUだけでなくメモリと周辺機器が入っているもの、と私は思っている。

SmartMXにはSecure_MX51というCPUが載っているようだ。
80C51ベースみたいなので、結構オーソドックスな作りだと思う。

面白いことに、MMUが載っている。
ROMが264KBくらいあるのでOSくらいは載りそうだけど、MMUがいるほどじゃないのでは・・・。

などと思ったけれども、「Secure multi-application」などと書いてある。
おサイフケータイに載っているFeliCaチップは、1つのFeliCaチップでEdyやSuicaのような複数カードをまかなうことができるが、それを指しているような気がする。
(FeliCaの場合は動的にシステム分割できたと思うが、SmartMXでもそういうことができるのかな)

 

SmartMXのドキュメントは「Secure dual interface」と書いてある。
"dual"とはなんだろう?

ISO/IEC 7816 + ISO/IEC 14443

のような気がするが、よくわからない。

 

SmartMXの無線プロトコルがどうなっているかが気になる。
NXPではなくPhilips Semiconductorsと呼ばれていたときの資料があった。

  • T=CL (ISO/IEC 14443-4)
  • MIFARE 1K / 4K
  • Self defined

ここら辺が、multi-applicationで選択できるところなのだろうか。
とはいえ106Kbpsベースであることだろう。
Self definedとはいえ、ある程度規定はされているのだろうな。


なお、私はNFC関係の仕事をしているわけはないので、ここに書いている記事も含めて、ネットで入手できた情報と、それを元に自分で考えたことくらいしか書いていません。
わざと間違ったことは書かないつもりですが、私が正しいと思っていることが間違っていることも多々あります。
ご注意くだされ。

 

いや、私よりも正しい情報を持っている人はたくさんいるはずなのに・・・。
もしかすると、NFCは普及しつつあるけれども、NFCの詳細については語るのがはばかられる文化になりつつあるのだろうか。

2012/04/08

NFC Controller Interface (NCI)って、なんだ?

なんとなくNFC Forumのドキュメント一覧を見ていると、目新しいものがあった。

「NFC Controller Interface」というドキュメントだ。
candidate(候補)と書いてあるので、まだ正式版ではないということだろうか。

 

分類は、Protocol。
LLCPやSNEPなどと同じくくりになっている。
説明を読むと、NFC Controllerとアプリケーションプロセッサ間のインターフェースを定義したものらしい。

むむ、これはかなり(私にとっては)重要なドキュメントじゃなかろうか?

どっちかを決めるものじゃないかな、と思っている。

  • ハードウェアとドライバ間のインターフェースを決めている
  • ドライバとアプリ間のインターフェースを決めている

アプリケーションプロセッサと書いているけど、"different physical transports"とあるので、ハードウェア間だといいなぁ。
でも、モバイルフォンとタブレットのどっちでも、なんて書かれていると、よくわからなくなりますな。

 

ダウンロードして読んでみればいいのだろうけど、電話番号とか住所を書かんといかんので、他のドキュメントとはちょっと扱いが違うのかも。
右上に「Member Pages」ってのも出てきているから、やめておこう。

2012/04/06

SmartMXというものがある

たまに、質問が来る。
知らないものは知らないのだが、なるべくわかる範囲で調べて返信する。
これでも真摯なのだ。

 

今回はSmartMXのことについて。
名前は聞いたことがあるが、NexusSに載っている、くらいのことしか知らない。
軽く調べておこう。


SmartMXは、NXPファミリーだ。
分類は、マイコン、だと思う。
ブロック図を見ると、

  • CPU : MX51
  • RAM
  • ROM
  • EEPROM
  • AES, 3DESコプロ
  • CIU ISO 14443 -- S2C (SigIn / SigOut)
  • CIU ISO 14443 -- RF Interface (LA / LB)
  • UART

などなどある。

 

このチップ自身には、RFがない。
また、SWPがない。
こういうものは、PN544みたいなチップを接続して実現するのだと思う。


気になったのは、SmartMXはSecure Elementなのか?というところ。
確かMifareとかって、SEをSIM上に持つんじゃなかったっけ?
FeliCaは専用チップを使っているので、それを徐々にSIMへ移動させようとしているところだったと思う。

例えばNexusSは、Androidのソースファイルを見る限りでは、セキュアエレメントとしてSmartMXが使われているように読めてしまう。
そしてソースを読む限りでは、Host CPUはPN544と会話しているように見える。
(単に、SE部分のソースは読み飛ばしているだけかもしれんが。)

 

また、SmartMXはMifare 1K / 4Kのエミュレーションをするらしい。
なんとなくUltralight系かと思っていたので、意表を突かれた。


やっぱりよくわからないので、返事は明日考えよう。。。

2012/04/04

FeliCa Lite-Sの相互認証はこんな感じだろうか

FeliCa Lite-Sのドキュメントをじっくり読みたいところだが、体力がない。。。
ざっとした印象だけで書くので、また間違っているところがあることだろう。


FeliCa Standardには、相互認証機能がある。
FeliCa Liteには、片側認証(内部認証)がある。

FeliCa Lite-Sにも相互認証機能があるが、それはFeliCa Standardのものとは異なる。
異なるらしい。FeliCa Standardはよくわかってないので、知らないのだ。
あちらには、プロプライエタリなコマンドがあるので、もっと細かい認証が可能であろう。

Lite-Sは、Liteにあった内部認証と、新しくできた外部認証を組み合わせて相互認証を実現するらしい。

 

■内部認証

これは、読み書きする側が認証するしくみ。
特定の値を書き込むと、特定の値をカードが演算して返すので、その結果を自分が想定する結果と比較する、というもの。
結果が正しければ「これは自分が発行したカードだ」などという判断をする。
その判断は読み書きした人しかできず、カードは単に言われた通りにアクセスできてしまうので「片側」と呼ばれているのだろう。

名前が変わったので、カードを発行した人が自分内部だけで認証する、という意味になったのかな。

 

■外部認証

これは、カード側が認証するしくみ。
単独でやるのではなく、内部認証に引き続き実施する想定のようだ。
内部認証で得るときには同時に複数のブロックデータを取得するのだが、そのデータを使って読み書き側が演算して認証データを作成。
その認証データを特定のブロックに書き込むと、認証済みEXT_AUTHフラグが立つらしい。
そうなると、ブロックごとに指定できる「認証後読み込み」や「認証後書き込み」の指定がされているブロックにアクセスできるようになるらしい。


なんとなく、わかったような気がする。

EXT_AUTHはいつフラグが落ちるのか、とか、EXT_AUTHはそもそもReadOnlyなのか、とかの疑問はまだ残っているのだが、資料を読んでいけば解決するのだろう。

最後はやはり、実物で確認だな。

2012/04/03

FeliCa Lite-Sのドキュメントが出た

平日は書かないつもりだったが、これは書かざるを得まい。
FeliCa Lite-Sのドキュメントが出たのだ。

読みながら、どういう製品なのか見ていこう。
まだまだ正しく把握できていないところもあるので、話半分で読んでもらえるとありがたい。


スターターマニュアルによると、ユーザブロック(ユーザが自由に使用できる16byte単位のブロック)ごとに以下の属性が設定できるらしい。

 

こういうことかしら?
調べてないので、あとで修正しそうだ。

 

W不可

認証なしW

認証後W

MAC後W

認証なしR

○1

○2

認証後R

×?

うーん、よくわからない・・・。
1と2は、今までもできた。MCブロックにビットを立てれば、そのブロックはRead Onlyで解除できなくなるのだ。

残りが、新設されたものだろう。
「読み書きするデータブロックにMACを付加して改ざんの検知が可能」と書かれている。
MACはLiteのときは片側認証で使っていたが、Lite-Sではあれを活用できるようだ。

なお、従来の片側認証は「内部認証」という呼び名に変わったようだ。
それに対してカード側が認証するしくみを「外部認証」と呼ぶ。
この「内部認証」と「外部認証」を組み合わせて、「相互認証」を実現する。

無線は暗号化されていない。
だから、13.56MHzのパケットモニタを作れば、平文が見えるということだ。
まあ、これは仕方あるまい。

 

アンチ・ティアリングというのは知らないが、まあ必要なら説明があるだろう。

Pollingディセーブル機能、というものがあるようだ。
ディセーブルにしていてもアクセスできるのかしら?


スターターマニュアルが、思いの外親切だ。
運用例があるので、あまり考えなくてもよさそうだ。

 

Lite-Sの特長が出ていそうな「5.2.5 ポイントカード」を読む。
この例では、S_PAD1~3に認証属性を設定している。

 

 

ポイントカードの説明には、「相互認証」と「相互認証とMACつき書き込み」の2つのパターンが解説してある。
前者ではポイントを書き込むブロックを、

認証後読み出し・認証後書き込み

と設定していたが、後者では

認証無し読み出し・認証後MACつき書き込み

に設定している。こうすると、正しいMACがないと書き込めないらしい。

 

そして私は知らなかったのが、Liteでは「署名」を付けることを推奨していたらしい。
Lite-Sでも使えますよ、という説明も書かれている。


7.3からは、その認証について説明がされているが、今日はここで時間切れだ。
(体力切れ、ともいう。)

FeliCa Lite-Sだが、まだ発売はされていないような感じだ。
またスイッチサイエンスさんから発売されるといいなあ。

2012/04/01

R/WはTargetがいなくなったことがわからないはずだ

ずっと悩んでいた、カードの捕捉状態を知ることができるか?という問題。

無線の気持ちになって考えてみた。


R/Wがポーリングコマンド(POL_REQ)を投げる。ATQとかでもいいや。
相手がいれば、POL_RESが返ってくるはず。
返ってくるので、InListPassiveTargetの戻り値が返ってくる。

 

さて、ここでしばらくカードが捕捉されたままとしよう。
R/Wは何かコマンドを送っているか?
送っていない。搬送波を出すだけだ。

本来の無線通信としては、送信が終わったら搬送波を出す必要はない(はず)。
ただNFCの場合、ターゲットに電源供給をしないといけないので、搬送波だけは出し続けなくてはならない。

搬送波って、川の流れのようなものだと思っている。
昔話「桃太郎」でおばあさんが川に洗濯しに行くが、洗濯しに行こうと行くまいと川は流れているのだ。
搬送波が川で、おばあさんの洗濯が送信データだろう。

川が流れなくなるのは、「桃太郎」のお話が終わったときだ。
つまり、川が流れているのは、物語が始まってから終わるまで。
NFCで搬送波が出続けるのも、ターゲットを捕捉してからリリースするまで。


搬送波というのは、常に流れているので、物語の進行とはあまり関係がない。
桃太郎が鬼退治している間も流れているのだ。
おばあさんの洗濯くらいで変わるものではない。

そう考えると、R/Wはカードがいなくなったことを知らないはずだ。
もちろん、コマンドを発行してレスポンスが返ってこない、ということになれば別だが、何もしていないのであればわからないだろう。

だから、GetGeneralStatusを使ってもカードが取り除かれたかどうかがわからないのだな。


組込開発であっても、お客さんの気持ちになって考えるということに変わりがない。
ただ、相手が人間だったりハードだったりするだけのことだ。