⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dmawince.c

📁 pxa270平台 windows mobile 5.2 wm9713 触摸屏+音频驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
    //
    // These are taken by wave (audio) driver.
    //
    pDMAGlobals->pArrayChannel[WMDMA_STEREO_OUT] = 1;    
    pDMAGlobals->pArrayChannel[WMDMA_STEREO_IN] = 1;
#	if WM_MONODAC    
    pDMAGlobals->pArrayChannel[WMDMA_MONO_OUT] = 1; 
#	endif /* WM_MONODAC */
#	if WM_VOICE
    pDMAGlobals->pArrayChannel[WMDMA_VOICE_OUT] = 1;
#	endif /* WM_VOICE */
#endif /* !WM_USE_DYNAMIC_DMA_CHANNEL */


    pDMAGlobals->gDmacIntrEvent =  CreateEvent(NULL, FALSE, FALSE, NULL);
    //
    // Create DMA IST
    // This thread will handle all DMA interrupts and be responsible for calling appropriate
    // second level handlers.
    // 
    if (!(InterruptInitialize(SYSINTR_DMA, pDMAGlobals->gDmacIntrEvent, NULL, 0))) 
    {        
		RETAILMSG(1,(TEXT("DMAC: Interrupt initialization failed IID = %d...\r\n"), SYSINTR_DMA));
		DEBUGMSG(1,(TEXT("SYSINTR_MAXIMUM = %d"), SYSINTR_MAXIMUM));
		xllpStatus = XLLP_STATUS_FAILURE; 
        goto finish;
	}

	pDMAGlobals->gDmacThreadReadyEvent =  CreateEvent(NULL, FALSE, FALSE, NULL);
    pDMAGlobals->gDmacIntrThread = 
        CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) DmacIntrThread, NULL, 0, NULL);
    if ( pDMAGlobals->gDmacIntrThread == NULL ) 
    {		
		DEBUGMSG(1,(TEXT("DMAC: CreateThread failed.\r\n")));
        xllpStatus = XLLP_STATUS_NO_RESOURCES;
        goto finish;
    }
    SetThreadPriority( pDMAGlobals->gDmacIntrThread, THREAD_PRIORITY_TIME_CRITICAL );
	WaitForSingleObject(pDMAGlobals->gDmacThreadReadyEvent, INFINITE);
    //
    // Initialize DMAC hardware
    // This will also stop any ongoing DMA activity
    //
	pDMAGlobals->hDMAEvent[0] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_0);
	pDMAGlobals->hDMAEvent[1] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_1);
	pDMAGlobals->hDMAEvent[2] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_2);
	pDMAGlobals->hDMAEvent[3] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_3);
	pDMAGlobals->hDMAEvent[4] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_4);
	pDMAGlobals->hDMAEvent[5] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_5);
	pDMAGlobals->hDMAEvent[6] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_6);
	pDMAGlobals->hDMAEvent[7] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_7);
	pDMAGlobals->hDMAEvent[8] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_8);
	pDMAGlobals->hDMAEvent[9] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_9);
	pDMAGlobals->hDMAEvent[10] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_10);
	pDMAGlobals->hDMAEvent[11] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_11);
	pDMAGlobals->hDMAEvent[12] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_12);
	pDMAGlobals->hDMAEvent[13] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_13);
	pDMAGlobals->hDMAEvent[14] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_14);
	pDMAGlobals->hDMAEvent[15] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_15);
	pDMAGlobals->hDMAEvent[16] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_16);
	pDMAGlobals->hDMAEvent[17] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_17);
	pDMAGlobals->hDMAEvent[18] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_18);
	pDMAGlobals->hDMAEvent[19] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_19);
	pDMAGlobals->hDMAEvent[20] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_20);
	pDMAGlobals->hDMAEvent[21] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_21);
	pDMAGlobals->hDMAEvent[22] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_22);
	pDMAGlobals->hDMAEvent[23] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_23);
	pDMAGlobals->hDMAEvent[24] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_24);
	pDMAGlobals->hDMAEvent[25] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_25);
	pDMAGlobals->hDMAEvent[26] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_26);
	pDMAGlobals->hDMAEvent[27] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_27);
	pDMAGlobals->hDMAEvent[28] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_28);
	pDMAGlobals->hDMAEvent[29] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_29);
	pDMAGlobals->hDMAEvent[30] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_30);
	pDMAGlobals->hDMAEvent[31] = CreateEvent(NULL,FALSE,FALSE,DMA_CHANNEL_31);


    XllpDmacHwInit();
    XllpDmacEnableInterrupt();
    Sleep(10);
	SetEvent(hFirstTime);  // Signal that GDE Setup has successfully completed.
finish:
    return xllpStatus;    
}

