ddk_dmac.c
来自「i.mx27 soc for wince 6.0」· 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 + -
显示快捷键?