コミックマーケット80で暑い中ブースを見に来ていただいた方、どうもありがとうございました。
そして、本が売り切れだった方、行ってみたら撤収した後だった方、すみませんでした。
今度からのイベント参加では、十分な数を用意するようにします。

さて、頒布していた本の「FPGA向けMPEG2デコーダ」の記事について、現状のソースコードを公開します。

m2v_dec_impl_r250.zip

1つめはデコーダIP本体、2つめはデコーダIPのテストに用いるソフトウェアデコーダです。
いずれも最初にreadme.txtをお読みください。

現状、
・単体テストは入力データ終端の取り扱いが上手く行かないかもしれません(=テストの最後でデータの取りこぼし等発生するかもしれません)
・結合テストは3フレーム目以降は動かないかもしれません。
・実機ではまだ動きません(ダレカタスケテ...)。回路図等もまだ含まれていません。
と、ひどい有様です。ただ、完璧を目指していてはいつまで経っても公開できないので、
大きな修正がある毎にアップしていきたいと思います。要望が多ければ管理しているsubversionのリポジトリ自体を見てもらえるようにできるかも。

前回のmakeから取り組んでいるプロジェクトなので、やりきってしまいたいですね。もうちょっと頑張ろうと思います。

気がついたら3ヶ月ちかく更新さぼってました...。

いきなりですが、夏コミに出展しています!本日(土曜日)、東地区T-02b サークル「silicombi」です!

今回の記事は「FPGA向けMPEG2デコーダをほぼフルスクラッチで作ってみた」です。
動画再生挑戦結局結合デバッグが通り始めたところまで進捗しましたので、そこまでの内容を書いています。

なお、ソースコードを当ブログで配布しますが、会場からのネットワークでトラブっているため、後日アップロードします。
ソースコード目当てで来られた方、申し訳ないですが少々お待ちください。