//******************************************************************************
//
// Function Name: DmacIntrThread
//
// Description: The IST for DMA Controller interrupt.
//  			   
//  
// Input Arguments:
//	
//	                 
// Output Arguments:
//  	
//
// Return Value: 
//	None 
//
// Notes: Calls the XllpDmacIntHandler which does the guts of the work
//
//*******************************************************************************
INT WINAPI DmacIntrThread
(
    void
)
{
	DWORD tmpDINT;
	//DWORD EventData;
	int i;
    XLLP_VUINT32_T  *pDCSR ;
    XLLP_VUINT32_T  tmpDCSR;
    XLLP_VUINT32_T  tmpDcsrClear;    

	SetEvent(pDMAGlobals->gDmacThreadReadyEvent);

    while (TRUE)
    {
		
	    WaitForSingleObject(pDMAGlobals->gDmacIntrEvent, INFINITE);
		// DMA interrupts are currently masked.  This routine will not be interrupted by another DMA interrupt.
		tmpDINT = pDmacHandle->DINT;
        for ( i=0; i<XLLP_DMAC_CHANNEL_NUM; i++ )
        {
            if (tmpDINT & (1u << i))
            {               
				// Provide the Waiting Object the current value of the channel Status Register.
				//    where data describing the specific cause of the interrupt is held. The
				//    Dma Engine clears the Status register when it acknowledges the interrupt.
				SetEventData(pDMAGlobals->hDMAEvent[i], pDmacHandle->DCSR[i]);
				// Acknowledge the given interrupt channel
				//pDmacHandle->DCSR[i] |= (0x1 << 2);  // Orig.
                pDCSR = &(pDmacHandle->DCSR[i]);
                tmpDCSR = *pDCSR;
                // Isolate all writeable bits, including those that
                // both report and clear a status.
                tmpDcsrClear = (tmpDCSR & XLLP_DCSR_WRITABLES_MSK);
                // Stop intr is not cleared by a simple write-back.  Must also
                //  restart the DMA (not done in ISR)
                if (tmpDCSR & XLLP_DMAC_DCSR_STOP_INTR)
                    tmpDcsrClear &= ~(XLLP_DMAC_DCSR_STOP_IRQ_EN);
                // Clear the status
                *pDCSR = tmpDcsrClear;
				// Signal the waiting thread
				SetEvent(pDMAGlobals->hDMAEvent[i]); // should search this list in priority order instead of linearly.
			// Stop searching if there are no more threads to signal
			if ((unsigned)i >= tmpDINT)
				break;
			}
		}
		// Now that we have SetEvent on all known interrupt source, we can re-enable DMA interrupts.
		InterruptDone(SYSINTR_DMA);
    }
	
    return XLLP_STATUS_SUCCESS;
}


BOOL XllpDmacAcquireMutex
(    
    HANDLE  *hDmacMutex,
    DWORD   timeout
)
{    
    //
    // Create the mutex for protecting access to shared data structures (channel array map)
    // Need to be acquired before calling XllpAllocate/FreeChannel
    //
    if ((*hDmacMutex = CreateMutex(NULL, FALSE, DMAC_MUTEX_NAME)) == NULL)
    {        
        return FALSE;
    }

    if (WaitForSingleObject(*hDmacMutex, timeout) == WAIT_TIMEOUT)
    {
        CloseHandle(*hDmacMutex);
        return FALSE;
    }

    return TRUE;
}

VOID XllpDmacFreeMutex
(
    HANDLE  hDmacMutex
)
{
    ReleaseMutex(hDmacMutex);
    CloseHandle(hDmacMutex);
}

void XllpDmacDumpStatus( XLLP_DMAC_CHANNEL_T aChannel )
{    

    //RETAILMSG(1,(TEXT("DMA:>DumpStatus DmaChan=%02d Src=0x%08x Tgt=0x%08x Cmd=0x%08x Dcsr=0x%08x DINT=0x%08x \r\n"),aChannel, pDmacHandle->DDG[aChannel].DSADR, pDmacHandle->DDG[aChannel].DTADR, pDmacHandle->DDG[aChannel].DCMD, pDmacHandle->DCSR[aChannel], pDmacHandle->DINT ));
    //RETAILMSG(1,(TEXT("DMA:>DrcmrRx=0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x \r\n"), pDmacHandle->DRCMR1[48], pDmacHandle->DRCMR1[50],pDmacHandle->DRCMR1[52],pDmacHandle->DRCMR1[54],pDmacHandle->DRCMR1[56],pDmacHandle->DRCMR1[58],pDmacHandle->DRCMR1[60] ));
    //RETAILMSG(1,(TEXT("DMA:>DrcmrTx=0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x \r\n"), pDmacHandle->DRCMR1[49], pDmacHandle->DRCMR1[51],pDmacHandle->DRCMR1[53],pDmacHandle->DRCMR1[55],pDmacHandle->DRCMR1[57],pDmacHandle->DRCMR1[59],pDmacHandle->DRCMR1[61] ));
}

void XllpDmacEnableInterrupt
(
)
{
	volatile XLLP_INTC_T  *v_pICReg;

	v_pICReg = ( XLLP_INTC_T *)VirtualAllocCopyPhysical(sizeof(XLLP_INTC_T),"v_pICReg",(PVOID)(BULVERDE_BASE_REG_PA_INTC));
	if (v_pICReg == NULL)
		return;

    INTC_DMAC_INT_EN(v_pICReg->icmr);
}

