STM32F446を使ったUSB High SpeedのUVCの続きです。VGAの画面をUVCの非圧縮 YUV形式で送ろうとすると 640*480*2 = 61440バイト/フレームのデータ送信が必要となります。High speedのアイソクロナス転送ではトランザクションあたり1024バイトを送ることができますので、1フレームを送るには614400/1024 = 600トランザクションが必要です。1マイクロフレームに1トランザクションしか使わなければ 8000/600 = 13.3フレーム/秒までしか送れません。これ以上のフレームレートで送るためには、1マイクロフレームで複数回の転送が必要になります。
High speedでは1マイクロフレームで3回までのアイソクロナス転送が可能ですが、まずは2回での動作確認をしてみます。準備としてはCofnig Descriptorを変更してやります。High speed対応のエンドポイントでは、次のようにwMaxPacketSizeで1回あたりの転送量とマイクロフレームあたりの転送回数を指定します。
これでDataInのハンドラが呼ばれた時に最大2048バイトを転送してみたのですが... 画面は真っ黒なままで何も表示されません。前回と同じようにDataInのハンドラが呼び出された回数を確認してみると...
ダメダメです。マイクロフレームに2回どころか、2マイクロフレームに1回も送れてないじゃないですかぁ。そこで送信のコードを追いかけててみたところ、stm32f4xx_ll_usb.c の USB_EPStartXfer()に次のコードを見つけました。
DIEPTSIZレジスタのMULフィールドには1マイクロフレームで送る転送数をセットしなければいけないのですが、これでは常に1回しか送らないことになってしまいます。この部分を修正したとろろ、ちゃんと2倍の速度で動くようになりました。
続いて3倍に挑戦してみたのですが、今度は全く動かず。DataInが1回しか呼び出されません。転送終了の割り込みがかからないということでしょうか?FIFOのサイズ設定を変更してみたりとかもしてみたのですが、やはり3パケットを送ることができません。もともと1パケットしか送れないコードだったくらいですから、これまでアイソクロナス転送で複数パケットを送るような使い方をされておらず、全くバグ取りができていないということでしょうか?
High speedでは1マイクロフレームで3回までのアイソクロナス転送が可能ですが、まずは2回での動作確認をしてみます。準備としてはCofnig Descriptorを変更してやります。High speed対応のエンドポイントでは、次のようにwMaxPacketSizeで1回あたりの転送量とマイクロフレームあたりの転送回数を指定します。
これでDataInのハンドラが呼ばれた時に最大2048バイトを転送してみたのですが... 画面は真っ黒なままで何も表示されません。前回と同じようにDataInのハンドラが呼び出された回数を確認してみると...
ダメダメです。マイクロフレームに2回どころか、2マイクロフレームに1回も送れてないじゃないですかぁ。そこで送信のコードを追いかけててみたところ、stm32f4xx_ll_usb.c の USB_EPStartXfer()に次のコードを見つけました。
if (ep->type == EP_TYPE_ISOC) { USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT); USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1 <
DIEPTSIZレジスタのMULフィールドには1マイクロフレームで送る転送数をセットしなければいけないのですが、これでは常に1回しか送らないことになってしまいます。この部分を修正したとろろ、ちゃんと2倍の速度で動くようになりました。
続いて3倍に挑戦してみたのですが、今度は全く動かず。DataInが1回しか呼び出されません。転送終了の割り込みがかからないということでしょうか?FIFOのサイズ設定を変更してみたりとかもしてみたのですが、やはり3パケットを送ることができません。もともと1パケットしか送れないコードだったくらいですから、これまでアイソクロナス転送で複数パケットを送るような使い方をされておらず、全くバグ取りができていないということでしょうか?