?? dma_test.c
字號:
/**************************************************************************************
*
* Project Name : S3C6400 Validation
*
* Copyright 2006 by Samsung Electronics, Inc.
* All rights reserved.
*
* Project Description :
* This software is only for validating functions of the S3C6400.
* Anybody can use this software without our permission.
*
*--------------------------------------------------------------------------------------
*
* File Name : DMA_test.c
*
* File Description : This file implements the functons for DMA controller test.
*
* Author : Wonjoon Jang
* Dept. : AP Development Team
* Created Date : 2007/01/02
* Version : 0.1
*
* History
* - Created(wonjoon.jang 2007/01/02)
*
**************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "def.h"
#include "option.h"
#include "library.h"
#include "sfr6400.h"
#include "system.h"
#include "sysc.h"
#include "dma.h"
#include "intc.h"
#include "gpio.h"
#include "timer.h"
static void DMAT_MemtoMem(void);
static void DMAT_MemtoMemLLI(void);
void Test_DMA(void);
volatile int g_DmaDone;
volatile int g_DmaDone0, g_DmaDone1, g_DmaDone2, g_DmaDone3;
volatile int g_TSize = 0x100000;
// SMDK6400 _DRAM_BaseAddress + 0x800_0000;
u32 uLLIBaseAddr = _DRAM_BaseAddress + 0x00100000;
u32 uTxBuffAddr = _DRAM_BaseAddress + 0x1000000;
u32 uRxBuffAddr = _DRAM_BaseAddress + 0x4000000;
#define uRxBuffAddr0 _DRAM_BaseAddress + 0x4000000
#define uRxBuffAddr1 uRxBuffAddr0 + 0x00800000
#define uRxBuffAddr2 uRxBuffAddr0 + 0x01000000
#define uRxBuffAddr3 uRxBuffAddr0 + 0x01800000
#define DMAC0TxSize 0x400
#define DMAC1TxSize 0xf0000
#define SDMAC0TxSize 0xf0000
#define SDMAC1TxSize 0xf0000
u32 uDataCnts=50000;
static DMAC oDmac0, oDmac1, oDmac2, oDmac3;
// Temp. function
void MemoryDump( u32 *DumpAddress, u32 line)
{
u32 i,j;
for(i=0;i<line;i++) {
printf("%08x : ",(u32)DumpAddress);
for(j=0;j<8;j++) {
printf("%08x ",*DumpAddress++);
}
putchar('\n');
}
putchar('\n');
}
void Mem_dump (void)
{
int ch;
while(1)
{
printf("dump address, '-1' to Exit \n");
//ch = Uart_getc();
ch = GetIntNum();
if(ch==-1)
{
break;
}
else
{
MemoryDump( ((u32 *)(ch)), 40);
}
}
}
bool CompareDMA(u32 a0, u32 a1, DATA_SIZE eDataSize, u32 uDataCnt)
{
u32* pD0 = (u32 *)a0;
u32* pD1 = (u32 *)a1;
u32 uSrcData = 0;
u32 uDstData = 0;
bool ret = true;
u32 uLoopCnt = 0;
u32 uTotDataCnt = uDataCnt * eDataSize; // Bytes
// u32 uTotLoopCnt = uTotDataCnt/4 + 1;
u32 uTotLoopCnt = uTotDataCnt/4;
DelayfrTimer(micro, 1);
for (uLoopCnt=0; uLoopCnt< uTotLoopCnt; uLoopCnt++) // 4Byte 竄困 厚背
{
uSrcData = *pD0;
uDstData = *pD1;
if (uSrcData != uDstData)
{
ret = false;
Disp(" %08x=%08x <-> %08x=%08x\n", pD0, uSrcData, pD1, uDstData);
Getc();
}
pD0++;
pD1++;
}
if (ret == false)
Disp("\n");
return ret;
}
bool Compare32(u32 a0, u32 a1, u32 words)
{
u32* pD0 = (u32 *)a0;
u32* pD1 = (u32 *)a1;
bool ret = true;
u32 ecnt = 0;
u32 i;
for (i=0; i<words; i++)
{
if (*pD0 != *pD1)
{
ret = false;
Disp(" %08x=%08x <-> %08x=%08x\n", pD0, *pD0, pD1, *pD1);
ecnt++;
}
pD0++;
pD1++;
}
if (ret == false)
Disp("\n");
return ret;
}
//////////
// Function Name : DmaxDone
// Function Description : DMA ISR Routine
// Input : None
// Output : None
// Version : v0.1
void __irq Dma0Done(void)
{
DMACH_ClearIntPending(&oDmac0);
//rDMAC0IntTCClear = 0xff;
printf ("DMA ISR %d\n", g_DmaDone);
g_DmaDone=1;
g_DmaDone++;
INTC_ClearVectAddr();
//Write_VECTADDR(0x0);
}
void __irq Dma1Done(void)
{
// printf("Current TC1 : %x\n",rDMAC1C0Control);
DMACH_ClearIntPending(&oDmac1);
//rDMAC1IntTCClear = 0xff;
printf ("DMA ISR %d\n", g_DmaDone);
g_DmaDone=1;
g_DmaDone++;
INTC_ClearVectAddr();
}
void __irq Sdma0Done(void)
{
DMACH_ClearIntPending(&oDmac2);
//rDMAC1IntTCClear = 0xff;
printf ("DMA ISR %d\n", g_DmaDone);
g_DmaDone=1;
g_DmaDone++;
INTC_ClearVectAddr();
}
void __irq Sdma1Done(void)
{
DMACH_ClearIntPending(&oDmac3);
//rDMAC1IntTCClear = 0xff;
printf ("DMA ISR %d\n", g_DmaDone);
g_DmaDone=1;
g_DmaDone++;
INTC_ClearVectAddr();
}
//////////
// Function Name : DmaxDoneW
// Function Description : DMA ISR Routine
// Input : None
// Output : None
// Version : v0.1
void __irq Dma0DoneW(void)
{
DMACH_ClearIntPending(&oDmac0);
// Disp("DMA0 ISR %d\n", g_DmaDone0);
if ( g_DmaDone0 < (g_TSize/DMAC0TxSize) )
{
DMACH_SetTransferSize(DMAC0TxSize,&oDmac0); // set TransferSize
DMACH_Start(&oDmac0);
}
else
{
INTC_Disable(NUM_DMA0);
}
g_DmaDone0++;
INTC_ClearVectAddr();
}
void __irq Dma1DoneW(void)
{
DMACH_ClearIntPending(&oDmac1);
// Disp("DMA1 ISR %d\n", g_DmaDone1);
if ( g_DmaDone1 < (g_TSize/DMAC1TxSize) )
{
DMACH_SetTransferSize(DMAC1TxSize,&oDmac1); // set TransferSize
DMACH_Start(&oDmac1);
}
else
{
INTC_Disable(NUM_DMA1);
}
g_DmaDone1++;
INTC_ClearVectAddr();
}
void __irq Sdma0DoneW(void)
{
DMACH_ClearIntPending(&oDmac2);
// Disp ("SDMA0 ISR %d\n", g_DmaDone2);
if ( g_DmaDone2 < (g_TSize/SDMAC0TxSize) )
{
DMACH_SetTransferSize(SDMAC0TxSize,&oDmac2); // set TransferSize
DMACH_Start(&oDmac2);
}
else
{
INTC_Disable(NUM_SDMA0);
}
g_DmaDone2++;
INTC_ClearVectAddr();
}
void __irq Sdma1DoneW(void)
{
DMACH_ClearIntPending(&oDmac3);
// Disp ("SDMA1 ISR %d\n", g_DmaDone3);
if ( g_DmaDone3 < (g_TSize/SDMAC1TxSize) )
{
DMACH_SetTransferSize(SDMAC1TxSize,&oDmac3); // set TransferSize
DMACH_Start(&oDmac3);
}
else
{
INTC_Disable(NUM_SDMA1);
}
g_DmaDone3++;
INTC_ClearVectAddr();
}
//////////
// Function Name : DMAT_MemtoMem
// Function Description : Memory to Memory Transfer Test
// Input : None
// Output : None
// Version : v0.1
static void DMAT_MemtoMem(void)
{
u32 i, csel, usel;
u32 uTsize, uBurst, uCh;
Disp("\nSelect DMA Controller : 0:DMA0, 1:DMA1, 2:SDMA0, 3:SDMA1 : ");
csel=GetIntNum();
Disp("\n");
switch(csel)
{
case 0:
Disp("Selected DMAC 0 ..... \n");
DMAC_InitCh(DMA0, DMA_ALL, &oDmac0);
INTC_SetVectAddr(NUM_DMA0, Dma0Done);
INTC_Enable(NUM_DMA0);
break;
case 1:
Disp("Selected DMAC 1 ..... \n");
DMAC_InitCh(DMA1, DMA_ALL, &oDmac1);
INTC_SetVectAddr(NUM_DMA1, Dma1Done);
INTC_Enable(NUM_DMA1);
break;
case 2:
Disp("Selected SDMAC 0 ..... \n");
DMAC_InitCh(SDMA0, DMA_ALL, &oDmac2);
INTC_SetVectAddr(NUM_SDMA0, Sdma0Done );
INTC_Enable(NUM_SDMA0);
break;
case 3:
Disp("Selected SDMAC 1 ..... \n");
DMAC_InitCh(SDMA1, DMA_ALL, &oDmac3);
INTC_SetVectAddr(NUM_SDMA1, Sdma1Done);
INTC_Enable(NUM_SDMA1);
break;
default : Assert(0);
}
Disp("\nSelect Channel : 0:CH0, 1:CH1, 2:CH2, 3:CH3, 4:CH4, 5:CH5, 6:CH6, 7:CH7 : ");
usel=GetIntNum();
Disp("\n");
switch(usel)
{
case 0:
uCh= DMA_A;
break;
case 1:
uCh= DMA_B;
break;
case 2:
uCh= DMA_C;
break;
case 3:
uCh = DMA_D;
break;
case 4:
uCh = DMA_E;
break;
case 5:
uCh = DMA_F;
break;
case 6:
uCh = DMA_G;
break;
case 7:
uCh = DMA_H;
break;
default : Assert(0);
}
Disp("\nSelect Transfer Width : 0:BYTE, 1:HWORD, 2:WORD : ");
usel=GetIntNum();
Disp("\n");
switch(usel)
{
case 0:
uTsize = BYTE;
break;
case 1:
uTsize = HWORD;
break;
case 2:
uTsize = WORD;
break;
default : Assert(0);
}
Disp("\nSelect Burst Size : 0:SINGLE, 1:BURST4, 2:BURST8, 3:BURST16, 4:BURST32, 5:BURST64, 6:BURST128, 7:BURST256 : ");
usel=GetIntNum();
Disp("\n");
switch(usel)
{
case 0:
uBurst = SINGLE;
break;
case 1:
uBurst = BURST4;
break;
case 2:
uBurst = BURST8;
break;
case 3:
uBurst = BURST16;
break;
case 4:
uBurst = BURST32;
break;
case 5:
uBurst = BURST64;
break;
case 6:
uBurst = BURST128;
break;
case 7:
uBurst = BURST256;
break;
default : Assert(0);
}
Disp("\nSelect Transfer Size [1~0x200_0000] : ");
uDataCnts=GetIntNum();
Disp("\n");
// 0. Clear the rx/tx buf.
for (i = 0; i<(uDataCnts*uTsize+16); i++)
{
*(u8 *)(uRxBuffAddr+i) = 0;
*(u8 *)(uTxBuffAddr+i) = 0;
}
// 1. Set up the tx buf.
for (i = 0; i<uDataCnts*uTsize; i++)
*(u8 *)(uTxBuffAddr+i) = (u8)(i+2)%0xff;
switch(csel)
{
case 0 :
// Channel, LLI_Address, SrcAddr, Src Type, DstAddr, Dst Type, Transfer Width, Transfer Size, OpMode(DEMAND), Src Req, Dst Req, Burst
DMACH_Setup((DMA_CH)uCh, 0x0, uTxBuffAddr, 0, uRxBuffAddr, 0, (DATA_SIZE)uTsize, uDataCnts, DEMAND, MEM, MEM, (BURST_MODE)uBurst, &oDmac0);
DMACH_Start(&oDmac0);
break;
case 1 :
// Channel, LLI_Address, SrcAddr, Src Type, DstAddr, Dst Type, Transfer Width, Transfer Size, OpMode(DEMAND), Src Req, Dst Req, Burst
DMACH_Setup((DMA_CH)uCh, 0x0, uTxBuffAddr, 0, uRxBuffAddr, 0, (DATA_SIZE)uTsize, uDataCnts, DEMAND, MEM, MEM, (BURST_MODE)uBurst, &oDmac1);
DMACH_Start(&oDmac1);
break;
case 2 :
// Channel, LLI_Address, SrcAddr, Src Type, DstAddr, Dst Type, Transfer Width, Transfer Size, OpMode(DEMAND), Src Req, Dst Req, Burst
DMACH_Setup((DMA_CH)uCh, 0x0, uTxBuffAddr, 0, uRxBuffAddr, 0, (DATA_SIZE)uTsize, uDataCnts, DEMAND, MEM, MEM, (BURST_MODE)uBurst, &oDmac2);
DMACH_Start(&oDmac2);
break;
case 3 :
// Channel, LLI_Address, SrcAddr, Src Type, DstAddr, Dst Type, Transfer Width, Transfer Size, OpMode(DEMAND), Src Req, Dst Req, Burst
DMACH_Setup((DMA_CH)uCh, 0x0, uTxBuffAddr, 0, uRxBuffAddr, 0, (DATA_SIZE)uTsize, uDataCnts, DEMAND, MEM, MEM, (BURST_MODE)uBurst, &oDmac3);
DMACH_Start(&oDmac3);
break;
default :
Assert(0);
}
while(g_DmaDone==0); // Int.
//while (!DMAC_IsTransferDone(&oDmac0)); // Polling
if (CompareDMA(uTxBuffAddr, uRxBuffAddr, (DATA_SIZE)uTsize, uDataCnts))
Disp(" >> Test Tx&Rx -> Ok << \n");
else
{
Disp(" >>*** Tx-data & Rx-data mismatch ***<< \n");
}
switch(csel)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -