FriskSDRプロジェクトはオシレータSi5351Aが動作するようになったところで中断していましたが、ようやく時間が取れるようになったので作業再開しています。I2Sが全二重で動作するようになったので、音が出るようになりました。アンテナを繋げばちゃんとAM放送が聞こえてきます。
今回のプロジェクトではChibiOSを使ってみています。STM32のチップのサポートが充実、USB対応、シェルがある、ペリフェラルの抽象化が適度、等々が魅力です。
ところで、STM32F303でUSBを使うためにはクロックを供給する必須です(HSI:内部RCクロックでは動作しない)。通常はクリスタルを付けるのですが、今回はSi5351Aを載せたので、MCUのクロックとして8MHzをSi5351Aから生成し、MCUに供給するという構成にしています。ところがSi5351Aを初期化するためにI2CでMCUからコマンドを送る必要があります。
このため、起動シーケンスとして、リセット直後RCオシレータ(HSI)で動作している間に、I2Cの初期化とコマンド送信し、クロックが起動したら外部クロック(HSE)に切り替えるという動作をしています。ChibiOSが起動する前に行う必要がありますので、この初期化はレジスタを直接操作して自前でおこないます。一方、起動後はI2Cの制御はChibiOS経由で行います。
F303でUSBを使うため、USBのDPをプルアップ必要があるのですが、基板に入れ忘れた(F072では不要だった)のでリワーク。これでUSBが使えるようになるはずだったのですが、なぜか動作させることができませんでした。果たしてChibiOSのUSBがF303で動作するのか確信が持てなかったので、原因究明のためSTM32F3-Discoveryボードで試してみることにしました。Discoveryボードの良いところは、MCUに直結したUSBコネクタが用意されているので、ハードウェアのミスに悩まなくて済むことと、ChibiOSにDiscoveryボード用の基本的なサンプルがあることです。このサンプルにUSBとCDCを追加して動作確認したところこちらはあっさり動作OKでした。
F303での実績ができたので、もう一度FriskSDRに戻って、いろいろ確認していると、プローブでチェックを繰り返した際に押しつぶされたハンダが延びてQFPの足の間でショートしているのを発見、これを直し、そしてChibiOSを最新にしてみたところ動作OKになりました。
コマンドを追加できるようになれば、試行錯誤が容易になります。まずは、Si5351Aの周波数を設定するコマンドを追加してみます。周波数から分周器の係数を求めるところはちょっと悩みましたが、できてしまえば簡単です。波形をオシロで確認して自在に周波数を設定できていることが確認できました。続いてTLV320AIC3204コーデックを初期化するコードを、mbedでやっていたIQDDSからコピーしてきてクロック設定のみの修正して入れてみたところ、あっさりI2Sの波形が出てくるようになりました。あとはChibiOSのI2Sを調べて、コードで正弦波を発生させてI2Sで送るようにしてみたところ、ちゃんとトーンが出てきました。ここまでは作業が速かったです。自作のボードから最初に音が出るとやはり感動です。
さて、SDRとして動作させるためには、ミキサした信号を取り込みつつ、音を再生する必要がありますから、I2Sを全二重で動作させる必要があります。全二重動作は、STM32F401ではIQDDSで実績があったのですが、あちらはmbedで、しかもSTM32のHALを直接操作して実現していました。
ところがChibiOSを調べてみたところ、残念ながらI2SのFull Duplexには対応していないようなのです。シンボルは定義されているのですが、それを指定するとエラーになるようわざわざプリプロセッサ指定がしてあります。ここで困って、少し方針を考えたのですが、STM32のHALのコードを参考に、ChibiOSを全二重対応させてみることにしました。STM32のI2S Full Duplexはちょっと変なので、できればこのレイヤのコードは触りたくないのですが、仕方ありません。なるべく変更が少なくて済むよう、なんとかコードを追加しました。ちょっと重複が出てしまいましたが、動作させることが最優先にして目を瞑ります。少しデバッグして、無事Full Duplexが動作するようにできました。
まずはループバックのテストとして、キャプチャバッファと再生バッファを共有する構成にして、ADCでキャプチャしたデータを、そのままDACに送り返されるようにします。そうしてスマホ用のマイクを接続して、音が通ることを確認します。
これが確認できたら、ADCのルーティングを変更して、QSDミキサの出力を取り込むようにします。アンテナ代わりにリード線を接続して、Si5351Aの周波数をAM放送の周波数の4倍に設定(ジョンソンカウンタで分周されるため。NHK第一567kHzなら2268kHzに設定する)してみると、これだけであっさりと放送が聞こえてきます。AMの復調をしているわけではないので、音は少しおかしい(周波数シフトしているだけなので、Loの周波数のわずかなずれで、両サイドの側波帯から再生される音が上下逆方向にずれる)のですが、聞き取ることは十分可能です。
Si5351Aの周波数には、ずれがわずかにあります。30ppm程度で十分許容範囲といえばそうなのですが、クリスタルの負荷Cの設定で合わせられるかなと試したところ、6pFの設定だと20ppmほど高い。8pFの設定だと30ppm強低いと、どっちもどっちでした。結局する設定する周波数に係数を乗じて合わせるようにしました。調整量は-20750ppb(part per billion)としました。
PGAのゲイン設定や再生音量の設定コマンドを追加していろいろ試しています。screen /dev/cu.usbmodem401でシリアルターミナルを開くとChibiOSのプロンプトが現れます。helpで追加したコマンドも表示されます。引数を付けてコマンドにいろいろ試せます。強いて不満があるとすると、コマンドヒストリが欲しいところです。
動画です。画面に見えているのはST-Link2ですが、USBも接続されています。コネクタで接続されたスピーカで音が再生されています。
今のところ判明した課題は、
-
TLC320AIC3204にはDCオフセットがあるようで、QSDミキサとの間にカップリングコンデンサを省略したのは拙かった。PGAのゲインを上げるとオフセットが飽和してしまう。DCを通しくてCを略してみたのだが、さすがに無理だったようだ。
-
全体のゲインは少し不足を感じる。AM放送なら大丈夫だが、他は少し厳しいかも。
-
アンテナ端子に僅かにLoが漏れる。この意味でもRFアンプは欲しいところ。
-
消費電流は70mAと多め。100mAのLiPoだと1時間ちょいで空になってしまう。
ミスもいくつかありましたので、改めて修正した基板を作る必要があると考えています。
引き続き、
- I2C LCDディスプレイの追加
- レバースイッチの追加
- USB複合デバイスとしてUSB Audioを追加し、キャプチャデータを取り込んでSDRソフトウェアから使えるようにする
- 同じくUSB複合デバイスとしてUSB HIDを追加し、HIDで制御可能とする
- 電源管理(消費電流削減とオフ状態の実装)。クロックを下げる、スリープを入れてみるなど。
等々を進めたいと思います。
実はプロジェクト名はNanoSDRにしてあるのですが、FriskSDRという名称も含めて再検討中です。
リファレンス
- I2S FullDuplex対応を追加したChibiOS https://github.com/edy555/ChibiOS/tree/I2SFULLDUPLEX
- 作業中のリポジトリnanosdr (githubに載せる予定)