void XllpDmacDisableInterrupt
(
)
{
	volatile XLLP_INTC_T  *v_pICReg;

	v_pICReg = ( XLLP_INTC_T *)VirtualAllocCopyPhysical(sizeof(XLLP_INTC_T),"v_pICReg",(PVOID)(BULVERDE_BASE_REG_PA_INTC));
	if (v_pICReg == NULL)
		return;

    INTC_DMAC_INT_DIS(v_pICReg->icmr);
}



//******************************************************************************
//
// Function Name: OSMemAlloc
//
// Description: Allocates a block of memory
//  			   
//  
// Input Arguments:
//	    numBytes:   Number of bytes to allocate
//	                 
// Output Arguments:
//  	
//
// Return Value: 
//	    void*:      Pointer to allocated memory. NULL if unsuccessful.
//
// Notes:
//      Memory allocated by this call is aligned on page boundary (4K on XScale)
//
//*******************************************************************************
VOID* OSMemAlloc
(
    UINT32   numBytes
)
{    
    return VirtualAlloc(0, numBytes, MEM_COMMIT, PAGE_READWRITE | PAGE_NOCACHE);
}

//******************************************************************************
//
// Function Name: OSMemFree
//
// Description: Frees a previously allocated block of memory
//  			   
//  
// Input Arguments:
//	    VOID* memPtr:   pointer to memory to deallocate
//	                 
// Output Arguments:
//  	
//
// Return Value: 
//	    
//
// Notes:
//      
//
//*******************************************************************************
VOID OSMemFree
(
    VOID*           memPtr
)
{    
    VirtualFree(memPtr, 0, MEM_RELEASE);
}

//******************************************************************************
//
// Function Name: OSGetMaxPages
//
// Description: Returns max number of physical pages that may be occupied by a user buffer
//  			   
//  
// Input Arguments:
//	    pBuffer:        Virtual address to user buffer
//      bufferLength:   Length of user buffer
//	                 
// Output Arguments:
//  	
//
// Return Value: 
//	    Maximum number of physical pages that can be spanned by user buffer
//
// Notes:
//      WinCe generally allocates memory aligned on page boundaries.
//
//*******************************************************************************
XLLP_UINT32_T OSGetMaxPages
(
    XLLP_UINT8_T    *pBuffer,
    XLLP_UINT32_T   bufferLength
)
{
    return ADDRESS_AND_SIZE_TO_SPAN_PAGES(pBuffer, bufferLength);
}

//******************************************************************************
//
// Function Name: OSLockPhysicalPages
//
// Description: Locks physical pages representing a virtual address space into memory.
//              Returns information about locked pages to user
//  			   
//  
// Input Arguments:
//	    VOID*  virtualAddress:  Pointer to virtual address space to lock
//      UINT32 numBytesTolock;  Number of bytes of linear address sace to lock
//      UINT32 osFlags:         OS specific flags.
//	                 
// Output Arguments:
//      UINT32 *pageAddresses:  Array in which list of all physical pages representing 
//                              buffer is returned
//
// Return Value: 
//      TRUE:   if successful
//      FALSE:  otherwise	    
//
// Notes:
//      Invokes LockPages on WinCE which is supported for .NET, PocketPC and SmartPhone
//      platforms
//
//*******************************************************************************
BOOL OSLockPhysicalPages
(
    VOID*           virtualAddress,
    XLLP_UINT32_T   numBytesToLock,
    XLLP_UINT32_T   *pageAddresses,
    XLLP_UINT32_T   osFlags
)
{
    return LockPages(virtualAddress, numBytesToLock, pageAddresses, osFlags);
}

//******************************************************************************
//
// Function Name: OSUnlockPhysicalPages
//
// Description: Unlocks previously locked physical pages representing a virtual 
//              address space into memory.
//              
// Input Arguments:
//	    VOID*  virtualAddress:      Pointer to virtual address space to lock
//      UINT32 numBytesToUnlock;    Number of bytes of linear address sace to unlock
//	                 
// Output Arguments:
//
// Return Value: 
//      TRUE:   if successful
//      FALSE:  otherwise	    
//
// Notes:
//      Invokes UnlockPages on WinCE which is supported for .NET, PocketPC and SmartPhone
//      platforms
//
//*******************************************************************************
BOOL OSUnlockPhysicalPages
(
    VOID*           virtualAddress,
    XLLP_UINT32_T   numBytesToUnlock
)
{
    return UnlockPages(virtualAddress, numBytesToUnlock);
}

//=============================================================================
//=========================Working DMA Sample Code ============================
//================================ Start ======================================
// 
// To validate the "DMA Engine" the following two routines were called in the 
// Keyboard IST when the "0" key was pressed. Diagnostic output via the function 
// NKDbgPrintfW(..) shows the  Virtual and Physical addresses used to setup and 
// run the Memory-to-Memory DMA transfer
// 
//		XllpDmacInit(void);
//		XllpDmacTest(void);
//
//			Note: XllpDmacTest was added to dma.def for validation testing.
//
//=============================================================================
//=============================================================================

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -