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

📄 dma.c

📁 编译环境为PB,或AK,实现27x平台上对DMA的控制,由于270平台上DMA都处在同一个一级中断下,要使用单个的DMA通道,通常也可以在OAL重新映射其中断号,但比较费事,本驱动实现对DMA的管理,
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************
**
**  COPYRIGHT (C) 2001, 2002 Intel Corporation.
**
**  This software as well as the software described in it is furnished under
**  license and may only be used or copied in accordance with the terms of the
**  license. The information in this file is furnished for informational use
**  only, is subject to change without notice, and should not be construed as
**  a commitment by Intel Corporation. Intel Corporation assumes no
**  responsibility or liability for any errors or inaccuracies that may appear
**  in this document or any software that may be provided in association with
**  this document. 
**  Except as permitted by such license, no part of this document may be 
**  reproduced, stored in a retrieval system, or transmitted in any form or by
**  any means without the express written consent of Intel Corporation. 
**
**  FILENAME:       dma.c
**
**  PURPOSE: Contains all primitive functions for DMA Controller Engine 
**           access and control
**                  
******************************************************************************/

#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <tchar.h>
#include <ceddk.h>

#include <bulverde_intr.h>
#include <bulverde_dma.h>
#include "dmawince.h"

extern volatile DMA_GLOBALS* pDMAGlobals;
extern volatile P_XLLP_DMAC_T	pDmacHandle;
//******************************************************************************
//
// Function Name: XllpDmacHwInit
//
// Description: Function called to initialize the DMAC hardware to default state   
//              Clears the DCSR and all channel to device mapping  			   
//  
// Input Arguments:
//	
//	                 
// Output Arguments:
//  	
//
// Return Value: 
//
// Notes:
//
//*******************************************************************************
VOID XllpDmacHwInit(void)
{
    XLLP_UINT32_T		i;

	//
    // clear all of the DMA CSR registers
	//
    for (i=0; i < XLLP_DMAC_CHANNEL_NUM; i++)
    {
        //
        // Do it twice in case there are certain sticky bits...
	    //  
        pDmacHandle->DCSR[i] = 0x0;
	    pDmacHandle->DCSR[i] = 0x0;
    }
    
	//
	// Clear the alignment register
    // Clear the interrupt register
	//
	pDmacHandle->DALGN = 0x0;
    pDmacHandle->DINT  = 0x0;
    
	//
    // clear the DMA Request to Channel Map Registers
	//
    for (i=0; i < XLLP_DMAC_DRCMR1_NUM; i++)
    {
        pDmacHandle->DRCMR1[i] = 0x0;
    }

	for (i=0; i < XLLP_DMAC_DRCMR2_NUM; i++)
    {
        pDmacHandle->DRCMR2[i] = 0x0;
    }
    
	//
    // clear the descriptor registers
    //
    for(i=0; i < XLLP_DMAC_CHANNEL_NUM; i++)
    {
        //pDmacHandle->DDG[i].DDADR = 0x0;
        pDmacHandle->DDG[i].DSADR = 0x0;
        pDmacHandle->DDG[i].DTADR = 0x0;
        pDmacHandle->DDG[i].DCMD  = 0x0;
    }
	
}



//******************************************************************************
//
// Function Name: XllpDmacRegisterDeviceHandler
//
// Description: Function called to register a handler that will be called for handling
//              interrupts related to this DMA channel.
//  			   
//  
// Input Arguments:
//		XLLP_UINT32_T		dmaChannel:     DMA channel
//      DeviceDmaIntHandler	dmaIntHandler:  Handler function
//	    void*				userContext:    User context to be passed back to handler
//	                 
// Output Arguments:
//  	
//
// Return Value: 
//	XLLP_ERR_BAD_CHANNEL:           When user passes an invalid DMA channel
//  XLLP_ERR_CHANNEL_NOT_ALLOCATED: When specified DMA chanel has not been allocated
//  XLLP_STATUS_SUCCESS:                  On success
//
// Notes:
//      Only one handler can be registered per DMA channel.
//      Should we be registering handlers or setting events ?
//      
//
//*******************************************************************************
XLLP_STATUS_T	XllpDmacRegisterDeviceHandler
(
	XLLP_DMAC_CHANNEL_T	dmaChannel,
	DeviceDmaIntHandler	dmaIntHandler,
	void*				userContext
)
{
    if(dmaChannel > XLLP_DMAC_CHANNEL_NUM)
	    return XLLP_ERR_BAD_CHANNEL;

	//
    //  Channel should be allocated before registering a handler
	//
    if (!pDMAGlobals->pArrayChannel[dmaChannel] )
        return XLLP_ERR_CHANNEL_NOT_ALLOCATED;

    pDMAGlobals->dmaChannelConfigInfo[dmaChannel].pDeviceHandler = dmaIntHandler;
    pDMAGlobals->dmaChannelConfigInfo[dmaChannel].pUserContext   = userContext;
    
    return XLLP_STATUS_SUCCESS;   
}
    

