【Felicaを使う】Felica Plug とマイコンの半二重シリアル通信
吉田茂は養父、吉田健三の財産50万円(現在換算で約40億円)を使い尽くした。
某氏「どこそこの家の養子になった誰それは、そこの財産を倍に増やしたそうだ」
吉田茂「そういう男は養子の風上にもおけませんな」
今回はGR-KURUMI(RL78/G13)を使用してFelica plugを制御する方法について説明します。
Felica plugの端子は以下のようになっています。
RC-S926のインターフェイスについては「FeliCa Plugユーザーズマニュアル」の「2.2.1 物理層」を参考にしました。
ソニー株式会社 | FeliCa | 法人のお客様 | 技術情報
端子名 | In/Out | Active | 内容 | GR-KURUMIの接続先 |
---|---|---|---|---|
RFDET | OUT | Low | 磁界検知信号 L:磁界入力信号有り H:磁界入力信号無し | 外部割込み端子 |
SW | IN | - | スタンバイ制御信号 L:省電力モード H:省電力モード解除 | PORT出力端子 |
IRQ | OUT | High | 無線データ受信信号 L:CPUへのデータ無し H:CPUへのデータ有り | 外部割込み端子 |
SEL | IN | - | データ転送方向信号&データ完了通知信号 L:Host CPU → FelicaPlug H:FelicaPlug → Host CPU | PORT出力端子 |
DATA | IN/OUT | High | シリアルデータ | PORT入出力端子 |
SPICLK | IN | - | シリアルデータ用クロック | PORT出力端子 |
磁界検出RFDET端子と無線データ受信信号IRQ端子はマイコンの外部割込み端子に接続しました。
SW端子、SEL端子、SPICLK端子はマイコンのPORT出力端子に接続しました。
DATA端子はIN/OUTの両方として使用するので、IN/OUT両方の機能に切り替えられるマイコンのPORT端子と接続しました。ちなみに初期状態ではPORT端子は入力端子にしておき、マイコンからFelica plugにデータを送信するときだけ、出力端子にして、送信完了したら入力端子に戻します。
またpull-up/pull-downは同マニュアルで以下のように説明されていました。
DATA,IRQ,RFDET:Pull-Up/Pull-Downの処理は不要です。
SW,SPICLK,SEL:モジュールに電源を供給しているとき、必ずH or Lを入力すれば、Pull-Up/Pull-Downともに不要です。
Felica Plugの磁界検出RFDET端子は、普段はHigh出力になっています。Felicaリーダー・ライターに接触すると磁界を検出してLOWに変化し、磁界を一定時間検出しないとHighに戻ります。
Felica PlugのIRQ端子は、普段はLOW出力です。Felica plugがFelicaリーダー・ライターからWrite Without EncryptionコマンドもしくはRead Without Encryptionコマンドを受信するとHighに変化します。
その後、最初のSPICLK立ち上がり時にLOWに戻ります。コマンドの内容や実際の波形については別記事でも検討します。
Felica plugはSPI通信ではなく、独自の三線式半二重シリアル通信という方式を採用しています。
SPI通信機能のないマイコンでSPI通信をする時、SPICLKをPORT端子に割り当てて、単純に出力をHigh⇔Lowにするのを繰り返して擬似的にクロックを作ることがあります。
Felica plugは基本的にそれと同じことをします。
例えば1byteのデータをマイコンRL78からFelica plugへ送信するプログラムは以下のようになります。
PORT7.1をDATA端子と接続し、PORT7.0をSPICLK端子と接続しています。PM7はPORTの入出力を制御するレジスタです。
GR-KURUMIのSPICLK端子出力をプログラムでHigh→LOW→High→LOWと変化させながら、送信したいデータを8bit目から順に1bitずつ送信します。
プログラムはSonyがArduino用に公開しているサンプルプログラムを参照しました。
Arduino向けFeliCa Plug 制御ライブラリの提供 « FeliCa Developers' Blog
void sendByte(unsigned char data) { int i; //DATA用端子を出力に設定 PM7 &= 0xFD; //8bit目から開始して、1bit目までデータ送信 for (i = 0; i < 8; i++) { P7.0 = 0; //CLK 立ち下げ if (data & 0x80) { //dataを1bit送信 P7.1 = 1; } else { P7.1 = 0; } data <<= 1; //dataを右に1bitシフト us_wait(1); //1us待機関数 P7.0 = 1; //CLK 立ち上げ us_wait(1); //1us待機関数 } //DATA用端子を入力に設定 PM7 |= 0x02; }
このプログラムを使って実際に0x1A=00011010のデータを転送したときの波形を以下に示します。 SPICLK立ち上がり時のDATAの値が送信され、8bit目から1bit目まで順に送信されているのが分かります。
Felica PlugからRL78へのデータ受信の場合も、基本的に送信と同じことをします。
GR-KURUMIのSPICLK端子出力をプログラムでHigh→LOW→High→LOWと変化させてやると、そのタイミングに合わせてFelica Plugがデータを1bitずつRL78へ送信してくれます。
送信と違う点は、別記事にて詳細に説明しますが、DATA用に使用しているPORT端子を入力に変更し、SEL端子をHighにしてやることだけです。
unsigned char receiveByte ( void ) { unsigned char data = 0; unsigned char i; //8bit目から開始して、1bit目までデータ受信 for (i = 0; i < 8; i++) { P7.0 = 0; //CLK 立ち下げ us_wait(1); //1us待機関数 data = data << 1; //dataを右に1bitシフト if(1 == P7.1) //dataを1bit受信 { data |= 0x01; } P7.0 = 1; //CLK 立ち上げ us_wait(1); //1us待機関数 } return data; }
SPI通信ならば入力と出力が同時に行われますが、Felica plugではSEL端子をHigh/Lowに変えることでデータの入出力方向を切り替えて、入力と出力を別々に行います。