開発日記

近況

諸事情で休止期間が入っていますが、MCU からのファミカセ操作の続きです.

今月にはいってからブートローダの作成、タイムアウトの実装、ROM dump が実装できました. ROM dump は DMA を利用するのでかなり早いです. 0x80000+0x40000 bytes の dump が 3 秒で終わります.

現在は flash programming の実装中です. flash programming は kazzo にある問題を解決するために仕様が複雑になり、MCU 用のコードを書いても細かい分析が実質不可能になっています. 対策として制御用コードを機種依存コードを排除して PC でもコンパイルできようにしてテスト環境を作ってシミュレータと称してデバッグを6月中にやっていました.

昨日ようやく flash programming の MCU 側での動作確認が始まりました. これに到達する前にシミュレータでは動くのに MCU ではなぜか止まるという現象が2件あり、原因分析にめぼしのありそうな場所をコメントいれたりして非効率な作業を行うことになりました. 奇数アドレスで uint16_t * の演算を行う address alingment error であったり*1 DMA の writeback レジスタの初期化を間違えていて、シミュレータでは起きるはずのないメモリ破壊が起きていました.

Erase Polling の波形分析

現在は erase の write cycle を出して、 polling の read cycle を出して polling が完了してしまったところで止まっています. シミュレータでは起きないので雑に作っているテスト環境が悪いのと根本的な設計が悪いので直します.


その波形をみていると無駄な時間がかなりあることに気づきました.
これが polling の read cycle で、 ΔX から 52.23 us あります. 詳しく調査していませんが, 次の read cycle 生成ための DMA controller の初期化を最初からやり直してるのでその時間に無駄がありそうです. DMA なんで ROM dump のように転送バイト数が多い場合は 53 us は相対的に短いのですが、2 byte 単位だと長いです.

これは Erase なので 53 us はいいのですが、 Programming Cycle としては間隔が長いです. デバイス別に AM29F040B は typ 7us, max 300us. SST39SF040 は max 20 us (typ 記載なし)です. max 300 us は 53 us より短いので polling が必要ですが、max 20 us なら polling せずに書いていっても大丈夫な気がします.

flash は programming の空き時間があるので疑似並列処理で空き時間を有効にしているけど、実際は programming に空き時間はないので erase の空き時間だけ切り替えたほうが早い. そのような改善案がたくさん思い浮かびました. (SST39SF040 Sector-Erase max 25 ms, Chip-Erase max 100ms. AM29F040B Sector Erase typ 1 sec, max 8 sec, Chip Erase typ 8 src, max 64 sec)


次にさっきの波形を拡大したメモリアクセスの波形です. これは私から新しい発見はないです. -51.14 us から -50.64 us の間の部分は DMA を動かしているものの CPU が動いてるとこういう隙間の時間が発生しているのでソフトウェアである以上仕方ないと解釈しています. 100%無駄なく完璧にやりたいなら CPLD を使うしかないかなと思います.

同じaddress生成しているならSPIだけ動かさずに memory strobe だけ動かせば時間短縮もできる気がしますが、read 周りのシフトレジスタと共有しているのでそれはできないです. 他の改善案は CPU と PPU の region 切り替えは GPIO でやっているのでそれを DMA で制御するようにシフトレジスタを追加すると polling の時間短縮ができそうな気がします.

*1:Cortex-m0 では起きるが 同 m3 では起きないらしい