圏9研究所 工作室

圏9研究所の開発情報資料など

STM32F411 BlackPill USB Speaker ISO(2)アイソクロナス転送

アイソクロナス転送の詳細

1.エンドポイント
1)仕様書
 Universal Serial Bus Device Class Definition for Audio Devices Release 1.0 March 18, 1998
 4.6 AudioStreaming Endpoint Descriptors

2)受信用エンドポイント Audio Data Endpoint Descriptor
 アイソクロナス転送タイプに変更 bmAttribures = 0x05

3)返信用エンドポイント Isochronous Synch Endpoint Descriptor
 追加
 ・フィードバック周期を bRefreshで設定する

2.フィードバック仕様
1)仕様書
 Universal Serial Bus Specification Revision 1.1 September 23, 1998
 5.10.4.2 Feedback

2)フィードバックデータ
(1)フィードバックデータ Ff
 An asynchronous sink provides feedback to an adaptive source by indicating accurately what its desired data rate (Ff) is, relative to the USB SOF frequency.

 USB SOF 周波数(ホスト側1kHz)に対して必要なデータ レート (Ff サンプル数) 

(2)Ff値データフォーマット
 Because the maximum integer value is fixed to 1,023, the 10.10 number will be left- justified in the 24 bits, so that it has a 10.14 format.

 固定2進小数点 24ビット(3バイト)10.14 形式

3)Ff値返信
 Isochronous transfers are used to read Ff from the feedback register. The desired reporting rate for the feedback should be 2^(10-P) frames. Ff will be reported at most once per update period. 

 P値による周期で更新
 エンドポイント bRefresh = (10-P)

4)ホスト側の処理
 It is possible that the source will deliver one too many or one too few samples over a long period, due to errors or accumulated inaccuracies in measuring Ff. 

 サンプル数を±1して配信

 

3.フィードバック値の例
 わかりやすい例としてUSB SOF周波数を基準とした計算例

1)フィードバックデータ Ff
(1)計算例設定値
 サンプリング周波数            48,000[Hz]
  USB SOF                 1,000[Hz]
 デバイス側周波数            48,048[Hz]
  ホスト側を基準として計測
  デバイス側が速い場合

(2)Ff 計算式
 デバイス側が速いのでサンプル数48より多く必要
  Ff = 48048/48000 * 48 = 48.048
  fs = Ff * 1000
  Ff 整数部 = fs / 1000
  Ff 小数部 = fs % 1000

(3)10.14形式変換 24ビット(3バイト)データ rate
 rate=(((fs / 1000) << 14)|((fs % 1000) << 4));

 

4.実装するフィードバック値計算
 計算例ではわかりやすいように周波数比で計算した
 実際は受信データ数とDAC送出データ数が同期しないといけない
 受信データ数とDACデータバッファポインタ位置の位相差でフィードバック値を計算する

1)同期イメージ

2)フィードバック値算出 USBD_AUDIO_dataOut()毎処理
・ホストから送信されたデータ数を基準とするためデータパケット受信処理に合わせて算出する
・更新周期はP値で設定した周期毎とする
・フィードバックが発散しないように制限を設けておく

タイミング

名称[単位]

内容

処理

毎回

ofs_packet[byte]

USBD Packet data offset

USBD側オフセット

USBD Packet data 数を累計

15360で正規化

4回毎

P:4msec

ofs_dac[word]

DAC側オフセット

DMA転送残数を取得し算出

ofs_diff[byte]

バッファ位相差

 バッファ中央値を基準に

 ±振り分ける

ofs_diff = ofs_packet - ofs_dac * 4

if (ofs_diff < -15360/2)    ofs_diff = ofs_diff + 15360;

if (ofs_diff > 15360/2)     ofs_diff = ofs_diff - 15360;

fs

フィードバック値

fs - ofs_diff * 48000 / 15360

fs基準値 48000

fs値制限 48000±750

 

5.フィードバック値返信タイミング
・お手本にならってタイミングを合わせる
・tx_flag により返信状況を管理する

1)返信処理一覧

関数

tx_flag

処理

USBD_AUDIO_DataIn()

0

tx_flag = 0;

USBD_AUDIO_IsoINIncomplete()

0

FNSOF値入手

tx_flag = 0;

エンドポイントフラッシュ

USBD_AUDIO_SOF()

1

FNSOF値入手

 if IsoINIncomplete()FNSOFbit 0同じ:

  フィードバック値返信

  tx_flag = 1;

2)FNSOF EVEN/ODD対策
・STM32F411内臓のUSBインターフェースでは受信SOFフレーム番号の偶数奇数位相を合わせないと返信できない
  FNSOF:Frame number of the received SOF
  OTG_FS_DSTS    Bits21:8
・返信できなかった場合 USBD_AUDIO_IsoINIncomplete()が呼ばれるので位相合わせ処理を行う

参考資料

community.st.com

 

6.フィードバック収束状況
 ・1sec程度で収束する
 ・収束値は計算基準値の約2倍
  計算基準値:48000 * ±0.5%= ±240
  実測値: 約±500

 

7.データハンドリング処理
 USBで受信したデータをデコードしバッファを介してDACに転送する
 ・80パケット毎にUSB受信バッファに蓄えたデータを処理する
 ・デコードしてDACバッファに格納する
 ・DMAでPWM DACへ転送(DMA_CIRCULAR)
 ・STM32CubeIDE MXのMiddlewareが生成する同期関数
  USBD_AUDIO_Sync(), TransferComplete_CallBack_FS(), HalfTransfer_CallBack_FS() は使用しない
 ・再生、停止処理は前回と同じ

 

8.解説
・P値はお手本の値を基にフィードバック収束の状況を見て決定
・フィードバック制限値はフィードバック収束値と偏差によって決める
 フィードバック制御可能な偏差許容値は ±1/48=±2.08% at 48kHz
・フィードバック収束状況はホストにより異なると思われる
・USB SOF周波数はTIM2_ITR1に接続して計測できる
 RM0383 Reference manual STM32F411xC/E advanced Arm®-based 32-bit MCUs

次はSTM32CubeMX設定