HOME
  Security
   Software
    Hardware
  
FPGA
  CPU
   Android
    Raspberry Pi
  
nLite
  Xcode
   etc.
    ALL
  
LINK
BACK
 

2022/07/17

USBの通信プロトコルを勉強する USBの通信プロトコルを勉強する

(今まで漠然としていた USBデバイスの通信方法を理解します)

Tags: [FPGA], [電子工作], [Xilinx XC6SLX9], [FPGA 2022]




● USBの信号仕様、通信プロトコルを勉強する

 今まで漠然としていた USBデバイスの通信方法を理解します。

 今回は USBの
 ・信号仕様
 ・通信プロトコル
 の両方を勉強します。

● AVRマイコンの GPIOを操作して自前で USB HOST機能を実装する

 いしかわきょーすけさんの製作記事。
USB ホスト倶楽部 - asahi net

 当時はこの AVRの実装をマルパクして Philips LPC2106の ARMマイコンに移植しました。

2004/03/16
OLIMEX LPC-H40(Philips LPC2106)
OLIMEX LPC-H40(Philips LPC2106)

  MOTHER BOARD for LPC-H40(LPC-H2106) and ASM Sample Program.

 しかし、その当時は単純に移植しただけで USBの通信プロトコル等は理解しませんでした。

 ビット送受信のタイミングとビット送受信のマイコンチップの違い部分だけを変更したら動いたので。

 今回は、プログラムの内容を読んで実装から USBの通信を理解します。

 いしかわさんのプログラムの内容と下記の資料が USBの通信プロトコルの理解に役立ちました。

USB Human Interface Devices

USBspcs.pdf (703KB) 1.0D 14/6/10 USB概説

TECH_I Vol.30~「改訂新版 USBハード&ソフト開発のすべて」

USB の基礎知識 Interface 2007年 1月号

 USBの通信速度
 High Speed - 480Mbits/s USB 2.0
 Full Speed - 12Mbits/s USB 1.1
 Low Speed - 1.5Mbits/s USB 1.1

 USB Low Speedは USBデバイスの D-にプルアップ抵抗(1.5kΩ)
 USB Full Speed USBデバイスの D+にプルアップ抵抗(1.5kΩ)
 (これでデバイスの接続を確認できる)

 USB Host側は D+と D-に大きいプルダウン抵抗(15kΩ)
 (デバイス側のプルアップ抵抗が勝つ様にプルダウン側の抵抗値が大きい)

 USBの通信は NRZI符号化データ
 (0の時は電位を反転し、1の時は変化させない)

 USBの通信で 1が 6個連続した場合は 0を入れる(ビット・スタッフィング)
 (信号の状態が変化しないからタイミングのズレが発生するから)

 USBの信号線の状態
StateLow speedFull speed
JD+ = L、D- = H左記の逆
KD+ = H、D- = L左記の逆
SE0D+ = L、D- = L左記と同じ
SE1
通常は発生しない
D+ = H、D- = H左記と同じ

SyncKJKJKJKK(00000001)
EOPSE0、SE0、J
USB (Communications)

 そして、PicoBlazeでの実装を試します。(ARMマイコンに移植した時と同じくマルパク)

2022/07/01
Xilinxの FPGA Spartan-6で PicoBlaze KCPSM 8 ビット マイクロコントローラーを動かす!
Xilinxの FPGA Spartan-6で PicoBlaze KCPSM 8 ビット マイクロコントローラーを動かす!

  PicoBlaze KCPSM6 in Spartan-6 with ISE WebPack


●いしかわきょーすけさんの AVR 用 USB マウス/ゲームパッド接続ファームウェア

softusbh2313.lzh
 の
usbh2313.asm
 を読み進めます。

 わかりやすいプログラムだー!

 AT2313の AVRマイコンを 12MHzで動かして 8clockで USBの 1bitを送受信しています。
 12MHz / 8clock = 1.5Mbps USB Low Speed
 1bit = 66.67ns

●ポート定義
;	AVR Port Assign List

;	PortD
;	      bit2  USB BUS D+
;	      bit3  USB BUS D-

●変数
	.def	icount		= r19 割込みカウンタ 10回ループ
	.def	connect		= r20 USBデバイスの接続状態 0 = 未接続、1 = 接続中
	.def	tcount		= r21 割込みタイマーで 1ms毎に +1する

	.equ    INTERVAL	= 10	; Interrupt Inverval(ms)(1msを 10回ループ)

	rjmp	TIM0_OVF	; Timer0 Overflow Handler 1ms毎の割込みタイマー

