📄 dmawince.c
字号:
P_XLLP_UINT8_T pDescriptor0;
P_XLLP_UINT8_T pDescriptor1;
P_XLLP_UINT8_T pSrcMemory;
P_XLLP_UINT8_T pDstMemory;
P_XLLP_UINT8_T pExtMemory;
volatile DMA_GLOBALS *pDMAGlobalsThread = NULL;
volatile P_XLLP_DMAC_T pDmacHandleThread = NULL;
//******************************************************************************
//
// Function Name: DmacTestThread
//
// Description: Test thread which waits for the channel specific test object
// to be signaled by the DMA IST, DmacIntrThread.
//
//
// Input Arguments:
//
//
// Output Arguments:
//
//
// Return Value:
// None
//
//
//*******************************************************************************
INT WINAPI DmacTestThread
(
void *Channel
)
{
XLLP_VUINT32_T tmp_dint;
XLLP_VUINT32_T tmpDCSR;
XLLP_UINT32_T idxChannel;
//void * EventHandle;
HANDLE EventHandle;
XLLP_UINT32_T i;
XLLP_UINT32_T EventData;
//XLLP_UINT32_T LastError;
P_XLLP_INT8_T pByteSrc;
P_XLLP_INT8_T pByteDst;
_TCHAR EventName[20];
HANDLE hSharedMap;
idxChannel = (unsigned int)(Channel);
NKDbgPrintfW(TEXT("idxChannel = 0x%X\r\n"), idxChannel);
RETAILMSG(1,(TEXT("DmacTestThread .....Initialized\r\n")));
// Compose the name of the channel event for use with CreateEvent(...) below.
_stprintf(EventName, TEXT("DMA_CHANNEL_%d"), idxChannel);
NKDbgPrintfW(TEXT("EventName = %s\r\n"), EventName);
// Memory mapped file for sharing DMA Globals information.
hSharedMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
0, sizeof(DMA_GLOBALS), GDE_SHARED_FILENAME );
// Memory mapped file should exist from setup in GDE_Init() .
if( ERROR_ALREADY_EXISTS != GetLastError() )
{
NKDbgPrintfW(TEXT("DmacTestThread. No existing MemMapFile . \r\n"));
return FALSE; // Memory mapped file set failed
}
// Get a valid process pointer to the buffer mapped above.
pDMAGlobalsThread = (DMA_GLOBALS *)MapViewOfFile( hSharedMap, FILE_MAP_ALL_ACCESS, 0, 0, 0 );
if( !pDMAGlobalsThread )
{
NKDbgPrintfW(TEXT("DmacTestThread. MapViewOfFile failed . \r\n"));
return FALSE; // Memory mapped file set failed.
}
// Map the DMAC registers.
pDmacHandleThread = NULL;
pDmacHandleThread = ( P_XLLP_DMAC_T)VirtualAllocCopyPhysical(sizeof(XLLP_DMAC_T),"pDmacHandle",(PVOID)(BULVERDE_BASE_REG_PA_DMAC));
if (pDmacHandleThread == NULL)
{
NKDbgPrintfW(TEXT("pDmacHandleThread mapping FAILED...\r\n"));
return 0; //
}
// Get event handle for this channel. Note that using the numerical event
// value, pDMAGlobalsThread->hDMAEvent[idxChannel], stored in the DMA_Globls
// struture will in general only work for threads that belong to the Device
// Manager (DM) process which contains the IST ( DmacIntrThread ) for the DMA Engine.
//
// Drivers or applications that belong to a different process must obtain
// the handle value by using the event name as shown below. A general solution
// will always use the event name.
// Note. For this implementation of WinCE is happens that the event handle is the
// same in each process. There is no guarantee this will continue to be the
// in future implementations.
//EventHandle = pDMAGlobalsThread->hDMAEvent[idxChannel];
//NKDbgPrintfW(TEXT("EventHandle in Test Thread = 0x%08X...\r\n"), EventHandle);
//if (EventHandle == NULL)
//{
// NKDbgPrintfW(TEXT("EventHandle Zero, NOT Initialized...\r\n"));
// return 0; //
//}
EventHandle = CreateEvent(NULL,FALSE,FALSE, EventName);
NKDbgPrintfW(TEXT("EventHandle in Test Thread = 0x%08X...\r\n"), EventHandle);
if (EventHandle == NULL)
{
NKDbgPrintfW(TEXT("EventHandle (Named) is Zero...\r\n"));
return 0; //
}
while (TRUE)
{
NKDbgPrintfW(TEXT("DmacTestThread BEFORE WaitFor...\r\n"));
// The DMA Engine will after processing an interrupt.
WaitForSingleObject(EventHandle, INFINITE);
NKDbgPrintfW(TEXT("DmacTestThread AFTER WaitFor...\r\n"));
// Get the DCSR value for the channel that interrupted.
EventData = GetEventData(EventHandle);
NKDbgPrintfW(TEXT("GetEventData in Test Thread = 0x%08X...\r\n"), EventData);
tmp_dint = pDmacHandleThread->DINT; // Get the current interrupt bits.
tmpDCSR = pDmacHandleThread->DCSR[idxChannel];
RETAILMSG(1,(TEXT("DmacIntHandler: chan=%d DINT=0x%08x DCSR=0x%08x DCMD=0x%08x\r\n"), idxChannel, tmp_dint, tmpDCSR, pDmacHandleThread->DDG[idxChannel].DCMD ));
// Display Source/Destination Data
pByteSrc = pSrcMemory;
pByteDst = pDstMemory;
for(i=0; i<32; i++)
{
NKDbgPrintfW(TEXT("\r\n..S-%x = 0x%X....\r\n"),pByteSrc, *pByteSrc);
NKDbgPrintfW(TEXT("..D-%x = 0x%X....\r\n"),pByteDst, *pByteDst);
pByteSrc++;
pByteDst++;
}
}
return XLLP_STATUS_SUCCESS;
}
//*******************************************************************************
//
// Function Name: XllpDmacTest
//
//
// Description: Setup a simple memory-to-memory transfer with the DMA hardware.
//
//
//*******************************************************************************
#define GDE_VIRT_BUFFER_DESCRIPTOR GDE_BUFFER_VIRTUAL + 0x2000
#define GDE_VIRT_BUFFER_SRC GDE_BUFFER_VIRTUAL + 0x2000 + 0x100
#define GDE_VIRT_BUFFER_DST GDE_BUFFER_VIRTUAL + 0x2000 + 0x300
#define GDE_PHYS_BUFFER_DESCRIPTOR GDE_BUFFER_PHYSICAL + 0x2000
#define GDE_PHYS_BUFFER_SRC GDE_BUFFER_PHYSICAL + 0x2000 + 0x100
#define GDE_PHYS_BUFFER_DST GDE_BUFFER_PHYSICAL + 0x2000 + 0x300
#define TESTBUF_SIZE 0x100
#define TEST_SIZE_TOTAL (2 * (sizeof(XLLP_DMAC_DESCRIPTOR_T) + TESTBUF_SIZE))
XLLP_BOOL_T XllpDmacTest( void )
{
XLLP_DMAC_CHANNEL_T Channel;
P_XLLP_UINT8_T pbDMATemp;
P_XLLP_UINT8_T pbPhyDMATemp;
PHYSICAL_ADDRESS PA;
XLLP_UINT32_T i;
P_XLLP_INT8_T pByteSrc;
P_XLLP_INT8_T pByteDst;
HANDLE gDmacIntrThread;
DMA_ADAPTER_OBJECT Adapter;
P_XLLP_UINT8_T pPhyDescriptor0;
P_XLLP_UINT8_T pPhyDescriptor1;
P_XLLP_UINT8_T pPhySrcMemory;
P_XLLP_UINT8_T pPhyDstMemory;
P_XLLP_UINT8_T pXlatPhyDescriptor;
P_XLLP_UINT8_T pXlatPhyDescriptor1;
P_XLLP_UINT8_T pXlatPhySrcMemory;
P_XLLP_UINT8_T pXlatPhyDstMemory;
XLLP_DMAC_COMMAND_T TestCmd;
NKDbgPrintfW(TEXT("\r\nDMAC Test...\r\n"));
// Initialize for this Process/Thread.
if( !XllpDmacInit() )
{
NKDbgPrintfW(TEXT("DmacTest-XllpDmacInit failed\r\n"));
return XLLP_FALSE;
}
// Obtain a DMA channel
NKDbgPrintfW(TEXT("\r\nObtain a channel\r\n"));
if(XLLP_STATUS_SUCCESS != XllpDmacAllocChannel( &Channel, XLLP_DMAC_CHANNEL_PRIORITY_MEDIUM))
{
NKDbgPrintfW(TEXT("XllpDmacAllocChannel failed\r\n"));
return XLLP_FALSE;
}
NKDbgPrintfW(TEXT("AllocChannel=%d \r\n"),Channel);
// Create a thread that waits for the above Channel event to be signaled.
gDmacIntrThread =
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) DmacTestThread, (void *)Channel, 0, NULL);
if ( gDmacIntrThread == NULL )
{
NKDbgPrintfW(TEXT("DTest--Create Test Thread Failed."));
return (FALSE);
}
// Map DMA for a Memory-to-Memory Transfer. NOT needed for Mem2Mem transfers.
XllpDmacMapDeviceToChannel(
XLLP_DMAC_MEM2MEM_MOVE,
Channel
);
// Allocate blocks of virtual memory for Descriptors, Source & Destination.
// DMA_GLOBALS. Not used for this test.
//-->
// Map both DMA pages into the local address space.
//
Adapter.ObjectSize = sizeof(DMA_ADAPTER_OBJECT);
Adapter.InterfaceType = Internal;
Adapter.BusNumber = 0;
pbDMATemp = (P_XLLP_UINT8_T)HalAllocateCommonBuffer(&Adapter, TEST_SIZE_TOTAL , &PA, FALSE);
if (!pbDMATemp)
{
//DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: pbDMATemp failed to allocate DMA buffer(s).\r\n")));
return(FALSE);
}
pbPhyDMATemp = (BYTE *)PA.LowPart;
//--<
pDescriptor0 = pbDMATemp;
pPhyDescriptor0 = pbPhyDMATemp;
pDescriptor1 = pDescriptor0 + sizeof(XLLP_DMAC_DESCRIPTOR_T);
pPhyDescriptor1 = pPhyDescriptor0 + sizeof(XLLP_DMAC_DESCRIPTOR_T);
pSrcMemory = pDescriptor1 + sizeof(XLLP_DMAC_DESCRIPTOR_T);
pPhySrcMemory = pPhyDescriptor1 + sizeof(XLLP_DMAC_DESCRIPTOR_T);
pDstMemory = pSrcMemory + TESTBUF_SIZE;
pPhyDstMemory = pPhySrcMemory + TESTBUF_SIZE;
NKDbgPrintfW(TEXT("pbDMATemp = 0x%X\r\n"), pbDMATemp);
// Display Virtual and Physical Address Values.
if (pbDMATemp)
{
// Save pointers to the virtual & physical addresses so the driver can access them.
NKDbgPrintfW(TEXT("pDescriptor0 = 0x%X\r\n"), pDescriptor0);
NKDbgPrintfW(TEXT("pPhyDescriptor0 = 0x%X\r\n"), pPhyDescriptor0);
NKDbgPrintfW(TEXT("pDescriptor1 = 0x%X\r\n"), pDescriptor1);
NKDbgPrintfW(TEXT("pPhyDescriptor1 = 0x%X\r\n"), pPhyDescriptor1);
NKDbgPrintfW(TEXT("pSrcMemory = 0x%X\r\n"), pSrcMemory);
NKDbgPrintfW(TEXT("pPhySrcMemory = 0x%X\r\n"), pPhySrcMemory);
NKDbgPrintfW(TEXT("pDstMemory = 0x%X\r\n"), pDstMemory);
NKDbgPrintfW(TEXT("pPhyDstMemory = 0x%X\r\n"), pPhyDstMemory);
pXlatPhyDescriptor = (P_XLLP_UINT8_T)XllpDmacGetPhysicalAds(pDescriptor0);
pXlatPhyDescriptor1 = (P_XLLP_UINT8_T)XllpDmacGetPhysicalAds(pDescriptor1);
pXlatPhySrcMemory = (P_XLLP_UINT8_T)XllpDmacGetPhysicalAds(pSrcMemory);
pXlatPhyDstMemory = (P_XLLP_UINT8_T)XllpDmacGetPhysicalAds(pDstMemory);
NKDbgPrintfW(TEXT(" Xlat pDescriptor0 Phy Addr = 0x%X\r\n"), pXlatPhyDescriptor);
NKDbgPrintfW(TEXT(" Xlat pDescriptor1 Phy Addr = 0x%X\r\n"), pXlatPhyDescriptor1);
NKDbgPrintfW(TEXT(" Xlat pSrcMemory Phy Addr = 0x%X\r\n"), pXlatPhySrcMemory);
NKDbgPrintfW(TEXT(" Xlat pDstMemory Phy Addr = 0x%X\r\n"), pXlatPhyDstMemory);
NKDbgPrintfW(TEXT("sizeof(XLLP_DMAC_DESCRIPTOR_T) = 0x%X\r\n"), sizeof(XLLP_DMAC_DESCRIPTOR_T));
}
else
{
NKDbgPrintfW(TEXT("pbDMATemp VirtualCopy failed\r\n"));
return XLLP_FALSE;
}
// Only one Descriptor for this test, so linking is not needed.
// Load data into the descriptor.
NKDbgPrintfW(TEXT("\r\n...Load the descriptor-Format...\r\n"));
TestCmd.aLen = TESTBUF_SIZE - 0x10;
TestCmd.aWidth = XLLP_DMAC_WIDTH_0;
TestCmd.aSize = XLLP_DMAC_RESERVED_SIZE;
TestCmd.aEndian = XLLP_FALSE; // Little Endian.
TestCmd.aFlyByT = XLLP_FALSE; // Normal Transfer. No Fly by
TestCmd.aFlyByS = XLLP_FALSE; // Normal Transfer. No Fly by
TestCmd.aEndIrqEn = XLLP_TRUE; // Interrupt when len = 0.
TestCmd.aStartIrqEn = XLLP_FALSE; // No Interrupt when Desc is loaded.
TestCmd.aAddrMode = XLLP_FALSE; // Src & Dst contains values for addresses.
TestCmd.aCmpEn = XLLP_FALSE;
TestCmd.aFlowTrg = XLLP_FALSE;
TestCmd.aFlowSrc = XLLP_FALSE;
TestCmd.aIncTrgAddr = XLLP_TRUE;
TestCmd.aIncSrcAddr = XLLP_TRUE;
NKDbgPrintfW(TEXT("\r\n...Load the descriptor-Call...\r\n"));
XllpDmacFillLinkedDesc(
(P_XLLP_DMAC_DESCRIPTOR_T)pDescriptor0,
(P_XLLP_DMAC_DESCRIPTOR_T)pPhyDescriptor1,
//(P_XLLP_DMAC_DESCRIPTOR_T)pXlatPhyDescriptor1,
XLLP_DMAC_DESC_STOP_CHANNEL,
XLLP_DMAC_DISABLE_DESC_BRANCH,
(XLLP_UINT32_T)pPhySrcMemory,
(XLLP_UINT32_T)pPhyDstMemory,
//(XLLP_UINT32_T)pXlatPhySrcMemory,
//(XLLP_UINT32_T)pXlatPhyDstMemory,
&TestCmd
);
NKDbgPrintfW(TEXT("\r\n...Load the descriptor-Done...\r\n"));
// Configure Channels to use Descriptors.
NKDbgPrintfW(TEXT("\r\n...Configure a channel for Descriptors...\r\n"));
NKDbgPrintfW(TEXT("DCSR[%d] = 0x%X ...\r\n"), Channel ,pDmacHandle->DCSR[Channel] );
XllpDmacCfgChannelDescTransfer(
(P_XLLP_DMAC_DESCRIPTOR_T)pPhyDescriptor0,
Channel,
//XLLP_DMAC_DRCMR_T aDeviceDrcmr,
XLLP_DMAC_MEM2MEM_MOVE,
XLLP_DMAC_ALIGNMENT_OFF
);
NKDbgPrintfW(TEXT("DDADR[%d] = 0x%X ...\r\n"), Channel ,pDmacHandle->DDG[Channel].DDADR);
NKDbgPrintfW(TEXT("DSADR[%d] = 0x%X ...\r\n"), Channel ,pDmacHandle->DDG[Channel].DSADR);
NKDbgPrintfW(TEXT("DTADR[%d] = 0x%X ...\r\n"), Channel ,pDmacHandle->DDG[Channel].DTADR);
NKDbgPrintfW(TEXT("DCMD [%d] = 0x%X ...\r\n"), Channel ,pDmacHandle->DDG[Channel].DCMD);
// Link Descriptors
// Only one Descriptor, so linking is not needed.
// Enable interrupts for the requested channel. Not Needed.
// Put a Pattern in the Src memory.
NKDbgPrintfW(TEXT("\r\n...Initialize Src/Dst memory....\r\n"));
pByteSrc = pSrcMemory;
pByteDst = pDstMemory;
for(i=0; i< 0x100; i++)
{
*pByteSrc++ = (XLLP_INT8_T)i;
*pByteDst++ = 0x5A;
}
// Display Source/Destination Data
pByteSrc = pSrcMemory;
pByteDst = pDstMemory;
for(i=0; i<16; i++)
{
NKDbgPrintfW(TEXT("\r\n..S-%x = 0x%X....\r\n"),pByteSrc, *pByteSrc);
NKDbgPrintfW(TEXT("..D-%x = 0x%X....\r\n"),pByteDst, *pByteDst);
pByteSrc++;
pByteDst++;
}
// Start the Transfer.
NKDbgPrintfW(TEXT("\r\n...The the M-M Xfer...\r\n"));
XllpDmacStartTransfer( Channel );
// Completed
NKDbgPrintfW(TEXT("\r\n...Completed DMAC Test...\r\n"));
return XLLP_TRUE;
}
#endif
//=============================================================================
//=========================Working DMA Sample Code ============================
//================================ Stop =======================================
//=============================================================================
//=============================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -