叶鋼は午前1時に計算をする

電子工作と計算の記録

【Felicaを使う】Felica Plug とマイコンの半二重シリアル通信

吉田茂は養父、吉田健三の財産50万円(現在換算で約40億円)を使い尽くした。

某氏「どこそこの家の養子になった誰それは、そこの財産を倍に増やしたそうだ」

吉田茂「そういう男は養子の風上にもおけませんな」

今回はGR-KURUMI(RL78/G13)を使用してFelica plugを制御する方法について説明します。  

Felica plugとマイコンインターフェイス

Felica plugの端子は以下のようになっています。

RC-S926のインターフェイスについては「FeliCa Plugユーザーズマニュアル」の「2.2.1 物理層」を参考にしました。

ソニー株式会社 | FeliCa | 法人のお客様 | 技術情報

端子名In/OutActive内容GR-KURUMIの接続先
RFDETOUTLow磁界検知信号
L:磁界入力信号有り
H:磁界入力信号無し
外部割込み端子
SWIN-スタンバイ制御信号
L:省電力モード
H:省電力モード解除
PORT出力端子
IRQOUTHigh無線データ受信信号
L:CPUへのデータ無し
H:CPUへのデータ有り
外部割込み端子
SELIN-データ転送方向信号&データ完了通知信号
L:Host CPU → FelicaPlug
H:FelicaPlug → Host CPU
PORT出力端子
DATAIN/OUTHighシリアルデータ PORT入出力端子
SPICLKIN-シリアルデータ用クロック 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ともに不要です。

f:id:yegang:20140812222810j:plain

 

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とマイコンの通信方式

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ずつ送信します。  

プログラムはSonyArduino用に公開しているサンプルプログラムを参照しました。

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目まで順に送信されているのが分かります。

f:id:yegang:20140812223021j:plain

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に変えることでデータの入出力方向を切り替えて、入力と出力を別々に行います。