RC-S620/Sハンズオン

SONY RC-S620/S
個人で購入できる型式認証済みのNFCカードリーダ SONY製 RC-S620/S。
UART接続となっており、USBシリアル変換アダプタを使うと直接パソコンから制御可能です。
マイコンやライブラリを使用した製作例は出てきますが、マイコンを使った作品製作前にあえて一度USBシリアルで触ってみることでコマンドの理解が深まります。
コマンドが似ているPN532の情報も活用しながら、RC-S620/SがサポートしているFeliCa,NFC-Type A/Bの3種類のカードを検出してみます。

RC-S620/S は生産終了のようです。後継の RC-S660/S は下記

RC-S660/Sハンズオン (作成中)
https://www.hmcircuit.jp/nfc/rcs660_hands_on.html


<ご注意>

・このサイトを参考に実験を行い、火災、感電等がおきましても筆者は一切責任を取ることはできません。必ず自己責任で安全に十分注意したうえで実施してください。
・隠しコマンドの実験は自己責任で実施してください。機器が破損しましても筆者は一切責任を取ることはできません。

認証のない無線機器の使用及び技適付き無線機器の改造は法律により禁止されています。
RC-S620そのものの分解改造や、外国製の日本国内の型式認証を受けていないNFCカードリーダを使用することは電波法違反となります。

1.RC-S620/Sの入手

交通系ICカードや社員証といった民間から、免許証やマイナンバーカードといった公的カードまで、NFCによる非接触ICカードが普及しています。
NFCは、非接触ICカードリーダが内蔵されたスマホを使えば、個人でも比較的手軽に扱うことができます。スマホアプリのサンプルコードも検索すると簡単に見つかります。

ところが、電子工作でNFCを扱おうとすると、単品のカードリーダモジュールが必要になります。
NFCカードリーダは「誘導式読み書き通信設備」として法律で規制されており、日本国内では技術適合に適合(型式指定)しているものでなければ使用できません。
海外の電子工作サイトを見ていると、PN532が良く使用されています。しかし残念ながら海外サイトで紹介されているモジュールは、日本で型式認証されておらず使用することはできません。

そこで国内でNFC絡みの作品を作ろうとする際に候補として挙がってくるのが、型式認証のついたRC-S620/Sです。
接続はUART、電源電圧は3.3Vと5Vの2種類に対応しており、マイコンボードと組み合わせて使いやすいです。

日本語の仕様書とコマンドリスト

RC-S620/SはSONY製というだけあり、型式認証がついてるだけでなく、なんと日本語の仕様書<簡易版>とコマンドリファレンス<簡易版>が公開されています。
下記公式ページの「技術情報」ボタンからpdfファイルとして入手できます。

RC-S620/S製品ページ

RC-S620/SはFeliCaのみならずNFC Type A/Bにも対応していますが、簡易版のコマンドリファレンスにはFeliCa関連のコマンドしか掲載されておりません。
ネットの情報によると、隠しコマンドを使うことでNFC Type A/Bを読むこともできるとの情報がありましたので、別ページで試してきます。

Switch Science での購入がおススメ

Switch Science で購入
RC-S620/Sはいくつかの通販サイトが出てきますが、

Switch Scienceさんでの購入

がおススメです。

理由はSwitch ScienceさんオリジナルのDIP化基板とフラットケーブルのキット

FeliCa RC-S620S/RC-S730 ピッチ変換基板のセット(フラットケーブル付き)

が有能すぎるためです。

RC-S620/Sはノートパソコンのタッチパッド裏側のようにフラットケーブルを差し込んで使用する構造となっており、フラットケーブルと専用コネクタがないと別の基板へ接続することはできません。
そこで変換キットの出番です。フラットケーブルを2.54mmピッチのPINヘッダへ変換でき、そのままブレッドボードへ接続することが可能です。
別途PINソケットを用意すれば、ユニバーサル基板へ接続することも可能です。

2. USBシリアルでの接続

RC-S620/SをFT232でPCへ接続
秋月電子さんで購入した手持ちのUSBシリアル変換アダプタがありましたのでそちらを使用しました。
今回使用したアダプタは、こちら。

FT232RL USBシリアル変換モジュール

FTDIチップの FT232を搭載したアダプタです。ロジックレベル電圧(VccIO)はジャンパピンで切り替えて選択できるタイプです。電源出力はUSBの5Vと3.3V出力が出ています。
一方のRC-S620/Sは3.3Vと5Vの両電源に対応しており、特に設定等も不要でVcc端子へ接続された電圧を自動で認識します。
仕様書によるとRC-S620/Sの消費電流はMAX100mAとなっており、一方のFT232の3.3V出力はMAX50mAとなっています。よって必然的に5V動作を選択することになります。

配線を組み立ててUSBシリアルアダプタをパソコンに接続すると、COMポートとして認識されます。手元のWindows10Pro 64bit Buld1909 環境では、USBを差し込むだけで自動でドライバがダウンロードされました。
Sponsored Link

3.Tera Termの設定

続いてWindows上でCOMポートとデータをやり取りするフリーソフトを設定してきます。

ここでは、有名なTeraTermを使用します。
TeraTermのイメージ
サーバにSSHログインしたり、USBシリアル通信によりデータをやり取りしたりと、電子工作や通信系に取り組む場合は何かとお世話になるソフトです。

