# MI_SendNDmaGXCommand*

## 構文

  `#include <twl/mi.h>`
  `void MI_SendNDmaGXCommand( u32 ndmaNo, const void* src, u32 commandLength );
  void MI_SendNDmaGXCommandAsync( u32 ndmaNo, const void* src, u32 commandLength,
  MINDmaCallback callback, void* arg　);`
  `
  void MI_SendNDmaGXCommandAsyncFast( u32 ndmaNo, const void* src, u32 commandLength,
  MINDmaCallback callback, void* arg　);`

## 引数

ndmaNo | 使用DMAチャンネル
src | 転送元アドレス
commandLength | 転送コマンドサイズ(バイト数)
callback | DMA終了時のコールバック
arg | DMA終了時のコールバック引数

## 返り値

なし。

## 説明

DMA を用いてディスプレイリスト ( GXコマンド列 ) をコマンドFIFOに送ります。転送元アドレスは 4バイトアラインメントする必要があります。

同期版の `MI_SendNDmaGXCommand()` は DMA の終了を関数内で待ちます。非同期版の `MI_SendNDmaGXCommandAsync()` と `MI_SendNDmaGXCommandAsyncFast()` は、DMA 終了時にコールバック callback を呼びます。コールバックは `MINDmaCallback` 型 (`void*` 引数1つを取る `void` 型関数 ) です。callback は システムのDMA割り込みハンドラ内から呼び出されますので、割り込み禁止状態で呼び出されます。

`MI_SendNDmaGXCommandAsync()` と `MI_SendNDmaGXCommandAsyncFast()` の違いは以下の通りです。前者は Geometry 転送 DMA を使用せず、通常の同期 DMA のみを使用しています。GXFIFO のアンダーハーフ割り込みを利用して少量ずつの DMA を行っています。後者は Geometry 転送 DMA を使用していますので、GXFIFO が少なくなったときに自動起動で DMA がスタートします。自動起動 DMA はハードウェアの制限により複数のものを同時に起動できませんので注意が必要です。( 但し同じタイプの自動起動 DMA は同時に複数起動することがハード的には可能です )

TWL-SDK ではグラフィクスコマンドの動作速度を優先する立場から `MI_SendNDmaGXCommandAsync*()`と他の `G3_ 系` API との排他処理を行なっておりません。このため `MI_SendNDmaGXCommandAsync*()`によりGX コマンドを転送している間に `G3_` コマンドによってコマンド FIFO へ直接GXコマンドを書き込んだ場合の動作は保証できません。API 呼び出し側でこうした事態が起こらないように注意する必要があります。

###
使用する DMA について

この関数は新規 DMA を用いますが、従来の DMA を用いで同様のことを行う関数は`MI_SendGXCommand*()` となります。`MI_SendGXCommand*()` 系の関数と `MI_SendNDmaGXCommand*()` 系の関数を同時に使用することは出来ません。

## 内部動作

IOレジスタの新規DMA レジスタを使用します。

## 参照

`MI_NDmaCopy*, G3_BeginMakeDL, G3_EndMakeDL`
`MI_SendGXCommand*`

## 履歴

2008/10/16 初版