« 2010年6月 | トップページ | 2010年8月 »

2010年7月の3件の記事

2010年7月29日 (木)

ARM STM32基板にSPIインターフェースを作る

トイストーリー3に感動
 家族と久しぶりに映画を見にいってきた。笑わないで!トイストーリー3である。でも、このアニメ映画は、はっきり言って子供向けではない。子供の気持ちを忘れないでいる大人のための映画である。

 電気スタンドがスキップしてくるPIXERフィルムのオープニングを見ているだけで昔CGに夢中になったころの感動で胸が躍るのだけど、この映画は中味が深い。表面の筋を追うだけでは(それだけでも十分面白いが)、作者の本当の意図を理解することは出来ない。

 話はアメリカの典型的な子供たちの玩具(おもちゃ)のたどる運命を、奇想天外なアクション仕立てで辿り、玩具の主人公たちの生きざま(?)の中で、友情の絆の尊さを子供たちに訴えることになっているが、実はこれは表向きの話で、底流には玩具に対する作者の深い愛情が流れている。

 そう、人間は何のために生きるのか。何を糧に生きていくのかを問うている。大学生になって故郷を旅立つ17才の玩具の主人が、主人公たちと別れを惜しむシーンは涙なしには見ていられない。半世紀も前に、古い生家の長い廊下を海に見立て、積み木を組み合わせて戦艦「長門」(大和でなく)を作り、敵空母と海戦をした幼時の記憶がよみがえる。どんな玩具(電子工作の部品も同じ)にも魂と命が宿っている。

久しぶりのAVR開発(7/19/2010)
 それはともかく、FPGAのフォトフレームプロジェクトである。FPGAのSPIインターフェースのコード開発まで進んだ(未テストだが)。次は、プロセッサーにSPIを実装して、いよいよ画像データをFPGAに送る段階である(第6ステップ)。

 当初の予定では、プロセッサーはJPEG画像をビットマップデータにするためにフラッシュが大きくて速度の速いARMを予定していた。しかし、まだ経験が浅いうえにSDカードのファイルシステムが未実装なので時間がかかる。

 早く画像が見たいので手っ取り早いAVRの方でSPIを実装することにした。AVR研究所と名乗りながら、ここ最近はFPGAばかりやっていたが、久しぶりのAVRの開発である。ついでなので、ChaNさんのFatFSのバージョンアップをすることにした。

 このファイルシステムの成長の速度はとても早く、2年前に作ったこのMega128基板のFatFSは、まだTinyFSがあったころの0.04で、去年のリニアPCMプレーヤーが0.07、今はさらに0.08まで上がり、機能が更に充実してきた。

Aa252398

 リリースノートを読ませてもらう。なになに、LFN(日本語ファイル名)が中規模なAVRでも使えるような改修がされている。32KB程度のフラッシュサイズでも動くようだ。素晴らしい。

 このファイルシステムはとても良く出来ていて、プロセッサーの機種に依存しないモジュールと、機種に依存する下部ルーチンが明確に分割されており、沢山のプラットホームで動く。

 バージョンが違っても、上部ルーチンを取り替えるだけで動くと嬉しいが、そこまでは難しいだろう。そのためもありリリースの度に機種毎のサンプルソースがついている。いたれりつくせりの配慮である。

 テストベンチとなるのは、これまで、当ブログに度々登場したMega128の自作基板である。通常は、ChaNさんのFatFSのサンプルソースが入っている。LED電光掲示板や、Xbee電力ロガーの親機にもなった。

 改修にとりかかる。おや、RTC.cが変えられていてエラーが出る。ディレクトリの表示でも変数未定義でコンパイルが止まる。FAT構造体も少し変わっている。やっぱり、全部のモジュールを取り替えた方が無難なようだ。コアサイズもだいぶ大きくなってしまった(25K -> 30K)。まあ、ここのソースは全部入り(コマンドすべてを試せる)なので仕方あるまい。

 SPIのコーディングそのものは、あっと言う間に終わった。早速テストに入る。ロジアナで出力波形を見ると、どうもうまくない。SPIになっていない。送信の合間にクロックが出っ放しになる。これでは同期送信の意味がない。非同期にはスタートビットとストップビットがついているので、1フレームを送ったあと適当に休むことが出来るが、SPIは正確に送信ビット数のクロックで止めないと、あとがめちゃめちゃになる。