TeraTermのサイトはこちら

HEX表示の有効可

RC-S620/Sとのデータのやり取りは、すべてHEX(16進数)コマンドにより行います。
ですがTeraTermをインストールするだけではHEXを表示することはできません。文字コードに置き換えられて文字化けしてしまいます。
そこでまずはTeraTermでHEXをそのまま表示できるように設定を変更していきます。
TeraTermの設定変更
1. TeraTermを終了します。
2. TeraTermをインスト―ルしたフォルダを開きます。
例えば C\Prigram Filer(x86)\teraterm です。
3. "TERATERM.INI" ファイルを探し、「右クリック→編集」と操作しエディタで開きます。
4. ”Debug”で文書内検索をかけて "Debug = off" を探し、 "Debug = on"に書き換えて上書き保存します。
5. TeraTermを起動します。

USBシリアルへ接続

USBシリアルへの接続
1. USBシリアルをパソコンへ接続した状態でTeraTermを起動すると、「新しい接続」画面が出てきます
2. シリアル を選択します。USBシリアルを複数台接続している場合は、プルダウンメニューでRC-S620/Sへ接続したUSBシリアルを選択します。

※「新しい接続」が出てこない場合

ファイル → 新しい接続 とクリックすると表示されます。

※USBシリアルが出てこない場合

接続を確認し、ます。USBシリアルの場合、PCと接続されていても電源出力端子をショートしているなどの理由により保護回路が作動していることがありますので、ブレッドボード側の配線も忘れずにチェックします。
問題なければドライバが当たっているか確認し、必要に応じUSBシリアルのIC型番をネット検索して手動でドライバをインストールします。

シリアル通信設定

シリアル通信設定
RC-S620/Sの通信規格に合わせシリアルポートを設定します

1. 設定 → シリアルポート とクリックしメニューを開きます
2. ボー・レート を115200(RC-S620/Sのデフォルト値)に変更します
3. その他の値はデフォルトのままでよいはずですが、画像の設定と異なる場合修正します

※ボー・レートの選択肢に 115200 が出てこない場合

ご使用のUSBシリアルが高速通信に非対応な可能性があります
USBシリアルのスペックを確認し、最大通信速度が115200bps未達の場合はUSBシリアルを高速通信対応の品種に交換します。
例えばFTDIチップ製FT231/FT232は115200bpsに対応しています。

端末の設定

端末設定
次に端末の設定をします

1. 設定 → 端末 とクリックしメニューを開きます。
2. 「漢字-送信」と「漢字-受信」を"SJIS"に設定します。
3. 「ローカルエコー」にチェックを入れます。

ローカルエコーは、送信するコマンドを手元に表示する機能です。
チェックを入れない場合、画面には受信データのみが表示されます。
ローカルエコー機能を使用しなくでも通信はできますが、コマンドが正しく送れているのかチェックしたり、コマンドを送信したタイミングを見られたりと何かと便利なため、有効にされることを推奨します。

※次項目 HEXへの切り替え 時にはローカルエコーが必要です

HEX表示への切り替え

端末設定
最後に表示をASCIIからHEXに切り替えます。
TeraTermにフォーカスが当たっている状態で"Shft + ESC"を押すたびに切り替わります。
「”Shift + ESC” → 何か文字を入力」をHEX表示になるまで繰り返します。


うまく切り替わらない場合は、"TERATERM.INI" ファイルの編集をミスっている可能性がありますので再確認します。

画面をクリアする

端末設定
HEX設定時に表示された文字をクリアします

設定 → バッファのクリア と操作すると、画面に残っている文字が全て消去されます。

クリア手順は、RC-S620/Sと通信を試していく時にもしばしば実行するため、ショートカットキー "loading = "lazy" alt + E + B"を覚えておくと便利です
Sponsored Link

4.HEXコマンドの送信

3章の手順でTeraTermでRC-S620/Sと通信できる準備が完了しました。
本章ではHEXのコマンドを送信する方法をご紹介します。

Tera TermマクロでのHEX送信

TeraTermでのHEX送信では、マクロを利用します。
キーボードから送信する場合、ASCII文字コードが割り当てられている値しか送信することができません。
例えば"0x61"を送信したい場合はaキーを押せば送信されますが、"0x00"を送信しようとしても割り当ててられているキーはなく送信することができません。
さらに、キーボードから送信する場合、キーを押すたびに1バイト送信するため、受け取り側がタイムアウトしてしまい全てのコマンドを受け取る前に受信終了してしまう可能性もあります。

そこであらかじめ送りたいコマンドをマクロとしてまとめて記述しておき、連続して一気に送る方法を使用します。
TeraTermのマクロ送信
マクロは、TeraTermの処理を自動化するためのプログラムで、windowsのbatファイルのようなイメージです。
拡張子は.ttlです。

送り方も非常に簡単で、 画像のように、送信したいコマンドをttlファイルに書いておき、TeraTerm上で コントロール→マクロ からttlファイルを選択すれば、ttlファイルに書かれた処理が自動で実行されます。
次にRC-S620/Sを制御するために必要なマクロコマンドをご紹介します
TeraTermマクロには様々なコマンドが用意されていますが、RC-S620/Sとの通信に必要なマクロコマンドは最低限下記2つです。

 send 
