DMAを通してやっと綺麗なJPEG画像が出た。DMAのステイタスビットは明示的にクリアしないと、初期化では元に戻らないのだ。2つバグが重なっていたためにわけがわからなくなっていた。いやあDMAを動かすのにこんなに手順が沢山必要とは思ってもいなかった。夕食に、珍しくビールをだして家族と乾杯する。家族も良く分からないまま祝福してくれた。酒を飲むと、そのあと何もしたくなくなるので最近は殆ど飲まないが、今日は嬉しいのであとはどうでもよい。STM32でSPIをDMAで動かす方法(1/16/2011)ソースコードは全体が出来てから公開しようと考えていたが、とりあえず、SPIでDMAを動かそうとしておられる方の参考のために、ノウハウをまとめておくことにする。これからご紹介するソースコードのオリジナルはここで、すべてSTマイクロの標準ペリフェラルライブラリを使うことを前提としている。レジスター単位に設定する方法もあるが、今後の運用性や、移植性を考えると面倒でも、こちらの方が便利だろう。・まず、関数は2つ用意し、初期設定のルーチンを、DMA_SPI2_Init()、DMAを動かす関数を、DMA_SPI2_Transfer()とする。DMA_InitStructure;で定義しておく。・初期化ルーチンでは、以下のように初期設定をしていく。転送データ(RGB565の1行分)を設定。以上の設定値で、DMAチャネルを初期化する。SPI2にDMAで動かすことを知らせる。DMAの初期化の終わり。DMAを使う前に実行する。・実際にDMAを動かす関数は、以下のようにし、処理ループの必要なところでこれを呼ぶ。ここでDMA転送が始まる}・DMAは必ず並行処理になるので、DMAが終わったかどうか調べる必要がある。処理ループ内で次のステートメントでDMAの処理の状態をチェックする。これはフラグだが、これ以外にも割り込みで処理する方法もある。・以上で、SPIはDMAを通してデータが送信されるようになる(受信は、全く別のチャネルで新たに設定)。ARMのDMAは、メモリ、ペリフェラル間での多彩な機能を持っているだけに、これを使いこなすのは逆に大変である。SPI側の設定は全く変える必要はない。・ペリフェラルの種類と転送先で使うDMAチャネルは一意に決まっている(マニュアルに詳しく出ている)。ペリフェラルによっては、DMAを使うということを知らせる必要があり、SPIでは上記のコマンドが必要であるが、必要でないペリフェラルもある。・また、SPIの場合は、ENABLEにした途端にスタートするが、次のスタートには必ずDISABLEにして再度、ENABLEにしないと始まらない(ここがはまる)。DMAのスタートは、これ以外に色々な方法がある(タイマー、割り込み)。ソフトで開始を始められるペリフェラルもある(ADCなど)。・さらにDMAステイタスビットは、初期化などではリセットされない。ユーザーが明示的にクリアしないとおかしくなる(ここもはまりやすい)。・データレングスは、バイト数ではない。転送単位のデータ数であることに注意。気になる処理時間だが、残念ながらDMAによって飛躍的には早くならなかった。DMAによるSPIは、ほぼスペックどおりの速さ(9Mbps)で、CPUを介して動かすときと大差ない。実測すると、JPEGのデコードは1行が2ms程度で、JPEGのデコードが予想以上に早く、全体では200ms程度しか改善されなかった(1.5~1.6秒)。動かすことが目的だったから、満足しよう。液晶モニターの電源をDC-DCコンバーターにする(1/18/2011)最終のゴール、第9ステップは、FPGA基板やCPU基板を液晶モニターケースに固定して、フォトフレームとして完成させることである。基板は、ケースに入らないので、外側に固定する。見栄えはよくないが、自作フォトフレームなのだから許してもらおう。それより電源が問題である。このあいだ液晶用の12V電源から降圧した5Vをケースの外に出してFPGAを動かしてみたが、5分もたたないうちに電源が不安定になりFPGAが誤動作した。FPGA基板の電流消費は、150mA以上あり、12Vから5Vに落とす際の消費熱量がレギュレーターの限界を超えているようだ。熱抵抗を計算してみるまでもなさそうである。ヒートシンクをつければ良いのだろうが、それより12Vからただ発熱させて5Vにするのは実に無駄である。いって、たかがフォトフレームくらいでDCアダプターを2つも使うのも非現実的だ。そこで、思いついたのが、ストロベリーリナックスで面白がって買ったDC-DCコンバーターである。5V入力で、9~20Vを出せる基板(¥945)である。9Vバッテリー(006P)をリチウム充電池で作ろうと買ってあった。高かったが、こいつ小さくても出力電流は500mA以上とれる。液晶モニターのインバータ電源(12Vで実測300mA)にしても問題ないはずだ。基板にピンを立ててブレッドボードでテストした。最初、ブレッドボード付属の5Vアダプターが昔の0.36Aしかとれないやつで、負荷をかけると電圧が上がらず、点灯しなかったが、2Aのアダプターでテストすると問題なく動作した。よし、これで電源周りは効率良く(DC-DCコンバーターの効率は90%近いので発熱もない)なった。今のところ、ディスプレイのインバーターが5V換算で0.7A、ロジックが0.13A、FPGAが0.15A、STM32が0.04Aなので、合計で1A少々。2A程度のアダプターなら全部をまかなっても余裕だ。液晶モニターのコネクター基板の工作を始めた。ついでにBMP画像を出すことをあきらめて、JPEGのため画像のスキャンを下から上に戻す修正もする。DC-DCコンバーターがコネクター基板に載らないので、汎用基板の小片を追加してハンダ付けする。レギュレーターをはずして配線を変更する。