ddk_dmac.c

来自「mx27 f14v2 源代码。包括ADS板上诸多驱动的源码。」· C语言 代码 · 共 1,172 行 · 第 1/3 页

C
1,172
字号
            INSREG32BF(&g_pDMAC->YSRA, DMAC_YSR_YS, pChannelCfg->YSR);
            INSREG32BF(&g_pDMAC->WSRA, DMAC_WSR_WS, pChannelCfg->WSR);
        }
        else if(g_pDllShared->Register2DFlagB == DMAC_CHANNEL_INVALID)
        {
            // Set B is free
            // keep track track of usage
            g_pDllShared->Register2DFlagB = chan;

            // Configure B set registers
            INSREG32BF(&g_pDMAC->XSRB, DMAC_XSR_XS, pChannelCfg->XSR);
            INSREG32BF(&g_pDMAC->YSRB, DMAC_YSR_YS, pChannelCfg->YSR);
            INSREG32BF(&g_pDMAC->WSRB, DMAC_WSR_WS, pChannelCfg->WSR);
            
            bSetB2DinUse = TRUE;
        }
        else   // No free 2D memory register set
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("DDKDmacConfigureChan: All 2D memory registers are used!!\r\n")));
            chan = DMAC_CHANNEL_INVALID;
            goto cleanup;
        }
    }

    // clear channel data
    memset(pChannelData, 0x00, sizeof(DMAC_CHANNEL_DATA));

    // Translate the input configuration into register values
    if(DmacTranslateCfg(pChannelCfg, pChannelData) == FALSE)
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("DDKDmacConfigureChan: Error in channel configuration!\r\n")));
        chan = DMAC_CHANNEL_INVALID;
        goto cleanup;
    }

    // Disable DMAC channel
    INSREG32BF(&g_pDMAC->CHANNEL[chan].CCR, DMAC_CCR_CEN, DMAC_CCR_CEN_DISABLE);       

    // Set source, destination addresses and data size
    g_pDMAC->CHANNEL[chan].SAR = pChannelData->SAR;
    g_pDMAC->CHANNEL[chan].DAR = pChannelData->DAR;
    g_pDMAC->CHANNEL[chan].CNTR = pChannelData->CNTR;

    // set other channel registers
    g_pDMAC->CHANNEL[chan].RSSR = pChannelData->RSSR;
    g_pDMAC->CHANNEL[chan].BLR = pChannelData->BLR;
    g_pDMAC->CHANNEL[chan].RTOR_BUCR = pChannelData->RTOR_BUCR;      

    if(bSetB2DinUse)
        CSP_BITFINS(pChannelData->CCR, DMAC_CCR_MSEL, DMAC_CCR_MSEL_2DMEM_SETB);

    // Set channel control register
    CSP_BITFINS(pChannelData->CCR, DMAC_CCR_CEN, DMAC_CCR_CEN_DISABLE);
    g_pDMAC->CHANNEL[chan].CCR = pChannelData->CCR; 

    DEBUGMSG(ZONE_INFO, (TEXT("DDKDmacConfigureChan: channel %d is configured! CCR(0x%08x)\r\n"), 
                                chan, &g_pDMAC->CHANNEL[chan].CCR));

cleanup:
    DEBUGMSG(ZONE_FUNCTION, (_T("DDKDmacConfigureChan- (chan = %d)\r\n"), chan));
    return chan;
}

