概要
USB OTG(USB On-The-Go)は、2001年にUSB-IFが策定したUSB 2.0の補足仕様です。従来のUSBはホスト(PC等)とデバイス(周辺機器)が固定されていましたが、OTGによりモバイル機器・組み込み機器が状況に応じてホスト役にもデバイス役にも切り替えられるようになりました。
スマートフォンやタブレットにUSBメモリを直接差し込んで読み書きしたり、プリンタに接続したりする機能はUSB OTGによって実現しています。また、組み込みシステムでもSTM32やiMX RT等のマイコンがOTGをサポートし、デバイスモード(PCに接続してデータ転送)とホストモード(USBデバイスを接続して制御)を1つのUSBポートで切り替えられます。
歴史・背景
USB OTGは2001年に「USB 2.0 Supplement」として策定されました。当時急速に普及していたモバイル機器(PDA・携帯電話)が、PCを介さずに直接周辺機器と接続できるようにすることが目的でした。
スマートフォンの普及とともにOTGは広く知られるようになり、AndroidではAPI Level 12(Android 3.1)からOTGが公式サポートされました。現在ではUSB Type-CコネクタとUSB PD(Power Delivery)の組み合わせにより、OTG的な役割切り替えがより柔軟になっています。
組み込み分野では、STM32F4/F7/H7シリーズ、NXP i.MX RT、Microchip PIC32などがUSB OTGコントローラを内蔵し、デバイス/ホスト切り替えを1つのUSBポートで実現しています。
技術仕様
OTGの役割切り替え
OTGでは接続するケーブルのIDピンで初期ロールが決まります:
| IDピン状態 | 役割 |
|---|---|
| GNDに接続(IDピン=Low) | A-device(ホスト側。Micro-AプラグのコネクタにIDがある) |
| 未接続(IDピン=High/HiZ) | B-device(デバイス側) |
HNP(Host Negotiation Protocol)
OTGの重要な機能の一つがHNP(ホストネゴシエーションプロトコル)です。通信中に双方の合意でホスト・デバイス役を動的に交代できます:
A-device(ホスト)がHNP要求をB-device(デバイス)に送信
→ B-deviceがホストに切り替わり
→ A-deviceがデバイスに切り替わり
→ 役割が逆転した状態で通信を継続
SRP(Session Request Protocol)
SRP(セッションリクエストプロトコル)により、バスパワー消費を最小化するためのセッション管理が可能です。A-deviceがバスの電源をオフにしている状態から、B-deviceからの要求でセッションを再開できます。
USB Type-CとCC(Configuration Channel)
USB Type-Cコネクタでは、IDピンの代わりにCC(Configuration Channel)ピンが役割決定に使われます。CC1/CC2の抵抗値でホスト/デバイス/デュアルロール(DRP)が決まります:
| CC電圧/状態 | 意味 |
|---|---|
| 5.1kΩ pull-down(Rd) | UFP(デバイス側、USB Function Port) |
| 56kΩ pull-up(Rp) | DFP(ホスト側、Downstream Facing Port) |
| DRP(Dynamic Role Port) | 交互にRp/Rdをトグルしてネゴシエーション |
動作原理
OTGコントローラの初期化
マイコン内蔵のOTGコントローラは通常「デュアルロールデバイス(DRD)コントローラ」として動作します:
// STM32F4 USB OTG FS 設定(TinyUSBを使用)
#include "tusb.h"
// OTGピン設定
// PA11: USB_FS_DM
// PA12: USB_FS_DP
// PA10: USB_FS_ID(IDピン)
void usb_otg_init(void) {
// IDピンの状態を読んでホスト/デバイスを判断
if (HAL_GPIO_ReadPin(USB_ID_GPIO_Port, USB_ID_Pin) == GPIO_PIN_RESET) {
// ID=Low → A-device → ホストモード
tusb_init(); // TinyUSBをホストモードで初期化
} else {
// ID=High → B-device → デバイスモード
tusb_init(); // TinyUSBをデバイスモードで初期化
}
}
// ホストモード:USB MSC(マスストレージ)でUSBメモリ読み取り
void host_task(void) {
if (tuh_msc_mounted(0)) {
// USBメモリがマウントされた
uint8_t buf[512];
tuh_msc_read10(0, 0, buf, 0, 1); // セクタ0読み取り
}
}
// デバイスモード:CDC仮想シリアルポート
void device_task(void) {
if (tud_cdc_available()) {
uint8_t buf[64];
uint32_t count = tud_cdc_read(buf, sizeof(buf));
tud_cdc_write(buf, count); // エコーバック
tud_cdc_write_flush();
}
}
TinyUSBでのOTGデュアルロール実装
// tusb_config.h
#define CFG_TUH_ENABLED 1 // ホスト機能有効
#define CFG_TUD_ENABLED 1 // デバイス機能有効
// ホストクラス定義
#define CFG_TUH_HUB 1
#define CFG_TUH_CDC 1
#define CFG_TUH_MSC 1
#define CFG_TUH_HID 4
// デバイスクラス定義
#define CFG_TUD_CDC 1
#define CFG_TUD_MSC 1
#define CFG_TUD_HID 1
用途・ユースケース
USB OTGが使われる場面:
- スマートフォン→USBデバイス接続: スマートフォンにUSBメモリ・ゲームコントローラ・USBオーディオを接続(Android OTG)
- 産業用ハンドヘルド機器: 検査端末がバーコードリーダーやUSBプリンターを直接制御(ホストモード)しつつ、上位PCにデータを転送(デバイスモード)
- カメラ・医療機器: デジタルカメラがPCのデバイスとして動作しつつ、プリンターのホストにもなれる(PictBridge)
- 開発・デバッグ: マイコン開発ボードがデバッグ時はデバイスモード(シリアルコンソール)、本番時はホストモード(USB HID制御)で動作
- 充電器・電源管理: USB PDコントローラとOTGを組み合わせてモバイルバッテリーの充電制御を実装
実装・開発のポイント
IDピン検出とモード切り替え
実装上の重要なポイントは、IDピンの変化を確実に検出してモードを適切に切り替えることです:
// IDピン割り込み検出でOTGモード切り替え
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
if (GPIO_Pin == USB_ID_Pin) {
if (HAL_GPIO_ReadPin(USB_ID_GPIO_Port, USB_ID_Pin) == GPIO_PIN_RESET) {
// A-device(ホスト)モードへ切り替え
usb_switch_to_host_mode();
} else {
// B-device(デバイス)モードへ切り替え
usb_switch_to_device_mode();
}
}
}
電源管理(VBUS制御)
ホストモードでは5V VBUSを接続デバイスに供給する必要があります。多くのOTGコントローラはVBUSスイッチICを外付けし、GPIOで制御します:
// VBUS電源供給のON/OFF(ホストモード時)
void usb_vbus_enable(bool enable) {
HAL_GPIO_WritePin(USB_VBUS_EN_PORT, USB_VBUS_EN_PIN,
enable ? GPIO_PIN_SET : GPIO_PIN_RESET);
}
USB Type-Cコネクタ使用時の注意
USB Type-Cコネクタを使う場合、CC1/CC2ピンのプルアップ/プルダウン処理が必要です。多くのマイコンには内部でCC処理するUSBC PHYが統合されていますが、ない場合はUSBC CCコントローラIC(FUSB302等)を外付けします。
他技術との比較
USB OTG vs 標準USB
標準USB(ホストとデバイスが固定)はシンプルですが柔軟性がありません。USB OTGを使うことで1つのUSBポートを多目的に使えますが、実装の複雑さが増します。組み込み機器でホスト・デバイス両方の機能が必要な場合にOTGは有効です。
USB OTG vs USB Type-C DRP
USB Type-CのDRP(Dual Role Port)はOTGと似た概念ですが、より高速な速度(USB 3.x/USB4)とPD(電力供給)のネゴシエーションも含む新しい仕組みです。将来的にはType-C DRPがOTGの役割を引き継ぐと考えられています。