2次元DMAのCURR_Y_COUNTに注意

By 酔漢 - Last updated: 日曜日, 7月 8, 2012 - Save & Share - Leave a Comment

昨日知り合いとBlackfin関連の話をしていたところ、「2次元DMAのバッファ管理には問題があるのか」という話しが出ました。数年前にそう言う事があった気がしましたが、さすがに記憶が薄れています。

調べ直してようやく思い出しました。CURR_Y_COUNTをバッファ管理に使う場合には、トリプル・バッファ以上にしなければなりません。ダブル・バッファでCURR_Y_COUNTを使う事はできません。

これは、CURR_Y_COUNTの特殊な動作のためです。CURR_Y_COUNTは、DMAコントローラが現在何番目の行転送を行っているか管理するためのレジスタです。このレジスタはCURR_X_COUNTと対で管理されています。CURR_X_COUNTは列カウンタで、1転送ごとにデクリメントされます。CURR_Y_COUNTは行カウンタで、1行転送終了後にデクリメントされます。

BF533のHWRやBF51xのHWRで確認すると、CURR_Y_COUNTのアップデート・タイミングは以下のようになっています。

何も問題無いように思えますが、とんでもない落とし穴が潜んでいます。行転送割り込みは行内の最後の列の転送完了で発生します。これを表で表すとこうなります。

転送終了した行番号

CURR_Y_COUNT
3 2
2 1
1 1
4 3
3 2

1行目と2行目の区別を付けることができません。

このようなことがおきるのは、2次元DMAの最後の転送でCURR_Y_COUNTが更新されないためです。結果的に、2次元DMAを使ってダブル・バッファを実装しても正しく転送中のバッファ位置を知ることはできません。最低でもトリプル・バッファを使う必要があります。

なお、DMAデスクリプタのリンクを使う場合には、ダブル・バッファも安全に管理できます。

Posted in TIPS • • Top Of Page

Write a comment