● USBの送信データをハードコードしている
 先頭は SYNC 8bit長
 最後は EOP 4bit長

DATA_EOP:
	.db		0x02, 0x02, 0x08, 0x08 EOP = SE0,SE0,J,J

DATA_PKT_ACK:
	.db		0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x04 SYNC = KJKJKJKK
	.db		0x08, 0x08, 0x04, 0x08, 0x08, 0x04, 0x04, 0x04 ACK = 01001011
	.db		0x02, 0x02, 0x08, 0x08 EOP = SE0,SE0,J,J

DATA_PKT_SETUP_TOKEN_0:
	...
●プログラムの開始
MAIN:
 AVRマイコンを初期化する

--- メインループ 1ms毎に実行 ---
MAIN_LOOP:
 1ms待つ

 connect変数が「未接続」なら MAIN_DISCONNECTにジャンプ

MAIN_CONNECT:
 USBの D-端子が Lowなら MAIN_DISCONNECTINGにジャンプ

 EOPを送信する(10回送信する)
 icountを +1して INTERVAL(10)に成るまで MAIN_LOOPにジャンプ

 DATA_PKT_DATA_IN_1_1を送信する
 USBパケットを受信する
 受信した内容が NAK/STALLなら MAIN_LOOPにジャンプ
 (簡易的に D-信号線の PID byteの LSB(PID0)のビットだけをチェックして、1の場合に NAK/STALLと判定している)

 DATA_PKT_ACKを送信する

MAIN_PROCESS:
 上で受信したパケットの内容を本格的に解析する

 USB_CONVを呼び出して NRZI符号化データをバイトデータに変換する

 バイトデータをイイ感じに解析して LED表示やデバグ用に通信出力を行なう

 MAIN_LOOPにジャンプ

MAIN_DISCONNECTING:
 USBデバイスが切断したかも?の時の処理

 LEDを 500ms 全点灯にする

 USBの D-端子が Lowなら connect変数を「未接続」にする
 (USBデバイスの接続状態を再チェックしている)

 MAIN_LOOPにジャンプ

MAIN_DISCONNECT:
 USBデバイスが切断中の時の処理

 USBの D-端子が Lowなら MAIN_LOOPにジャンプ

MAIN_CONNECTING:
 USBデバイスが接続したかも?の時の処理
 (上記の MAIN_DISCONNECTから処理が移ってくる)

 LEDを 500ms 全点灯にする

 USBの D-端子が Lowなら MAIN_LOOPにジャンプ

 LEDを全点灯にする

 USBの D+端子と D-端子を出力モードにする
 USBの D+端子と D-端子を Lowにする

 10ms待つ

 USBの D+端子と D-端子を入力モードにする

MAIN_CONNECTING_AFTER_RESET:
 1ms待つ
 EOPを送信する(40回送信する)

 DATA_PKT_SETUP_TOKEN_0を送信する

 DATA_PKT_SET_ADDRESS_1を送信する
 USBパケットを受信する(受信した内容は破棄している)

MAIN_CONNECTING_SET_ADDRESS:
 DATA_PKT_DATA_IN_0_0を送信する
 USBパケットを受信する
 受信した内容が NAK/STALLなら MAIN_CONNECTING_SET_ADDRESSにジャンプ
 (簡易的に D-信号線の PID byteの LSB(PID0)のビットだけをチェックして、1の場合に NAK/STALLと判定している)

 DATA_PKT_ACKを送信する

 1ms待つ
 EOPを送信する

 DATA_PKT_SETUP_TOKEN_1を送信する

 DATA_PKT_SET_CONFIGURATION_1を送信する
 USBパケットを受信する(受信した内容は破棄している)

MAIN_CONNECTING_SET_CONFIG:
 DATA_PKT_DATA_IN_1_0を送信する
 USBパケットを受信する
 受信した内容が NAK/STALLなら MAIN_CONNECTING_SET_CONFIGにジャンプ
 (簡易的に D-信号線の PID byteの LSB(PID0)のビットだけをチェックして、1の場合に NAK/STALLと判定している)

 DATA_PKT_ACKを送信する

 LEDを全消灯にする
 connect変数を「接続」にする
 MAIN_LOOPにジャンプ