Avrspibad

 クロックラインのDDRを入力方向にすることで、クロックを止めることができたが、どうやってもストップビットの9ビット目が残る。それに、まれにだが途中でクロックが止まらないところが発生するときがある。ボーレートや、CPUの周波数でも状態が変化する。TXEN(送信開始/停止)も入れるが効果なし。暫くやってみたがあきらめた。

 Mega168(328)の標準USARTでは、この前のリニアPCMプレーヤーで使ったようにSPI(マスターだけ)になることが出来るが、Mega128は古い機種なのでその機能を持っていない。データシートにないことをやろうとするのはそもそも無理なようだ。

Mega128のUSARTでSPIを作るのはあきらめ最終目的のSTM32へ(7/23/2010)

 ブレッドボードでMega168のSPIマシンを作っても良いが、SDカードの配線を組み直すことを考えたら、当初の計画通り、STM32の方で開発してしまう方が早そうだ。SDカードが組み込まれている雑誌付録のCQ-STARM基板、STM32F103VB6基板を取り出した。

 これも1年ぶりのARMである。情けないことにすっかり操作を忘れている。Eclipseの新規プロジェクトすらマニュアルを見ないと作れない。ソースコードは、ねむいさんのFatFSのソースを拝借する。これはMartin Thomas氏がChaNさんのコードを基にSTM32用に公開したものに、「ねむい」さんがSTMのライブラリバージョンを3に上げ、Dfu下でも動くようにしてくれたものだ。

A5221938 ディレクトリごとまとめてEclipseのプロジェクトフォルダーに放り込み、refreshをかける。無事、Eclipseのプロジェクトが出来た。makefileとソースの#includeファイルのディレクトリパスを、こちらの環境に合わせコンパイルする。

 おお、エラーも出ずビルドはすんなり終わった。それでは書き込みだ。一番楽な、UARTからプログラムをロードするフラッシュローダーを用意する。この基板はたくさんのブートモードに対応するため、ジャンパーを追加してある。どれがどれだったか、これも全く忘れている。

 おやあ、愛用していたFlashLoaderが動かない(JTAGはセットアップが難しいので先送り)。あちこちいじってみたが、動かない。電源電圧を測るとあれあれ2.5Vしかない。どうも試行錯誤しているときに電源コネクターを逆差ししたらしい。またやったか。しつこいレギュレーターの呪いだ。USBから3.3Vを出すLDOが壊れてしまったようだ。時々しか動かない。

 Digikeyを覗く。ピンコンパチの300mA出力のレギュレーターLDS3985を見つけた。基板に乗っているLD2985のupgrade版らしい。2倍の容量がある。価格も安い(¥101)。これは買うしかないだろう。懸案のXilinx XCS250E(¥1309)と一緒に発注する。総額は¥7865で、送料無料ラインを余裕で超えた。「ねむい」さんに刺激されてSTM32Fのピンコンパチの新型、STM32F107VC6(¥1369)と、Primer2や、ストロベリーリナックスのSTBee基板の512KBチップSTM32F103VET6(予備のつもり¥1542)がゲタとなった。

 で、CQ-STARMの方だが、LDOが壊れても、3.3Vラインに電源を供給すれば問題ないことに気づき、JTAGのコネクターのVccピンに乾電池をつなぐ。うむ、これまでのRTCソフトのLEDが点滅して無事UARTにも時計表示が出る。本体は大丈夫なようだ。

Stm32_fatfs しかし、依然としてFlash Loaderが動いたり、止まったり安定しない。電源が低すぎる(3.3Vが3.1V)のか。翌日、3.3VのACアダプターとブレッドボードでしっかりした配線にしてやりなおし。おおお、FlushLoaderが動いたぞ。プログラムのロードも上手くいった。

 やった。AVRで見た馴染みのFatFSのメッセージがARMでよみがえる。flでファイルリストが出た。何と、日本語ファイルも問題なく表示。これはすごい。全く問題なし。感激、感激である。「ねむい」さん、Thomasさん、それにChaNさん、ありがとう。

DigiKeyからチップが届いてXilinx基板は生き返った(7/26/10)
 フォトフレーム計画そっちのけで道草を食っている。DigiKeyは例によって品物が来るのが早い。注文したFPGAチップ、CPUチップなどは、休みをはさんで3日で届いてしまった。本来なら、こわれたSTM32基板のLDO修復から始めるところだが、大物のFPGAをそのままにしておくわけにはいかない。