HEXを送信するコマンドで、カードリーダにコマンドを送信するために使用します。

send スペース $1バイト目$2バイト目$・・・・・$nバイト目

例えば 0x00 0xff 0xd4 0x00 を送りたい場合、次のように記述します。
send $00$FF$d4$00

 pause/mpause 
指定秒数待つコマンドで、コマンド送信後に次のコマンドを送信するまでカードリーダーの処理時間を待つために使用します。

pause スペース 秒数
mpause スペース ミリ秒数


例えば1秒待ちたい場合、次のように記述します。

pause 1
または
mpause 1000

以上2コマンドがあれば最低限の通信はできますが、他のコマンドを組み合わせるとさらに高度なプログラムを作ることもできます。
例えばpauseのではなく期待した応答内容が返ってくるまで待つための wait を使って、無駄に長い時間待たずに「カードリーダ側の処理が終わったら次の処理に移る」ように改良することができます。

TeraTermマクロについて詳しくは、リファレンスのリンクを張っておきます。

TTL コマンドリファレンス

コマンドを作成したら、拡張子をttlに変えて保存します。

RC-S620/Sにコマンドを送ってみる

それでは、実際にRC-S620/Sのコマンドを送信して動作確認をしてみます。
今回送信するコマンドはこちら。RC-S620/Sをリセットするコマンドです。
試される場合はテキストエディタにコピペし、拡張子をttlにして保存してTeraTermマクロから実行ください。

send $00$00$ff$03$fd$d4$18$01$13$00

実際に送信すると、次のようになります。
TeraTermのマクロ送信
前章の設定でローカルエコーをONにしていますので、マクロに記述したデータがまずはそのまま画面に表示されます。
次に受信データが2つ続いています。
まずACK応答ですが、これは「返事」に相当するデータです。
私たちがLINEで「了解!」と返すように、コマンドの内容に依らずまずはコマンドを理解したことを報告する決まったデータを返してきます。
ACK応答を返した後は、コマンドで指示された作業に取り掛かります。
処理が完了すると「回答や報告」に相当するデータを返してきて、一連の流れが終了します。

マイコンと組み合わせて物を作っていく時は、ACKを活用して操作をコントロールすることができます。例えばACK応答がなかったら通信エラーとみなして再度コマンドを送り直したり、ACKが送られてきたらレスポンスデータ本体が送られてくるまでは処理中LEDを光らせながら待ったりといった使い方ができます。

5. コマンドについて

それでは、コマンドの中身を見ていきましょう。リファレンスを読み比べてみると、PN532も同じコマンド構造のようです。
なお、RC-S620/Sでは「1バイト = 8ビット」です。(今時1バイトが8ビットでないマイコンなんて見かけないですが一応・・・)
コマンドの中身
データ数255バイト以下の「ノーマルフレーム」では、パケットは送受信問わず下記の順番で並べます。

1. プリアンブル

パケットの先頭につく記号で、1バイト "0x00" 固定です。
開カギかっこ"「"のようなイメージで、メッセージの始まりを表す記号です。

2. Start of Packet

文字通り、データ本体のパケットの開始を示しています。
2バイト "0x00 0xFF" 固定です。
例えるならば「もしもし」みたいな感じでしょうか。

3. LEN

データ部の長さ(バイト数)です。
"0xFF" (255バイト)より長くなる場合は「拡張フレーム」と呼ばれる長いデータに対応したフレームフォーマットが使用されますが、ICカードと文章でもやりとりしない限りお世話になることはないので割愛します。
詳細は公式コマンドリファレンスの2章を参照ください。

※ACKフレームの場合は、LEN="0x00"が指定されており、データ情報は持ちません。

4. LCS

LENのチェックサムです。チェックサムとは、通信誤りの検出に使用するデータです。文字通り「足し算したときの値」が条件を満たしているか否かでチェックします。
RC-S620/Sでは、「LEN + LCS の下位1バイトが 0x00」がルールになっています。
もし受信データの LEN + LCS ≠ 0x00 であった場合、ノイズの混入などで正しく通信できていなかったことを受信側で発見できます。
画像の例でレスポンスデータのチェックサムを検証してみます
LEN = "0x03" , LCS = "0xFD" より
LEN + LCS = 0x03 + 0xFD = 0x100
下位バイトが0x00となっており、誤りなく受信できたことが確認できます。

なお、ノーマルフレームでは LEN ≦ 0xFF であるため、LEN + LCS = 0x100 と考えて問題ありません。
つまり送信コマンド組み立てる際は、 LCS = 0x100 - LEN を計算します。

※中身が空っぽのACKフレームの場合は例外的に、LCS="0xFF"が指定されており、LEN + LCS = 0xFF となってます。
ACKフレームは予約された特殊パケットのため例外です。
PN532のマニュアルでは、LEN, LCS ではなく "0x00 0xFF" セットで『ACK パケットコード』と記載があります。

5. データ部

データ部は、2バイトのコマンド部のあと、nバイトの各種情報部が続く構造になっています。
各種情報はプログラミングにおける関数の引数のようなもので、コマンドによってさまざまな情報を扱います。例えばカーリーダをを制御するパラメータだったり、カードから読み取った情報だったりです。
コマンドによっては、情報が付加されない場合もあります。