USB_SND_ROM:
 USBに指定のビット長で指定の内容を送信するサブルーチン
 1bitの送信処理を 8clkで実装しており、1.5Mbpsに成る様にしている。

左側のカッコの数字が命令のクロック数
USB_SND_ROM_LOOP:
[3]	lpm					; r0 = (Z)
[1]	inc		ZL
[1]	out		PORTD, r0
[1]	dec		arg1
[2]	brne	USB_SND_ROM_LOOP
USB_SND_ROM_LOOPEND:

USB_RCV:
 USBから EOPに成るまで受信するサブルーチン
 1bitの受信処理を 8clkで実装しており、1.5Mbpsに成る様にしている。

左側のカッコの数字が命令のクロック数
USB_RCV_RCVLOOP:
[1]	in		arg1, PIND
[2]	st		Z+, arg1
[1]	andi	arg1, 0x0C
[1]	breq	USB_RCV_ENDLOOP
[1]	dec		tmp1
[2]	brne	USB_RCV_RCVLOOP
USB_RCV_ENDLOOP:

USB_CONV:
 下記の処理を行なうサブルーチン

USB_CONV_NRZI:
 NRZI符号化データを 0/1の情報にビット変換する

USB_CONV_BYTE:
 0/1のビット情報をバイトデータに変換する(1が 6ビット連続した時の処理も行なう)

HEX_TO_CHAR:
CONSOLE_PUT_CHAR:
CONSOLE_PUT_HEX1:
CONSOLE_PUT_HEX2:
CONSOLE_PUT_HEX4:
 デバグ用のイイ感じの通信出力

TIM0_OVF:
 タイマー割り込みの処理
 tcountを +1する

DELAY_1MS:
 1ms待つ
 (tcountの値が変化するまで待つ)

DELAY_100MS:
 100ms待つ(上記を 100回呼んでいる)



Tags: [FPGA], [電子工作], [Xilinx XC6SLX9], [FPGA 2022]

●関連するコンテンツ(この記事を読んだ人は、次の記事も読んでいます)

USB HOST機能を FPGAに実装する方法、FPGAの GPIOに USB HIDデバイスを接続したい!!
USB HOST機能を FPGAに実装する方法、FPGAの GPIOに USB HIDデバイスを接続したい!!

  FPGAに USB HOST機能を実装して Low Speedの USB HIDデバイスを接続するのら

USB HOST機能が欲しいのでワンチップマイコンの GPIOで USB HOST機能を実現する
USB HOST機能が欲しいのでワンチップマイコンの GPIOで USB HOST機能を実現する

  FPGAに USBデバイスを接続したいのですが、USB HOSTの通信を実装できないので困っています

OLIMEX LPC-H40(Philips LPC2106)
OLIMEX LPC-H40(Philips LPC2106)

  MOTHER BOARD for LPC-H40(LPC-H2106) and ASM Sample Program.

AMD Xilinxの FPGA Spartan-6 XC6SLX16のボードを買ってアーケード ゲームを動かす
AMD Xilinxの FPGA Spartan-6 XC6SLX16のボードを買ってアーケード ゲームを動かす

  ALINX AX309 XC6SLX9の中華クローンの XC6SLX16版を購入しました

FPGA Spartan-6 XC6SLX16でファミコンを動かす!
FPGA Spartan-6 XC6SLX16でファミコンを動かす!

  Xilinx FPGA Spartan-6 XC6SLX16 NES clone in ALINX AX309

Xilinxの FPGA Spartan-6で PicoBlaze KCPSM 8 ビット マイクロコントローラーを動かす!
Xilinxの FPGA Spartan-6で PicoBlaze KCPSM 8 ビット マイクロコントローラーを動かす!

  PicoBlaze KCPSM6 in Spartan-6 with ISE WebPack

パソコンと USBで接続して使用する USB 8ch 24MHzロジック アナライザ
パソコンと USBで接続して使用する USB 8ch 24MHzロジック アナライザ

  Cypress EZ-USB FX2LP CY7C68013A使用で内部のバッファ ICに LVC245Aを使用のチョイ性能アップ版




[HOME] | [BACK]
リンクフリー(連絡不要、ただしトップページ以外は Web構成の変更で移動する場合があります)
Copyright (c) 2022 FREE WING,Y.Sakamoto
Powered by 猫屋敷工房 & HTML Generator

http://www.neko.ne.jp/~freewing/hardware/usb_protocol/