A7293040 XilinxのSpartan3E、XCS250Eチップを厳重な防湿袋から取り出す。いよいよ0.5ミリピッチ100ピンのハンダ付けである。机の周りを片付けて深呼吸し気分を換えて気を落ち着かせる。まずパッドにごく薄くハンダメッキをする。位置あわせを慎重に行って、テープで仮止めし、ルーペで確認する。対角線上の数ピンを軽くハンダ付けし、ずれていないことを確かめてから、フラックスをたっぷりつけ、慎重に各辺をパッドからピンにハンダが吸いあがるようにコテをあてて固定していく。新しいハンダは殆ど使わない。うまく行きそうだ。

 しかし、最後の辺でほんのわずかだが狂いが出ているのを発見する。うーむ、どうしてか。ピンの剛性は余り高くない。ハンダ付けでチップを押している間に少しづつずれてしまったようだ。それならピンをずらせば良いのか。ルーペで見ながら、慎重にずれたピンをピンセットで調整する。何だ、簡単にピンは動く。少しのずれはこれで修正が可能だ。

A7293038 機械でハンダ付けしたように均一にはならないが、何とか全部のピンがハンダ付けできたようだ。祈る気持ちで通電。見事、雑誌付録FPGA基板は生き返った。予備があるのでこんどは余裕をもってFPGAをいじれる(おいおい)。 

JTAGでDfuローダーを焼き、Dfu経由でプログラムロードが通った(7/27/10)
 こわれたLDOを新しいLDS3985に取替え、CQ-STARM基板も正常に復帰した。しかし、頼みのFlash Loaderが安定してくれない。あるときは簡単にチップを認識し、ファームロードを何度やっても問題ないのに、一度ご機嫌を損ねると、全くチップを無視する。

「ねむい」さんのブログによれば、最近のSTM32F105、107には、このシステムブートローダーにERRATAがあるようだが、103で不調というのは聞いたことがない。しかも動き方が気持ち悪い。動くときと動かない時の区別がわからない。ROMがこわれている?まさか。UARTの受信側を10KΩで釣って見る方法もだめだった。Falsh Loaderを新しいバージョン(1.3 -> 2.2)にあげたが、こんどは全く認識してくれなくなった。嗚呼。

 ARMのプログラムロードのもうひとつの方法、Dfuは、このあいだフラッシュの頭からサンプルプログラムをFlash Loaderで焼いてしまったので消えている。JTAGは準備が大変だ。しかし、Flash Loaderは動かない、Dfuを消してしまったとなると、あとはJTAG経由しか残っていない。あのややこしいJTAGに頼るしかなくなってしまった。このあいだお世話になったEclipseでの開発環境整備のページを最初から読み直し、いちから出直しである。

 この環境、複雑なこともさることながら、プロジェクト単位に同じようなスクリプトをduplicateして作っていかないと動かないというのが、どうも理解できない。これを回避する方法はあるのだろうが、経験が浅いのでどうやって良いのか分からない。

 しかし、同じ設定をしたはずなのに、今度は、何度やってもうまく書き込めない。すべてエラーで止まってしまう。設定ファイルの海の中で、わけもわからずひたすら泳ぎまわるだけである。本筋と関係ない(プログラムのロード)ところでつまづいている。何を無駄なことをやっているのか自分で自分がいやになる時である。

 ただ救いがある。ツールの一部分、OpenOCDだけは正常に動いており、チップを認識している。結局Eclipseでの動作はあきらめ、DOS画面で、OpenOCDを立ち上げ、TelnetでOpenOCDそのものに手動でコマンドを送ってファームを焼くことにする。いやあ、これも難しい。いくらやってもエラーで叱られる。

 そのうち、いつのまにか、CPU基板のLEDがブリンクし始めた。おや、JTAGでLED点滅ファームが書けたようだ。気を落ち着け、少しづつコマンドを調べて、簡単なファームをbinファイルで書いてみる。よしよし、0x08000000のフラッシュの最初からなら、binファイルで書き込めている。

 これまで動かなかったFatFSは考えてみたら、Dfuのためにオフセットしてある。フラッシュの頭をちゃんとしたDfuローダーにしてやる必要があるのだ。そこで思い出したのが、また「ねむい」さんのDfuローダーV3版だ。

 ありがたくソースを頂く。おお、バイナリまでついている。コンパイルエラーが怖いので、こいつをそのままJTAGで書き込むことにしよう。よーし、書けた。PC側のDfuSeもバージョンアップする。やったやった、USBをつなぐとPCが反応し、DfuSeにターゲットチップの型番が出た。

Ws000000 とりあえず、STM32の書き込み手段のうち、2つまで復活した。この3日間ほとんどこれにかかりきりだった。Dfuseを通して、最初のFatFSプログラムを送り込み、動作を確認した。やれやれ、やっと元の道に戻ってこれた。それにしてもこのところ「ねむい」さんのブログにはお世話になりっぱなしである。ありがとうございました。

| | コメント (2) | トラックバック (0)

2010年7月18日 (日)