5-1. コマンドコード/レスポンスコード
コマンド(カードリーダへの送信)なのかレスポンス(カードリーダから受信)なのかを表す情報です。
コマンド"0xD4"、レスポンス"0xD5"のいずれかとなります。
0xD4 : コマンド(ホストコントローラ ⇒ カードリーダ)/0xD5 : レスポンス(カードリーダ ⇒ ホストコントローラ)
5-2. サブコマンドコード/サブレスポンスコード
コマンド名を表すコードです。
例えば "0x18" は Resetコマンドを表し、"0x19" はResetレスポンスを表しています。
各コマンドコードとコマンドの対応は、コマンドリファレンスに記載されています。

5-3. 各種情報(名称や内容はコマンドによってさまざま)
コマンドに渡す/コマンドが返してくれる情報です。
たとえばカードの情報を読んでくれるコマンドでは、この部分にカードから読み取った情報が付いてきます。
Resetコマンドの場合はパラメータを表す1バイトの情報のみです。
コマンドによっては存在しない場合もあり、例えば画像の例のResetレスポンスコードでは情報は持っていません。

6. DCS

データ部のチェックサムです。
データ部の全バイトとDCSの合計した値の最下位バイトが "0x00" となるような値です。
データ部の全バイトとDCSの合計した値を"0x100"で割った時の余りが"0x00"と言い換えることもできます。

画像のレスポンスデータで実際に計算してみます。
データ部 = "0xD5 0x19" , DCS = "0x12" より
データ部の全バイトとDCSを足すと
0xD5 + 0x19 + 0x12 = 0x100
となり、通信誤りなくデータを受信できたことが分かります。

送信コマンドを組み立てる際はDCSを計算して付与する必要がありますが、以下の方法で計算すると求まります。
DCS = 0x100 - データの合計の最下位バイト
または
DCS = 0x100 - データの合計 % 0x100

<例題>
データ = "0xD4 0x32 0x81 0xB7"
データ合計 = "0x23E"
データ合計の最下位バイト(データの合計を0x100で割った余り) = "0x3E"
DCS = "0x100" - "0x3E" = "0xC2"
<検算>
データ合計 + DCS
= "0x23E" + "0xC2" = "0x300"
(データ合計 + DCS) の最下位バイト = "0x00" が成立しOK

7. ポストアンブル

パケットのお尻につく記号で、1バイト "0x00" 固定です。
閉カギかっこ"」"のようなイメージで、メッセージの終わりを表す記号です。

<参考>Win10の電卓でHEX計算

参考としてLEN,LCS,DCSの計算に便利なWindows10標準搭載の電卓の機能を紹介します。
Win10電卓のプログラマーモード
実運用でコマンドを送信する際はホストコントローラ(マイコン)にプログラムを組んで計算させますが、USBシリアルでちょこっと試したい際は手計算が必要になります。
なじみのない16進数を暗算でパパっと計算するのはなかなか難易度が高いため、「プログラマー電卓」をフル活用します。

まずはいつも通りWindows10の電卓を開いたら、左上のメニューをクリックし「プログラマー」を選択します。
Win10電卓による10進・16進計算・変換
コマンド計算でのプログラマー電卓の活用方法は、「変換」と「計算」の2つの場面で使用します。

変換での活用:LENを求める


1. 送りたいコマンドのデータのバイト数を10進数で数える
2. 電卓の”DEC” (decimal)ボタンをクリックし、10進数モードにする
3. 手順1で数えたバイト数を電卓に入力する
4. ”HEX”(hexadecimal)ボタンの横に、16進数表記に変化された結果が表示される(=LEN)

※逆に受信データのLENを10進数に直したいときは、”HEX”モードを選択し受信したLENを入力すると、”DEC”の右に10進数での値が表示されます。

計算での活用例:DCSを求める


1. "HEX"ボタンをクリックして16進モードにする
2. 送りたいコマンドのデータを次々足していく
3. 表示された答えの最下位バイト(右側から2桁)を記憶
4. 手順3で求めたデータ合計の最下位バイトを16進モードで100から引く

6.FeliCaを検出してみる

Swintch Science様のRC-S620/S販売ページに、Arduino用ライブラリのリンクがありました。
中身を見てみると、コマンドリファレンスに書かれたコマンドを具体的にどのように使用すればFeliCaにアクセスできるかが分かります。
そこで、オリジナル作品を作る前にRC-S620/Sのコマンドに慣れる意味も含め、Arduinoライブラリをお手本にTeraTermマクロを組み立てて、身近なFeliCaであるSuicaを検出してみました。

お手本にしたライブラリ:Arduino向けRC-S620/S制御ライブラリの提供

FeliCaを検出するTera Termマクロ

※下記マクロはリトライはしないため、カードが検出されない場合はそのままプログラムが終了します。
コピペで試される場合はFeliCaをカードリーダの上に載せてからマクロを実行ください。
また、コピぺ時に余計なスペースや改行が入った場合は削除してからttl保存してください。

また、コメントしてSONY様の公式資料である「RC-620/Sコマンドリファレンス<簡易版> Version2.11」および「NFC/FeliCa対応機器・アプリケーション開発時時の注意事項 Version1.3」の対応ページ数を記載しておきます。

;リセット ※詳細はコマンドリファレンスp.49参照
send $00$00$ff$03$fd$d4$18$01$13$00
mpause 100

;arduinoライブラリに書かれている各種初期設定
;RFConfiguration (various timings) ※公式リファレンスに記載ないがググるとPN532のマニュアル p.101 に同じコマンドの記載あり
send $00$00$ff$06$fa$d4$32$02$00$00$00$f8$00
mpause 100

;RFConfiguration (max retries = 0) ※詳細はコマンドリファレンスp.28,p.42~参照
send $00$00$ff$06$fa$d4$32$05$00$00$00$f5$00
mpause 100

;RFConfiguration (additional wait time = 24ms) ※詳細はコマンドリファレンスp.42~ および 開発時の注意事項p.16 参照
send $00$00$ff$04$fc$d4$32$81$b7$c2$00
mpause 100

;FeliCaをポーリング
;InListPassiveTarget (FeliCa 212kbps) ※詳細はコマンドリファレンスp.50~参照
;Type-A/Bをポーリングしたい場合はパラメータ変更(7章参照)
send $00$00$ff$09$f7$d4$4a$01$01$00$ff$ff$00$00$e2$00
mpause 1500

;RFConfiguration (RF Off) ※詳細はコマンドリファレンスp.42~ 参照
send $00$00$ff$04$fc$d4$32$01$00$f9$00

実行結果

手持ちのSuicaをセットし、マクロを実行した結果です。
TeraTermの画面で読むにはあまりにも長いため、パワポへ張り付けて整理してみました。
RC-S620/SでSuicaを検出

ポーリングレスポンスを読む

次にInListPassiveTargetに対する応答から、FeliCaの情報を取出してみます
応答データからカード情報を取り出す InListPassiveTargetそのものに対する応答コマンドの部分と、カードからのポーリングレスポンスを伝言ゲームしている部分がセットになっています。
赤色で示した「ターゲットデータ」の部分が、必要となる「ポーリングレスポンス」情報を持っている部分です。

それでは、ターゲットデータを順番に見ていきます。
情報の見方については、技術情報に記載があります。

資料:技術情報 内の、「FeliCa技術方式の各種コードについて」 

論理番号


ここでは1枚しか検出しなので1固定になります。

ポーリングレスポンスデータ長


「ポーリングレスポンスデータ長」バイト~数えたポーリングレスポンスのデータ長を、バイト数で示しています。
例では 0x12 となっており、10進数に直すと 18バイト となります。
実際にバイト数を数えてみると、
ポーリングレスポンスデータ長:1バイト
レスポンスコードバイト:1バイト
製造ID:8バイト
製造パラメータ:8バイト
合計:18バイト
となっており、一致します。

IDm・PMmをスマホアプリで確認


カードリーダがFeliCaカードを識別したり性能を確認したりするための情報です。
IDmはカードによって固定されている場合、乱数になる場合があります。ICコードはICによって割り当てられた値、応答時間パラメータはカードのスペックを表していますます。
Suicaでは固定となっているため、Androidスマホで読み取った値と比較し、通信エラー等なく正しく読み取れているかどうか確認していみます。
AndroidでFeliCaの情報を読み取るアプリは、 NFC TagInfo を使用しました。

NFC TagInfo ストアページ

スマホアプリで確認
製造ID、製造パラメータともにスマホと同じ値が取得できていることが確認できました。

RC-S620/SをUSBシリアルとTeraTermマクロで制御して無事にFeliCaを検出することができました。
次章では、コマンドリファレンスに記載がない NFC Type-A/B の検出に挑戦します。

7.隠しコマンドによるType-A/Bの検出

カタログによるとRC-S620/SはNFC Type-A/Bに対応していますが、公式コマンドリファレンス<簡易版>にはFeliCaに関する情報しか載っていません。
<完全版>のコマンドリファレンスは、BtoBを前提とした代理店に連絡して入手しないといけないようで、個人にはハードルが高くなっています。
NFC Type-A/Bに対応しているとして売っておきながら使用方法を隠すというのは納得がいかないですが、キレていても始まらないのでGoogle先生に相談です。
すると、どうもPN532とコマンド共通性がありそうとの情報を入手しました。
PN532のユーザーマニュアル内にRC-S620/Sと同じ名前のコマンドが存在し、また、RC-S620/SでPN532のコマンドが使用できるという記事も出てきます。
しかし私が扱いたいType-Bについての詳細な情報は見つからなかったため、実験でいろいろ試していきます。

【PDF】 PN532 User Manual

RC-S620/S vs PN532 概要
PN532といえば海外の電子工作サイトではよく登場するカードリーダライタで、Adafruit製のブレークアウトボードはmbedの公式チュートリアルページにも使われています。

PN532の日本国内内型式認証済みモジュールを探してみると、電子鍵向けの以下の製品、しかも国産品が見つかりました。

超小型NFCリーダーライタモジュール -株式会社ヌマタ

ただし、当然ながらBtoB専売。型番をググっても通販サイトは出てきません。
RC-S620/SとPN532を比較をまとめると、
『RC-620/Sは個人で型式認証付きが買えるが情報不十分、PN532は情報完全だが個人で型式認証付きが買えない』
ということになります。

JCR-N01を秋月電子さんあたりが扱ってくれればな~海外のライブラリや工作ブログの情報がそのまま使えるんだけどな~などとと考えつつ、PN532とRC-S620/Sのドキュメントを比較してみます。