//******************************************************************************
//
// Function Name: XllpDmacUnregisterDeviceHandler
//
// Description: Function called to unregister a previously registered handler 
//  			   
//  
// Input Arguments:
//		XLLP_UINT32_T		dmaChannel:     DMA channel
//	                 
// Output Arguments:
//  	
//
// Return Value: 
//	XLLP_ERR_BAD_CHANNEL:           When user passes an invalid DMA channel
//  XLLP_ERR_CHANNEL_NOT_ALLOCATED: When specified DMA chanel has not been allocated
//  XLLP_STATUS_SUCCESS:                  On success
//
// Notes:
//      Only one handler can be registered per DMA channel.
//      All interrupts for the specified DMA channel are disabled before unregistering
//      the handler
//      
//
//*******************************************************************************
XLLP_STATUS_T	XllpDmacUnregisterDeviceHandler
(
	XLLP_DMAC_CHANNEL_T		dmaChannel	
)
{

    if(dmaChannel > XLLP_DMAC_CHANNEL_NUM)
	    return XLLP_ERR_BAD_CHANNEL;

	//
    //  Channel should be allocated before registering a handler
	//
    if (!pDMAGlobals->pArrayChannel[dmaChannel] )
        return XLLP_ERR_CHANNEL_NOT_ALLOCATED;

    XllpDmacDisableInterrupts( dmaChannel,	XLLP_ALL_INTERRUPTS_SOURCE);

    pDMAGlobals->dmaChannelConfigInfo[dmaChannel].pDeviceHandler = NULL;
    pDMAGlobals->dmaChannelConfigInfo[dmaChannel].pUserContext   = NULL;
    
    return XLLP_STATUS_SUCCESS;   
}

//******************************************************************************
//
// Function Name: XllpDmacEnableInterrupts
//
// Description: Function called to enable specific interrupts related to specified DMA channel
//  			   
//  
// Input Arguments:
//		XLLP_UINT32_T		dmaChannel:         DMA channel
//		XLLP_UINT32_T		interruptBitmask:   Specified bitmask of interrupts to enable
//	                 
// Output Arguments:
//  	
//
// Return Value: 
//	XLLP_ERR_BAD_CHANNEL:           When user passes an invalid DMA channel
//  XLLP_ERR_NO_HANDLER:            When specified DMA chanel does not have a handler
//  XLLP_STATUS_SUCCESS:                  On success
//
// Notes:
//      A handler mut be registered for a DMA channel before interupts can be enabled
//      Only one handler can be registered per DMA channel.
//
//*******************************************************************************
XLLP_STATUS_T	XllpDmacEnableInterrupts
(
	XLLP_DMAC_CHANNEL_T	dmaChannel,	
	XLLP_UINT32_T		interruptBitmask
)
{    
    UINT32              intMask;

	//
	// Check for errors in DMA channel
	//
    if(dmaChannel > XLLP_DMAC_CHANNEL_NUM)
		return XLLP_ERR_BAD_CHANNEL;
    
	//
    //  Need a handler before enabling interrupts for channel.
	//
    if (!pDMAGlobals->dmaChannelConfigInfo[dmaChannel].pDeviceHandler)
        return XLLP_ERR_NO_HANDLER;   
        
	//
	// Enable the interrupts
	//    
    intMask     = pDmacHandle->DCSR[dmaChannel];
	intMask    |= interruptBitmask;
    pDmacHandle->DCSR[dmaChannel] = intMask;

    //RETAILMSG(1,(TEXT("DMA: EnableInt chan=%d DCSR=0x%08x \r\n"), dmaChannel, pDmacHandle->DCSR[dmaChannel] ));
    return XLLP_STATUS_SUCCESS;
}

//******************************************************************************
//
// Function Name: XllpDmacDisableInterrupts
//
// Description: Function called to disable specific interrupts related to specified DMA channel
//  			   
//  
// Input Arguments:
//		XLLP_UINT32_T		dmaChannel:         DMA channel
//		XLLP_UINT32_T		interruptBitmask:   Specified bitmask of interrupts to disable
//	                 
// Output Arguments:
//  	
//
// Return Value: 
//	XLLP_ERR_BAD_CHANNEL:           When user passes an invalid DMA channel
//  XLLP_STATUS_SUCCESS:                  On success
//
// Notes:
//
//*******************************************************************************

XLLP_STATUS_T    XllpDmacDisableInterrupts
(
	XLLP_DMAC_CHANNEL_T	dmaChannel,	
	XLLP_UINT32_T		interruptBitmask
)
{
    UINT32              intMask;

	//
	// Check for errors in DMA channel
	//
    if(dmaChannel > XLLP_DMAC_CHANNEL_NUM)
		return XLLP_ERR_BAD_CHANNEL;
    
	//
	// Disable the interrupts
	//
    intMask     = pDmacHandle->DCSR[dmaChannel];
	intMask  &= ~interruptBitmask;
    pDmacHandle->DCSR[dmaChannel] = intMask;	

    return XLLP_STATUS_SUCCESS;
}

//******************************************************************************
//
// Function Name: XllpDmacGetRemainingXfrLength
//
// Description: Function called to retrieve remaining transfer length for specified 
//              DMA channel for currently attached descriptor
//  			   
//  
// Input Arguments:
//		XLLP_UINT32_T		dmaChannel:         DMA channel
//	                 
// Output Arguments:
//  	
//
// Return Value: 
//  XLLP_ERR_BAD_CHANNEL:           For out of range DMA channel
//	XLLP_INT32_T:                   Length remaining to be transferred for current descriptor
//
//
// Notes:
//
//
//*******************************************************************************
XLLP_INT32_T	XllpDmacGetRemainingXfrLength
(
	XLLP_DMAC_CHANNEL_T	    dmaChannel	
)
{
	//
	// Check for errors in DMA channel
	//
    if(dmaChannel > XLLP_DMAC_CHANNEL_NUM)
		return XLLP_ERR_BAD_CHANNEL;
 
	//
	// Read the Descriptor Command register
	//    
    return (pDmacHandle->DDG[dmaChannel].DCMD & XLLP_DCMD_LEN_MASK);
}


//******************************************************************************
//
// Function Name: XllpDmacInterruptHandler
//
// Description: Function called at interrupt time to handle DMAC interrupts and
//              invoke registered handlers
//  			   
//  
// Input Arguments:
//
//	                 
// Output Arguments:
//  	
//
// Return Value: 
//
//
//
// Notes:
//  If a handler is not reistered for a DMA channel then all interrupts for that
//  channel are disabled.
//
//*******************************************************************************
#if 0    // pkdebug. Remove this entire function. Not used or needed.
/***
VOID XllpDmacInterruptHandler
(    
)
{   
    XLLP_UINT32_T   status = XLLP_STATUS_SUCCESS;
    XLLP_VUINT32_T  *dcsrP ;
    XLLP_VUINT32_T  tmpDINT;
    XLLP_VUINT32_T  tmpDCSR;
    XLLP_VUINT32_T  tmpDcsrClear;    
    XLLP_UINT32_T   i;
    XLLP_UINT32_T   intExists = FALSE;


    //
    // For each interrupting channel, get copy of DCSR 
    // Clear all interrupt reasons in real DCSR
    // Call registered handler if one exists; else, disable ints for channel
    // Don't stop for errors.  Just record at least one, at end.
    //
    // Exit this loop only when no interrupts are pending
    //
    while(1)
    {
        tmpDINT = pDmacHandle->DINT;        

        for ( i=0; i<XLLP_DMAC_CHANNEL_NUM; i++ )
        {
            if (tmpDINT & (1u << i))
            {                
                intExists = TRUE;
                dcsrP = &(pDmacHandle->DCSR[i]);
                tmpDCSR = *dcsrP;
				
//                RETAILMSG(1,(TEXT("DmacIntHandler: chan=%d DINT=0x%08x DCSR=0x%08x DCMD=0x%08x\r\n"), i, tmpDINT, tmpDCSR, pDmacHandle->DDG[i].DCMD ));

⌨️ 快捷键说明

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