DMA Copy

ADSP-BF533はコアクロックとSDRAMクロックの比が非常に大きいため、SDRAMアクセスのペナルティを無視できません。おまけにSDRAMからL1メモリにコピーしようとするとSDRAMアクセスがバースト化されません。さらにL1命令メモリをソースにもデスティネーションにも使うことができません。
そこでDMAを使ったコピールーチンを作りました。MDMA0を使っています。
SIC_IWRとSIC_IMASKを内部で変更していますがこれが他の部分での利用と衝突しないように気をつけてください。

#include 
#include 

	// SIC_ISR mask of MDM0 complete interrupt
#define MDMA0_INT ( 1<<21 )

void dmaCopy( void * dst, void * src, int count );


	// テストデータ
char srcBuf[20] = "Chiba City Blues";
char dstBuf[20];
	// テストデータ終わり
	

main(void)
{
        
	dmaCopy( dstBuf, srcBuf, strlen( srcBuf ) );
    while(1)
                ;
        
}

    // DMAによる汎用コピープログラム
void dmaCopy( void * dst, void * src, int count)
{
	struct {
	    void * ndp;                 // 次のデスクリプタ
	    void * sa;                  // バッファ・アドレス
	    unsigned short config;
	    unsigned short xcnt;        // 転送データ数
	             short xmod;        // アドレス増減値
	}srcDsc, dstDsc;
        

        // デスクリプタ・アドレス指定
    *pMDMA_D0_NEXT_DESC_PTR = &dstDsc;
    *pMDMA_S0_NEXT_DESC_PTR = &srcDsc;


        // デスティネーション
        // 転送後、DMAを終了
    dstDsc.ndp = 0;
    dstDsc.sa = dst;
    dstDsc.xcnt = count;
    dstDsc.xmod = 1;
    dstDsc.config = DI_EN | DMAEN | WNR | WDSIZE_8;
        
        // ソース
        // 転送後DMAを終了
    srcDsc.ndp = 0;
    srcDsc.sa = src;
    srcDsc.xcnt = count;
    srcDsc.xmod = 1;
    srcDsc.config = DMAEN | WDSIZE_8;

    	// MDMA割り込みを禁止
    *pSIC_IMASK &= ~ MDMA0_INT;
        // MDMA終了でウェイクアップ
    *pSIC_IWR |= MDMA0_INT;
	csync();
    
    // キックスタート
    // ラージ・デスクリプタ・リンク&デスクリプタサイズ=7
    *pMDMA_S0_CONFIG = DMAEN |       WDSIZE_8 | 0x7700;
    *pMDMA_D0_CONFIG = DMAEN | WNR | WDSIZE_8 | 0x7700;
    
        // ウエイクアップ待ち
    csync();
    idle();
    csync();
    	// ウエイクアップクリア
    *pMDMA_D0_IRQ_STATUS = DMA_DONE;
     
}