ddk_dmac.c
来自「i.mx27 soc for wince 6.0」· C语言 代码 · 共 1,172 行 · 第 1/3 页
C
1,172 行
// Function: DDKDmacIsChannelIntr
//
// This function returns true if the channel has interrupted.
//
// Parameters:
// chan
// [in] - channel returned by DDKDmacRequestChan function.
//
// Returns:
// Returns TRUE if channel interrupt pending, otherwise returns FALSE.
//
//------------------------------------------------------------------------------
BOOL DDKDmacIsChannelIntr(UINT8 chan)
{
UINT32 mask = CHAN_MASK(chan);
return ((g_pDMAC->DISR & mask) == mask);
}
//------------------------------------------------------------------------------
//
// Function: DDKDmacClearChannelIntr
//
// This function returns true if the channel has interrupted.
//
// Parameters:
// chan
// [in] - channel returned by DDKDmacRequestChan function.
//
// Returns:
// None
//
//------------------------------------------------------------------------------
void DDKDmacClearChannelIntr(UINT8 chan)
{
UINT32 mask;
DEBUGMSG(ZONE_FUNCTION, (TEXT("+DDKDmacClearChannelIntr\r\n")));
mask = CHAN_MASK(chan);
g_pDMAC->DSESR = mask;
g_pDMAC->DBOSR = mask;
g_pDMAC->DRTOSR = mask;
g_pDMAC->DBTOSR = mask;
g_pDMAC->DISR = mask;
DEBUGMSG(ZONE_FUNCTION, (TEXT("-DDKDmacClearChannelIntr\r\n")));
}
//------------------------------------------------------------------------------
//
// Function: DDKDmacEnableChannelIntr
//
// This function enables interrupts for the desired channel.
//
// Parameters:
// chan
// [in] - channel returned by DDKDmacRequestChan function.
//
// Returns:
// None
//
//------------------------------------------------------------------------------
void DDKDmacEnableChannelIntr(UINT8 chan)
{
UINT32 mask;
DEBUGMSG(ZONE_FUNCTION, (TEXT("+DDKDmacEnableChannelIntr\r\n")));
mask = CHAN_MASK(chan);
// Clear any pending interrupt status
g_pDMAC->DSESR = mask;
g_pDMAC->DBOSR = mask;
g_pDMAC->DRTOSR = mask;
g_pDMAC->DBTOSR = mask;
g_pDMAC->DISR = mask;
// Enable channel interrupt
g_pDMAC->DIMR &= ~mask;
DEBUGMSG(ZONE_FUNCTION, (TEXT("-DDKDmacEnableChannelIntr: DIMR=0x%x\r\n"), g_pDMAC->DIMR));
}
//------------------------------------------------------------------------------
//
// Function: DDKDmacDisableChannelIntr
//
// This function disables interrupts for the desired channel.
//
// Parameters:
// chan
// [in] - channel returned by DDKDmacRequestChan function.
//
// Returns:
// None
//
//------------------------------------------------------------------------------
void DDKDmacDisableChannelIntr(UINT8 chan)
{
UINT32 mask;
DEBUGMSG(ZONE_FUNCTION, (TEXT("+DDKDmacDisableChannelIntr\r\n")));
mask = CHAN_MASK(chan);
// Disable channel interrupt
g_pDMAC->DIMR |= mask;
// Clear any pending interrupt status
g_pDMAC->DSESR = mask;
g_pDMAC->DBOSR = mask;
g_pDMAC->DRTOSR = mask;
g_pDMAC->DBTOSR = mask;
g_pDMAC->DISR = mask;
DEBUGMSG(ZONE_FUNCTION, (TEXT("-DDKDmacDisableChannelIntr: DIMR=0x%x\r\n"), g_pDMAC->DIMR));
}
//-----------------------------------------------------------------------------
//
// Function: DmacAlloc
//
// This function allocates the data structures required for interaction
// with the DMAC hardware.
//
// Parameters:
// None.
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL DmacAlloc(void)
{
BOOL rc = FALSE;
PHYSICAL_ADDRESS phyAddr;
DEBUGMSG(ZONE_INIT, (_T("DmacAlloc+\r\n")));
if (g_hFileMap == NULL)
{
g_hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,
PAGE_READWRITE, 0, sizeof(DMAC_DLL_SHARED), _T("DMAC_DLL_SHARED"));
if (g_hFileMap == NULL)
{
DEBUGMSG(ZONE_ERROR, (_T("DmacAlloc: CreateFileMapping failed!\r\n")));
goto cleanUp;
}
}
if (g_pDllShared == NULL)
{
g_pDllShared = (DMAC_DLL_SHARED *)MapViewOfFile(g_hFileMap,
FILE_MAP_ALL_ACCESS, 0, 0, 0);
if (g_pDllShared == NULL)
{
DEBUGMSG(ZONE_ERROR, (_T("DmacAlloc: MapViewOfFile failed!\r\n")));
goto cleanUp;
}
}
if (g_pDMAC == NULL)
{
phyAddr.QuadPart = CSP_BASE_REG_PA_DMAC;
// Map peripheral physical address to virtual address
g_pDMAC = (CSP_DMAC_REGS *)MmMapIoSpace(phyAddr, sizeof(CSP_DMAC_REGS), FALSE);
// Check if virtual mapping failed
if (g_pDMAC == NULL)
{
DEBUGMSG(ZONE_ERROR, (_T("DmacAlloc: MmMapIoSpace failed!\r\n")));
goto cleanUp;
}
}
rc = TRUE;
cleanUp:
// If initialization failed, be sure to clean up
if (!rc) DmacDealloc();
DEBUGMSG(ZONE_INIT, (_T("DmacAlloc- (rc = %d)\r\n"), rc));
return rc;
}
//-----------------------------------------------------------------------------
//
// Function: DmacDealloc
//
// This function deallocates the data structures required for interaction
// with the DMAC hardware. Note that data structures for individual channels
// are freed in DmacDeinit.
//
// Parameters:
// None.
//
// Returns:
// Returns TRUE.
//
//-----------------------------------------------------------------------------
BOOL DmacDealloc(void)
{
DEBUGMSG(ZONE_INIT, (_T("DmacDealloc+\r\n")));
// Unmap peripheral registers
if (g_pDMAC)
{
MmUnmapIoSpace(g_pDMAC, sizeof(CSP_DMAC_REGS));
g_pDMAC = NULL;
}
// Unmap view of shared DLL memory
if (g_pDllShared)
{
UnmapViewOfFile(g_pDllShared);
g_pDllShared = NULL;
}
// Close handle to shared DLL memory
if (g_hFileMap)
{
CloseHandle(g_hFileMap);
g_hFileMap = NULL;
}
DEBUGMSG(ZONE_INIT, (_T("DmacDealloc- (rc = %d)\r\n"), TRUE));
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: DmacTranslateCfg
//
// This function is used to translate the input channel configuration into
// DMAC register values.
//
// Parameters:
// pChannelCfg
// [in] - channel configuration.
//
// pChannelData
// [out] - DMAC channel register values
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//------------------------------------------------------------------------------
static BOOL DmacTranslateCfg(DMAC_CHANNEL_CFG *pChannelCfg, DMAC_CHANNEL_DATA *pChannelData)
{
BOOL rc = FALSE;
DEBUGMSG(ZONE_FUNCTION, (_T("DmacTranslateCfg+\r\n")));
// Translate configuration for CCR
switch(pChannelCfg->RepeatType)
{
case DMAC_REPEAT_DISABLED:
pChannelData->CCR = CSP_BITFVAL(DMAC_CCR_ACRPT, DMAC_CCR_ACRPT_DISABLE) |
CSP_BITFVAL(DMAC_CCR_RPT, DMAC_CCR_RPT_DISABLE);
break;
case DMAC_REPEAT_ONCE:
pChannelData->CCR = CSP_BITFVAL(DMAC_CCR_ACRPT, DMAC_CCR_ACRPT_AUTOCLEAR_RPT) |
CSP_BITFVAL(DMAC_CCR_RPT, DMAC_CCR_RPT_ENABLE);
break;
case DMAC_REPEAT_FOREVER:
pChannelData->CCR = CSP_BITFVAL(DMAC_CCR_ACRPT, DMAC_CCR_ACRPT_DISABLE) |
CSP_BITFVAL(DMAC_CCR_RPT, DMAC_CCR_RPT_ENABLE);
break;
default:
DEBUGMSG(ZONE_ERROR, (_T("DmacTranslateCfg: Invalid repeat type\r\n")));
goto cleanUp;
}
if((pChannelCfg->DstMode >= DMAC_TRANSFER_MODE_LINEAR_MEMORY) && (pChannelCfg->DstMode <= DMAC_TRANSFER_MODE_EOBE) &&
(pChannelCfg->SrcMode >= DMAC_TRANSFER_MODE_LINEAR_MEMORY) && (pChannelCfg->SrcMode <= DMAC_TRANSFER_MODE_EOBE) &&
(pChannelCfg->DstSize >= DMAC_TRANSFER_SIZE_32BIT) && (pChannelCfg->DstSize <= DMAC_TRANSFER_SIZE_16BIT) &&
(pChannelCfg->SrcSize >= DMAC_TRANSFER_SIZE_32BIT) && (pChannelCfg->SrcSize <= DMAC_TRANSFER_SIZE_16BIT) )
pChannelData->CCR |= CSP_BITFVAL(DMAC_CCR_DMOD, pChannelCfg->DstMode) |
CSP_BITFVAL(DMAC_CCR_SMOD, pChannelCfg->SrcMode) |
CSP_BITFVAL(DMAC_CCR_DSIZ, pChannelCfg->DstSize) |
CSP_BITFVAL(DMAC_CCR_SSIZ, pChannelCfg->SrcSize) ;
else
{
DEBUGMSG(ZONE_ERROR, (_T("DmacTranslateCfg: Invalid dest/src configuration\r\n")));
goto cleanUp;
}
if (pChannelCfg->MemDirIncrease)
pChannelData->CCR |= CSP_BITFVAL(DMAC_CCR_MDIR, DMAC_CCR_MDIR_INCREMENT);
else
pChannelData->CCR |= CSP_BITFVAL(DMAC_CCR_MDIR, DMAC_CCR_MDIR_DECREMENT);
// BUCR & RTOR share the same address. Which register is written depends on
// whether ext request enable (REN) is set in CCR.
if (pChannelCfg->ExtReqEnable)
{
pChannelData->CCR |= CSP_BITFVAL(DMAC_CCR_REN, DMAC_CCR_REN_ENABLE) |
CSP_BITFVAL(DMAC_CCR_FRC, DMAC_CCR_FRC_NOEFFECT);
pChannelData->RSSR = CSP_BITFVAL(DMAC_RSSR_RSS, pChannelCfg->ReqSrc);
// Set source clock of request time out counter is HCLK
if (pChannelCfg->ReqTimeout)
pChannelData->RTOR_BUCR = CSP_BITFVAL(DMAC_RTOR_EN, DMAC_RTOR_EN_ENABLE) |
CSP_BITFVAL(DMAC_RTOR_CLK, DMAC_RTOR_CLK_HCLK) |
CSP_BITFVAL(DMAC_RTOR_PSC, 0) |
CSP_BITFVAL(DMAC_RTOR_CNT, pChannelCfg->ReqTOCounter);
else
pChannelData->RTOR_BUCR = 0;
}
else
{
pChannelData->CCR |= CSP_BITFVAL(DMAC_CCR_REN, DMAC_CCR_REN_DISABLE) |
CSP_BITFVAL(DMAC_CCR_FRC, DMAC_CCR_FRC_FORCE_DMA_CYCLE);
pChannelData->RSSR = 0; // default
pChannelData->RTOR_BUCR = CSP_BITFVAL(DMAC_BUCR_BU_CNT, pChannelCfg->BusClkCounter);
}
// Translate other registers data
pChannelData->SAR = pChannelCfg->SrcAddr;
pChannelData->DAR = pChannelCfg->DstAddr;
pChannelData->CNTR = pChannelCfg->DataSize;
pChannelData->BLR = CSP_BITFVAL(DMAC_BLR_BL, pChannelCfg->BurstLength);
rc = TRUE;
cleanUp:
DEBUGMSG(ZONE_FUNCTION, (_T("DmacTranslateCfg- (rc = %d)\r\n"), rc));
return rc;
}
//-----------------------------------------------------------------------------
//
// Function: DmacShowRegister
//
// This function prints out the values in the DMAC registers.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
static void DmacShowRegister(UINT32 channelMask)
{
UINT32 mask;
UINT8 i;
DEBUGMSG(1, (TEXT("DMAC General Registers:\r\n")));
DEBUGMSG(1, (TEXT("DCR(0x%08x)\r\n"), g_pDMAC->DCR));
DEBUGMSG(1, (TEXT("DISR(0x%08x)\r\n"), g_pDMAC->DISR));
DEBUGMSG(1, (TEXT("DIMR(0x%08x)\r\n"), g_pDMAC->DIMR));
DEBUGMSG(1, (TEXT("DRTOSR(0x%08x)\r\n"), g_pDMAC->DRTOSR));
DEBUGMSG(1, (TEXT("DBOSR(0x%08x)\r\n"), g_pDMAC->DBOSR));
DEBUGMSG(1, (TEXT("DBTOCR(0x%08x)\r\n"), g_pDMAC->DBTOCR));
DEBUGMSG(1, (TEXT("2D memory registers:\r\n")));
DEBUGMSG(1, (TEXT("WSRA(0x%08x)\r\n"), g_pDMAC->WSRA));
DEBUGMSG(1, (TEXT("XSRA(0x%08x)\r\n"), g_pDMAC->XSRA));
DEBUGMSG(1, (TEXT("YSRA(0x%08x)\r\n"), g_pDMAC->YSRA));
DEBUGMSG(1, (TEXT("WSRB(0x%08x)\r\n"), g_pDMAC->WSRB));
DEBUGMSG(1, (TEXT("XSRB(0x%08x)\r\n"), g_pDMAC->XSRB));
DEBUGMSG(1, (TEXT("YSRB(0x%08x)\r\n"), g_pDMAC->YSRB));
for(i = 0, mask = 1; i <= DMAC_NUM_CHANNELS; i++, mask <<= 1)
{
if(mask & channelMask)
{
DEBUGMSG(1, (TEXT("Channel %d:\r\n"), i));
DEBUGMSG(1, (TEXT("SAR(0x%08x)\r\n"), g_pDMAC->CHANNEL[i].SAR));
DEBUGMSG(1, (TEXT("DAR(0x%08x)\r\n"), g_pDMAC->CHANNEL[i].DAR));
DEBUGMSG(1, (TEXT("CNTR(0x%08x)\r\n"), g_pDMAC->CHANNEL[i].CNTR));
DEBUGMSG(1, (TEXT("CCR(0x%08x)\r\n"), g_pDMAC->CHANNEL[i].CCR));
DEBUGMSG(1, (TEXT("RSSR(0x%08x)\r\n"), g_pDMAC->CHANNEL[i].RSSR));
DEBUGMSG(1, (TEXT("BLR(0x%08x)\r\n"), g_pDMAC->CHANNEL[i].BLR));
DEBUGMSG(1, (TEXT("RTOR_BUCR(0x%08x)\r\n"), g_pDMAC->CHANNEL[i].RTOR_BUCR));
DEBUGMSG(1, (TEXT("CCNR(0x%08x)\r\n"), g_pDMAC->CHANNEL[i].CCNR));
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?