2015/05/31

Logitech G400 のデータパスを解析してみる

--------------------------------------------
2015/05/31 初出
2015/06/04 rafa様の関連記事を追記
--------------------------------------------
rafa様の記事(-rafalog: 鼠とオシロ)に便乗する形でLogitechの名機であるG400のデータパスをマイコンを使って覗いてみました.

ハードウェア (Hardware)

ハードはこんな感じに,ポリウレタン線でMISO,MOSI,SCLK,SSをセンサのピンから引き出します.

基盤が載っている筺体が違うことに気がついた方は相当の鼠ソムリエですが,コイツです.筺体のデザインに関しては,今まで触った100種以上(店頭で触ったものも含む)のマウスの中で最も良いです.
「ワクワクしながら家に持ち帰ったら,センサー性能と実装に絶望した」という悲しい過去があります.事務用マウスも一応ウォッチしていると良いことがあったりなかったりですね.

極めて良い筺体形状なので,一年ほど前にG400の基盤を無理やり載せました.その作業内容や顛末とかも記事にすると面白そうですが,「ひたすら筺体と基盤を弄って物理的・電気的整合性をとるだけ」という単純作業なので割愛します.基盤にメモが書いてあるのはその時の名残です.

マイコンはいつもの CY8CKIT-042 PSoC® 4 Pioneer Kitを使用します.このキットは色々な所で売っています.(秋月)


ソフトウェアの実装(Software implementation)

IDEは,PSoC Creator  3.0 SP2 (3.0.0.3140)を使用します.コードは全世界に公開できるクオリティに達していないので,「見たい」という奇特な方はご連絡を・・・ということで.
データのキャプチャにはSPI Slave コンポーネントを使用します.このコンポーネントはMaster(MCU)にぶら下がってSlaveとして振る舞います.MCUと本当のSlaveであるセンサ間でのみ通信が行われるので,全バイトデータをキャプチャすればMCUとセンサのやりとりを(理論上は)キャプチャできます.
図のように,2入力(マウス側のMOSI,MISO)をORゲートのコンポーネントで論理和にし,SPI SlaveのMOSIに入力します.SCLKとSSはマウスから引っ張ってきたものをそのまま使用します.このコンポーネントからマウスへのデータ転送は行わない(というよりMasterはG400の基板上のMCUなのでデータを送ると何が起きるか分からない)ので,NC(No Connect)とします.

SPI Slaveの設定はこんな感じにします.

ADNSシリーズはCPHA=1,CPCL=1なのでそのように設定します.ビットレートは1.5Mbpsとします.
もし違うマウスで調べる場合は,対象マウスのMCUからでているSCLKのビットレート調べて,それと同じ値にする必要があります.他の項目はDefaultで問題ありません.

プログラム

プログラムは,MCUかセンサからデータが来たら保存するという事を2000byte分行うだけです.
データレートも見たいので,2000byte分の取得の開始時間と終了時間もTimerを使用してマイクロ秒単位で記録しておきます.
2000/取得にかかった時間 でデータレートを算出できます.


データ (Data Result)

データは本来は2000バイト取得していますが似たようなデータは割愛しています.
もし,特定の条件でのデータが見たいという奇特な方がいらっしゃればコメントして下さい.

データレート(Data Rate)

以下がデータレートの測定結果です.
Stream Read Info ->
Size    :       2000
Start   :       5814 us
End     :       17684 us
Time    :       11870 us ( 12 ms )

Data Rate : 168 Byte/ms

このように,約12msの間に2000Byteをやりとりしていることが分かります.つまり,1msあたり168Byte程度になります.MotionBurstはMCUがセンサに1Byte分の命令を送り,7Byte分のデータを受け取るので,1通信に8Byteのやりとりが発生します.(詳しくはデータシートのMotion Readの項を参照)
これらを勘案すると,MCUはセンサーへ1msの間に複数回アクセスしている可能性が高いと言えます.168/8=21なので,大体20回変位データを取得してるんじゃないの?と考えられます.とりあえず生データを見てみましょう.

2015/06/04追記
rafa様がオシロスコープでRazer Abyssusの解析をしてくださいました.
-rafalog: 初代AbyssusのSPI通信解析
これを見ると,AbyssusはMotion→Delta_X→Delta_Yレジスタの転送をしたところで,NCS(SS)をプルアップして強制的に転送を止めています.確かに,これだと変位のスループットが稼げます.記事によると,Abyssusは1msで6回程度アクセスしているようです.
データシートには「転送後にNCSをHIGHにする必要がある」,とは書いてありましたが「転送中にNCSをHIGHにすれば転送を中断できる」ことには気づきませんでした.ゲーミングデバイスは奥が深いですね.

生データ(Raw Data)

以下から生データになります.前半はマウスが静止している時のもので,後半はマウスを動かしている時のものです.静止時はMOSIのみとMISOのみのものも取りました.

移動中に0x80になっている部分は,Motionレジスタなので7bitが1になっているはずなので,本当は0xf0になります.つまり,データのキャプチャが1Clock分遅れており,データが微妙にずれているという結果になります.もう少しちゃんと書く必要がありますね.

MOSI&MISO (No Motion)

55 50 00 00 00 bd 00 50 00 00 00 0a 01 1f 55 50 00 00 00 50 00 00 00 3d c3 0a 01 1f
55 50 00 00 00 bd 00 50 00 00 00 0a 01 1f 55 50 00 00 00 50 00 00 00 3d c3 0a 01 1f
55 50 00 00 00 bd 00 50 00 00 00 0a 01 1f 55 50 00 00 00 50 00 00 00 3d c3 0a 01 1f
55 50 00 00 00 bd 00 50 00 00 00 0a 01 1f 55 50 00 00 00 50 00 00 00 3d c3 0a 01 1f


MOSI (No Motion)

55 00 00 00 00 00 00 00 00 00 00 00 01 00 55 00 00 00 00 00 00 00 00 00 c3 00 01 00
55 00 00 00 00 00 00 00 00 00 00 00 01 00 55 00 00 00 00 00 00 00 00 00 c3 00 01 00
55 00 00 00 00 00 00 00 00 00 00 00 01 00 55 00 00 00 00 00 00 00 00 00 c3 00 01 00
55 00 00 00 00 00 00 00 00 00 00 00 01 00 55 00 00 00 00 00 00 00 00 00 c3 00 01 00


MISO+Data Offset (No Motion)

※MOSIのデータで1列目のバイトを決めているので,MISOのみのデータは行がずれています.
00 50 00 00 00 3d 00 0a 00 1f 00 50 00 00 00 bd 00 50 00 00 00 0a 00 1f 00 50 00 00
00 50 00 00 00 3d 00 0a 00 1f 00 50 00 00 00 bd 00 50 00 00 00 0a 00 1f 00 50 00 00
00 50 00 00 00 3d 00 0a 00 1f 00 50 00 00 00 bd 00 50 00 00 00 0a 00 1f 00 50 00 00
00 50 00 00 00 3d 00 0a 00 1f 00 50 00 00 00 bd 00 50 00 00 00 0a 00 1f 00 50 00 00


Low Speed (MOSI&MISO)

