マイコン工作実験日記

Microcontroller を用いての工作、実験記録

32KクリスタルでUSBを動かす

2013-06-17 00:22:10 | SAM4
ABDACBからサイン波を出力した際のノイズが気になるので、クリスタルを変更してみようと思います。しかし、現在使用している12MHzのクリスタルはPLLを通してUSBの48MHzを作るのにも使っています。これまでのクロックの使い方はこんな感じです。

このままでクリスタルを24.576MHzに変更してしまうと、USBクロックが狂ってしまうので、別途48MHzを作る方法を考えねばなりません。SAM4LにはPLLとは別にDFLL (Digital Frequency Locked Loop)という機能が用意されており、既存のクロックを逓倍した周波数を生成することができます。仕様では8~150KHzのクロック源から、20~150MHzのクロックを生成できるようです。PLLと違ってdivierはありませんが、multiplierに設定する乗数を大きくできるので、低い周波数から高い周波数を作れるようです。そこで、32KHzクリスタルの出力から48Mhzを生成してUSBを動かしてみることにしました。具体的には、32768Hzを1465倍して48.00512MHzを作ります。


新しいクロック系統は上図のようになります。DFLLの入力クロックはGCLK0という約束になっているので、32KHzクリスタルの出力を加えるにはOSC32の出力をいったんGCCTRL0を通してやる必要があります。DFLL出力が48MHzになるので、GCCTRL7も素通しになりました。

最初は、DFLLがロックしなくてしばらく悩みましたが、DFLL0CONFのCALIBフィールドを誤って0にしてしまったのが原因でした。この部分を書き換えないようにレジスタを設定しないと、出力周波数によってはロックしなくなってしまうようです。こうして、無事32KHzからUSB 48MHzを生成して、動かすことに成功。CDCでコンソールアクセスに使ってるだけですが、問題無く使えています。FREQMを使って、各クロックの周波数を計ってみた結果がこちらです。

各クロックはFREQMを使って順番に測定していますが、測定値にはばらつきが生じます。DFLL0とGCLK7は同じになるべきですが、値が違うのはそのためです。

FREQMに関連して、ひとつ面白いことに気がついたのですが、次の記事ネタにすることにします。これで安心して、12MHzクロックの方を交換できます。近日中に秋月で24.576MHzを買ってこよう。

6月18日追記
44.1KHz系列で必要なクロックは 24.576MHzではなくて、22.5792MHzでした。データシートの数字を1段間違えて拾っていました。あぁ。。。これは秋月には無いみたい。

ABDACBから音を出す

2013-06-15 19:32:41 | SAM4
SAM4LにはDACCという通常のD/A変換器機能も用意されています。ABDACBはオーディオ用となっているのですが、それでは何がオーディオ用に違っているのかという点についてまずは書いておこうと思います。

DACCは10bit, 1チャンネルですが、ABDACBはひとつで16bit, 2チャンネル。ABDACBではDAC/DACNのコンプリメンタリ出力が可能となっており、音量調節機能も用意されています。前記事で書いたように、LPFを介してアンプを接続することができます。サンプリング周波数としては、8000Hzから44.KHz, 48KHzまでをサポートしていますので、電話の音声通話からCD/DVDクオリティの音楽再生データを扱うことができます。

さらにオーディオ用にオーバサンプリングの機能を有しているのが、通常のDACであるDACCとの大きな違いです。基本的に128倍の周波数でのアップサンプリングによる元データの補間をおこなうことができます。USB用のクリスタルを使えるように、125倍や136倍のアップサンプリングを使用するモードも用意されています。今回の基板ではすでに、12MHzのクリスタルを実装済みですので、このモードを使用することにします。

ABDACBもDMAが使えますので、IISCから受信したオーディオデータをいったんメモリに蓄えて、それをそのままABDACBにDMA送信してやれば、それだけで再生が可能です。もちろん、IISCで受信するデータとABDACBで送信するデータの形式が同一になっていなければなりません。今回はどちらも16bitのコンパクト・ステレオ形式を使いました。この形式では32bitワードのなかに左チャンネル16bitと右チャンネル16bitをまとめて入れてワード単位で転送します。いっぺんに、2チャンネル分の転送ができてしまうので、DMAチャネルもひとつしか使わずに済みます。

このようにDMA転送するだけで再生できるので、CPUにはほとんど負荷かかりません。しかしながら、今回の方式にはひとつ大きな問題があります。それはクロックの同期がとれていないことです。IISCはスレーブ動作となっているので、44.1kHzオーディオデータはWT32側が出力するマスタークロックに同期して受信されます。一方、ABDACBも44.1kHzのサンプリングレートで、データを送信しますが、こちらはGCLK6で生成される48MHzを元に動作します。この2つのクロックの同期がとれていれば問題無いのですが、全く独立に動いているために受信と送信のペースが同じにはなりません。特にABDACBではオーバサンプリング・クロックとして本来であれば、47.9808MHzが必要であるところを、48MHzで済ませています。そのために、送信のペースがちょっと早めになってしまいます。どのくらい早いかを、もう少し具体的に確認してみましょう。

47.9808Mhzという周波数は、44.1Khzを8 ×136倍した数字です。本来であれば、このクロックを8 ×136で割ることで、44.1KHzのサンプリング周波数を得て、そのタイミングでデータを送信すべきです。このクロックが48MHzになると...

48000000 / 8 / 136 = 44117.647

となり、毎秒17, 18サンプルも多く送信してしまうことになります。



この問題に対処するために、IISCで受信したデータはいったんバッファ・キューにためて、送信処理はこのキューからバッファを取り出しながら行うこととしました。キューの残りが少なくなったらならば、ABDACBに送信すべきサンプルデータをひとつ重複させることで送信ペースを落としてやります。この処理を追加して、音楽を再生してみた時の様子が次のログです。



送受信は128サンプル単位でおこなっています。Normalが通常の128サンプル単位で送信した回数、slowerが速度調整のために、1サンプル加えた129サンプル単位で送信した回数です。およそ10秒間でslowerが200から210程度増えるようです。予想よりちょっと多めですがクロック速度誤差の影響かな? 実際に音楽を聞いてみると、もちろんちゃんと聞こえます。これでいいような気がしたのですが、試しにサイン波を再生してみると、"バサバサ"というノイズが入っているのがはっきりとわかります。つじつま合わせで1サンプル追加している影響でしょうか?うーん、困ったなぁ。

秋月に24.576MHzのクリスタルがあるようなので、こいつにクリスタルを交換すれば少しは改善されるかもしれません。試してみようかなぁ。でも、これをやってしまうと、今度はUSB用の48MHzをどうやって作るかを考えねばなりません。

ABDACBにアンプをつなげた

2013-06-10 00:33:09 | SAM4
SAM4LSのIISCを使ってWT32からオーディオ・データを受信できていそうなことが確認できたので、次の段階として、受信データをそのままABDACB(Audio Bit Stream DAC)に送信して、再生することにします。



ABDACBは差動信号を出力することができます。これをLPFを介してアンプに接続。アンプとしてはBlueHANDでも使ったTPA6132A2を使用。単に手持ちのものを使っただけです。ABDACBの機能については次回の記事でより詳しく触れることにしますが、音量調節の機能も備わっているので、レジスタへ書き込むだけで音量調節とミュート制御が可能です。部品数少なくて済むので、助かりますね。TPA6132A2にはEnable端子があるので、これは後ほどSAM4LSのGPIOまたはWT32のPIO端子で制御する予定。今のところは、ジャンパで吊ってあります。

FREQMを使ってFsを計ってみる

2013-06-04 23:07:47 | SAM4
前回の記事では、IISCを使ってI2Sデータが受信できることを確認しました。今回は、IISCのワードクロック周波数を別の方法で確認してみることにします。

SAM4LにはFREQM (Frequency Meter)という機能が備わっており、指定したクロックの周波数を計測することができます。仕掛けとしてはタイマーとカウンターを組み合わせて使うようなもので、基準となる既知速度のクロックを使って計測時間を設定し、その期間に測定対象のクロックが何回入るかをカウントするというものです。

