FM3マイコンを使ってみる3 -FatFsとTFT液晶表示の実装-

今月(2012年7月号)のInterface誌は予想に反して私のようなホビイストには
とてもありがたい内容となっておりました。
ねむいさんは正直Windowsネイティブな環境でもGCCでビルド
デバッグできるのになぜか面倒なcygwinを使わせた上糞の役にも立たないLED
点滅で終わらせて実用的な作例はIARとかKEILのIDEのみで行って「んんんn〜〜!!!
GCCは面倒ですぞ〜!CQ出版がお勧めするIARやKEILを使ってくだされ〜!1!」
って
販促するパタンで畳み掛けると思ったのですがどうせなら開き直ってDS-5とか
推せよとかいつも思っていたのですが今回は全然そういう事は全くなく、
オープンソースなソフトウェア(OSS)をフルに活用した記事が満載でした。
もちろんOSSにもメリットデメリットがあって邑中 雅樹氏の講演のスライド13p目
それが集約されていると思います。タダより高くつくものはないです。
しかしながら趣味でやる場合は互いに情報を出し惜しみすることなく情報を
やり取りすることによって敷居を低くできるので横のつながりを大切にして
いきましょうね。

私も"ねむいさんのページ見てもわかりづらくてOpenOCD動かせられなかったけど
他の人のページに書いてあるやり方だったら一発で出来た"と言われないような
記事作りを心がけて行きます(←まだ根に持ってる)




…さて戯言はこの辺にしといてFM3マイコンはFatFsとシリアル&i8080バス
接続タイプのTFT-LCDドライバを使ったいつものの実装を目標と
しています。FM3のデータシートや
アプリケーションノートは情報散らばりすぎでいまいち組み方がわかりづら
かったのですが、上記IF誌に収録されていた作例にわかり易いサンプル例が
多数収録されておりそれを最大限に活用させていただきました。


●UARTとFatFs
UARTは前回行ったのと同じですが、前回jujurou氏よりコメントいただいた通り
SRAMの割りあてはSTM32F4の時のように目くじら立てるほどのことではないことが
判明しふつーに128kByteの内蔵SRAMとして使うことにしました。私が試した限りでは
すべてのSRAM領域でDMA可能でなおかつコード実行も可能でした。

というわけでChaN氏の作例にならってMFSを使ったMMC用のドライバも作り、
危なげなくFatFsも動作確認しました。ちなみにChaN氏はDMAを使用せずFIFOを
使用していますがSCKを18MHzにしたリード速度は下画像のようになりました。

STM32F107(DMA転送)の時とほぼ同じですね〜。SPIモードの場合の理論上の
転送スピードは18MHzの時約2.2MByte/Secになりますから無理してDMA化する必要が
なかったようですね。尤もFM3においては内部の遅延により+3.3V駆動の際に保証
されるSCLKの最高速度は7.2MHzにしかならないそうです。
STM32F4とかはSPIでも42MHzまで叩き出せるのにs**kです。


●シリアル接続タイプのTFT-LCD
扱いも容易でaitendoさんで手軽に購入できるようになったシリアル接続タイプの
TFTLCDも、FatFsの時と同じくMFSを利用してHALを作りました。もちろんGPIOによる
ソフトウェアSPIにも対応していますが…FM3のGPIOはAPBバスにぶら下がっていて
なおかつ1HCLK分ウエイトが掛かっているようでGPIOの出力レジスタに8bitのデータ
投げるような単純にstr命令だけが連続するような操作でもMAX12MHz、ビットバンド
領域の単純なビット操作はその半分のMAX6MHzしか出ないことが判明し、あまりお勧め
できません。

↑0xFFと0x00を交互にPDORFxに全速力でブン投げた時のI/Oトグル波形…
 STM32F1(18MHz)以下ですかorz

↑ビットバンドなアクセスの場合はCortexの仕様上最短2クロックサイクル
 かかるのでさらにその半分orz
 TFT-LCDのRES線制御等の1ビット分だけの制御の場合はリードモディファイ
 ライトが行われないビットバンド領域のアクセスの方が早いです。
 ちなみにFM3にはSTやNxP系ARMマイコンにあるGPIO出力ポートのビット
 セット/リセットレジスタなぞありませんorz

また、上のFatFsの話の時は7.2MHzしかSPIの速度が出せないと述べていますが
リードのことは考えずただLCDにシリアル信号をブン投げるだけなら18MHzでも
全く問題ないのでどしどし使いましょう。とくにFM3では9bitシリアルもハード
ウエアで設定可能であり、9bitシリアルにしかI/Fが対応していないTFT-LCD
モジュールなどでは速度面で重宝します。

↑ということで9bitシリアルにしか対応してないHX8340B(N)なTFT-LCDモジュールを
 ハードウエア9bitSPIで動かしてみました。表示が早くなって感激です!
 これでNokia6070その他9bitシリアルな液晶さんたちが救われます!ちなみに…、

 いないさんの大事な部分が見切れていますがこれはPNG表示ルーチンの仕様です。


●外部バスとi8080バス接続タイプのTFT-LCD

今回のFM3基板に乗っかっているチップはA24までExternalBusInterfaceとして
アドレスバスが出せられます。
とはいえLCDを駆動するだけならアドレス線は一本だけで十分ですが…

