

#include <nitro/mi.h>void MI_DmaCopy32( u32 dmaNo,
const void* src,
void* dest,
u32 size );void MI_DmaCopy32_SetUp( u32 dmaNo,
const void* src,
void* dest,
u32 size );void MI_DmaCopy16( u32 dmaNo,
const void* src,
void* dest,
u32 size );void MI_DmaCopy16_SetUp( u32 dmaNo,
const void* src,
void* dest,
u32 size );void MI_DmaCopy32Async( u32 dmaNo,
const void* src,
void* dest,
u32 size,
MIDmaCallback callback,
void* arg );void MI_DmaCopy32Async_SetUp( u32 dmaNo,
const void* src,
void* dest,
u32 size,
MIDmaCallback callback,
void* arg );void MI_DmaCopy16Async( u32 dmaNo,
const void* src,
void* dest,
u32 size,
MIDmaCallback callback,
void* arg );void MI_DmaCopy16Async_SetUp( u32 dmaNo,
const void* src,
void* dest,
u32 size,
MIDmaCallback callback,
void* arg );| dmaNo | 使用DMAチャンネル |
| src | 転送元アドレス |
| dest | 転送先アドレス |
| size | 転送サイズ |
| callback | DMA終了時のコールバック |
| arg | DMA終了時のコールバック引数 |
なし。
DMA を用いてコピーを行います。
*_SetUp() は実際にはDMAを行なわず、その設定のみを行います。実際のDMA開始は MI_DmaRestart() を呼んで下さい。
MI_DmaCopy16*() は 16ビット単位でコピーを行います。転送元アドレス、転送先アドレスは2バイトアラインメントする必要があります。
MI_DmaCopy32*() は 32ビット単位でコピーを行います。転送元アドレス、転送先アドレスは4バイトアラインメントする必要があります。
MI_DmaCopy16(), MI_DmaCopy32() は DMA の終了を関数内で待ちます。
MI_DmaCopy16Async*(), MI_DmaCopy32Async*() は、DMA終了時にコールバック callback を呼びます。コールバックは MIDmaCallback 型 ( void* 引数1つを取る void
型関数 ) です。callback は システムのDMA割り込みハンドラ内から呼び出されますので、割り込み禁止状態で呼び出されます。
Async 型の API の機能を引き出すにはその使用法を十分に理解する必要があります。
例として、次のような Call_BackGroundJob_with_DMA()というTCM内に配置された関数がある場合を考えます。
このときは以下のような処理が行なわれます。
callback() の中で、isDmaFinished に TRUE を入れます。
isDmaFinished を終了フラグとしてポーリングし、DMAが終了するまでの間 BackGroundJob()
を呼びつづけることが可能です。
但し、この処理が意図通りに処理されるには以下のようなことに注意しなくてはなりません。
isDmaFinished が TCM 内に取られていないと while(!isDmaFinished) のチェックでストールします。
BackGroundJob() がARMバスにアクセスするとストールします。
BackGroundJob() を呼びつづけることは出来ません。
//--- sample code ( This code must be in ITCM ) void Call_BackGroundJob_with_DMA(void) { vu32 isDmaFinished = FALSE; : MI_DmaCopy32Async( dmaNo, srcArea, destArea, dataSize, callback, (void*)&isDmaFinished ); while( !isDmaFinished ){ BackGroundJob(); } : } void callback( void* arg ) { *(vu32*)arg = TRUE; }
旧DMAC にはハードウェア上の不具合があり、多重DMAで DMA0 のソースアドレスに
0xmmnnnnnn (mm=0x04, 0x08〜0xff で、nnnnnn は任意) を指定すると条件により不正リードアクセスが発生します。転送終了時のソースアドレスもこの制限を受けます。
そのためソースアドレスや転送終了時のソースアドレスがこのアドレス範囲に入っている場合は、ライブラリ内部で
OS_Panic() で停止するようになっています。
ただし TWL では SCFG_SetDmaFixed() でこの旧DMA 回路の不具合修正を行うか行わないかの選択が可能になっており、修正を行っている場合はアドレスのチェックを行いません。
IOレジスタのDMAnソースレジスタ(0x40000B0 + 12n)、DMAnデスティネーションレジスタ(0x40000B4 + 12n)、DMAnコントロールレジスタ(0x40000B8 + 12n)を使用します。( n は 使用するDMAチャンネルです。)
MI_DmaFill*, MI_DmaClear*, MI_DmaSend*, MI_CpuCopy*, MI_DmaRestart
2009/11/20 DMAコントローラの不具合について追記
2007/10/31 _SetUp() 追加
2005/03/08 用語統一 [割込み] → [割り込み]
2004/12/22 callback の呼び出しについての記述を追加
2003/12/01 初版