📄 xsdma.c
字号:
*
* ASSUMPTIONS: All DMA registers are fresh from reset
*
* CALLS:
*
* CALLED BY:
*
* PROTOTYPE: UINT32 XsDmaHWSetup (void);
*
*******************************************************************************
*/
UINT32 XsDmaHWSetup (void)
{
UINT32 status;
XsDmaInitAll();
status = XsIcRegisterHandler (XSIC_DMA_SGNL,
XsDmaInterruptHandler,
(void *) NULL);
if (status)
{
LOGERROR(status, ERR_L_XSDMA, ERR_S_DMA_HWSETUP, status, 0, 0, 0);
}
else
{
// No problems, now enable the DMA ints at the Interrupt Controller.
// Ignore return values, the parameters were range-checked just above.
(void) XsIcEnableIrqDeviceInt (XSIC_DMA_SGNL);
}
return (status);
} // XsDmaHWSetup ()
/*
*******************************************************************************
*
* FUNCTION: XsDmaInitAll
*
* DESCRIPTION: Initializes all DMA registers to a benign state.
*
* INPUT PARAMETERS: None
*
* RETURNS: None
*
* GLOBAL EFFECTS: Resets all registers pertaining to DMA. If there was a
* DMA engine transferring data, that block will be completed,
* but no further blocks will start.
*
* ASSUMPTIONS: None
*
* CALLS: None
*
* CALLED BY: XsDmaHWSetup
*
* PROTOTYPE: static void XsDmaInitAll (void);
*
*******************************************************************************
*/
static
void XsDmaInitAll(void)
{
UINT i;
// clear all of the DMA CSR registers
for (i=0; i < XSDMA_CHANNEL_NUM; i++)
{
XsDmaControlRegsP->DCSR[i] = 0x0;
}
// clear the interrupt register
XsDmaControlRegsP->DINT = 0x0;
// clear the DMA Request to Channel Map Registers
for (i=0; i < XSDMA_DRCMR_ID_NUM; i++)
{
XsDmaControlRegsP->DRCMR[i] = 0x0;
}
// clear the descriptor registers
for(i=0; i < XSDMA_CHANNEL_NUM; i++)
{
XsDmaControlRegsP->DDG[i].DDADR = 0x0;
XsDmaControlRegsP->DDG[i].DSADR = 0x0;
XsDmaControlRegsP->DDG[i].DTADR = 0x0;
XsDmaControlRegsP->DDG[i].DCMD = 0x0;
}
} // XsDmaInitAll ()
/*
*******************************************************************************
*
* FUNCTION: XsDmaSetBurstSize
*
* DESCRIPTION: Sets the burst size of the DMA transfer for the specific device,
* and replaces the deafault burst size in the DMA Device Table
*
* INPUT PARAMETERS: XsDmaDeviceNamesT deviceName,
* XsDmaBurstSizeT - the burst size (8,16 or 32 bytes).
*
* RETURNS: None
*
* GLOBAL EFFECTS: None
*
* ASSUMPTIONS: None
*
* CALLS: None
*
* PROTOTYPE: VOID XsDmaSetBurstSize (XsDmaDeviceNamesT deviceName,
* XsDmaBurstSizeT burstSize);
*
*******************************************************************************
*/
VOID XsDmaSetBurstSize (XsDmaDeviceNamesT deviceName, XsDmaBurstSizeT burstSize)
{
switch (burstSize)
{
case XSDMA_BURST_SIZE_8:
DmaDeviceTable[deviceName].best_burst = DCMD_SIZE_8;
break;
case XSDMA_BURST_SIZE_16:
DmaDeviceTable[deviceName].best_burst = DCMD_SIZE_16;
break;
case XSDMA_BURST_SIZE_32:
DmaDeviceTable[deviceName].best_burst = DCMD_SIZE_32;
break;
}
}
/*
*******************************************************************************
*
* FUNCTION: XsDmaSetDataWidth
*
* DESCRIPTION: Sets the data width of the DMA transfer for the specific device,
* and replaces the deafault data width in the DMA Device Table
*
* INPUT PARAMETERS: XsDmaDeviceNamesT deviceName,
* XsDmaDataWidthT - the data width (8,16 or 32 bytes).
*
* RETURNS: None
*
* GLOBAL EFFECTS: None
*
* ASSUMPTIONS: None
*
* CALLS: None
*
* PROTOTYPE: VOID XsDmaSetDataWidth (XsDmaDeviceNamesT deviceName,
* XsDmaDataWidthT dataWidth);
*
*******************************************************************************
*/
VOID XsDmaSetDataWidth (XsDmaDeviceNamesT deviceName, XsDmaDataWidthT dataWidth)
{
switch (dataWidth)
{
case XSDMA_DATA_WIDTH_8:
DmaDeviceTable[deviceName].data_width = DCMD_WIDTH_1;
break;
case XSDMA_DATA_WIDTH_16:
DmaDeviceTable[deviceName].data_width = DCMD_WIDTH_2;
break;
case XSDMA_DATA_WIDTH_32:
DmaDeviceTable[deviceName].data_width = DCMD_WIDTH_4;
break;
}
}
/*
*******************************************************************************
*
* FUNCTION: XsDmaGetFreeChannel
*
* DESCRIPTION: Finds an unused DMA channel. Information about the device
* for which the channel will be used is recorded. That
* information will be used in building descriptors and in
* XsDmaStart().
*
* INPUT PARAMETERS:
* XsDmaChannelPriorityT desiredPriority: (high, medium, low)
* XsDmaDeviceNamesT deviceName: Name of the target device for
* the DMA channel. One device is always assumed to be
* XSDMA_DN_MEMORY. This is the name of the other device,
* which may also be XSDMA_DN_MEMORY.
* BOOL isTarget: If TRUE, this channel will be
* used to transfer data from memory to the specified device.
* If FALSE, this channel will be used to transfer data from
* the specified device to memory.
* XsDmaChannelStatusT * statusP: Address of a variable to receive a
* report on the relative priority of the assigned channel to
* the priority that was requested. Also indicates if no
* channel was available.
*
* RETURNS: INT: Assigned channel's number or XSDMA_CHANNEL_UNAVAILABLE
* if none are free
*
* GLOBAL EFFECTS: None
*
* ASSUMPTIONS: None
*
* CALLS: XsDmaModifyChannelUsage
* XsDmaMapDevice2DrcmrId
*
* CALLED BY: Anyone
*
* PROTOTYPE: INT XsDmaGetFreeChannel (XsDmaChannelPriorityT,
* XsDmaDeviceNamesT,
* BOOL,
* XsDmaChannelStatusT*);
*
* DESIGN DETAILS: The used channels are stored as bits within a static
* integer. Other information is stored in the
* XsDmaChannelConfigTable.
*
* NOTE: For more static systems, this function could be replaced by
* pre-allocation of channels and initialization of the
* XsDmaChannelConfigTable during system initialization or at
* compile time.
*
*******************************************************************************
*/
INT XsDmaGetFreeChannel (XsDmaChannelPriorityT desiredPriority,
XsDmaDeviceNamesT deviceName,
BOOL isTarget,
XsDmaChannelStatusT *status)
{
INT channel;
XsDmaChannelConfigEntryT* channelConfigP;
// Get free channel and record it in log. Leave pre-existing subroutine
// alone.
channel = XsDmaModifyChannelUsage(CHANNEL_OP_GET, 0, desiredPriority, status);
// Record information about channel usage in data base.
if ( XSDMA_CHANNEL_UNAVAILABLE != channel)
{
channelConfigP = &XsDmaChannelConfigTable[channel];
channelConfigP->isAssigned = TRUE;
// Simplify logic with default of memory-to-memory transfer.
channelConfigP->sourceDeviceName = XSDMA_DN_MEMORY;
channelConfigP->targetDeviceName = XSDMA_DN_MEMORY;
channelConfigP->drcmrId = XSDMA_DRCMR_ID_MEMORY;
if (XSDMA_DN_MEMORY != deviceName)
{ // Not memory-to-memory transfer
// Parameters validated by XsDmaModifyChannelUsage ().
channelConfigP->drcmrId = XsDmaMapDevice2DrcmrId ( deviceName,
isTarget);
if (isTarget)
{
channelConfigP->targetDeviceName = deviceName;
}
else
{
channelConfigP->sourceDeviceName = deviceName;
}
} // if (XSDMA_DN_MEMORY != deviceName)
} // if ( XSDMA_CHANNEL_UNAVAILABLE != channel)
DM_CwDbgPrintf(DM_CW_DMA_0, "Allocated Channel: %d \r\n", (UINT)channel);
return(channel);
} // XsDmaGetFreeChannel ()
/*
*******************************************************************************
*
* FUNCTION: XsDmaFreeChannel
*
* DESCRIPTION: Return a DMA channel to the free channel pool (deallocate
it). Includes guaranteeing a safe and consistent state by
unregistering any handler for that channel. If a
non-memory device had the channel allocated, the channel is
unmapped in that device's DRCMR. No-ops without error
indication if the specified channel is not allocated.
*
* INPUT PARAMETERS: INT Channel - the channel to free
*
* RETURNS: UINT32
* Success: ERR_NONE (0)
* Failure: ERR_T_ILLPARAM: out of range channel
*
* GLOBAL EFFECTS: None
*
* ASSUMPTIONS: None
*
* CALLS: XsDmaModifyChannelUsage
* XsDmaUnregisterHandler
*
* CALLED BY: Anyone
*
* PROTOTYPE: UINT32 XsDmaFreeChannel(INT);
*
* NOTES: Any descriptors using this channel are now invalid.
* The process of unmapping the channel disables interrupts
* from this channel (in the DCSR).
*
*******************************************************************************
*/
UINT32 XsDmaFreeChannel(INT channel)
{
int dummy;
XsDmaChannelStatusT dummyChannelStatus;
UINT32 status = ERR_NONE;
XsDmaChannelConfigEntryT* channelConfigP;
XsDmaDrcmrIdT thisDrcmrId;
status = XsDmaRangeCheckChannel (channel);
if (!status)
{
channelConfigP = &XsDmaChannelConfigTable [channel];
// XsDmaUnregisterHandler() also disables interrupts for channel.
dummy = XsDmaUnregisterHandler (channel);
dummy = XsDmaModifyChannelUsage(CHANNEL_OP_RESET, channel, 0,
&dummyChannelStatus);
channelConfigP->isAssigned = FALSE;
// For non-memory devices, unmap the channel # from the device's DRCMR
// register by clearing the MAPVLD bit; it is easiest to set reg to 0.
thisDrcmrId = channelConfigP->drcmrId;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -