NFC#07 通信処理実装[後編]-RC-S660/S通信
前回に引き続き、 FT232H を介した RC-S660/S との通信を実装していきます。
前回は FT232H と通信するための処理を実装しました。
今回はこれらの処理を使用して、 FT232H の設定及び RC-S660/S との通信処理を実装していきます。
・スマートフォンやICカードとの連携機能を実装したいエンジニア
・IoT機器や非接触決済の技術に関心のある開発者
開発環境
- OS: macOS Sonoma 14.5
- Xcode: Xcode 15.4 (15F31d)
FT232H を介した RC-S660/S とのデータ通信
前回実装した各メソッドを利用し、 FT232H を介した RC-S660/S とのデータ通信を実装します。
ここではファームウェアバージョン取得を例にします。
モジュールに合わせた FT232H 設定
まずは FT232H を介して通信したいモジュールの通信仕様に合わせて、各 FT232H 設定処理を呼び出していきます。
今回使用する RC-S660/S の通信仕様は以下の通りです。
| 項目 | 設定 |
| 通信方式 | UART |
| ボーレート | 115,200 bps(デフォルト) |
| データビット | 8 bit |
| パリティビット | なし |
| ストップビット | 1 bit |
| 制御 | なし |
通信仕様で明記されていない以下の設定については、実装を進める中で調整していきます。
| 項目 | 設定 |
| レイテンシタイマ | 16 ミリ秒(FT232Hデフォルト値) |
| イベントキャラクタ | 使用しない |
| エラーキャラクタ | 使用しない |
| ブレーク信号 | 使用しない |
設定値を定めたら、 Start メソッドのドライバ固有起動処理として FT232H 設定処理を追加します。
// MARK: FT232H 一般設定
// 1. デバイス初期化
ret = this->ResetDevice(Ft232hReqResetArg::ResetDevice); // デバイスリセット:0
if (ret != kIOReturnSuccess) {
os_log(OS_LOG_DEFAULT, "ResetDevice Error. ret:0x%{public}08x", ret);
Stop(provider, SUPERDISPATCH);
return ret;
}
// デバイス初期化に合わせてビットモードもリセットする
ret = this->SetBitMode(Ft232hBitMode::Reset, 0xFF); // AD0 〜 AD7 全てリセット(0x00)
if (ret != kIOReturnSuccess) {
os_log(OS_LOG_DEFAULT, "SetBitMode Error. ret:0x%{public}08x", ret);
Stop(provider, SUPERDISPATCH);
return ret;
}
// 2. レイテンシタイマ設定
ret = this->SetLatencyTimer(0x0010); // FT232H のデフォルト値 16 ミリ秒
if (ret != kIOReturnSuccess) {
os_log(OS_LOG_DEFAULT, "SetLatencyTimer Error. ret:0x%{public}08x", ret);
Stop(provider, SUPERDISPATCH);
return ret;
}
// 3. イベントキャラクタ、エラーキャラクタ設定
ret = this->SetEventChr(0x00, false); // 無効
if (ret != kIOReturnSuccess) {
os_log(OS_LOG_DEFAULT, "SetEventChr Error. ret:0x%{public}08x", ret);
Stop(provider, SUPERDISPATCH);
return ret;
}
ret = this->SetErrorChr(0x00, false); // 無効
if (ret != kIOReturnSuccess) {
os_log(OS_LOG_DEFAULT, "SetErrorChr Error. ret:0x%{public}08x", ret);
Stop(provider, SUPERDISPATCH);
return ret;
}
// 4. ビットモード設定
// NOTE:デバイス初期化時にリセットしており、既にUARTモードのため、UART通信の場合は実行しなくても良い
ret = this->SetBitMode(Ft232hBitMode::Reset, 0xFF); // AD0 〜 AD7 全てUART(0x00)
if (ret != kIOReturnSuccess) {
os_log(OS_LOG_DEFAULT, "SetBitMode Error. ret:0x%{public}08x", ret);
Stop(provider, SUPERDISPATCH);
return ret;
}
// MARK: FT232H UART設定
// 5. ボーレート設定
ret = this->SetBaudrate(115200); // ボーレート:115,200 bps
if (ret != kIOReturnSuccess) {
os_log(OS_LOG_DEFAULT, "SetBaudrate Error. ret:0x%{public}08x", ret);
Stop(provider, SUPERDISPATCH);
return ret;
}
// 6. データ特性設定
ret = this->SetDataCharacteristics(Ft232hReqSetDataArgBreak::Off, // ブレーク信号は使用しない
Ft232hReqSetDataArgStopBits::One, // ストップビット:1 bit
Ft232hReqSetDataArgParityBits::None, // パリティビット:なし
Ft232hReqSetDataArgDataBit::Eight); // データビット:8 bit
if (ret != kIOReturnSuccess) {
os_log(OS_LOG_DEFAULT, "SetDataCharacteristics Error. ret:0x%{public}08x", ret);
Stop(provider, SUPERDISPATCH);
return ret;
}
// 7. フロー制御設定
ret = this->SetFlowCtrl(Ft232hReqSetFlowCtrlArg::Disable); // フロー制御なし
if (ret != kIOReturnSuccess) {
os_log(OS_LOG_DEFAULT, "SetFlowCtrl Error. ret:0x%{public}08x", ret);
Stop(provider, SUPERDISPATCH);
return ret;
}
モジュールとの通信
FT232H の設定が全て正常完了すると、 RC6-S60/S とのデータ通信が可能となります。
今回はデータ通信の確認として、 RC-S660/S のファームウェアバージョン取得コマンドのコマンド送信・レスポンス受信を例とします。
なお、単純化のため、 Start メソッドのドライバ固有起動処理に実装します。
// MARK: FWバージョン取得
os_log(OS_LOG_DEFAULT, "=== Get Firmware Version ===");
// ファームウェアバージョン取得コマンドの送信
uint8_t sendBuffer[] = {
0x00, 0x00, 0xff, 0x00, 0x0e, 0xf2, 0x6b, 0x04,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x56, 0x00, 0x00, 0x3c, 0x00
};
ret = this->SendData(sendBuffer, 22);
if (ret != kIOReturnSuccess) {
os_log(OS_LOG_DEFAULT, "SendData Error. ret:0x%{public}08x", ret);
Stop(provider, SUPERDISPATCH);
return ret;
}
// レスポンス受信
uint8_t *recvBuffer = nullptr;
size_t length = 0;
ret = this->RecvData(&recvBuffer, &length);
// 今回は受信データを使用しないためそのまま破棄する
if (recvBuffer != nullptr) {
delete[] recvBuffer;
}
if (ret != kIOReturnSuccess) {
os_log(OS_LOG_DEFAULT, "RecvData Error. ret:0x%{public}08x", ret);
Stop(provider, SUPERDISPATCH);
return ret;
}
FT232H と RC-S660/S の接続
続いてハードウェアを準備します。
今回から実際に RC-S660/S と通信するため、 FT232H と RC-S660/S を接続します。
今回の UART 通信では TXD(送信), RXD(受信)のみ使用します。

FT232H で該当するピンは、 TXD = AD0, RXD = AD1 となります。

RC-S660/S のピン配置は、モジュールに刻印されている「1」から順に下表の通りとなります。
なお、 RC-S660/S のインターフェースは FPC / FFC 用コネクタであるため、ブレッドボードで使用できるようにするためにスイッチサイエンス社のピッチ変換基盤を使用しています。
| No. | ピン名称 | 機能 |
| 1 | VDD | 電源端子(DC 3.3 V) |
| 2 | TXD | TXD信号 |
| 3 | RXD | RXD信号 |
| 4 | GND | GND端子 |
| 5 | Reserve | なし |
| 6 | Reserve | なし |

それでは FT232H と RC-S660/S を接続しましょう。

TXD / RXD は交互に接続します。
一方の送信データ(TXD)は、もう一方にとっては受信データ(RXD)となるためです。
RC-S660/S は DC 3.3V を電源とします。また、消費電流は最大 140mA のため、電源の電流容量は 200mA 以上とされています。
FT232H にも 3.3V 出力は備わっていますが、電流容量が小さいため、安定動作のために 5V – 3.3V の降圧レギュレーターを使用しています。

前回インストールしたドライバのアンインストール
以前の記事 の「Appendix: ドライバインストール状態の確認」で、ドライバが未インストールの場合のみインストールボタンが表示されるようにしています。
よって、今回の実装を反映したドライバをインストールするために、前回インストールしたドライバをアンインストールします。
ドライバのアンインストールは systemextensionsctl コマンドを使用します。
ターミナルを開き、以下のコマンドを実行します。
% systemextensionsctl uninstall <ドライバの teamID> <ドライバの Bundle Identifier>
コマンドを実行すると、機能拡張ブロックのダイアログが表示されるため、ログインユーザーのパスワードを入力して OK ボタンをクリックします。

アンインストールが正常に完了すると Success が表示されます。
また、 systemextensionsctl list コマンドを実行すると、前回インストールしたドライバがなくなっていることが確認できます。

動作確認
それではビルドして動作確認してみましょう。
デバイスが Mac に接続されている場合、アプリを実行する前にデバイスを抜いておきます。
以前の記事 と同様に、ドライバインストール後、コンソールをアプリを開いてからデバイスを接続します。

デバイスを接続してしばらくすると、送受信データのサイズ及びデータダンプが出力されます。
送信データ SendData は、送信バッファに設定したデータがそのまま出力されていることが分かります。
また、受信データ RecvData に RC-S660/S からのレスポンスデータが出力されていることが分かります。
これらのデータの内容については、次回詳しく見ていきたいと思います。
おわりに
今回はドライバからUSBデバイスに通信する処理を実装しました。
また、 FT232H を介して、目的である RC-S660/S と通信することもできました。
これで RC-S660/S を使ってNFCカードへアクセスするための準備が整いました。
次回は、NFCカードへのアクセスの前に、 RC-S660/S で取り扱うパケットを見ていきたいと思います。

