PSoC5LP Prototyping Kitで作るUSBオーディオI/F(I2S出力対応) その2

 前回、I2S用のビットクロックを作ろうとして、コンデンサと抵抗を外付けしてVCO(Voltage Controlled Oscillator)を作りましたが、今回はそれを分数分周器に置き換えました。そのため、アンプやI2S DAC以外の外付け部品は要らなくなりました(*´▽`*)

ソースはこちら


ちょっと温度が変化したり指で触ったりするだけで周波数が変わっちゃう”なんちゃってVCO”と違い、安定した入力クロックを好きに分周できるので、
  1. 最初に、入力クロックがきっちり正しいと仮定して分周比を計算
  2. その分周比でUSBホストからのSoF(Start of Frame)の到着間隔(1ms)を基準に、実際に出力されたパルスをカウント
  3. カウント結果を基に誤差を修正。出力周波数は分周比に完全に比例するので、修正値の計算も簡単!
ということで、PC側で再生デバイスのサンプリングレートを変更しても、即座に追従できるようになりました・・・おぉぅ・・・(゜ロ゜) 
(PCでサンプリングレートを変更したときのファンファーレがうるさくてすみません。。。)

生成しているビットクロックの周波数変動も殆ど無く、今まで上下にゆらゆら揺れていた再生バッファの溜まり具体もほぼ横一直線ヽ(´▽`)ノワーイ

分数分周器(Fractional Divider)

 分周器と言えば入力されたクロックの整数分の1の周波数を作るものが一般的ですが、例えば入力クロックの3/5とか5/11に分周できれば、非整数倍の周波数を作れます。しかも、分母に与える数を大きくするだけで、簡単に精度が上がります。分母を32bitにすれば43億分の1ですよ奥様!ただし、例えば分周比3/5なら「入力クロックのパルスを5回に3回だけ通過させ、残りの2回は遮断する」という動作になるため、クロックが歯抜けになりジッタが増えます。なので、オーディオ用のクロックとしてはよろしくないんじゃないかと思って避けてたのですが・・・試してみたところ、私の耳ではジッタが生じてるのかどうか全然分かりませんでした(゜◇゜)
まぁよく考えてみれば、I2Sのビットクロックはだいたい3MHz(44.1kHz時)~6MHz(96.0kHz時)なので、それがたかだか1クロック分前後しても分からないですよねー(´・ω・`)

分数分周器の作り方

 分数分周器を作るには、X回にY回の割合でヒットするIF文を作れればOKです。そうなると「(0,0)から(100,30)まで線を描画したければ、横に100ドット移動する間に、縦に(なるたけ均等に)30ドット移動すればいいじゃない!」という、ブレゼンハムさんの直線描画アルゴリズムを思い出します。なみに「PUれぜん」じゃなくて「BUれぜん」です。)オリジナルのアルゴリズムは真の直線との誤差が少なくなるように工夫されているようですが、簡略化すると、count=0と初期化しておいて、入力クロックの1パルス毎に

if ( (count+=Y) >= X) {
 count -= X;
 出力をhighにする;
} else {
 出力をlowにする;
}

とすればよさそうです。ね、簡単でしょう?byボブ・〇ス

・・・

いやいや、いくらアルゴリズムは簡単でも、CPUでクロック毎に処理なんてできるわけないやろー!(ビシッ

うん、そうですね(´・ω・`)

自分で論理回路部品が作れちゃうUDB!

ということで、1クロック未満で処理できるように、PSoCのUDB(ユニバーサルデジタルブロック)を使ったカスタムコンポーネントとして作りましたヽ(´▽`)ノ  

PSoC5LPにはUDBが24個あって、それぞれのUDB毎にちょっとした論理回路を作れるPLD(Programmable Logic Device)と、簡単な数値計算ができるデータパスというものがあるようでした。今回は足し算、引き算とかの数値計算をするので、練習を兼ねてデータパスを使う方法で作ってみました。

データパスを作る方法も、(1)Datapath Configuration Toolで作る方法と、(2)PSoC Creator内蔵のUDBエディターで作る方法があるようなのですが、ドキュメントを読むと(2)のUDBエディターのほうが簡単でオススメのようだったので、こちらで作りました!右上の緑色の枠に8種類の演算動作を定義しておいて、左上のINSTR_ADDR[0]~[2]の3ビットで、この8種類のうちどれを実行するのかをセレクトする、という仕組みみたいでした(*´▽`*)
 

見た目はこんな感じにしました(≧∇≦)b
それっぽい!


そして、これを組み込んだものがこちらになります(●´ω`●)

おわりに

PSoCのカスタムコンポーネント初めて作ってみましたが、自分で好きな論理回路を作れるのは楽しいかも(*´▽`*) FPGAってこういう感じなんですかねー@@;でも、クロック回りとかまだよくわかってないので、もうちょっと勉強したいと思います(〃'▽'〃)

コメント

このブログの人気の投稿

ESP32: Visual Studio CodeでESP-IDFを使う(Windows編)

PSoC5LP Prototyping Kitで作るUSBオーディオI/F(I2S出力対応)

ESP32: Visual Studio CodeでESP-IDFを使う(Linux編)