既知のクロックとしては、32Kクリスタルを追加で実装して、これを使用。IWS端子に入るクロックを直接計測することはできないので、IWS端子をGCLKへの入力となるGCLK_IN1端子とつないでおきます。そして、GCLK_IN1に入ったクロックをGCLK2として出力するように、SCIFを設定してやります。こうすれば、GCLK2の出力をFREQMで計ることができますので、IWSの周波数を調べられることになります。



音楽が流れ始めるとWT32からクロックが出て、再生を止めるとクロックも止まることが確認できました。周波数値としては、44100と出て欲しいところですが、計測時間が短く基準クロックの32KHzが対象クロックの44.1KHzに近いこともあり、この実験では44040が精一杯の値です。

IISCをつなげる

2013-06-01 01:09:40 | SAM4
SAM4LとWCA-009の間のシリアルはつながったので、続いてオーディオ信号です。今回は、I2Sを使ってつなぎます。

SAM4LにはI2S用のインタフェースとしてIISC (Inter-IC Sound Controller)が備わっているので、これを使います。IISCで受信したデータは、ABDACB(Audio Bit Stream DAC)を使って再生する計画。SAM4Lではペリフェラル間でCPUを介さずに直接DMAすることはできないので、いったんCPUのメモリを介してDMAする必要があります。このあたりの制約は、SAM7/SAM3と同じですね。



I2Sでつなぐには、どちらをマスターにするかを決めねばなりません。今回も、WT32側をマスターとして、上図のように接続しています。SAM4L側をマスターにすると、クロックの生成が必要になりますが、IISCのクロック源として使用するGCLK6はABDACBのクロック源ともなっています。GCLK6をABDACBの要求するクロック速度にしてしまうと、IISCからWT32に対して供給するクロック速度としては適さなくなってしまうので、IISCはスレーブ側にせざるを得ないという事情もあります。

WT32側は2点の設定が必要です。
  1. PSTOOLをつかって、PSKEY_DIGITAL_CONFIGの値を0x0406に設定。これで16ビット左詰めのデータフォーマットを選択します。
  2. iWRAPで SET CONTROL AUDIO I2S I2Sを設定し、I2Sマスターモード動作を選択。
ソフトの方は、まずはIISCの動作確認から始めることとします。DMAの割り込みをかけてみて受信フレーム数にみあう割り込みがかかるかどうかを調べてみました。128サンプル毎にDMAすることとし、およそ10秒間受信してみました。



受信しているMP3を再生したデータは44.1Kサンプル/秒ですので、44100 × 10 / 128 = 3445回の割り込みが発生するはずです。測定実験は手動でおこなっていますので、この程度の誤差は生じるでしょうから、問題無く受信できている見て良いでしょう。現在は単に空読みしているだけですが、これをABDACに流してやれば音を出せるハズです。




USARTにとりかかる

2013-05-28 21:24:37 | SAM4
続いてUSARTをWCA-009とつなげて動かします。




USART機能は、これまでのSAM7/SAM3と似ているのですが、LIN機能まで統合されているようです。SAM4LにはPicopower UARTという受信検知を省電力でおこなう機能も備わっており、これも試してみたいところなのですが、残念ながら通信速度が9600bpsで固定されているという制限があります。WCA-009はいつも115,200bpsでつないでおり、9600だと操作や表示速度にも影響が出そうなので、今回はPicopower UARTは使いません。

SAMシリーズのUSARTは伝統的(?)にFIFOを持っていません。一文字ずつ送受信していたのでは、割り込みのオーバヘッドが大きすぎます。そこでDMAを使うことになります。SAM7/SAM3では各ペリフェラルにPDCというDMAチャネルが付いているという構成になっていました。これが、SAM4Lでは少し変わっています。従来のPDCと同等のPDCAという機能が用意されていますが、PDCAはペリフェラルからは独立したDMAチャネルという構成になっています。従ってDMAを使う場合には、ペリフェラルとPDCAとを結び付けるという設定処理が必要となっています。またひとつのPDCAチャネルは受信か送信かの1方向しか処理できないので、例えばUSARTの送受ともDMA処理をおこないたければ、2チャンネルのPDCAの割り当てが必要となります。SAM4Lでは16チャネルのPDCAが備わっています。