//-----------------------------------------------------------------------------
//
// Function:  DDKDmacStartChan
//
// This function starts the specified channel.
//
// Parameters:
//      chan
//          [in] - DMAC channel to start.
//
// Returns:
//      Returns TRUE if the start request is successful, else returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL DDKDmacStartChan(UINT8 chan)
{
    BOOL rc = FALSE;

    DEBUGMSG(ZONE_FUNCTION, (_T("DDKDmacStartChan+ %d\r\n"), chan));

    // Validate channel parameter
    if(chan >= DMAC_NUM_CHANNELS)
    {
        DEBUGMSG(ZONE_ERROR,
            (_T("DDKDmacStartChan: Invalid channel %d\r\n"), chan));
        goto cleanUp;
    }

    // Check if channel is in use
    if((g_pDllShared->ChannelAllocated & CHAN_MASK(chan)) == 0)
    {
        DEBUGMSG(ZONE_WARN,
            (_T("DDKDmacStartChan:  Chan %d start ignored, not allocated"), chan));
        goto cleanUp;
    }

    INSREG32BF(&g_pDMAC->CHANNEL[chan].CCR, DMAC_CCR_CEN, DMAC_CCR_CEN_DISABLE);
    INSREG32BF(&g_pDMAC->CHANNEL[chan].CCR, DMAC_CCR_CEN, DMAC_CCR_CEN_ENABLE);

    rc = TRUE;

cleanUp:
    DEBUGMSG(ZONE_FUNCTION, (_T("DDKDmacStartChan- (rc = %d)\r\n"), rc));
    return rc;
}


//-----------------------------------------------------------------------------
//
// Function:  DDKDmacStopChan
//
// This function stops the specified channel.
//
// Parameters:
//      chan
//          [in] - DMAC channel to start.
//
// Returns:
//      Returns TRUE if the stop request is successful, else returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL DDKDmacStopChan(UINT8 chan)
{
    BOOL rc = FALSE;

    DEBUGMSG(ZONE_FUNCTION, (_T("DDKDmacStopChan+\r\n")));

    // Validate channel parameter
    if(chan >= DMAC_NUM_CHANNELS)
    {
        DEBUGMSG(ZONE_ERROR,
            (_T("DDKDmacStopChan: Invalid channel %d\r\n"), chan));
        goto cleanUp;
    }

    INSREG32BF(&g_pDMAC->CHANNEL[chan].CCR, DMAC_CCR_CEN, DMAC_CCR_CEN_DISABLE);

    rc = TRUE;

cleanUp:
    DEBUGMSG(ZONE_FUNCTION, (_T("DDKDmacStopChan- (rc = %d)\r\n"), rc));
    return rc;
}

//-----------------------------------------------------------------------------
//
// Function:  DmacGetTranStatus
//
// This function queries the status of a channel transfer.
//
// Parameters:
//      chan
//          [in] - channel returned by DDKDmacRequestChan function.
//
// Returns:
// Bitmap indicating type of interrupt status. DMAC_TRANSFER_STATUS_COMPLETE  
// indicates that the DMA cycle completed with out error.
// DMAC_TRANSFER_STATUS_NONE indicates that the DMA cycle is ongoing.
// Any other return value indicates error in the transfer.
//
// In interrupt mode, the return value indicate 
// the type of pending interrupt
//
//-----------------------------------------------------------------------------
UINT32 DDKDmacGetTransStatus(UINT8 chan)
{
    UINT32 rc = DMAC_TRANSFER_STATUS_NONE;
    UINT32 mask;

    DEBUGMSG(ZONE_FUNCTION, (_T("DDKDmacGetTransStatus+\r\n")));

    // Validate channel parameter
    if(chan >= DMAC_NUM_CHANNELS)
    {
        DEBUGMSG(ZONE_ERROR, (_T("DDKDmacGetTransStatus: Invalid channel\r\n")));
        goto cleanUp;
    }

    // Check if channel in use
    mask = 1 << chan;
    if((g_pDllShared->ChannelAllocated & mask) == 0)
    {
        DEBUGMSG(ZONE_ERROR, (_T("DDKDmacGetTransStatus: Channel%d not allocated\r\n"), chan));
        goto cleanUp;
    }

    // Get transfer status
    if((g_pDMAC->DSESR & mask) != 0)
        rc |= DMAC_TRANSFER_STATUS_ERROR;

    if((g_pDMAC->DBOSR & mask) != 0)
       rc |= DMAC_TRANSFER_STATUS_BUFFER_OVERFLOW;

    if((g_pDMAC->DRTOSR & mask) != 0)
       rc |= DMAC_TRANSFER_STATUS_REQ_TIMEOUT;

    if((g_pDMAC->DBTOSR & mask) != 0)
        rc |= DMAC_TRANSFER_STATUS_BURST_TIMEOUT;

    // Interrupt pending with no error
    if( (g_pDMAC->DISR & mask) == mask && rc == DMAC_TRANSFER_STATUS_NONE)
        rc |= DMAC_TRANSFER_STATUS_COMPLETE;

cleanUp:
    DEBUGMSG(ZONE_FUNCTION, (_T("DDKDmacGetTransStatus- (rc = 0x%X)\r\n"), rc));
    return rc;

}