-----Stream-----
55 50 80 00 fa bd 00 50 80 ff fd 0a 01 1f 55 50 80 00 fd 50 80 00 fb 3d c3 0a 01 1f
55 50 80 00 fc bd 00 50 80 00 fb 0a 01 1f 55 50 80 ff fd 50 80 00 fa 3d cb 0a 01 1f
55 50 80 00 fe bd 00 50 80 00 fa 0a 01 1f 55 50 80 00 fb 50 80 00 fb 3d c3 0a 01 1f
55 50 80 00 fe bd 00 50 80 00 f9 0a 01 1f 55 50 80 00 fc 50 80 00 fb 3d c3 0a 01 1f
55 50 80 00 fd bd 00 50 80 00 fd 0a 01 1f 55 50 80 00 fb 50 80 02 fa 3d c3 0a 01 1f
55 50 80 01 fd bd 00 50 80 00 fc 0a 01 1f 55 50 80 01 fb 50 80 01 fc 3d c3 0a 01 1f
55 50 80 01 f9 bd 00 50 80 01 fc 0a 01 1f 55 50 80 00 fb 50 80 00 fc 3d cb 0a 01 1f
55 50 80 02 fa bd 00 50 80 00 fb 0a 01 1f 55 50 80 02 fc 50 80 01 fb 3d c7 0a 01 1f
55 50 80 02 fb bd 00 50 80 00 fb 0a 01 1f 55 50 80 02 fb 50 80 01 fb 3d c3 0a 01 1f
55 50 80 00 fb bd 00 50 80 03 fa 0a 01 1f 55 50 80 01 fc 50 80 01 fb 3d c3 0a 01 1f
55 50 80 03 fa bd 00 50 80 01 fc 0a 01 1f 55 50 80 01 fb 50 80 00 fc 3d c7 0a 01 1f
55 50 80 03 fa bd 00 50 80 01 fa 0a 01 1f 55 50 80 02 fa 50 80 02 fd 3d cb 0a 01 1f
55 50 80 01 fa bd 00 50 80 03 fb 0a 01 1f 55 50 80 01 fa 50 80 03 fa 3d c3 0a 01 1f
...
-----Stream END-----


Middle Speed (MOSI&MISO)

-----Stream-----
55 50 80 06 1c bd 00 50 80 06 1c 0a 01 1f 55 50 80 07 24 50 80 04 1e 3d c7 0a 01 1f
55 50 80 05 1b bd 00 50 80 04 1d 0a 01 1f 55 50 80 04 1d 50 80 05 26 3d cf 0a 01 1f
55 50 80 02 1e bd 00 50 80 00 1e 0a 01 1f 55 50 80 fe 1c 50 80 04 26 3d c7 0a 01 1f
55 50 80 02 1d bd 00 50 80 00 1f 0a 01 1f 55 50 80 00 1e 50 80 00 1d 3d c7 0a 01 1f
55 50 80 00 28 bd 00 50 80 00 1d 0a 01 1f 55 50 80 ff 1e 50 80 00 1d 3d c7 0a 01 1f
55 50 80 00 29 bd 00 50 80 01 1d 0a 01 1f 55 50 80 fe 1c 50 80 00 1e 3d c7 0a 01 1f
55 50 80 fc 28 bd 00 50 80 01 1f 0a 01 1f 55 50 80 ff 1c 50 80 ff 1c 3d cf 0a 01 1f
55 50 80 fc 1f bd 00 50 80 01 1d 0a 01 1f 55 50 80 fe 1c 50 80 fb 1e 3d c7 0a 01 1f
55 50 80 fc 1e bd 00 50 80 fc 1d 0a 01 1f 55 50 80 fa 27 50 80 fc 1e 3d c7 0a 01 1f
55 50 80 fb 1c bd 00 50 80 fb 1e 0a 01 1f 55 50 80 f8 26 50 80 fa 1d 3d c7 0a 01 1f
55 50 80 fa 1e bd 00 50 80 fa 1d 0a 01 1f 55 50 80 f9 1a 50 80 f7 27 3d c7 0a 01 1f
55 50 80 f9 1c bd 00 50 80 f7 1c 0a 01 1f 55 50 80 f9 1c 50 80 f8 1c 3d cf 0a 01 1f
55 50 80 f4 23 bd 00 50 80 f8 1c 0a 01 1f 55 50 80 f9 1a 50 80 f7 1b 3d c7 0a 01 1f
...
-----Stream END-----


まとめ 

ここからわかったことをまとめます.
  • G400はMotionBurstを使用している
  • 1msの間にセンサから複数回(おそらく10回以上)変位を読んでいる
複数回アクセスは予想通りですね.(G300でもやっていました)
AnkerのマウスもMotionBurstを使っていましたし,ゲーミングマウスでのデータ取得はMotionBurstが基本なのかもしれません.

キャプチャを正確にしてデータが取れたら,さらに分かることが多そうです.なにか分かったら,また記事にしたいと思います.

0 件のコメント:

コメントを投稿