PN532コマンドとの共通性

カードリーダーをイニシエーター(カードを読み取る側)として使用する際に用いるコマンドを比較してみます。
ターゲット(スマホ決済のように読み取られる側)のコマンドは本記事では登場しないため省略します。
RC-S620/S vs PN532 コマンド
コマンド名を示す1バイトのコードも、コード名も、見事に同じです。
まさかコマンド名の列が1列で済むとは・・・。
RC-S620/Sでは、送信を表す"0xD4"のことを「コマンドコード」と呼ぶため、コマンド名に対するコード番号は「サブコマンドコード」と呼んでいます。
一方、PN532では”0xD4”はただの定数として名前なしで記載されており、コマンド名に対するコード番号のことを「コマンドコード」と呼んでいます。(PN532 user manual p.65参照)

さらにコマンドの対する応答時についてくるレスポンスコード"0xD5"も、PN532ではただの定数として書かれていますが値はRC-S620/Sと同じ”0xD5”です。
また、レスポンス時についてくるコード番号(RC-S620/Sではレスポンスコードと呼ぶ)の値は、PN532でははっきりと「コマンドコード + 1」と書かれています。
一方RC-S620/Sではサブレスポンスコードとしてコマンド名と対応させて一覧で記載されていますが、値はすべて「サブコマンドコード+1」となっており、pn532と全く同じ値です。

具体例ですと、どちらのICでも、”0xD4 0x02” に対しては、"0xD5 0x03 ・・・ " という応答が返ってくるということです。

NFCについて国際規格で規定されているのはカードとカードリーダ間の無線通信だけです。
カードリーダとホストコンピュータ間の有線コマンドはICメーカが自由に作れるはずです。
しかし並べて比較してみると、どちらかがOEM生産なのでは?と思ってしまうほど共通しています。

それでは、早速RC-S620/S に対し PN532 のコマンドを送り付けてNFC Type-A/Bをポーリングしてみます。

InListPassiveTarget

ポーリングにはどちらのICも "InListPassiveTarget" を使います。
RC-S620/S vs PN532 inlistpassivetarget
RC-S620/S怪しすぎます。特にBRTY。
FeliCaに関する部分はパラメータが完全一致です。
コマンドの構文は同じです。
いかにも隠しコマンドがありそうです!

早速試していくのですが、NFC-Type B には必須パラメータとして AFI(応用分野識別子)が必要です。
AFIについては JIS X 6322-3 7.7.3に記載があります。
名前の通り応用分野を特定するのに使用し、特定の応用分野を持ったICカードだけを検出したい場合に指定します。
AFI=”0x00”は「応用分野を特定しない全分野」を意味しており、AFI="0x00"が指定されたポーリングに対しては全てのICカードがポーリングリスエストに応答しないといけないと定められています。
つまり、不明なカードを探す場合はAFI="0x00"としてInListPassiveTargetコマンドを組み立てる必要があります。

身近なType-BカードとしてはICカード免許証があり、仕様書も公開されています。
免許証の仕様書にはAFIが記載されており、AFI = "0x00" とのことです。

免許証仕様書のURLは時々変わるようなので興味のある方は
「ICカード免許証 仕様」
でググって警察庁のpdfファイルを探してみてください。

以上、InListPassiveTargetコマンドを組み立てることができました。
それでは早速チェックサムなどの必要な情報をつけて、カードリーダに送るフルコマンドを組み立てましょう。
inlistpassivetargetフルコマンド
コマンドが準備できましたので、先ほど6章でFeliCaを検出したマクロのポーリング部を一部に書き換えて投げてみます。

NFC Type-A

TeraTermマクロ


USBシリアル接続されたRC-S620/Sを使ってType-Aのポーリングを試すTeraTermマクロです。
お試しになる場合、6章でご紹介したFeliCaを検出するマクロのInListPasiveTarget(黄色文字部分)を書き換えて実行ください。

;InListPassiveTarget Type-Aをポーリング
;6章FeliCaポーリングマクロのInListPassiveTarget部を下記に書き換え
send $00$00$ff$04$fc$d4$4a$01$00$e1$00

社員証をポーリングしてみる


手元にType-Aカードの社員証がありましたので、早速試してみました。
社員証をポーリング
送信したマクロは、6章でFeliCaのポーリングに使用したマクロのInListPassiveTarget部分を、上記マクロに書き換えたものです。
初期化などの一連のやり取りがありますが、ポーリングに関係のあるやり取り部分にマーキングしています。

ACK応答(青線部)に続いて、レスポンス(白線部)が返ってきています。

Type-Aのポーリングはリファレンスに記載のないコマンドでしたが、データ部は12バイトもあり、エラーコードではなくカードの情報が返ってきていると思われます!

レスポンスデータを読む


社員証ポーリングレスポンス
全体の構文としてはFeliCaと同じですが、ターゲットデータはFeliCaの19バイトに対しType-Aは9バイトと短くなっています。
またPN532では、ターゲットデータ内はカード識別IDであるRFIDを含む図のような構文になっています。