ずっとMPEG2の作業ばっかりやっていると、たまに違うことをやりたくなるわけでして。
先週、無性にアートワークがしたくなった時があって、ちょうどあったフリスクの空きケースを見て
思ったわけです。
「神は言っている。フリスクサイズのマイコンボードを(ry」

で、ありきたりではありますが、設計してみました。
フリスクケースに収めれば、携帯オーディオプレイヤーに。普通にピンヘッダつければブレッドボードでも使えそうなマイコンボードに。

使ったマイコンは最近秋月で単品販売を始めたルネサスRX(R5F56218BDFP)です。デコード専用IC等は載せません。
検証してませんが、たぶんRXならソフトウェアデコードできるだろう、と思いまして。

回路図はこちら3枚。
frisk-rx1.sch.sheet1.png frisk-rx1.sch.sheet2.png frisk-rx1.sch.sheet3.png
または→frisk-rx1.sch.pdf

ご覧になると分かるとおり、まだ定数値をTBDにしている箇所が結構あります。
(まだ何にも考えずに作っている証拠ですw)

現時点でのレイアウトも載せておきます。
frisk-rx1.brd.top.png frisk-rx1.brd.bottom.png

なお、今回のマイコンはD/Aが1chしかありませんので、別途D/A (MCP4922)を載せました。
そして、その基準電圧をRXの持つD/Aから出すようにしてみました。MCP4922は
出力段のアンプでゲイン2倍を選べるので、RXのD/A出力を中心に振ることができるうえ、
そのD/A電圧でボリューム調整ができるのでは、と思ったためです。
これでまっとうな音が出るのかは、試してないのでまだ不明です。
※詳しい方、ぜひツッコミいただけると嬉しいです。

とりあえずアナログ部分の試作評価と、ソフトウェアデコードが出来るのかをRX-Stickでも使って検証していきたいと考えています。

今回はMPEG2デコードIPの全体構成についてです。

その前に、まず動画像の基本を軽く解説します。
動画像とは、パラパラ漫画のように複数の静止画を連続して表示することで実現されます。これについてはご存じの方が大半でしょう。この静止画のことをフレームと呼びます。

問題はフレームの情報をどうやって圧縮するかです。1枚1枚をJPEGなどで圧縮すれば良さそうに思えますが、それだけでは圧縮率を上げることが出来ません。
そこで、動画像の時間的連続性を利用します。

動画像では多くの場合、連続する2枚のフレームの間に共通要素があります。シーンチェンジの瞬間を除き、前後2枚が全く別の画像になることは稀で、
・カメラの動きによる背景の移動
・物が動くことによる、一部の画像の移動
・全く変化無し
など、少なからずとも共通点があります。そこで、1枚前のフレームからの差分を用いることで、データ量を減らす工夫をします。

mpeg2mb.png

また、MPEG2ではフレーム内を図のように空間的に分けて取り扱います。16x16ピクセルの領域をマクロブロック と呼び、1つのマクロブロック(MB)は6つの小ブロック からなります。(分かりやすくするために私は「小」ブロックと読んでますが、規格書ではただの "block" と表されています)
小ブロックは 8x8 のサイズで、輝度成分4つと色差成分2つの計6つです。

なお、MPEG-2規格そのものについては書き始めるときりがないので、当ブログではあまり詳しく解説しません。
その代わり、
・「MPEG Video 技術」 http://home.catv.ne.jp/dd/pub/book/mpeg.html
・規格仕様書「ISO/IEC13818-2 Information technology -- Generic coding
of moving pictures and associated audio
information: Video」
などが参考になります。規格書は本来無料で手に入るものではありませんが、ドラフト版ならばネットで探せば手に入ります。
(大学の理工系図書館や、けいはんなの国立図書館なら正式版を読めるかと思います)


ふぅ、導入だけで書き疲れてしまいましたが、ここから本題のIP構成です。

mpeg2blocks.png

青色の枠が自作するモジュールです。

vctrl ・・・ 入力したビットストリームを解析し、デコードの必要な情報の取り出しと、画素データをrun&lengthペアに分解するところまで行います。run&lengthペアとは、量子化されたデータから、非ゼロの値と、その間にあったゼロの個数とをペアで表したものです。8x8の小ブロック単位で取り扱うので、最大64項目あります。

vdequant ・・・ run&lengthペアと量子化係数を用いて逆量子化を行います。vdequantを出る時点で、各ブロックのデータは8x8の周波数領域画素データになっています。

vidct ・・・ 8x8のIDCT(逆離散コサイン変換)を行います。vidctの出力は、8x8の空間領域画素データになります。

vmc ・・・ 動き補償を行います。前述の通り、MPEG2では直前のフレームとの差分を用いるので、前フレームの参照MBを計算し、vidctからの画素データを足し合わせて、最終的な画像を作ります。作った画像はフレームバッファにいったん格納します。

vdispdrv ・・・ 1枚のフレームをすべて処理し終わったあと、フレームバッファから画像を読み取ってLCDに転送します。

ざっとこんな感じ。すでに全てのモジュールを書き終えていて、単体でのデバッグを進めている段階です。

さて、次回はもうちょっと詳しい内容に踏み込んで書こうと思います。今日はここまで。

復活後一発目の記事では、まず現在作業している内容について紹介しようかと思います。

過去にはMP3プレイヤー(を途中まで)とかアンプ(今は訳あって使ってないけど)とかを書いてましたが、今はちょっとお休みしています。

現在はというと、MPEG2デコーダIPの製作を進めています。
この手のものって市販のIPが存在するので新規性はないんですが、動画コーデックの勉強を兼ねているので良しとします。

その代わり、
  • XC3S250E (Xilinx Spantan3E) ×1の中に収める。すなわち、DWM2007年7月号の付録基板で使えるようにする。
  • フルスクラッチで作る (=OpenCores等からIPの一部をコピーしたりしない。全部自分で書く)
  • (後に述べる)制約条件さえ満たしていれば、MPEG2の規格通りのストリームを処理する。(=コーデック仕様を都合に合わせて勝手に改変しない)
を目標にしています。

まあ、規模の小さいFPGAなんで、解像度が高いのとかはもちろん無理で、以下のように条件を設定しています。
  • MPEG2 PS (ISO13818-2) に準拠
  • 解像度は最高 320x240 (QVGA) まで
  • フレームレートは30fps固定
  • プログレッシブ形式限定
  • フレームタイプは I と P のみ許可
などです。
実は、これをmakeで出したくて前回のMTM06に参加してました。もちろん完成してませんでしたが^^;
会場で見に来てくれた方に次回こそは完成品持ってきます!なんて言っちゃったので頑張って作らないとw

というわけで、これから何回かに分けて製作の様子を公開していこうと思います。
実機で走るレベルまで達成したら、ソースは公開するつもりです。お楽しみに。(MPEG2はライセンス問題とかグレーなところがありますが、趣味でだれでも使えるようオープンにして、いろんな人に使ってもらってこそ取り組んだ甲斐があるので...)

今回は取り組みの紹介まででしたー。
最終投稿が2009年10月というヒドイ放置状態のブログですが、そろそろ復活させようと思います。

(ブログ開設時はJustsystem経由のTypePadで始めましたが、サービスの有料化に伴い
さくらのブログにこっそり引っ越し、さらに、さくらブログの扱いにくさに辟易して
さくらのレンタルサーバ上にMovableTypeを構築して引っ越ししてきました。)
今ご覧になっているこのブログ http://kimushu.thyme.jp/blog/ が今後更新されていきます。

社会人になったこともあり今までほどの工作ペースは出せないかもしれませんが、
今後も「ぼちぼち」工作記録として綴っていこうと思います。

なお、過去の記事もコピーしてきましたが、画像および添付していたデータを紛失していますorz
ご了承ください

(紛失分データはバックアップから発掘でき次第upしますが、たぶん復活しないファイルも多々ありそうです...どうしてこうなった)

電源を使ってみた

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

先日組み立てた電源を使ってみました。評価をするといっても、素人なのであまり
どういう点を見ればよいのか分かりませんが、まずはオシロで波形を。

sany0028.jpg 今回計測したのは正負両電源の方です。可変抵抗を調整して±7.5Vが出力されるようにしました。

AC100Vからは、RSで買ったトロイダルトランス(9V×2系統出力)を通してAC9V×2とし、それを電源基板のAC入力につないでいます。
ちょっと机の上がカオスになっているので実験の様子の写真はご勘弁を(笑)


負荷にはブレッドボード上に組んだOPA604+LT1010アンプをつなぎましたが、今回は無音(入力信号0固定)の状態として正負電源出力部の電圧を見ました。なお、無音時のアンプの消費電力は正負ともに46mAでした。レギュレータがほんのり熱くなる程度。

前回コメントで指摘いただいたリプルの少なさは嘘じゃないようですね。60Hzとかその高調波らしきものが見つかりません。ただ、負電源側にややノイズが入っています。

んー、一度LM2941と2991のデータシートを比較してみたほうが良さそう。
続きはまた次回で。

気づいてみたらほぼ半年ぶりの更新orz

久々の更新は、いま取り組んでいるヘッドフォンアンプです。
なおMP3プレーヤーは、デバッグ大変→信号見たい→ロジアナ欲しい…というわけで開発停止中。

そもそもの発端は、ちょっと奮発していいヘッドフォンを買ったものの、以前作ったUSB-DACでは力不足で全然ドライブできていないじゃん!となったためです。

そこで、「USB-DAC+ヘッドフォンアンプ」を作ることにしました。

まだ書きかけですが、回路図+ボード図は(これらのデータは趣味での製作用途に限りお使いください。商用利用は禁止いたします。)

まず、電源基板(Sheet#1)から。電源はトランス出力を受けて、
全波整流→平滑→シリーズレギュレータで安定化
というポピュラーな流れのものです。ただしアンプ用の正負両電源です。
また、それとは別に正の方からUSB-DACの電源(+3.3V)も取ります。
正負電源は電圧を何処まで確保できるか分からなかったので可変としています。
最終的には±7Vぐらいで使うことになりそう…。

どこぞのオーディオの基板のように、電解コンデンサをいっぱいならべてみました。

写真はレギュレータICとIC出力近傍のタンタルを除き、他の部品を実装した状況です。敢えてICを取り付けずに、この状態でコンデンサに直接電圧(コンデンサの耐圧ぎりぎりで)を与えて「エージング」をしてみました。

コンデンサを半田付けしたときの熱で、性能が劣化するようで、それをエージングで修復できるそうです。そこまで気をつかったことがなかったので、初めての試みです。
手持ちのDC電源が一台しかないので、正側と負側を交代交代で10時間ずつ行いました。
正直言えばその10倍(100時間)くらいやりたいところですが、通電したまま家を出るのが
ためらわれたので、在宅中だけでこつこつやり、10時間で切り上げました。
(あとは実際使い始めてからのエージングに期待)

さてエージングを終えたら、ICの実装です。

正負電源のレギュレーションにはナショセミのLM2941-LM2991ペアを使いました。TO220の5本足で、数少ない「LDOかつ可変かつ負電源用もある」ペアです!

写真のように、45度傾け、足を交互にずらすと2.54mmピッチに実装できます。なお、黒いのは+3.3V用のレギュレータです。


ちなみに裏はこんな感じです。グランドはスズメッキ線ではなく、
銅箔テープ(サンハヤト T-30C)を貼り付けて直接半田付けしています。(回路図でメッシュになっている部分です)


回路図に書いていますが、記事にも型番を記しておきます。
ブリッジ:東芝 1GWJ42(ショットキーバリア)×4本
ブリッジ出力平滑:東信 1CUTWE222M×2個(正負1個ずつ)
レギュレータ:LM2941T(正)、LM2991T(負)、TA48033S(+3.3V)
レギュレータ保護ダイオード(出力側の方がコンデンサ容量大きいので):V19B (ファーストリカバリ)
レギュレータ出力平滑:東信 1CUTSJ102M0×8個(正負3個ずつ、+3.3Vに2個)

電源評価およびUSB-DAC、アンプの本体についてはまた後日紹介したいと思います。

先日、突然avr-usbの本家サイトが閉鎖してしまいました。
どうやら「AVR-USB」という名称がAtmel登録の商標に引っかかるとのこと。
新しい名前にして復活します、との予告があったので楽しみにしていました。

そして今日、復活しました。
その名も「V-USB」です。Virtual USBの略らしい。
本家サイト:http://www.obdev.at/products/vusb/index.html

・・・ヴァーチャル?なんかしっくり来ないな~と最初は思っていましたが、
virtualの意味を再確認して納得。
英英辞典「virtual」alc英和辞典「virtual」
つい2番の意味で考えたからしっくり来なかったんですね。このV-USBのvirtualは1番の意味ですね。なるほど~。たしかにピッタリ。
英和辞典だといまいちピンと来ないですが、英英辞典だとよく分かります。

というわけで、avr-usbあらため「V-USB」誕生を素直に喜びたいと思います。ぱちぱち。
このブログでも、V-USBを使ったプロジェクトを色々考えていくつもりです。
でも、まずはMP3プレーヤー作ってしまわねば…

MP3プレイヤーの操作部には、PSoCのCapsenseを使うつもりでいます。Capsense部は基板を分けてPSoCとタッチパッドのみのパターンにしておき、メインコントローラとはI2Cで通信することにしてあります。プレイヤーに関してはまだ時間がかかるので後日レポートするとして、今日はそのI2Cテスト用にUSB-I2Cブリッジを製作したので紹介します。

USB-I2Cブリッジとは要するに、USB経由でパソコンと繋ぎ、PCからI2C機器とやりとりするためのアダプタです。手持ちの部品で何とかならないかなと思っていたらありました。

・i2c-tiny-usbプロジェクト (http://www.harbaum.org/till/i2c_tiny_usb/)
前に作ったHIDaspxも利用している、AVR-USBを用いたI2Cブリッジです。ATtiny45でUSB-I2Cブリッジを作ってしまおうというものです。すばらしいですね。

ただ欠点が。上記プロジェクトのハードウェアはクロック外付けのため、ピン数の都合上 RESET# ピン(Pin1)をI/Oとして使っちゃってます。それでファームのプログラムにHVSP (高電圧シリアルプログラミング)が必要になってしまい、ライタとしてSTK500とかAVRDRAGONとかがいるんです。どちらも持ってないので困った困った。ところが今は内部RCクロックを使ってAVR-USBを動かしてしまう例があるのです。それが EasyLogger (http://www.obdev.at/products/avrusb/easylogger.html) です。

で、組み合わせてみたのが今回作った内蔵オシレータタイプUSB-I2Cブリッジというわけです。
usbi2c-20090401.zip

上のzipには、回路図/ボード図PDF/Eagleデータ/ファームウェアソース&バイナリ/テスト用コンソール&バイナリが入っています。オープンソース・オープンハードウェアプロジェクトですが、Eagleデータは商用利用への転用を禁止します。


回路は非常に単純な構成となりました。i2c-tiny-usbの回路からクロックを外し、I2Cの出力ピンを変更した程度です。

USBのコネクタが逆なのは、作り始めてからピンの順番(1→4)を逆で設計していたことに気がついたからです^^; 手持ちで68Ωが無かったので75Ωにしたり、結構アバウトです。なにより、使ったマイコンがATtiny45-20PUではなく、ATtiny45V-10PUです。ファームは16.5MHzで動かすのでオーバークロックになりますが、実際やってみたらちゃんと動いたのでそれで良し、ということで。汎用の操作コンソールツールを作って(tool/usbi2c.exe)、試しにEEPROM (AT24C256)の読み書きをやってみました。


I2CはSCL、SDAラインをプルアップする必要があります。ブリッジ側ではプルアップを入れていない(3.3Vのターゲットを繋ぐ場合への考慮)ので、ターゲット側で10kΩプルアップを入れました。

なお、usbi2c.exeのコマンド構文は

(Write)      <SLA>:<DATA0> <DATA1> ... <DATA n>
(Write&Read) <SLA>:<DATA0> <DATA1> ... <DATA n>,<LEN>
(Quit)       q

※<SLA>…Slave address (8~119) in hexadecimal
         If omitted, previous SLA will be used
※<DATAn>…Write data byte in hexadecimal
※<LEN>…Read length in decimal

Examples with 24C256 (SLA:0x50)
* Read 8 bytes from address 0x0000
> 50:00 00,8

* Write 3 bytes ("ABC") to address 0x0120
> 50:01 20 41 42 43

です。(なんか<pre>~</pre>の中で日本語を使いたくなくなるのは私だけ?)
EEPROMの読み書きは問題なくできたので、ちゃんと通信出来ているようです。今度デジタルオシロの有るところに持って行って、通信波形を確認したいですね。というか家にデジタルオシロ欲しい。あぁ、AVRDRAGONも欲しい…。

AVR-USBはやっぱり素晴らしいですね。今後もいろいろ作っていきたいです。内蔵オシレータも面白いですが、tiny2313や12MHz水晶を大量に買い込んでおきたいですね。