このように構成は変わったものの機能的には大きな変化はないので、理解は難しくないのですが、実際にドライバを作ると割り込みハンドラーが3つも必要になります。SAM7/SAM3ではPDCがUSARTに付属していましたので、DMAの終了割り込みもUSARTの割り込みハンドラ内で処理することができました。SAM4Lではこれが分離されており、しかもPDCAは送受信で別チャネルであるために、割り込みのベクタも別に用意されています。そのため、合計で3つの割り込みハンドラーが必要になってしまうのです。



3つも割り込み使うこともあり、ついついPDCAの割り込み許可するのを忘れてしまったりしましたが、送受信とも動き始めました。

ASTを動かしてみる

2013-05-25 15:57:05 | SAM4
SAM4Lの方ですが、どうにかUSB CDCでPCとつなげられるところまではきました。しかし、時々うまくつながられないことがあります。どうやら CONTROL転送にバグがあるらしく、ZLP (Zero length packet)のINパケットを処理しそこなっているようです。どういう条件でこの問題が発生するのかをちゃんと絞り込めないとバグを取れそうもありません。まだちゃんとSAM4LのUSBCの動作を理解できていないってことですね。

USBの方はじっくりと見直すことにして、簡単にできそうな作業を並行して進めていこうかと思います。まずは試しにRTCを動かしてみることにしました。ところが、SAM4L にはRTCという名前のペリフェラルがありません。AST(Asynchronous Timer)が、RTCの機能をもっているようです。ASTは、SAM3SのRTTとRTCの両方の機能を兼ね備えたものになっており、ASTをカレンダーモードに設定することで、RTCと同じように使えます。ASTではクロック源も選択できるので、これを正しく選択して適切な分周比を設定してやらねばなりません。

今回は内蔵の32KHz RCオシレータを使うことにしましたが、次のような手順での設定が必要でした。
  1. BSCIFのRC32KCRにて、32KHz RCオシレータをイネーブルする
  2. BPMのPMCONにて、32KHzクロック源として32KHz RCオシレータを選択する
  3. ASTのCLOCKレジスタにて、ASTのクロック源として32KHzクロックを選択する

選択できるのはいいけど、設定するのは面倒になりました。

こうしてUSBでPCとつないで、ASTで計時できるようになりました。



今回は内蔵のRCオシレータを使っていますが、もちろん外付けの32KHzクリスタルを使うこともできます。SAM3Sでは、32KHzクリスタル用の端子(XOUT32/XIN32)がPIOと兼用になっていましたが、SAM4Lでは専用のピンが割り当てられています。SAM3SではUSARTのRTS/CTS機能とぶつかっていたので不便に感じていました。これは、ちょっと嬉しい相違点です。

USBの作業中

2013-05-18 19:16:29 | SAM4
しょっちゅう寄り道ばかりしているのですが、SAM4Lのコードも書いてはいます。まだUSBのCDCドライバを作っているのですが、まだようやくとenumerationが動き始めているところで、CDCでの通信までには至っていません。




動き始めてはいるのでクロックがらみの設定は問題ないことは確認できました。しかし、USBのコントローラであるUSBCの仕様がこれまでのSAM7, SAM3のUDPとは全く違うものなので、手探り状態でコードを書いたり、修正しているようなありさまです。わたしはAVRとかAVR32のUSBについては全く知らないのですが、そちらの方に近いのかもしれませんね。

SAM7/SAM3のUSBがFIFOメモリ経由でデータを読み書きしていたのに対し、SAM4LのUSBはSRAMメモリとダイレクトにDMAしてくれます。この方がわかり易く使いやすいのですが、もともと32KBしかないSRAMを割かなくてはならないのがちょっとツライところです。


まずはクロックから