例えばNFCIDの長さは"0x04"(4バイト)、実際のNFCIDも4バイトとなっており、それっぽい応答になっているようには見えます。
しかし、RC-S620/Sの公式リファレンスがない以上Type-Aに対するレスポンスの構文がPN532と同じかどうかわからないため、スマホアプリで同じ社員証を読み取って比較してみます。

読み取り結果をスマホアプリで確認


NFCID確認
NFCIDが一致しています。
他の情報は、アプリケーションで活用する場面はないと思いますので割愛します。

以上より、PN532のコマンドを使ってType-Aのポーリングが可能であり、応答データの構文もPN532と同じであることが確認できました。

NFC Type-B

続いてNFC Type-Bです。身近な例としては、ICカード免許証やマイナンバーカードに使用されています。

TeraTermマクロ


USBシリアル接続されたRC-S620/Sを使ってType-BをポーリングするInListPassiveTargetのマクロです。
Type-A同様、お試しになる場合、6章でご紹介したFeliCaを検出するマクロのInListPasiveTarget(黄色文字部分)を書き換えて実行ください。

;InListPassiveTarget Type-Bをポーリング
;6章FeliCaポーリングマクロのInListPassiveTarget部を下記に書き換え
send $00$00$FF$05$FB$D4$4A$01$03$00$DE$00

免許証をポーリングしてみる


マクロを用意し、Type-Bカードである免許証で試してみました。
免許証をポーリング
こちらもType-A同様エラーコードではなく長い応答が返ってきており、何らかの情報を取得できているようです。

早速レスポンスデータの中身を読んでみます。

レスポンスデータを読む


社員証ポーリングレスポンス
PN532ユーザーマニュアルによると、Type-Bの場合はATQB(リクエスト応答)が返ってきます。
ATQBとはポーリングに対するカードの応答信号で、ポーリングを「呼びかけ」とするとATQBは「返事+自己紹介」のようなイメージです。
ATQBについては JIS X 6322-3 7.9 に記載があります。
ATQBは図中に示したように
”0x50” , PUPI , 応用データ , プロトコル情報 , CRC_B
の順で情報が並んでいます。

PUPI
通信時にカードを識別する、整理券番号のようなイメージの情報です。
Type-AのNFCIDと異なり通信ごとの使い捨てとなっており、電波を受けてICカードの電源が入るたびにICカード内で乱数が生成されます

応用データ
ICカード内に搭載されているアプリケーションをカードリーダに伝える情報です。
免許証では仕様書により "0x00 0x00 0x00 0x00" と定められており、実際に返ってきた情報を見ても一致していることが分かります。

プロトコル情報
ICカードが採用しているパラメータ情報を持っており、許容伝送速度や最大フレームサイズといった当該ICカードがサポートしている通信規格情報が含まれています。

CRC_B(巡回冗長検査コードB)
受信エラー検出のために使われる値であり、カードリーダ内で受信データのチェックに使用するためのものです。
InListPassiveTargetの応答としては省略されています。
PCとカードリーダで通信する際のDCSと同じような役割を持った情報で、CRC_B自体に新しい情報は入っていないため、省略されていても困りません。

読み取り結果をスマホアプリで確認


JISや仕様書と見比べてきて、コマンドが正常に動作しているといえますが、スマホアプリで確認してみます。
ATQB確認
まずPUPIです。
通信開始時に毎回生成される使い捨ての乱数であり、値が変化していることが確認できます。

応用データは、いずれも ”0x00 0x00 0x00 0x00” となっており、免許証仕様書の値と一致しています。

プロトコル情報はバイトの並び順が異なり、RC-S620/Sの応答はリトルエンディアン、スマホアプリはビックエンディアンとなってはいるものの、値としては同じ値が取得できていることが確認できます。

以上、RC-S620/Sのコマンドリファレンス<簡易版>に記載のないNFC Type-A/Bのポーリングを試してみました。
InListPassiveTargetコマンドはPN532の同コマンドと互換性があり、PN532のユーザーマニュアルに従って実装することで NFC Type-A/B をポーリングできることが確認できました。

8.Type Bと通信してみる

7章でType-Bのポーリングに成功しました。本章ではいよいよカードと通信してみます。
題材は仕様書が公開されているICカード免許証です。

通信コマンドの選択

カード通信する系のコマンドは下記3つありますが、結論としてはType-Bでは InDataExchange を使用します。

CommunicateThruEx


RC-S620/Sのリファレンス<簡易版>に記載のある唯一のコマンドです。しかし、 とあります。
よって CommunicateThruExはFeliCa専用コマンドであり、Type-Bには使えないとわかります。
※NFC Type-Bは106kbps
ということで頼みの綱はまたもやPN532のユーザーマニュアルになります。

InDateExchange


カードとカードリーダ間のプロトコルデータ交換コマンドです。
エラー処理や論理ターゲットの選択といったことを全自動で行ってくれるため、使用したいターゲット番号とカードに投げたい情報を渡すだけで通信できます。

InCommunicateThru


カードとカードリーダ間の基本的なデータ交換コマンドです。
InDateExchangeと異なり、渡した情報をカードにそのまま投げるコマンドであり、ホストコントローラ側で論理ターゲットの選択を手動で実施する必要があります。
ユーザーマニュアルやJISを熟読のうえ、InSelectなど他のコマンドと合わせて全て自分でプログラムする必要があります。
ユーザーマニュアルにも、 とはっきり書かれています。

