« 2010年12月26日 - 2011年1月1日 | トップページ | 2011年1月16日 - 2011年1月22日 »

2011年1月9日 - 2011年1月15日の1件の記事

2011年1月11日 (火)

フォトフレーム:JPEG画像の出力に成功。しかし問題山積

みなさま新年おめでとうございます。
 当研究所はブログの公開から足掛け3年、電子工作そのものは始めてもう4年になりました。AVR研究所という名前がついておりますが、最近はFPGAやARMばかりでAVRを使う機会が少なく、そろそろ名前を変えなければいけません。

 AVRをやり始めてからAVRが急速に普及し、特にArduinoの人気に支えられて扱うお店が飛躍的に増えました。今開発の中心になっているARMプロセッサーSTM32も雑誌の付録でいじっている2年前はマイナーでしたけど、最近は何故か話題になることが多くなり、参考書の種類も増え、手に入るCPU基板も多様になってきました。

 自分が気に入って選んだディバイスに人気が出て扱う人が増えるというのは何となく嬉しいものですが、当研究所は、余り個別のハードウエアにはこだわらないことにしています。AVR研究所という名前も、電子工作をAVRで始めたというだけのことで、それ以上の思いはありません。あくまでも実用、アプリケーションがあってこそのハードウエアというのが基本の考えです。

 ただ、フォトフレームや、BeagleBoardを触っていて感じたことですが、今の電子工作、少し凝っていくと、殆どが市販のPC(それも古い)や10年前の携帯端末の機能に限りなく近づいていくだけで面白みがありません。

 そういう意味で、当研究所では、これからは、なるべくこうした機器の機能とぶつからない分野に狙いを定めて工作を考えていこうと思っています。よろしくお願いいたします。

 それはさておき、今年のお正月も電子工作で明け暮れていました。先日、懸案のJPEGが動き出しほっとしたところです。年末からの作業日誌をご紹介します。

P1093581

LAN電源コントローラーの修理(12/29/2010)
 3年前に作ったマイクロチップ社のNICチップENC28J60を使ったプリンターの電源を遠隔制御するコントローラーが時々誤動作するようになった。このディバイス(ブログ2008年8月29日「LAN電源制御成功!」)は、がた老AVR研究所が作った機械の中では最高の働き者で、地下の工作室にあるレーザープリンターを2階や1階のパソコンからネットを通して電源の入り切りが出来るので評判が良い。完成以来ずっと電源は入ったまま全く故障もせずに元気に稼動してきた。

 ところが、ここ数ヶ月前から、たまに誤動作するようになった。時々ネット上で行方不明になる。リセットすると正常になるので放ってあったが、最近はプリンターの電源が入ったとたんにコントローラーがリセットされプリンターの電源がすぐ切れてしまうようになった。うまく入るときもあるが、これでは役に立たない。家族の苦情も出てきた。症状から見て、電源不良の疑いが濃い。

A4111243

 また例の3端子レギュレーターか。プリンターの大電流が流れる時に一瞬、CPUの電源電圧が低下し、リセットしてしまうのだろう。電圧ロガーのようなものがあれば良いが、症状の出ているときを見計らって(暫くプリンターを動かさないときに起きやすい)、ケースをはずして電圧を測ってみた。3年前の作品である。構成などすっかり忘れている。あれえ、問題のレギュレーターはLANチップの3.3V用しか使っていない。CPUの電源は秋月の5Vアダプター直付けだ。電圧を測ってみる。4.5V。うーむ、この程度ではリセットしないはずだが。

P1093582

 と、ケースの中にあるACアダプターのモールドが割れているのを見つけた。中味が見える。何だ何だ。何故モールドが割れているのだ。割った覚えはない。熱で割れたのだろうか。中を見ると、見事に電解コンデンサーの一ヶのトップが膨れている。おおー、これに違いない。これを交換すれば動くかもしれない。とりあえずは予備のアダプターと交換してみよう。

P1063565

別の5Vアダプターをつけてテストしてみる。よーし全く問題なく稼動する。やっぱり予想通り電源が故障の原因だった。予備の5Vアダプターのケーブルを切り、このコントローラーの電源に作り替える。取り外した故障のアダプターの出力電圧をオシロで調べてみた。無負荷でも3Vくらいのところから、激しい脈流になっている。平均では4.5Vでも、これでは正常に動かないはずだ。とりだしたコンデンサーは容量が1/3の300μFに低下していた。 密閉機器に入っていたから、熱が原因かもしれないが、良く見るとこのコンデンサーの耐圧は6.3Vしかない。温度は105度まで耐えられるようだが5V出力なのにこの耐圧では問題が起きるはずだ。

P1063560

JPEGライブラリの実装に苦労する(1/3/2011)
 年末・年始の行事も一段落して、電子工作に時間をかけられるようになった。フォトフレームプロジェクトの第8ステップにあたるJPEGライブラリの実装を暮から始めている。

 今までのIJGのソースをモディファイしようと準備していたが、とっかかりがなかなか見つからず困っていた。しかし前回の記事のようにsirius506さんのソース(MP3Player)を雑誌のダウンロードページで見つけ、JPEGデコードの道筋がついた。

 このソースは、こちらが意図しているのと同じJPEGからビットマップへの伸張(IJGではデコードと呼ばずdecompressと言う)だけなので、ライブラリの量が少なくて助かる。JPEGライブラリと、ユーザーインターフェースのモジュールをソースを読みながら選択してEclipseにとりこむ。

 彼のブログの記事を参考に、少しづつ移植作業を開始する。現在のBMPファイルを表示する本体プログラムに機能を追加していく。彼の記事のいう変更点はすべて修正が済んでいた(当たり前か)。Makefileにもモジュールを追加登録する。

 移植のコツというのがあるとすれば、全体を通して流れが確認できたら、とりあえずエラーを恐れずにコンパイルをしてみることだ。あまり周到に調べていってもきりがない。エラーはあとから少しづつつぶせる。

 最初のビルド。案の定、山ほどコンパイルエラーが出る。これは想定済みである。ひとつづつエラーメッセージを読み個別に解決していく。時間計測をTOPPERS/JSPのサービス関数でやっているので、当面はすべてコメントアウトする。SYSLOGなどのコードは、はずすか、UARTにメッセージを出すコードに置き換えていく。

 やっかいだったのが、boolタイプの定義でコンパイルエラーが出ていることである。このエラーはWebで調べてもはっきりしない。そもそも以前からオリジナルのコードにも「ねむい」さんの修正が入っている。エラーメッセージは予約語を二重定義していることを怒っているようなので、思い切って定義そのものを削除する。何故か、これで上手く行った。(未定義エラーのときは適当に設定。falseとtrueの2つだけなので余り心配ない)

 出力が問題だ。Sirius506さんのオリジナルはLCDに出している。ソースを調べているうち意外な機能を発見した。ソースコードを読む限りは、このライブラリは入出力のピクセルサイズを変えられるような感じがする。スケーラーがついていて1/8単位で縮めることが出来るようだ。良かった。これで大抵のJPEGファイルは何もしなくても表示ができそうだ(このあとreadmeファイルでも確認した)。

 出力は、今度のSPIはDMAを使ってやろうと思っているので、当面、UARTにただ16進出力を出し続けるコードにする。出てくる警告は無視し、エラーだけをつぶして行く。遂にビルドはNO ERRORとなった。フラッシュのサイズは80KBくらい。こんどの石は512KBあるので楽勝だ。

DMAが動かない(1/6/2011)
 コンパイルが通ったので、久しぶりにFPGAとSTM32基板、液晶モニターを組み立てて電源を入れてみる。おやあ、画面の上部に縞模様がでて画像が乱れている。SRAMアクセスがうまく行っていないようだ。これの原因究明までやっている余裕はない。JPEGのテストが先だ。

 「ねむい」さんから頂いたDFUSeで快調にファーム書き込みを終える。いちいちDFUManagerを動かしてDFUファイルに変換する手間が省けて効率が良い。「ねむい」さんありがとう。

 BMPファイルのブラウズのルーチンに間借りする形でJPEGデコードが動くようになっている。JPEGファイルをいくつかSDカードに入れてテスト。画面には出てこないがUARTに16進ダンプが流れる。

 よし、暴走せずに終わった。ふむふむ、このデコードは1行単位のようだ。頭の部分しか表示していないので何ともいえないが、ビットマップデータらしいコードが出ている。同じデータでなく変化しているので、JPEGデコードはうまくいっているようだ。

 このプログラムのもともとはChaNさんのFatFSのARM版である。ChaNさんのFatFSには速度を測るタイマーがついているのを思い出した。調べてみる。あった。これは1ms単位で測れるルーチンで、ARMではsystickを使って実装している。これを最初コメントアウトした時間計測のルーチンに使わせてもらう。

 640×480のJPEGデコードは、900msくらいかかっていることがわかった。これまでのBMPファイルでの送出が、2秒近辺なので、あわせると3秒。うーむ、やっぱりDMAを使いたいな。JPEGがデコードし終わってから、SPIで送るのだが、DMAを使えば、SPIの転送とJPEGデコードをかぶらせて処理時間を短縮できる。

 えらそうなことは言っているが、当研究所ではDMAの実装は始めてである。大型コンピューター時代から理屈はいやというほど知っているが(大型機ではチャネルと呼んでいた)、実際に動かしたことはない。8ビットのAVRにはない機能で前からマスターしたいと思っていたが機会がなかった。

 STM32のDMAを調べ始めた。ここが一番詳しい。しかし、SPIの例が見つからない。設定はわかるが、どうして動かし始めるのかが良く分からない。サンプルコードはタイマーの割り込みがスタートになっている。SPIの送信は何がトリガーになるのだろう。

 こういうのは動かしてみるのが一番だ。見よう見まねで、コードを掻き集め、コーディングをすませて実際にテストしてみる。しかし、ピクリとも動かない。オシロで見てみるが全くSPIは動いていない。

 こうなると意地になるのが癖である。片っ端からウェブでDMAを勉強する。わからない。暫く経ってから、突然、本体のFatFSがDMAを使用していることに気づいた。あわててソースを読み込む。ふむふむ、DMA転送の度に、初期化をしている。おお、ひとつコマンドが抜けていた。SPI_I2S_DMACmd()というコマンドがSPIとDMAをつなぐ。そうだよな。おかしいと思った。

P1113583

 勇躍、コードを入れ替えテストする。よーし、何か画面がでたぞ。バッファーがずれているようで縞模様にしかならないが、やっとSPIがDMAで動いた。嬉しい。あとはデータの位置を直せば画面が出るだろう。それにしてもDMAは大変だ。

やっとJPEGで画像が出た(1/8/2011)
 DMAは動いたが、まともな画像が出てこない。JPEGライブラリが本当に画像をデコードしているのか確かめないことにはDMAが悪いのかどうかはわからない。で、DMAの開発を一時中断し、時間はかかるがSPIでJPEGデコードデータを検証することにした。

 JPEGは3バイトのフルカラービットマップで出てくる。これを16ビットRGBに変換してやる必要があるが、これはすでにBMPのところでやっている。それをそっくり持ち込んでJPEGをSPIで出すコードはすぐ出来た。

 テストする。おおお、確かに画像が出た。BMPとスキャンが逆なので(BMPは下から、JPEGは上から)、画像が天地さかさまで、画面上部が例のSRAMトラブルで乱れているが、きれいな画像データが表示されている。

P1083566

 いやあ感激の一瞬である。FPGAを使ったフォトフレームプロジェクトは遂に、第8ステップをクリアした。ARMのJPEGルーチンがやっとのことで動いたのだ。いくつかJPEGファイルを入れてみる。1024×768のファイルも問題なく表示された。スケーリングもしている。

 それに何となくDMAを使って表示しているときより早いような気がする。DMAからはまだまともな画像にはなっていないが、こんなに早くはなかった。一息ついていた。気になったので、DMAに戻して例の時間計測ルーチンをファイルの読み込みから画像を出すまでに入れなおして時間を測ってみた。

 何と何と、結果を見て驚いた。勘はあたっていた。DMA経由より、SPI単独の方が早いのだ。3つのJPEGファイルでテストしているが、どのファイルもDMA転送では、2.1秒近辺なのに対し、DMAなしが1.7秒程度と、20%以上も早い。ついでにBMPファイルでの表示時間も測ってみる。これは2秒前後であった。何だとDMAの方が遅いじゃないか。

 JPEGが早いのは、読み込むファイルのサイズが1/4しかないことが大きな理由であろう。DMAが遅いわけは、まだ良くわからない。DMAルーチンは元のFatFSのコードを参考にしておりDMA転送の度に初期化をし(Deinit)、設定し直して動かしている。この時間が長くかかりすぎているのかもしれない(Deinitをはずすと動かない)。

 次のDMA転送のために全部のデータを送り終えるまで待つようにしているのをバッファーの半分で開始するようにしたら

while(DMA_GetFlagStatus(DMA1_FLAG_HT5)== RESET); // TC5からHT5にする

2秒から1.7秒程度に縮まった。しかしこれでもSPIで送るシリアル処理と同じ程度だ。DMAの意味がない。それにDMAはまだまともな画像が出ない。

P1093579

 ソースコードはまだぐちゃぐちゃだし、BMPとJPEGの画像の天地の問題も解決されていないし、画像の上部には縞模様が出たまま(これはあとで接触不良が判明し解決した)で、問題山積というところだが、まあ、そうは言っても、フォトフレームプロジェクトは、第9ステップの実装を残すところまで来た。このあたりでブログに報告することにしよう。
(追記:上記のDMAの問題は、すべてこちらのコーディングミスでした。後記のブログ記事参照)

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

« 2010年12月26日 - 2011年1月1日 | トップページ | 2011年1月16日 - 2011年1月22日 »