前回の DMA descriptor の構成を基礎に programming の task 切り替えを実装途中. ソースコードは大して長くないのに考えることが多すぎて非常に疲れる. 2022年8月のコードはごっそり削除. ソフトのコードでここまで密度が高いのはあまりなくて verilog かいなと思った.
programming task は bank register 書き込み後に flash programming の task を開始するという流れにして指定バイト数書き込み後に task は停まる. 指定バイト数はバンクの領域と同じにするはずだし、自動でバンク切り替えするには MCU の中の RAM が大量に要りそうとか難しそうでいまのところ実装していない. bank register 書き込みのコマンドに Erase をいれることも可能.
そんな流れで片側の領域のみだがシミュレータでちゃんと動いていることを確認している. 次は並列programmingを実装する.
このtaskの設計のために仕様書を書いてプログラムを書いて仕様書を訂正という作業がかなり長い中、fifo の制御で data 0xff が 64 byte 単位で連続する場合は飛ばせるようにするというのが、2022年夏に書いてあってそれだけは実装していなかった.
これをちゃんとやるには fifo に無圧縮のデータをいれるより Runlength で符号化したデータをいれたほうがいいということに気づいて簡単に実験するコードを作った(下記の rle_decode). Runlength の仕様は byte 0 に同じデータを繰り返す回数かバラバラのデータが繰り返す回数を 1 から 128 で記載するという基本的な方式. あまり凝ったことをしても fifo として data 0xff を飛ばすという目的に離れてしまう. その目的に離れないレベルで繰り返しdataを2byte単位にしてみたり小手先で変えてみたものの、最初の単純な仕様がデータ削減に一番いいらしいことがわかった.
とはいえ Runlength 符号の対応はなくてもいいので MCU で安定して動いてから実装することになる予定.
def rle_decode(src, limit) dest = [] mask = limit - 1 while src.size != 0 d = src.shift l = d & mask if l == 0 l = limit end if (d & limit) != 0 dest.concat Array.new(l, src.shift) next end dest.concat src.slice!(0, l) end dest end