クルマに例えるなら
・InDataExchange : AT
・InCommunicateThru : MT
ということになります。
クルマはMTに乗りたいですが、通信コマンドは何も迷わずAT一択です。

InDateExchange

それでは、実際にInDateExchangeを使ってみます。
免許証の仕様書に例として記載されているMF(ルートフォルダ)を選択するコマンドを試してみます。
MFを選択
InDateExchangeではターゲット番号を指定しますが、ターゲット番号が01しかないとわかっている場合でもInDataExchangeはInListPassiveTargetでカードと通信確立してから使用する必要があります。
InListPassiveTargetを実行しないと、カードリーダとカード間でプロトコルを設定するといった通信に必要な前処理が走らないためです。


TeraTermマクロ


基本的には、6章で試したFeliCaをポーリングするマクロの
InListPassiveTargetを7章で試したType-Bのものに書き換えた上で
InDataExchangeを足していきますが、一部コマンドを見直します。

まず Various Timing はターゲットがFeliCaまたはMifare(Type-A)の時のためのパラメータであり、Type-Bでは無関係でありカットします。
次に、MAX Retries は、デフォルト0xFF(無限)のままでよく、これもカットします。

;リセット ※詳細はコマンドリファレンスp.49参照
send $00$00$ff$03$fd$d4$18$01$13$00
mpause 100

;arduinoライブラリに書かれている各種初期設定
;RFConfiguration (additional wait time = 24ms) ※詳細はコマンドリファレンスp.42~ および 開発時の注意事項p.16 参照
send $00$00$ff$04$fc$d4$32$81$b7$c2$00
mpause 100

;InListPassiveTarget Type-Bをポーリング
send $00$00$FF$05$FB$D4$4A$01$03$00$DE$00
mpause 900

;InDataExchange MFを選択(無線コマンド 00 A4 00 00 )
;※免許証仕様書 Ver.008 p.2-17 参照
send $00$00$FF$07$F9$D4$40$01$00$A4$00$00$47$00
mpause 900

;RFConfiguration (RF Off) ※詳細はコマンドリファレンスp.42~ 参照
send $00$00$ff$04$fc$d4$32$01$00$f9$00
MFを選択
免許証を載せてマクロ実行してみました。
InDataExchangeはそもそもリファレンス<簡易版>に記載すらされていない隠しコマンドですが、エラーで止まってしまうこともなく通りました。
早速PN532マニュアルおよび免許証仕様書を見ながらレスポンスデータを確認します。

レスポンスデータを読む


MF選択レスポンス
応答データの構造もPN532のマニュアルとコンパチです。
まずInDataExchangeに対するレスポンスであることを示すサブレスポンスコードは、
"0x41"となっており、サブコマンドコード"0x40"に対し1を足した値となっています。

続いてステータスが続きます。
ステータスは、InDataExchangeコマンドが正常に実行できたか否かを示しており、
"0x00" は 正常終了 を表しています。
失敗した場合はステータスはエラーコードになり、例えばタイムアウトの場合は"0x01"になります。

DataIn部分は、カードが送ってきた情報部分です。
免許証の仕様書を見ると、SELECTコマンドに対する応答はSELECTコマンドのステータス情報が返ってくるとのことです。
"0x90 0x00" は「SELECTコマンド正常終了」を表しています。
実験成功です!!

以上、RC-S620/Sに対しPN532のコマンドを送り付けることで、Type-Bと通信できることが分かりました。

9.コマンド組み立てプログラム(C言語)

以上コマンドを見てきましたが、実運用でマイコンから制御する際にチェックサムなどを手計算してプログラミングするのは効率が悪すぎます。
そこでコマンドを組み立てるプログラムを用意しました。
データパケット部のみのコマンドからフルコマンド化する機能と、ICカードの無線コマンドをInDataExchangeフルコマンド化する機能を持たせてあります。
マイコンで使用するためにプログラミングした関係上、webになじまないですがC言語を採用しております。

※ブラウザのみで使えるフリーのオンライン実行環境 paiza.io 様 を使用しております。
プログラムの中身を書き換えてその場で実行できます。
マイコンへ転用される場合、toFullCommand関数の出力部をUART送信に書き換えください。



ここまでの手順でだいぶカードリーダのコマンドについて理解が深まってきました。
次回はカードのコマンドを試しながら、作品を設計してきます。
Sponsored Link

参考文献・サイト

総務省 電波利用ホームページ|電波環境|高周波利用設備の概要
RC-S620は、このページの個別の許可を不要とする要件「2.-(2)-ア」に該当します。
https://www.tele.soumu.go.jp/j/sys/others/highfre/
Sony Japan | FeliCa | 法人のお客様 | 製品情報 | RC-S620/S
RC-S620公式サイトです。「技術情報」ボタンから製品仕様書<簡易版>とコマンドリファレンス<簡易版>(いずれも日本語)をダウンロードできます。
https://www.sony.co.jp/Products/felica/business/products/RC-S620.html
Sony Japan | FeliCa | 法人のお客様 | ダウンロード
FeliCaを開発したSONY公式のpdf資料が多数掲載されています。特にFeliCa共通資料3種類は、コマンドリファレンスと合わせて目を通しておくことをお勧めします。
https://www.sony.co.jp/Products/felica/business/tech-support/