Raspberry Pi 3でDMAするためにBroadcom BCM2837のマニュアルを読む

DMAはCPUを介さずに直接メモリにアクセスしてメモリコピーする方式のことをいう。
メモリ→メモリ、
メモリ→ペリフェラル
ペリフェラル→メモリの3種類のDMAでコピー可能だ。

ラズパイのメインLSIはラズパイ世代ごとに違う。
ラズパイ3は Broadcom BCM2837で ここにマニュアルがある。
ちなみにラズパイ1やラズパイ2だとLSIBroadcom BCM2835やBCM2836だったりするが、マニュアルに書いてあることは同じだった。

...と読んでいったら実はこのマニュアル,
表紙だけBCM2837で中身のページにははBCM3835って書いてある。
なんだこれ。

以下メモ

概要

  • BCM2835のDMA Controllerは16個のDMAチャネルを提供している。
    各チャネルは3つのシステムバス上を共有して独立に動く。
  • DMAチャネルは Control Block(CB) というデータ構造をメモリからレジスタに読み込む。
    Control BlockはDMAによるoperationを定義している。
    各Control Blockは次のControl Blockへのポインタを持っている連結リストになっていて、処理が終わると次のControl Blockが読み込まれる。
  • メインメモリからペリフェラルへの転送はペリフェラルが発行する Data Request(DREQ) 信号でpaceされる。
  • ペリフェラルPanic 信号も出す。
    Panic信号はFIFO underflowやFIFO overflowや他のcritical situationがあることを示すもの。
  • ペリフェラルのDMAチャネルへの割当はソフトで制御可能

DMA Controller Registers

  • DMA Controllerは16個のDMAチャネルから構成される
    このDMAチャネルはベースアドレスが違うだけで、すべて同類のメモリマップを持つ
  • DMAチャネル0は0x7E007000、チャネル1は0x7E007100,...という感じで0x100おきに隣接している

DMAチャネル レジスタアドレスマップ

  • DMAチャネルのレジスタのうち、
    書き込めるのはCS,CONBLK_AD,DEBUGのみである。
    他のレジスタ(TI, SOURCE_AD, DEST_AD, TXFR_LEN, STRIDE, NEXTCONBK)は書き込めず、Control Block構造体から自動で読み込まれる
Control Blockデータ構造
  • Control Block(CB)は8words(8byte)の長さの構造体
32-bit word offset Description Register
0 Transfer Information TI
1 Source Address SOURCE_AD
2 Destination Address DEST_AD
3 Transfer length TXFR_LEN
4 2D Mode Stride STRIDE
5 Next Control Block Address NEXTCONBK
6-7 Reserved N/A
  • DMAはCB構造体をDMAレジスタマップのCONBLK_ADレジスタへセットして、ACTIVEビットを立てると開始する。
  • DMA transferが完了したら(length->0になったら)、DMAはNEXTCONBKレジスタにあるデータ構造体にCONBLK_ADレジスタを更新し、CBをそのアドレスからフェッチする。
  • DMAはNEXTCONBKレジスタが0x0000_0000にセットされたら終了する。