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

📄 xsdma.c

📁 优龙YLP270开发板 光盘自带的BIOS和实验例程源码 强烈推荐
💻 C
📖 第 1 页 / 共 4 页
字号:
*
* 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 + -