XP2の外付けSRAM双方向アクセスに成功

UARTのソースコードを換えてみる(7/10/10)
 FPGAによるフォトフレームプロジェクトは山場を迎えた。外付けSRAM(ビデオRAM)にSPIインターフェースを通してデータを送り込み、そのデータを読んでRGBインターフェースへ画像データを出力する段階の開発である。これが動くとFPGAの機能は、ほぼ完成する(このあとはプロセッサーでのJPEGデコード機能などの開発)。

 気持ちに余裕がでてきたので、SPIを組み込む前に、この前、感動したwww.fpga4funのUART(このサイトではRS-232Cと言っている)を実際に動かしてみたくなった。コードはこちらが作ったもの(これも雑誌からの借り物だが)よりかなりコンパクトになっている。リソースはそれに比例して少なくなっているのだろうか。

Fpga4uart

 サイトの記事に出ているソースコードは抜粋で、実際のソースコードはzipファイルで落とせるようになっている。早速ダウンロードして解凍する。うーむ、サイトに出ているもの較べるとコード量が多い。エラー処理などの機能が追加されているようだ。

 クロック周波数、ボーレートなどを調整し、エラー処理などを簡略化して、これまでのUARTテストプログラムに入れて動かしてみた。ありゃあ、うんともすんとも言わない。ネットに公開されているコードが動かないということはまずあり得ない。自分が直したところがいけないに違いない。

 気を落ち着けて、最初からひとつづつ調べていく。その結果、単純な入力ミス(ボーレートが一桁多かった)、インターフェースミス(論理が逆だった)などが見つかる。これを直してfpga4funのUART送受信コードは無事動いた。

 気になるリソース使用量はどうだっただろうか。元のUARTのスライスが165だったのに対し、138まで下がった。一時は、96まで下がり、すごいと思っていたが、一行記載漏れがあり(これが原因で送信が最後まで動かなかった)、これを補うと動いたものの、スライスは大きく増えてしまった。まあ、それでも15%以上のリソース削減である。

 エラー処理などは少し残してあるので、これを削ればスライスはもっと少なくなるかもしれない。ただ、受信は、まだ不具合が残っており、ファイル転送などでデータを一気に送ると受信ミスがある。まあ、これは本筋と関係ないので、これ以上関わるのはやめることにする。

SPIとSRAMアクセスの間にバッファーが要るか(7/12/2010)
 SPIインターフェースの詳細設計に入る。この第5ステップの開発には実はSPI受信機能より、もっと重要な機能の開発がある。間断なく続くビデオインターフェースへのデータ転送の合間に、双方向でSPIからのデータをSRAMへ書き込む処理と、SPI読み込みとSRAM書き込みの間の非同期処理である。この間はバッファーを設ける必要があるだろう。これをどの段階で、どの程度の深さ(バッファー量)が必要なのか見極めなければならない。

 SPIはプロセッサー側がマスター、FPGAはスレーブなので、送信を待たせるわけにはいかない。マスターがCS(Chip Select)を上げて、クロックを動かせば、どんなことがあってもデータを読まなければならない。勿論、プロトコルを作って送信を待たせることも出来るが、この程度のしかけでは大げさすぎる。

 一方、SRAMのアクセスは、ピクセルクロック単位に時刻が決められた待ったなしの読み込みなので、これまたこれを邪魔してはいけない。FPGAは同時処理なので両者を同時に動かせるが、非同期なので、そこを通るデータは正確に受け渡す必要がある。これを調整するのがデータバッファーで、普通、FIFO(First In First OUT)とか, リングバッファーなどと呼ばれる。こういうシステムの設計でこのあたりが最も難しく、また最も面白い部分である。

 しかし、FPGAは完全な並列マシンなので、だいぶ気楽だ。これがプロセッサーのマルチタスク構造だと、やれプリエンプティブだの、ノンプリエンティティブだの、タスクスイッチオーバーヘッドと言ったOSの機能を気にしなければならないが、FPGAは基本的には全く独立して並行に動くので、データの動きにさえ気を遣っておればよい。

 それと、QVGAなのでピクセルクロックと、SRAMアクセスの間に余裕がある。たまたま、SRAMが書き込み中で読めなくても、2クロック後には、SRAMが空くので、そのときまで待って(5クロックくらい余裕がある)、読めばよい(ピクセルが少しずれるか?)。

 テストベンチは、SPIのデバッグのためUARTインターフェースを残し、プロセッサー側からSPIでデータを送った後、UARTコマンドで送り返して検証することにする。

A7183034

FIFOは要らないことがわかった(7/13/2010)
 少し意気込んで詳細設計に入ったが、SRAMのアクセス時間30ns(現在の33Mhzマスタークロック)、ピクセルクロックの間隔196ns、SPIの読み取り間隔などを詳しく計算しているうち、どうもFIFOなどの大掛かりな仕掛けは必要なさそうな感じがしてきた。

 SPIの8ビットデータが揃うのは、ARMの最速SPIが18Mhzで動くとして、1クロック55ns×8 =440nsだ。一方、SRAMのアクセス時間は、8ビットがクロック1サイクル30nsで読み書きできる。VGAインターフェースへの読み出しと、SPIからの書き込みがかぶっても、それぞれ2クロック以内にSRAMはあく。

 SPIの方はもっと余裕がある。SPIのシフトレジスターは、データが連続していれば、1フレーム(8ビット)のあとも次のデータは55ns後に来るが、読んだ8ビットデータをラッチするバッファーを一つ置いておけば、次の440ns後まで次のデータは来ない。1バイトのバッファーさえおいておけば、FIFOのようなしかけは不要だ。ピクセルクロックでの読み出しと、SPIのバッファー取り込みが、かぶったとしても、次のドットは196ns後なので、余裕でデータを読み込める。

 詳細設計に自信が出来てきたので、ソースコードを整理し始める。これまで分割してきたソースを統合する。UARTとビデオインターフェースのソースは別々だったので、これをまず総合する。そのあとSPIモジュールを足し、SPIからのデータをSRAMに書き込むプロセスを書き加える。

 www.fpga4fun.comで新しいHDLの書き方を覚えたが、alwaysを分けた簡明なコーディングは難しい。相互に関係する変数が多く、プログラム言語と違って外部変数を複数のモジュールで勝手にいじれないので(外部変数は参照のみ)、モジュールを分けるのは一苦労だ。

 7セグLEDから始まって、UART、SRAM、カラーバーと、沢山モジュールを開発してきたが、結局、1つのalwaysループに殆ど全てのプロセスを含める必要が出てきた。使い回しが難しい。このあたりがIPコアプロセッサーが幅を利かせている理由なのだろう。

Isplever

 メインループは350ステップを越えてしまった。いやな予感がする。案の定、論理合成でエラーが出る。Latticeの論理合成ステップは一風変わっていて、ソースコードをSAVEした時点で軽いエラーチェックが入り、Synplifyの論理合成でもう一回、Place&Routeという次のステップでも、もういちど結線上の論理エラーを出してくる。

 ところが、このPlace&Routeでのエラーメッセージは、どこでこのエラーが起きているのか教えてくれないので弱った。これは、このあとメッセージの中にステートメント番号が入っているところを見つけたが、最初は途方に暮れていた。

やっとSRAM双方向アクセスが通った(7/16/10)
 ソースが大きくなりすぎ苦労している。まずコンパイルにあたる論理合成が通らない。SRAMのアドレス操作が難しい。SPIによる書き込みと、ビデオインターフェースが間断なく読み込む処理は、頻繁にアドレスを換えて動く。複数のモジュールでひとつの変数をいじることが出来ない制約が重くのしかかる。何度か頓挫する。気分転換に別のことをやって再度挑戦するということの繰り返しである。

 やっとのことでソースコードが完成した。しかし、すぐにテストに入る気にならない。今度のモジュールはほぼ完成形で、SPIもビデオインターフェースもすべて組み込んである。ただ、SPIの送り側はまだ開発していないのでテスト手順が難しい。メモに書いてある手順をもういちど確認して、恐る恐る動かし始めた。

 まずオシロで出力を見るが、ビデオインターフェースが全く動いていない。UARTは動いている。しかし、SRAMから出てくるデータはめちゃめちゃである。ビデオインターフェースが動いていないのに何故だろう。

A7163030

 規模の大きなプログラムが動かないときの原因究明の常套手段は、分割してひとつづつ動かしてみることである。新しく入れたルーチンを次々にコメントアウトしていく。結局、最後のUARTまでになっても、SRAMの書き込みがうまくいかない。UARTはデバッグ用なのだけど、キーボードから入れたデータはゴミになって返ってくる。

 UARTにこだわっているわけではない。双方向でそれぞれが別のアドレスを指示しながらSRAMを読み書きできなければフォトフレームは動かない。UARTが動いていなければSRAM双方向アクセスの検証ができず、先に進めないからだ。

 アドレスを共通にするとUARTはちゃんとSRAMにデータを書き込み、正常に読み出せる。読み込みと書き込みのアドレスは、次のassign文で区別しているのだが、これがどうにもうまく動かない。 

  assign SRAMアドレス = (書き込みのとき)? 書き込みアドレス : 読み込みアドレス

Sram716

結局、ロジックアナライザーに出馬を願うことにした。ICプローブがFPGA基板にうまく接続できないので使用をためらっていたが、ロジアナでなければこれ以上の解析は無理だ。シミュレーターもあるが準備が大変だ。考えた末、基板のピンのパッドに10ミリくらいの0.5ミリ錫メッキ線を半田付けしてスタブを作り、そこへプローブをつける。アドレス線と、WriteEnableで5本のスタブを出した。

Sram_ok

苦労した甲斐があって、一発で原因が判明した。プログラムは思ったようには動かない、書いたように動くという好例だ。アドレスの切り替えに余裕を持たせて1クロック待ってから、Enableを出したつもりだったが、ロジアナで見てみると、Enableの前でアドレスが切り替わってしまっている。

 何だ、考えてみれば、assign文は組み合わせ回路なので遅延がない。さっきの書き込みの切り替えは、書き込みリクエストのフラグではなく、じかにWriteEnableにするだけで良いのだ。わかってしまえば、なんでもない話だった。

 ソースを作り替えて論理合成。おお、全く問題なくUARTが動く。懸案だったSRAMの双方向アクセスがやっと完成した。ロジアナさまさまである。ビデオインターフェースがまだ動かないが、これはwireとかreg変数の受け渡しか何かのミスだろう。FPGAでの開発は一山越したように思う。

 残るSPIの検証は、送り側の開発が必要である。久しぶりにSDカードの付いたAVRのMega128基板を取り出して、テストベンチの開発を準備する。うーむ、プログラミング言語は楽で良い。

| | コメント (4) | トラックバック (0)

2010年7月 9日 (金)

Lattice XP2基板にもSRAMを外付けする

 日本のサッカーワールドカップはベスト16で終わった。それでも大健闘である。開催直前のチーム力ではとても予選を勝ち抜けるレベルとは思えなかった。監督の指示次第でああも力が変わるのか。期間が短かったので、選手のフィジカル能力やテクニックが急に上がったわけではないだろう。ちょっとした監督のアドバイスか何かで選手の中の意識の変化が好成績をもたらしたように思う。

S_a7093011

 日本代表の変貌振りをたとえに使うのは少々おこがましいが、当研究所の電子工作の最近の状況には似たようなところがある。アナログ液晶モニターにFPGAでカラーバーを出そうとして、うまくいかずイライラして気分が優れなかった。コンポジット同期をあきらめ、同期信号を水平と垂直に分離して、やっと少しましになったが、それでも満足できる鮮やかな色にならない。

 どうしようかと迷った挙句、とにかく出たことにして不承不承、次のステップに移ることにした。ところが次のステップの検討に入った途端、憂鬱な気持ちが、きれいさっぱり晴れてしまったのである。もともと、アナログ液晶は、NTSCのビデオモニターにするために買ったはずで、本来のフォトフレーム用には26万色のデジタル液晶が用意してある。アナログは、これまでの行きがかかり上(たまたま最初買ったモニターがアナログ液晶だった)、何とか完成させようと意地になっていただけということに気が付いた(ビデオDACのBU3616Kが無駄になりそうだが)。

 趣味の電子工作なのに、こんなに目標や、目的にこだわることが馬鹿げていることにもっと早く気づくべきだった。ただ、がた老AVR研究所はあくまでも実用的な目的を持った電子工作をモットーにしている。これは前に何度も書いたが、現役時代に身に付いてしまった所長の一種の職業病である。目的と手段を混同することを極端に恐れ、一旦決めた目標にとことんこだわってしまう癖が直らない。

 と言って、逆に、このこだわりもしつこさもなければ、味も素っ気もない趣味になってしまうような気もする。そう、難しそうなことに挑戦することで気分が高まり、興奮するという効果がある。難しいものだ。考え方の持ちようで楽しみにも苦しみにもなる。

S_a7093017

SPIインターフェースを作るステップに入る(7/1/2010)
 FPGAでフォトフレームを作るプロジェクトは、第5ステップのプロセッサーとFPGAのインターフェースを設計する段階に入った(第4ステップのビデオDAC制作は延期)。当初の計画では、プロセッサーとFPGAの間は、シリアルのSPIでつなぐことにしている。動画ではないのでバス接続は始めから考えていない(QVGA程度ならシリアルでもフレームレートを落とした動画くらいは出せるかもしれない)。

 SPIそのものは難しいインターフェースではない。同期クロックがマスター側から供給され、スレーブ(FPGA)はそのクロックを監視していてフレーム(8ビットが通常)ごとにシフトレジスターを動かし、データを移すだけである。UARTよりはるかに簡単だ。

 ここのステップの設計の要点は、SPIそのものより、プロセッサーから大量の画像データをいかに簡易にFPGAがフレームデータとして受け取り、SRAM(VRAM)に展開するか、そのタイミングはどうするか、という全体の構成である。そろそろプロセッサー側のユーザーインターフェースも一緒に考えておかないと具体的な設計が出来ない。なかなか思ったような構成がまとまらない。

 FPGAは電気モーターのように、スイッチを入れれば、勝手に動くだけにしておきたい。VRAMにあるフレームデータを黙々とRGBインターフェースに送ると同時に、プロセッサーからのデータが来れば、誤りなくアドレスの最初から末尾までをSRAMに移す。FPGAはなるべく判断や制御をさせない仕様にしておかないとあとが大変だ。

 データの最初を識別するプロトコルをどうするか迷う。トリガーを何にするか、SPIで一気にデータを送ってもエラーにならないか、ブロック単位でACKを入れるべきか、お手本をウェブで探すが、ここまで詳しく解説しているところは見つからない。自分なりに作るしかないようだ。

 色々検討した結果、プロセッサーからFPGAに送るタイミングは、一番簡単な、SPIのチップセレクトを感知して、ここから一気にデータをシーケンシャルに送り込む方法でやってみることにした。プロセッサーとFPGAの間の距離も短いので、150KBくらいなら問題ないように思われる。まあ、動かしてみて駄目ならそのとき考えればよい。

 次に問題なのが、テスト環境である。作ったインタフェースがうまく動いているか、これだけコンポーネントが多くなってくると、しっかりしたテスト計画をたてておかないと泥沼に落ちると抜けられなくなる。

 プロセッサーは当初、STM32を考えていたが、今のところSDカードのファイルシステムが完全に動いていない。ここの開発をやっている時間が惜しい。とりあえずはAVRのMega128か、Mega328を使ってSPIをテストすることにする。

 デジタル液晶の部分もまだ実装が済んでいない。XP2にSRAMもつけていない。やれやれ、フォトフレームの道はまだまだ遠い。

fpga4fun.comのソースコードに感動する(7/3/10)

Fpga4fun SPIの開発のため、参考書やウェブでお手本にするソースコードを探しているうち、このサイトで、これこそがRTL(Register Transfar Level)設計だと言うVerilogHDLのサンプルソースを見つけ、久しぶりに興奮している。

 このサイトは、FPGAを勉強し始めた頃、ブックマークしてあったが、あまり真剣に読んでこなかった。英語ということもあるが、ソースコードの書き方が、これまで雑誌などに見るスタイルとかけ離れていたため、馴染めず、斜め読みしかしていなかった。

 それが、SPIの勉強がてら、ここのSPIやRS-232C(UARTのこと)のVerilogHDLソースを仔細に読んでみて驚いた。実に簡単に実現している。ここのソースの特徴は、always節がやたらと多いことである。これに対してこれまで参考にしていた雑誌などのサンプルコードでは、alwaysはクロックを作るところと、メインのalwaysくらいしかない。

 ソフト屋からすると、ステートマシンの全体の流れがつかめるので、このほうが見やすい。そして機能ごとにサブモジュールにわけ、サブモジュールが協調して全体が動くというしかけになっている。今までこの作り方に何の疑問も持っていなかった。

 ところが、このサイトのソースコードは、殆どのREG変数(実態はフリップフロップ)単位にalwaysがついており、これらがそれぞれクロックと同期しながら独立して動く。例えば、最終的なUARTの送信データの出力回路は、何とassign文一行である。(変数stateは、別のループで動くステートマシンのステップで、muxbitがデータ)

// combine start, data, and stop bits together
assign TxD = (state<4) | (state[3] & muxbit);

このステートメントだけで、シリアルの一本の送信ラインTxDに、スタートビットから始まる8ビットのデータがボーレート単位に送られ、最後にストップビットが付いて送信されていくことが想像できるだろうか。ソフト屋には無理である。

 RTL(Register Transfar Level)記述という言葉が始めて理解できるソースコードである。そうか、FPGAというハードウエアはこういう風に動くほうが自然なのだ。沢山のサーキットが同期したクロックを貰いながらそれぞれの仕事をし、最終的に必要な出力を出す。良い勉強になった。

