2020年5月14日木曜日

STM32でDCCを作る方向で (13) STM32CubeMXが吐いたUAC1.0 sampleについて

前回は、USB Audio Class 1.0のsample codeをSTM32CubeMXに吐き出させた.

それ以来sample codeを眺めて過ごす日々である.わたしはsoftwareで飯を食った技術者ではないので、codeを読む能力は低いし、CPU周りのsystemの知識も少ない.

そのsample codeをSTM32に焼いてwin10に接続する.するとwin10のplug&playシーケンスは正常にUSBデバドラの組み込みを完了する.しかし、音楽再生してもaudio streamがUSBを飛んで行かない.windowsのlogを読む知識が無いので何が悪いのか判らない.

windowsでの検討は棚上げにして、Linuxに接続してみる.Linuxだとdmesgにいろいろなmessageが出るので判りやすい.音楽再生するとaudio streamがブシブシ飛ぶ.しかし音は出ない.

その辺の事情が分かったので今回はsample codeについて書くことにしよう.

INDEXページへ


【device setup処理】
(1)USB devceのsetup処理がどうなっているか?

hostからsetup dataが来ると、割り込みでここに飛んでくる.
    ファイル名:usbd_conf.c        関数名:HAL_PCD_SetupStageCallback()
ここにbreak pointを仕掛けてdebuggerで追いかければ動作を追えるだろう.

例えば、Get Descriptorの場合は、何か所か経由して最終的な飛び先は、
    ファイル名:usbd_ctlreq.c        関数名:USBD_GetDescriptor()
この中でさらに様々なdescriptorへと分岐してhostへの返信が成される.

(2)肝心のAudio Classのsetupはどういう経路で分岐するのか?

setup command parseの過程で一旦はInterface requestの処理関数へ飛んで行く.
    ファイル名:usbd_ctlreq.c        関数名:USBD_StdItfReq()
この関数内からUSBD_AUDIO_Setup()へ飛ぶ.
     pdev->pClass->Setup(pdev, req)    →USBD_AUDIO_Setup()
USBD_AUDIO_Setup()の中でInterface関係の各種処理がなされる.Audio Class routine中でStandard requestとAudio Class処理がされる.微妙なかんじ.

いろいろと解析した印象では、setup処理についてはsample codeそのまんまでちゃんと動いているようだ.ただし、USB Audio Class 1.0のFull Speedだがね.


【audio stream data処理】
(3)HOSTから飛んでくるaudio streamがどう処理されているか?

audio stream packetが来る毎にここへ飛んでくる.DACへ出力する起点だ.
    ファイル名:usbd_audio.c        関数名:USBD_AUDIO_DataOut()

この関数の中身を覗いてみる.

    haudio->wr_ptr += AUDIO_OUT_PACKET;
AUDIO_OUT_PACKET=176である.stream data pointerを176増やす.
packet sizeが176bytesであるらしい.
176bytesという数字は、176/2bytes/2ch=44sample →1mSec と計算される.
isochronous転送が1mSec毎なのだろう.descriptorにも1mSecと書かれている.

    if (haudio->wr_ptr == AUDIO_TOTAL_BUF_SIZE)
AUDIO_TOTAL_BUF_SIZE=14080である.
176の80倍が14080である.つまり80mSec分のstream dataが溜まるまで待ってから以下の操作を行う.

   pdev->pUserData->AudioCmd(&haudio->buffer[0],,,,,);
この関数がDAC出力の核心である.

AudioCmd()を覗く.
AUDIO_AudioCmd_FS(uint8_t* pbuf, uint32_t size, uint8_t cmd){
  switch(cmd)  {
    case AUDIO_CMD_START:
    break;
    case AUDIO_CMD_PLAY:
    break;
  }
  return (USBD_OK);
}
あらまぁ、、、空っぽだ.これじゃぁstreamを捨てている.音が出るわけがない.
DACへ出力するためのroutineを自分でここに書かなくちゃいけないってことね.


ここまで理解するのに5日かかった.

かしこ

0 件のコメント:

コメントを投稿