こちらに関しては7月号の付録に収録されている松浦氏のMP3プレーヤーのLCD/SRAM
アクセス初期化部をかなり参考にさせていただき、さらにSTM32/LPC2388のように
柔軟性を上げて作り込みました。
今回の松浦氏の紹介にあるMP3プレーヤーの基板の回路に互換性をもたせてあります
ので他の方も再現できると思います(タッチパネル制御はADCを使用せず、ADS7843に
任せていますので非互換です)

↑この写真ではすでにタッチパネル制御も入れてます。

●タッチパネル制御
タッチパネルによる座標情報はタッチパネルコントローラICであるADS7843を
使用して得ています。AD7843はSPI通信の信号はかなり遅めにする必要があるので
簡素なGPIOによるソフトSPIでも十分間に合います。

さて、タッチパネルはキャリブレーションが必須ですが、キャリブレーションした
後のデータはこのFM3基板上実装されたFRAM(MB85RC16)にストアしました。
こちらに関してもChaN氏がFRAM向けのI2Cドライバとして実装されていたので
こちらを活用し、ストア・リストアするルーチンを作り込みました。
使用していて気付きましたが、やはりFRAMであってもWRITEを行った後は少し
ウェイトを挿入しないと次のWRITE操作に影響が出ることが分かり、なるべく
一つのデータにまとめて一つのWRITE操作で書き込むようにしています。




…ということでChaN氏のFatFsとファイラを実装して動かすという当初の目的が
達成されたわけですが、PWM出力と外部SRAM、あと外部SRAMとのDMA転送も試して
みたいのでもう少しコードは練った上での公開とさせていただきます。
公開しています。

STM32F0とXMEGAのFatFsのDMA化とTIのStellarisと東海自然歩道のネタが次に控えて
いて書くことがたくさんあり過ぎますがもう少しだけFM3です。



おまけ:FM3マイコンの性能やデバッグ効率を上げる小ネタです。

●FM3のパフォーマンスをアップする
HCLKが72MHz以上の時、FM3はプリフェッチバッファが有効になるそうですが
(元から有効化されてるみたいですが)この時さらに先読みした命令をストアできる
トレースバッファを有効化することもできます。FUJITSU提供のテンプレートでは
有効化するルーチンは無いので自分で挿入する必要があります。
消費電流は100mAオーバー(HCLK=144MHz時)で結構発熱しますがそれを厭わない方は
ガシガシ使って行きましょう。





●OpenOCD経由のフラッシュ書き込み速度を増加してデバッグ効率のアップ
現在のOpenOCDのFM3のフラッシュ書き込みルーチンは、I/Dコードバスに
ぶら下がった内蔵SRAM領域にフラッシュ書き込み操作とフラッシュに書き込む
データをJTAG/SWDで転送・実行していますが、ワークメモリの容量はハード
コーディングされています。128kByteもあるMB9BF618Tではもっと大容量の
メモリを確保可能なのでこの部分をデバイスID別に可変にするようにしました
(MB9BF618Tの場合は32768Byteにしました)。

ワークエリア増やしてもあんまし変らんだろと思っていましたがなんと
驚くべき結果が!!!!!

> "C:¥Devz¥AVR¥WinAVR¥utils¥bin¥make.exe" program
openocd -s C:/Devz/ARM/OCD/tcl -f interface/jtagkey2.cfg -f target/mb9bf618t_flash.cfg -c "mt_flash main.elf"
Open On-Chip Debugger 0.6.0-dev-00595-g445a54a-dirty (2012-05-26-12:03)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.sourceforge.net/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
adapter_nsrst_delay: 100
jtag_ntrst_delay: 100
trst_only separate trst_push_pull
500 kHz
cortex_m3 reset_config sysresetreq
verify Capture-IR is disabled
Info : device: 6 "2232H"
Info : deviceID: 67358712
Info : SerialNumber: 22222222A
Info : Description: Amontec JTAGkey-2 A
Info : max TCK change to: 30000 kHz
Info : clock speed 500 kHz
Info : JTAG tap: mb9bfxx8.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
Info : mb9bfxx8.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : JTAG tap: mb9bfxx8.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x00000114 msp: 0x20010000
Rize up to Internal PLLed Clock!
15000 kHz
auto erase enabled
Info : Fujitsu MB9Bxxx: Sector Erase ... (0 to 9)
Info : Fujitsu MB9B500: FLASH Write ...
wrote 1048576 bytes from file main.elf in 18.625118s (54.980 KiB/s)
verified 941740 bytes in 0.828131s (1110.534 KiB/s)
Info : JTAG tap: mb9bfxx8.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
shutdown command invoked

> Process Exit Code: 0
> Time Taken: 00:21


なんと
wrote 1048576 bytes from file main.elf in 18.625118s (54.980 KiB/s)
となって、前々回と比べると5倍以上高速化出来るようになりました!
なんというか新生青銅聖衣を装着して敵の本拠地にカチ込まんとする
星矢さんのような"よぉしこれで全力で戦える!!!"な気分です。


一通り検証も終わったのでOpenOCDビルド時のFM3向けパッチとして公開しています
今回のパッチはiruka氏とjujurou氏の物を合わせたのをベースにしてます。
また、OpenOCDのFM3向けコンフィグファイルと組み合わせないと性能が
出ないので上のOpenOCDのビルド&デバッグ方法をよく読み試してください。

Go to top of page