2013-04-28 17:52:59 | SAM4
ようやくとSAM4Lでの開発作業を開始しました。SAMシリーズの名前を冠していても、これまでのSAM7やSAM3S/SAM4Sとは内部の構成が全く違っているので、コツコツとデバイスドライバを用意する作業を進めていくしかありません。もちろんATMELが提供してくれるライブラリもあるで、それを使えば自分でドライバを作る必要なんかないわけですが、苦労してドライバを自分で作るのも楽しみの一部なので、やっぱり自作する道を選んでしまいます。

SAM4Lではクロックの構成もこれまでとは随分と違っています。32KHzのRC発振器で動き始めるのは同じですが、これ以外にも115KHzRC発振器、4,8,12MHzRC発振器、80MHz RC発振器と内蔵RC発振器だけでも4種類も用意されています。アプリケーションの用途や使用する周辺機能での要求に応えるためにこれらの発振器が用意されているのでしょうが、具体的にどのような用途を想定しているのか、まだわからずにいます。

当面はいつものようにUSB CDCでつなげる環境が欲しいので、USB CDCドライバの開発が最優先事項です。USBを使うためにはクロック精度が必要となるので、おのずとクロック源としては内蔵RC発振器ではなく外付けクリスタルが必要となります。12MHzのクリスタルを使って、これをPLLを使って192MHzを生成。さらにこれを分周して作った48MHzをUSBクロックならびにCPUクロックとして使うことにします。

SAM4LではSCIF(Serial Control Interface)を設定することで、クロックの設定をおこないます。SCIFはGCLK0からGCLK11の12個のクロック生成ユニットを持っており、それぞれクロック源と分周比を指定することで異なる周波数のクロックを生成して周辺機能部分に供給したり、マイコンの端子から出力することができます。GCLK7がUSBのクロック源となるので、こいつを設定してやらなければならいということをようやくと理解。しばらく地道な作業が続きそうです。

A基板で始めるSAM4L

2013-04-16 00:39:50 | SAM4
いろいろと手間取りましたが、結局QFPパッケージのSAM4LS4Bを入手できましたので、ようやくとSAM4Lを使い始めることにします。今回は変換基板を使うこともあり、久しぶりに秋月A基板を使うことにしました。まずは動かすのに必要最低限の部品で組み上げて基本動作確認を進めます。





いつものようにUSB給電動作。電源周りとJTAG(SWD)だけ配線してあります。空いているスペースには後ほどWCA-009やアンプを追加してゆくつもりです。たったこれだけの配線でも、ユニバーサル基板を使っているとVCCとGNDの配線を面倒に感じてしまします。秋月でもパワーメッシュユニバーサル基板を作ってくれないかなぁ。

SAM4Lではコア電源を生成する内蔵レギュレータの動作としてスイッチングレギュレータのモードと、リニアレギュレータのモードの2種類をサポートしています。入力電圧VDDINが2.3V以上ではスイッチングレギュレータの方が効率が良いのでオススメということになっているのですが、外部部品としてインダクタが必要となるので、今回は追加部品の必要が無いリニアレギュレータのモードで動作させることにしました。

A基板を使う都合上20ピンのJTAGコネクタを配置していますが、実際に使っているのはSWDの線だけです。まずはSWDで見えることを確認するのが動作確認の第一歩。SAM-ICESAM-BAでつないでみるといのが常套手段なのですが、SAM4Lのデータシートを確認してみるとSAM-BAのセクションがありません。以前使ったSAM7A3と同じようにROMブートの機能が無いのでした。そこで今回はJlink commanderを起動して接続確認。



無事にSWDでつながりました。Cortex-M4という表示を見て、改めて自分が初めてM4を使い始めようとしていることに気付かされました。コアがM4とは言っても、SAM4Lは低消費電力が売りなのでクロック速度は48Hzまで。SAM4Sと同じくFPUオプションは無し。SAM4SではサポートされているBit-banding機能もSAM4Lには無いし、SRAMも32KBと少なめです。SAM4Sでは外部メモリを持つことができますが、現存するSAM4Lデバイスには外部メモリインタフェースもありません。個人的にはもう少し内蔵SRAM容量の多いデバイスを追加して欲しい気がします。