//------------------------------------------------------------------------------
//
// Function:  DmacGetTranSize
//
// This function returns the number of bytes transferred by a channel.
//
// Parameters:
//      chan
//          [in] - channel returned by DDKDmacRequestChan function.
//
// Returns:
//       number of bytes transferred by a channel.
//
//------------------------------------------------------------------------------
UINT32 DDKDmacGetTransSize(UINT8 chan)
{
    UINT32 rc;
    
    DEBUGMSG(ZONE_FUNCTION, (_T("DmacGetTranSize+\r\n")));
    
    rc = g_pDMAC->CHANNEL[chan].CCNR;

    DEBUGMSG(ZONE_FUNCTION, (_T("DmacGetTranSize- (rc = 0x%X)\r\n"), rc));
    return rc;
}

//------------------------------------------------------------------------------
//
// Function:  DDKDmacSetSrcAddress
//
// This function sets the source address for the next DMA cycle.
//
// Parameters:
//      chan
//          [in] - channel returned by DDKDmacRequestChan function.
//
//      src
//          [in] - source address for next DMA cycle
// Returns:
//       None
//
//------------------------------------------------------------------------------
void DDKDmacSetSrcAddress(UINT8 chan, UINT32 src)
{
    DEBUGMSG(ZONE_FUNCTION, (_T("DDKDmacSetSrcAddress+\r\n")));
    
    g_pDMAC->CHANNEL[chan].SAR = src;

    DEBUGMSG(ZONE_FUNCTION, (_T("DDKDmacSetSrcAddress- (chan = %d src = 0x%X)\r\n"), 
                            chan, src));
}

//------------------------------------------------------------------------------
//
// Function:  DDKDmacSetDestAddress
//
// This function sets the destination address for the next DMA cycle.
//
// Parameters:
//      chan
//          [in] - channel returned by DDKDmacRequestChan function.
//
//      dest
//          [in] - destination address for next DMA cycle
// Returns:
//       None
//
//------------------------------------------------------------------------------
void DDKDmacSetDestAddress(UINT8 chan, UINT32 dest)
{
    DEBUGMSG(ZONE_FUNCTION, (_T("DDKDmacSetDestAddress+\r\n")));
    
    g_pDMAC->CHANNEL[chan].DAR = dest;

    DEBUGMSG(ZONE_FUNCTION, (_T("DDKDmacSetDestAddress- (chan = %d dest = 0x%X)\r\n"), 
                        chan, dest));
}

//------------------------------------------------------------------------------
//
// Function:  DDKDmacSetTransCount
//
// This function sets the transfer byte count for the next DMA cycle.
//
// Parameters:
//      chan
//          [in] - channel returned by DDKDmacRequestChan function.
//
//      count
//          [in] - transfer byte count for next DMA cycle
// Returns:
//       None
//
//------------------------------------------------------------------------------
void DDKDmacSetTransCount(UINT8 chan, UINT32 count)
{
    DEBUGMSG(ZONE_FUNCTION, (_T("DDKDmacSetTransCount+\r\n")));
    
    g_pDMAC->CHANNEL[chan].CNTR = count;

    DEBUGMSG(ZONE_FUNCTION, (_T("DDKDmacSetTransCount- (chan = %d count = 0x%X)\r\n"), 
                        chan, count));
}

//------------------------------------------------------------------------------
//
// Function:  DDKDmacSetBurstLength
//
// This function sets the transfer burst length for the next DMA cycle.
//
// Parameters:
//      chan
//          [in] - channel returned by DDKDmacRequestChan function.
//
//      burstLen
//          [in] - Burst length for next DMA cycle
// Returns:
//       None
//
//------------------------------------------------------------------------------
void DDKDmacSetBurstLength(UINT8 chan, UINT32 burstLen)
{
    DEBUGMSG(ZONE_FUNCTION, (_T("DDKDmacSetTransCount+\r\n")));
    
    INSREG32BF(&g_pDMAC->CHANNEL[chan].BLR, DMAC_BLR_BL, burstLen);

    DEBUGMSG(ZONE_FUNCTION, (_T("DDKDmacSetTransCount- (chan = %d burstLen = 0x%X)\r\n"), 
                        chan, burstLen));
}

//------------------------------------------------------------------------------
//
// Function:  DDKDmacSetRepeatType
//
// This function sets the transfer repeat type for the next DMA cycle.
//
// Parameters:
//      chan
//          [in] - channel returned by DDKDmacRequestChan function.
//
//      repeatType
//          [in] - Repeat type for next DMA cycle
// Returns:
//       None
//
//------------------------------------------------------------------------------
void DDKDmacSetRepeatType(UINT8 chan, DMAC_REPEAT_TYPE repeatType)
{
    DEBUGMSG(ZONE_FUNCTION, (_T("DDKDmacSetRepeatType+\r\n")));
    
    switch(repeatType)
    {
        case DMAC_REPEAT_DISABLED:
            INSREG32BF(&g_pDMAC->CHANNEL[chan].CCR, DMAC_CCR_RPT, DMAC_CCR_RPT_DISABLE);
            INSREG32BF(&g_pDMAC->CHANNEL[chan].CCR, DMAC_CCR_ACRPT, DMAC_CCR_ACRPT_DISABLE);
            DEBUGMSG(ZONE_INFO, (_T("DDKDmacSetRepeatType: No repeat.\r\n")));
            break;

        case DMAC_REPEAT_ONCE:
            INSREG32BF(&g_pDMAC->CHANNEL[chan].CCR, DMAC_CCR_RPT, DMAC_CCR_RPT_ENABLE);
            INSREG32BF(&g_pDMAC->CHANNEL[chan].CCR, DMAC_CCR_ACRPT, DMAC_CCR_ACRPT_AUTOCLEAR_RPT);
            DEBUGMSG(ZONE_INFO, (_T("DDKDmacSetRepeatType: Repeat once.\r\n")));
            break;

        case DMAC_REPEAT_FOREVER:
            INSREG32BF(&g_pDMAC->CHANNEL[chan].CCR, DMAC_CCR_RPT, DMAC_CCR_RPT_ENABLE);
            INSREG32BF(&g_pDMAC->CHANNEL[chan].CCR, DMAC_CCR_ACRPT, DMAC_CCR_ACRPT_DISABLE);
            DEBUGMSG(ZONE_INFO, (_T("DDKDmacSetRepeatType: Repeat forever.\r\n")));
            break;

        default:
            DEBUGMSG(ZONE_ERROR, (_T("DDKDmacSetRepeatType: Invalid repeat type.\r\n")));
    }
    DEBUGMSG(ZONE_FUNCTION, (_T("DDKDmacSetRepeatType- (chan = %d repeatType = 0x%X)\r\n"), 
                        chan, repeatType));
}    

//------------------------------------------------------------------------------
//

⌨️ 快捷键说明

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