#include <windows.h>
#include <CEDDK.h>
#include "bsp_cfg.h"
#include <oal_intr.h>
#include <s3c6410.h>
#include "s3c6410_dma_controller_macro.h"
#include "s3c6410_dma_controller.h"
#ifdef REMOVE_BEFORE_RELEASE
#define DMA_MSG(x)
#define DMA_INF(x)
#define DMA_ERR(x) RETAILMSG(TRUE, x)
#else
//#define DMA_MSG(x) RETAILMSG(TRUE, x)
#define DMA_MSG(x)
#define DMA_INF(x) RETAILMSG(TRUE, x)
//#define DMA_INF(x)
#define DMA_ERR(x) RETAILMSG(TRUE, x)
//#define DMA_ERR(x)
#endif
#define DMA_MUTEX TEXT("S3C6410_DMA_Mutex")
static volatile S3C6410_DMAC_REG *g_pDMAC0Reg = NULL;
static volatile S3C6410_DMAC_REG *g_pDMAC1Reg = NULL;
static volatile S3C6410_SYSCON_REG *g_pSysConReg = NULL;
static HANDLE g_hMutex = NULL;
DMA_ERROR DMA_initialize_register_address(void *pDMAC0Reg, void *pDMAC1Reg, void *pSysConReg)
{
DMA_ERROR error = DMA_SUCCESS;
DMA_MSG((_T("[DMA]++DMA_initialize_register_address(0x%08x, 0x%08x, 0x%08x)\n\r"), pDMAC0Reg, pDMAC1Reg, pSysConReg));
if (pDMAC0Reg == NULL || pDMAC1Reg == NULL || pSysConReg == NULL)
{
DMA_ERR((_T("[DMA:ERR] DMA_initialize_register_address() : NULL pointer parameter\n\r")));
error = DMA_ERROR_NULL_PARAMETER;
}
else
{
g_pDMAC0Reg = (S3C6410_DMAC_REG *)pDMAC0Reg;
g_pDMAC1Reg = (S3C6410_DMAC_REG *)pDMAC1Reg;
g_pSysConReg = (S3C6410_SYSCON_REG *)pSysConReg;
DMA_INF((_T("[DMA:INF] g_pDMAC0Reg = 0x%08x\n\r"), g_pDMAC0Reg));
DMA_INF((_T("[DMA:INF] g_pDMAC1Reg = 0x%08x\n\r"), g_pDMAC1Reg));
DMA_INF((_T("[DMA:INF] g_pSysConReg = 0x%08x\n\r"), g_pSysConReg));
g_pSysConReg->SDMA_SEL = 0xcfffffff; // All DMA is set to Normal DMA except Security TX, RX
DMA_INF((_T("[DMA:INF] All DMA Source is set to Normal DMA\n\r")));
}
if (g_hMutex == NULL)
{
g_hMutex = CreateMutex(NULL, FALSE, DMA_MUTEX);
if (g_hMutex == NULL)
{
DMA_ERR((_T("[DMA:ERR] DMA_initialize_register_address() : CreateMutex() Failed\n\r")));
error = DMA_ERROR_NOT_INITIALIZED;
}
}
DMA_MSG((_T("[DMA]--DMA_initialize_register_address() : %d\n\r"), error));
return error;
}
BOOL DMA_request_channel(DMA_CH_CONTEXT *pCtxt, DMA_SOURCE DMASrc)
{
volatile S3C6410_DMA_CH_REG *pDMACHReg;
BOOL bRet = TRUE;
int i;
DMA_MSG((_T("[DMA]++DMA_request_channel(%d)\n\r"), DMASrc));
pCtxt->DMASrc = DMASrc;
if (g_pDMAC0Reg == NULL || g_pDMAC1Reg == NULL)
{
DMA_ERR((_T("[DMA:ERR] DMA Register Address is Not initialized\n\r")));
bRet = FALSE;
goto CleanUp;
}
switch(DMASrc)
{
case DMA_UART0_TX:
case DMA_UART0_RX:
case DMA_UART1_TX:
case DMA_UART1_RX:
case DMA_UART2_TX:
case DMA_UART2_RX:
case DMA_UART3_TX:
case DMA_UART3_RX:
case DMA_PCM0_TX:
case DMA_PCM0_RX:
case DMA_I2S0_TX:
case DMA_I2S0_RX:
case DMA_SPI0_TX:
case DMA_SPI0_RX:
case DMA_I2S_V40_TX:
case DMA_I2S_V40_RX:
case DMA_MEM:
case DMA_FIMG:
pCtxt->Controller = DMAC0;
break;
case DMA_PCM1_TX:
case DMA_PCM1_RX:
case DMA_I2S1_TX:
case DMA_I2S1_RX:
case DMA_SPI1_TX:
case DMA_SPI1_RX:
case DMA_AC97_PCMOUT:
case DMA_AC97_PCMIN:
case DMA_AC97_MICIN:
case DMA_PWM:
case DMA_IRDA:
case DMA_EXTERNAL:
case DMA_SSS:
pCtxt->Controller = DMAC1;
break;
default:
DMA_ERR((_T("[DMA:ERR] DMA_request_channel() : Unknown DMA Source [%d]\n\r"), DMASrc));
bRet = FALSE;
goto CleanUp;
break;
}
// Lock DMA Access
DMA_lock();
// Enable DMAC HCLK
g_pSysConReg->HCLK_GATE |= (1<<12); // DMAC0 HCLK Pass
g_pSysConReg->HCLK_GATE |= (1<<13); // DMAC1 HCLK Pass
if (pCtxt->Controller == DMAC0) // Find available channel in DMAC0
{
for (i=0; i<8; i++)
{
if (i == 3) continue; // for OneNAND DMA channel
pDMACHReg = (S3C6410_DMA_CH_REG *)((ULONG)g_pDMAC0Reg + DMA_CH_REG_OFFSET + i*DMA_CH_REG_SIZE);
if (!(pDMACHReg->Control0 & TCINT_ENABLE)) // Check channel in use with TC Int Enable Bit !!!
{
pDMACHReg->Control0 |= TCINT_ENABLE; // Set TC Int Enable Bit to reserve this channel!!!
break;
}
}
if (i < 8) // there is available channel
{
DMA_INF((_T("[DMA:INF] DMA_request_channel() : Ch[%d] in DMAC0 is Available for DMASrc[%d]\n\r"), i, DMASrc));
pCtxt->Channel = (DMAC_CH)i;
pCtxt->dwIRQ = IRQ_DMA0_CH0+i;
pCtxt->pCHReg = (void *)pDMACHReg;
pCtxt->bValid = TRUE;
DMA_dmac0_enable();
}
else if (DMASrc == DMA_MEM) // DMA MEM2MEM can use channel in DMAC1
{
pCtxt->Controller = DMAC1;
}
else // there is no available channel
{
DMA_ERR((_T("[DMA:ERR] DMA_request_channel() : No Available Channel in DMAC0 for DMASrc[%d]\n\r"), DMASrc));
bRet = FALSE;
goto CleanUp;
}
}
if (pCtxt->Controller == DMAC1) // Find available channel in DMAC1
{
for (i=0; i<8; i++)
{
if (i == 3) continue; // for OneNAND DMA channel
pDMACHReg = (S3C6410_DMA_CH_REG *)((ULONG)g_pDMAC1Reg + DMA_CH_REG_OFFSET + i*DMA_CH_REG_SIZE);
if (!(pDMACHReg->Control0 & TCINT_ENABLE)) // Check channel in use with TC Int Enable Bit !!!
{
pDMACHReg->Control0 |= TCINT_ENABLE; // Set TC Int Enable Bit to reserve this channel!!!
break;
}
}
if (i < 8) // there is available channel
{
DMA_INF((_T("[DMA:INF] DMA_request_channel() : Ch[%d] in DMAC1 is Available for DMASrc[%d]\n\r"), i, DMASrc));
pCtxt->Channel = (DMAC_CH)i;
pCtxt->dwIRQ = IRQ_DMA1_CH0+i;
pCtxt->pCHReg = (void *)pDMACHReg;
pCtxt->bValid = TRUE;
DMA_dmac1_enable();
}
else // there is no available channel
{
DMA_ERR((_T("[DMA:ERR] DMA_request_channel() : No Available Channel in DMAC1 for DMASrc[%d]\n\r"), DMASrc));
bRet = FALSE;
goto CleanUp;
}
}
CleanUp:
// Disable DMAC HCLK when No channel is allocated
if (!(g_pDMAC0Reg->DMACConfiguration & DMAC_ENABLE))
{
g_pSysConReg->HCLK_GATE &= ~(1<<12); // DMAC0 HCLK Mask
}
if (!(g_pDMAC1Reg->DMACConfiguration & DMAC_ENABLE))
{
g_pSysConReg->HCLK_GATE &= ~(1<<13); // DMAC1 HCLK Mask
}
// Unlock DMA Access
DMA_unlock();
if (bRet == FALSE) // Request is denied
{
// Clear DMA Channel Context
memset((void *)pCtxt, 0x0, sizeof(DMA_CH_CONTEXT));
}
DMA_MSG((_T("[DMA]--DMA_request_channel() : %d\n\r"), bRet));
return bRet;
}
BOOL DMA_release_channel(DMA_CH_CONTEXT *pCtxt)
{
volatile S3C6410_DMA_CH_REG *pDMACHReg;
BOOL bRet = TRUE;
DMA_MSG((_T("[DMA]++DMA_release_channel() : Ch%d in DMAC%d, \n\r"), pCtxt->Channel, pCtxt->Controller));
if (pCtxt->bValid == FALSE)
{
DMA_ERR((_T("[DMA:ERR] DMA_release_channel() : Invalid DMA_CH_CONTEXT\n\r")));
bRet = FALSE;
goto CleanUp;
}
// Stop DMA Channel
DMA_channel_stop(pCtxt);
// Lock DMA Access
DMA_lock();
pDMACHReg = (S3C6410_DMA_CH_REG *)pCtxt->pCHReg;
pDMACHReg->Control0 &= ~TCINT_ENABLE; // Clear TC Int Enable Bit to release this channel!!!
if (pCtxt->Controller == DMAC0) // Release channel in
DMA.rar_S3C6410 DMA
版权申诉
30 浏览量
2022-09-21
18:51:07
上传
评论
收藏 9KB RAR 举报
钱亚锋
- 粉丝: 86
- 资源: 1万+
最新资源
- pta题库答案c语言之排序4统计工龄.zip
- pta题库答案c语言之树结构7堆中的路径.zip
- pta题库答案c语言之树结构3TreeTraversalsAgain.zip
- pta题库答案c语言之树结构2ListLeaves.zip
- pta题库答案c语言之树结构1树的同构.zip
- 基于C++实现民航飞行与地图简易管理系统可执行程序+说明+详细注释.zip
- pta题库答案c语言之复杂度1最大子列和问题.zip
- 三维装箱问题(Three-Dimensional Bin Packing Problem,3D-BPP)是一个经典的组合优化问题
- 以下是一些关于Linux线程同步的基本概念和方法.txt
- 以下是一个简化的示例,它使用pygame库来模拟烟花动画的框架.txt
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