結局XP2にも外付けSRAMをつける(7/6/2010)
 あれこれ悩んでいたが、XP2基板にもSRAMを載せることにした。XilinxのチップをDigiKeyに発注するゲタ(送料無料にする品物)がどうしても見つからない。DE0は有力な候補だが、これ以上、開発対象を増やしたくない。となるとXP2基板にも4メガビットSRAMのCY7C1041Dをつけないと先に進めない。

 XP2はSpartan3Eに較べるとI/Oピンは倍近くあるのでピンアサインは余裕である。SRAMの場所は、XP基板の下にし、スペースを稼ぐ。アドレスバス18本、データバス8本、制御線2本、電源を入れれば30本の配線である。ここでも慎重に、アートワークを紙に描き、終わったところをサインペンで消しながらハンダ付けしていく。

 ハンダごてを新調して、UEW線のハンダ付けは飛躍的に早くなった。これまで被覆を熱ではがす工程が、もたもたしていると被覆を炭化させてしまって何度もハンダをつけなおすなど、時間がかかっていたのだが、今度は殆ど一回で、綺麗に泡を吹いて被覆がはがれてくれる。やはり道具には金をかけるものである。

 夜遅くから始めて、深夜(というより明け方)のワールドカップサッカーのキックオフ前にはすべて完成した。計算してみると1本2箇所のハンダ付けに、5分というところだ。まずまずの生産性に満足する(アートワークは済んでいる)。念のためテスターで結線を確認する。UEW線はハンダ付けがされていても、まれに接触不良が起きる。うむ、大丈夫なようだ。

S_a7093015

Initial文ではメモリーの初期設定が出来ないとは(7/8/2010)
 SRAMが付いたので、UARTからテストに入る。SPIが動いてSRAMにデータが入ったかどうかを確認するにはUARTが必須だ。デジタル液晶の実装が出来ていないので確認の術がないからだ。

 UARTは、fpga4fun.comのコードではなく、用心して前に動いたコードを入れる。リセットのところを直さなければならない。このあいだ正論理ではまったところである。雑誌の回路図を良く見ると、シュミットトリガーのインバーターがしっかり付いていた。慌て者だから、こういうところを見逃す。

 論理合成する。問題なし。コンフィギュレーションも無事に終わった。あまり期待もせず、UART端末を立ち上げる。ふむ、何もでない。30本の配線だ。最初から動くことを期待するのが間違っている。念のため、リターンキーを押す。ややや、行が変わったぞ。キーボードを押すと、おお、文字がエコーバックされる。何だ、何だ。動いている。

 文字を入れて、リターンキーを押すと、入れた文字が正しく返ってきた。ええー、ちゃんとSRAMまで動いているではないか。しかし、プロンプトの>や、リセットしたあとのメッセージは何も出ない。ソースコードはリセットのところを修正しただけで、何も変えていない。XilinxとLatticeで仕様が違うところがあるのだろうか。まさか。

 何かエラーがでていないか、論理合成のメッセージから確認する。すると、

Initial statement will only initialize memories through the usage of $readmemh and $readmemb. Everything else is ignored

initial begin
MSG[0] <= 8'h0D;  // CR
MSG[1] <= 8'h0A;  // LF
MSG[2] <= 8'h2A;  // '*'
     ・・・

という警告(warning)が見つかった。プロンプトや初期メッセージのデータを収容するところだ。何い、intial文では$readmemhなどを通してでないと、メモリの初期化が出来ないと言っている。何だこれは? あわてて$readmemhを調べるが、これはファイルから、HEXフォーマットでデータを入れるシステム文で、こんな大げさなことはやりたくない。

 論理合成ツールのバージョンや、グレードでこういうことになっているのかもしれないが、たかだか10数文字のコンスタントに、これだけの手間をとらすのは理不尽だ。ウェブに助けを求めるが、適当な対策は見つからない。

 待てよ、このメッセージはinitial文では駄目と言っている。ということは他では出来るということなのか。試しに、メインalwaysのリセットのところにぶちこんでみた。最初はうまく動かないが、リセットすればデータは入る。

 やった、やった、やりました。論理合成ツールはまんまと騙されて(?)warningがなくなった。ファームを作り直して恐る恐る電源を入れる。おおう、プロンプトが戻ってきた。***FPGA***という初期メッセージも出る。Xilinxのときと違って、全く安定している。改行のないテキストファイルを作ってファイル転送する。これも問題なし。

 いやあ、久しぶりの快感だ。ハンダ付けは完全試合だった。SRAMが正しく動いている。これでSPIのテストの準備は整った。SDカードを読むプロセッサーをマスターとしてFPGAスレーブにSPIでデータを送り、UARTで結果を見るのが次のステップだ。

| | コメント (0) | トラックバック (0)

« 2010年6月 | トップページ | 2010年8月 »