📄 xllp_dmac.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//
/******************************************************************************
**
** Copyright 2001, 2002 Intel Corporation. All Rights Reserved.
**
** Portions of the source code contained or described herein and all documents
** related to such source code (Material) are owned by Intel Corporation
** or its suppliers or licensors and is licensed by Microsoft Corporation for distribution.
** Title to the Material remains with Intel Corporation or its suppliers and licensors.
** Use of the Materials is subject to the terms of the Microsoft license agreement which accompanied the Materials.
** No other license under any patent, copyright, trade secret or other intellectual
** property right is granted to or conferred upon you by disclosure or
** delivery of the Materials, either expressly, by implication, inducement,
** estoppel or otherwise
** Some portion of the Materials may be copyrighted by Microsoft Corporation.
**
** FILENAME: xllp_dmac.c
**
** PURPOSE: contains all primitive functions for Bulverde DMA Controller register
** access and control
**
******************************************************************************/
#include <windows.h>
#include <bulverde_intr.h>
#include <bulverde_dma.h>
#include <xllp_dmac.h>
#define XLLP_DMAC_DDADR_RESERVED_MASK 0xFFFFFFF0
#define XLLP_DMAC_DRCMR_ENABLE 0x80
#define XLLP_DMAC_DRCMR_DISABLE 0x00
volatile P_XLLP_DMAC_T pDmacHandle;
/**
* Channel priority sets
**/
const XLLP_DMAC_CHANNEL_T aPrioritySetCount = 8;
const XLLP_DMAC_CHANNEL_T ChannelPriorityHigh[]=
{
XLLP_DMAC_CHANNEL_0,
XLLP_DMAC_CHANNEL_1,
XLLP_DMAC_CHANNEL_2,
XLLP_DMAC_CHANNEL_3,
XLLP_DMAC_CHANNEL_16,
XLLP_DMAC_CHANNEL_17,
XLLP_DMAC_CHANNEL_18,
XLLP_DMAC_CHANNEL_19
};
const XLLP_DMAC_CHANNEL_T ChannelPriorityMedium[]=
{
XLLP_DMAC_CHANNEL_4,
XLLP_DMAC_CHANNEL_5,
XLLP_DMAC_CHANNEL_6,
XLLP_DMAC_CHANNEL_7,
XLLP_DMAC_CHANNEL_20,
XLLP_DMAC_CHANNEL_21,
XLLP_DMAC_CHANNEL_22,
XLLP_DMAC_CHANNEL_23
};
const XLLP_DMAC_CHANNEL_T ChannelPriorityLow[]=
{
XLLP_DMAC_CHANNEL_8,
XLLP_DMAC_CHANNEL_9,
XLLP_DMAC_CHANNEL_10,
XLLP_DMAC_CHANNEL_11,
XLLP_DMAC_CHANNEL_24,
XLLP_DMAC_CHANNEL_25,
XLLP_DMAC_CHANNEL_26,
XLLP_DMAC_CHANNEL_27
};
const XLLP_DMAC_CHANNEL_T ChannelPriorityLowest[]=
{
XLLP_DMAC_CHANNEL_12,
XLLP_DMAC_CHANNEL_13,
XLLP_DMAC_CHANNEL_14,
XLLP_DMAC_CHANNEL_15,
XLLP_DMAC_CHANNEL_28,
XLLP_DMAC_CHANNEL_29,
XLLP_DMAC_CHANNEL_30,
XLLP_DMAC_CHANNEL_31
};
// This is only needed when running without the XLLP DMA Engine.
XLLP_STATUS_T XllpDmacInitHandle(P_XLLP_DMAC_T address)
{
pDmacHandle = address;
return 0;
}
/******************************************************************************
XLLP_DOC_HDR_BEGIN
Function Name: XllpDmacFillLinkedDesc
Description: XllpDmacFillLinkedDesc is used to setup a descriptor or chained
descriptors for DMA transfer operations. To setup a descriptor
(ie. no chaining), the pointer to the next descriptor pNextDesc
is expected to be zero, otherwise pNextDesc expected to be a
valid descriptor pointer. Users wanting to chain multiple
descriptors will call this function to accomplish that task.
Global Registers Modified:
None
Input Arguments:
pDesc: Hold the pointer to the descriptor to be configured, cannot be a
null pointer.
pNextDesc: Holds the pointer to the next descriptor used in the DMA transfer
process after completely transferring data in the current descriptor
pDesc if the channel is not programmed to be stop. pNextDesc can
be a null pointer only if this descriptor is not meant to be chained.
aStopContinue: Specifies whether or not to configure this descriptor to stop
the channel after completely transferring data in this descriptor.
aBranch: Specifies whether to configure this descriptor to enable or disable
the descriptor branching mechanism. Valid values are element of type
XLLP_DMAC_DESC_BRANCH_T (1 or 0).
aSrcAddr: Holds the source address for this descriptor, cannot be null.
aTargetAddr: Holds the target address for this descriptor, cannot be null.
pCmd: Holds the commands for this descriptor. Users are required to initialize
the various fields of pCmd data structure before making this call.
Output Arguments:
None
Return Value:
None
XLLP_DOC_HDR_END
*******************************************************************************/
void XllpDmacFillLinkedDesc(
P_XLLP_DMAC_DESCRIPTOR_T pDesc,
P_XLLP_DMAC_DESCRIPTOR_T pNextDescPhyAddr,
XLLP_DMAC_DESC_ENABLE_T aStopContinue,
XLLP_DMAC_DESC_BRANCH_T aBranch,
XLLP_UINT32_T aSrcAddr,
XLLP_UINT32_T aTargetAddr,
XLLP_DMAC_COMMAND_T* pCmd
)
{
XLLP_VUINT32_T aTargetValue;
/* Construct command value from pCmd */
XLLP_UINT32_T aCommand = (XLLP_UINT32_T)(
( pCmd->aLen) | ((pCmd->aWidth) << XLLP_BIT_FIELD_14)|
((pCmd->aSize) << XLLP_BIT_FIELD_16) |
((pCmd->aEndian) << XLLP_BIT_FIELD_18) |
((pCmd->aFlyByT) << XLLP_BIT_FIELD_19) |
((pCmd->aFlyByS) << XLLP_BIT_FIELD_20) |
((pCmd->aEndIrqEn) << XLLP_BIT_FIELD_21)|
((pCmd->aStartIrqEn) << XLLP_BIT_FIELD_22)|
((pCmd->aAddrMode) << XLLP_BIT_FIELD_23)|
((pCmd->aCmpEn) << XLLP_BIT_FIELD_25) |
((pCmd->aFlowTrg) << XLLP_BIT_FIELD_28) |
((pCmd->aFlowSrc) << XLLP_BIT_FIELD_29) |
((pCmd->aIncTrgAddr) << XLLP_BIT_FIELD_30)|
((pCmd->aIncSrcAddr) << XLLP_BIT_FIELD_31)
);
/* Clear reserved bit fields of DDADR */
XLLP_VUINT32_T aNextDesc = (XLLP_UINT32_T)pNextDescPhyAddr;
aNextDesc = (XLLP_UINT32_T)(aNextDesc & XLLP_DMAC_DDADR_RESERVED_MASK);
aTargetValue = (XLLP_UINT32_T)(aNextDesc + (aBranch<<XLLP_BIT_FIELD_1) + aStopContinue);
/* Fill descriptor entries */
pDesc->DDADR = (XLLP_UINT32_T)(aNextDesc) + (aBranch<<XLLP_BIT_FIELD_1) + aStopContinue;
pDesc->DSADR = (XLLP_UINT32_T)aSrcAddr;
pDesc->DTADR = (XLLP_UINT32_T)aTargetAddr;
pDesc->DCMD = (XLLP_UINT32_T)aCommand;
}
/******************************************************************************
XLLP_DOC_HDR_BEGIN
Function Name: XllpDmacCfgChannelDescTransfer
Description: XllpDmacCfgChannelDescTransfer configures the specified DMA
channel for a Descriptor Mode transfer operation. To configure
a channel for a no descriptor mode transfer, use the
XllpDmacCfgChannelNoDescTransfer primitive. It is expected that
the developer has already made calls to XllpDmacAllocChannel for
an available channel and bound it to a service routine for interrupt
that may occur on the channel, and XllpDmacFillLinkedDesc to
configure the descriptor before calling this primitives.
Global Registers Modified:
DDADRx, DRCMRx registers. DSADRx, DTADRx, and DCMDx register will be modified
when the descriptor is loaded. x indicates the channel number
Input Arguments:
pDesc: Hold the pointer to the descriptor to be used in configuring the
specified DMA channel. The pointer cannot be null.
aChannel: Specifies the channel to be configured for the DMA transfer.
aDeviceDrcmr: Specifies the device to be mapped to the DMA channel for the transfer
operation.
aLignment: Indicated whether to enable byte alignment for memory accesses
Output Arguments:
None
Return Value:
None
XLLP_DOC_HDR_END
*******************************************************************************/
void XllpDmacCfgChannelDescTransfer(
P_XLLP_DMAC_DESCRIPTOR_T pDesc,
XLLP_DMAC_CHANNEL_T aChannel,
//XLLP_DMAC_DRCMR_T aDeviceDrcmr,
XLLP_DMAC_DEVICE_T aDeviceDrcmr,
XLLP_DMAC_ALIGNMENT_T aLignment
)
{
XLLP_VUINT32_T aTargetData;
if (aLignment == XLLP_DMAC_ALIGNMENT_ON)
{
aTargetData = pDmacHandle->DALGN;
aTargetData |= (1 << aChannel);
pDmacHandle->DALGN = aTargetData;
}
/* Map device to channel */
/* No mapping required for mem2mem moves */
if (aDeviceDrcmr != XLLP_DMAC_MEM2MEM_MOVE)
{
XllpDmacMapDeviceToChannel(aDeviceDrcmr, aChannel);
}
pDmacHandle->DDG[aChannel].DDADR = (XLLP_UINT32_T)pDesc;
}
/******************************************************************************
XLLP_DOC_HDR_BEGIN
Function Name: XllpDmacCfgChannelNoDescTransfer
Description: XllpDmacCfgChannelNoDescTransfer configures the specified DMA
channel for a No Descriptor Mode transfer operation. To configure
a channel for a descriptor mode transfer, use the
XllpDmacCfgChannelDescTransfer primitive. It is expected that the
developer has already obtained an available channel using the
XllpDmacAllocChannel primitive and bound it to a service routine
for interrupt that may occur on the channel.
Global Registers Modified:
DRCMRx, DSADRx, DTADRx, DCSRx, and DCMDx registers, where x indicate the
channel number
Input Arguments:
aSourceAddr: Source address of the DMA transfer to be configured
aTargetAddr: Target address of the DMA transfer to be configured
pCmd: Commands for the channel to be configured. Users are required to
initialize the various fields of pCmd data structure before making this
call.
aChannel: Specifies the channel to be configured for the DMA transfer.
aDeviceDrcmr: Specifies the device to be mapped to the DMA channel for the transfer
operation.
aLignment: Indicated whether to enable byte alignment for memory accesses
Output Arguments:
None
Return Value:
None
XLLP_DOC_HDR_END
*******************************************************************************/
void XllpDmacCfgChannelNoDescTransfer(
XLLP_UINT32_T aSourceAddr,
XLLP_UINT32_T aTargetAddr,
XLLP_DMAC_COMMAND_T* pCmd,
XLLP_DMAC_CHANNEL_T aChannel,
XLLP_DMAC_DEVICE_T aDeviceDrcmr,
XLLP_DMAC_ALIGNMENT_T aLignment
)
{
XLLP_VUINT32_T aCommand, aTargetData;
if (aLignment == XLLP_DMAC_ALIGNMENT_ON)
{
aTargetData = pDmacHandle->DALGN;
aTargetData |= (1 << aChannel);
pDmacHandle->DALGN = aTargetData;
}
/* Map device to channel */
/* No mapping required for mem2mem moves */
if (aDeviceDrcmr != XLLP_DMAC_MEM2MEM_MOVE)
{
XllpDmacMapDeviceToChannel(aDeviceDrcmr, aChannel);
}
/* Set the No Descriptor Fetch bit in DCSR*/
aTargetData = pDmacHandle->DCSR[aChannel];
aTargetData |= XLLP_DMAC_DCSR_NO_DESC_FETCH;
pDmacHandle->DCSR[aChannel] = aTargetData;
/* Construct command value from pCmd */
aCommand = (
(pCmd->aLen) | ((pCmd->aWidth) << XLLP_BIT_FIELD_14)|
((pCmd->aSize) << XLLP_BIT_FIELD_16) |
((pCmd->aEndian) << XLLP_BIT_FIELD_18) |
((pCmd->aFlyByT) << XLLP_BIT_FIELD_19) |
((pCmd->aFlyByS) << XLLP_BIT_FIELD_20) |
((pCmd->aEndIrqEn) << XLLP_BIT_FIELD_21)|
((pCmd->aStartIrqEn) << XLLP_BIT_FIELD_22)|
((pCmd->aAddrMode) << XLLP_BIT_FIELD_23)|
((pCmd->aCmpEn) << XLLP_BIT_FIELD_25) |
((pCmd->aFlowTrg) << XLLP_BIT_FIELD_28) |
((pCmd->aFlowSrc) << XLLP_BIT_FIELD_29) |
((pCmd->aIncTrgAddr) << XLLP_BIT_FIELD_30)|
((pCmd->aIncSrcAddr) << XLLP_BIT_FIELD_31)
);
pDmacHandle->DDG[aChannel].DSADR = aSourceAddr;
pDmacHandle->DDG[aChannel].DTADR = aTargetAddr;
pDmacHandle->DDG[aChannel].DCMD = aCommand;
}
/******************************************************************************
XLLP_DOC_HDR_BEGIN
Function Name: XllpDmacStartTransfer
Description: XllpDmacStartTransfer starts the DMA transfer process for the
specified channel.
Global Registers Modified:
DCSRx register, where x indicate the channel number
Input Arguments:
aChannel: Specifies the channel to start the DMA transfer on.
Output Arguments:
None
Return Value:
None
XLLP_DOC_HDR_END
*******************************************************************************/
void XllpDmacStartTransfer( XLLP_DMAC_CHANNEL_T aChannel )
{
pDmacHandle->DCSR[aChannel] |= XLLP_DMAC_DCSR_RUN;
}
/******************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -