📄 dma.c
字号:
/******************************************************************************
**
** 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 + -