STM32でDCCを作ろう!
INDEXページへ
かれこれ1weekぐらい悶々と、そして鬱々としていた.
1)STM32がhungupしたり、
2)hostのデバドラが黙って停まってたり、
その原因が判らなくてずーっと停滞していたため.
1)STM32がhungupする原因は簡単に推測できた.
内部状況を逐次UART(115200bps)へ出力するようにしていたのだけれど、これが処理をblockしていて、USB setup処理が邪魔されて死んでいた.
UART送信を中止し、logを一旦5kBほどのRAMに蓄積しておいて、暇になったらUARTへ一気に送信するようにして解決.
2)hostが黙って停まるトラブルは原因がさっぱり判らなかった.
hostが何にへそを曲げているのかが判れば解決は簡単なんだけど、windowsはトラブル原因をメッセージしてくれない.
windowsでのdebugは諦めて、Linuxでdebugする.
Linuxのデバドラはエラーメッセージを出してくれる.
usb 2-2: 1:1: cannot get freq (v2): err -32
usb 2-2: parse_audio_format_rates_v2(): unable to retrieve number of sample rates (clock 18)
サンプリング周波数設定がうまく行ってないらしいというのが唯一の手掛かり.
STM32の内部状態をダンプしてみるが、異常は見当たらない.
Linux上でwiresharkを動かして流れるpacketを一つ一つチェックしたら、変なのが見つかった.
hostは384kHzに設定しろとpacket outしている.
しかしSTM32のbufferには、192kHzがpacket inしている →読めてない
これが原因で、hostデバドラが停まっているらしい.
悪いのはわたしだ.STM32 sample codeのUSB受信手順を承知していなかった.
背景を説明すると、、、USBのsetupは8bytesのデータで行われるのが基本であるが、すべて8bytesとは限らない.サンプリング周波数設定などでは、後続の4bytesが384000とか48000のようなサンプリング周波数を直接表現している.
EZ-USBにせよ、STM8SのUSB IPにせよ、setup 8bytesはhardwareがお膳立てして提供してくれる.しかし
後続のN bytesはヒラサカがprogramして読まなくちゃいけない.たぶん他のUSB IPでも同じなんじゃないかな?
問題はこの「後続読みの作法」に在った.
STM32 sample codeの後続読みは2つの手順による.
手順1: N bytes読んでくれと依頼してさっさとexit
USBD_CtlPrepareRx(pdev, pbuf, N);
return;
手順2: 「読めましたハンドラ」で別途待ち受ける
USBD_AUDIO_EP0_RxReady() {
サンプリング周波数処理;
}
つまり、別の場所にある「読めましたハンドラ」で待ち受けてサンプリング周波数処理するようになっている.source code的には1と2は離れ離れである.めんどー
めんどいのはsourcer codeが遠くに在るだけじゃない.待ち受けはサンプリング周波数の他にもいろいろある.mute、volumeも待ち受けなくちゃいけない.だから、待ち受けハンドラに、待ち受け中はFs/mute/volumeのどれなのかをわざわざ伝達してるんだよ.
元受けの電通(手順1)が働かずに、下請けのパソナ(手順2)に丸投げしているような状態だと言えるだろう.
待ち受け禁止のためだけど、めんどー
てなわけで、原因が判ったので明日以降は少しは進むでしょう.
かしこ