CH559でUSBデバイスを作ってみる。とりあえずマウス

回路

USBデバイスと後々USBホストをしたいのでブレッドボードでは辛いので基板を制作
本当はTVSダイオード付けたりFullSpeed出せるからインピーダンス整合とか考えなければならない気がする


ピン配置の違うAZ1117になってたので違法建築で修正

開発中のデバッグ出力にUARTを使ってて素のCH340で見てたら抜き差し時に謎に逝ってしまった。
今はロボコンで作ったusb-to-uart-v1で見てて特にトラブルなし

プログラム

参考資料:

ディスクリプタのやりとりは知ってるけど、その下の層のパケット単位でのやりとりは無知すぎて結構苦戦しましたが

とりあえずカーソルをくるくる回す嫌がらせデバイスが完成!

と思いきや、windowsに刺すと動かない。デバイスマネージャーにはちゃんとHID準拠マウスって出てくるのに…
まぁwindowsだから動かなくてもしかたないか、とwindowsアンチなので無視することに。
…やっぱり気になるので調査

Wiresharkで通信を覗いてみる

ディスクリプタの受け渡しが終わった後ちゃんとEndpoint 1のINにレポートを要求してレポート返してるけど、なんか合間合間にストールがどうたら言ってる

原因

UEPn_CTRLレジスタのbUEP_R_TOGbUEP_T_TOG、DATA0とDATA1を決めるって書いててなにこれって思って適当に入れてました。
データパケットにはDATA0とDATA1があり交互に送ることでパケットの欠落を検知するとか。
Endpoint0で行われるControl転送は送るデータのうちの最初はDATA0でその次から交互にするので
マウスのレポートは3byteだから一回で終わるのでずっとDATA0でいいと思ってました。
データの区切り関係なくデータパケットを送るたびに切り替えるらしい

つまりDATA0しか送ってなかったのでwindowsは半分くらいパケットをロストしてるとしてレポートを受け取ってもカーソルの動きに反映しなかった?linuxでは動いたけどlinuxのドライバがゆるいのかな?
とりあえず挙動としてはwindowsのほうが正しそう。今回は疑ってごめんね?


bUEP_T_TOGをトグルするようにしたらちゃんとwindowsでもカーソル動きました

あとちょくちょくカーソルが止まる問題とレポートを受け付けない問題がありましたが、
カーソル止まる問題はwiresharkで見るとURB_FUNCTION_ABORT_PIPEと出てました
10msにするとなくなったので多分応答が間に合ってなかったのかな(FPU乗って無いのでsinfとcosfで時間食われてそう)
レポート受け付けない問題は、今回xの変位とyの変位以外送ること無いのでHIDレポートディスクリプタを標準マウスのやつからボタンをもぎ取った形に改変してたら、それがダメだったらしく、ボタンも含めて3byte送れば受け取りました

通信が成り立ってないとき何が起こってるかわからんし、ロジックアナライザ欲しい

最終的なコードはこちら
https://github.com/Netetra/ch55x-template/blob/main/examples/usbd_mouse.c

これ書いてて見つけたけどプロトコルはこれが分かりやすそう
https://avr.jp/user/EC/PDF/USBspcs.pdf