📄 s3c6400_dma_controller.c
字号:
pCtxt->DstPeri = 0; // Memory (Don't Care)
pCtxt->FlowCtrl = PERI_TO_MEM; // Peripheral -> Memory
break;
//-------------------
// DMA Source in DMC1
//-------------------
case DMA_PCM1_TX:
pCtxt->SrcAHBM = AHB_M1; // Memory
pCtxt->DstAHBM = AHB_M2; // Peripheral
pCtxt->SrcPeri = 0; // Memory (Don't Care)
pCtxt->DstPeri = DMAC1_PCM1_TX; // PCM1_TX
pCtxt->FlowCtrl = MEM_TO_PERI; // Memory -> Peripheral
break;
case DMA_PCM1_RX:
pCtxt->SrcAHBM = AHB_M2; // Peripheral
pCtxt->DstAHBM = AHB_M1; // Memory
pCtxt->SrcPeri = DMAC1_PCM1_RX; // PCM1_RX
pCtxt->DstPeri = 0; // Memory (Don't Care)
pCtxt->FlowCtrl = PERI_TO_MEM; // Peripheral -> Memory
break;
case DMA_I2S1_TX:
pCtxt->SrcAHBM = AHB_M1; // Memory
pCtxt->DstAHBM = AHB_M2; // Peripheral
pCtxt->SrcPeri = 0; // Memory (Don't Care)
pCtxt->DstPeri = DMAC1_I2S1_TX; // I2S1_TX
pCtxt->FlowCtrl = MEM_TO_PERI; // Memory -> Peripheral
break;
case DMA_I2S1_RX:
pCtxt->SrcAHBM = AHB_M2; // Peripheral
pCtxt->DstAHBM = AHB_M1; // Memory
pCtxt->SrcPeri = DMAC1_I2S1_RX; // I2S1_RX
pCtxt->DstPeri = 0; // Memory (Don't Care)
pCtxt->FlowCtrl = PERI_TO_MEM; // Peripheral -> Memory
break;
case DMA_SPI1_TX:
pCtxt->SrcAHBM = AHB_M1; // Memory
pCtxt->DstAHBM = AHB_M2; // Peripheral
pCtxt->SrcPeri = 0; // Memory (Don't Care)
pCtxt->DstPeri = DMAC1_SPI1_TX; // SPI1_TX
pCtxt->FlowCtrl = MEM_TO_PERI; // Memory -> Peripheral
break;
case DMA_SPI1_RX:
pCtxt->SrcAHBM = AHB_M2; // Peripheral
pCtxt->DstAHBM = AHB_M1; // Memory
pCtxt->SrcPeri = DMAC1_SPI1_RX; // SPI1_RX
pCtxt->DstPeri = 0; // Memory (Don't Care)
pCtxt->FlowCtrl = PERI_TO_MEM; // Peripheral -> Memory
break;
case DMA_AC97_PCMOUT:
pCtxt->SrcAHBM = AHB_M1; // Memory
pCtxt->DstAHBM = AHB_M2; // Peripheral
pCtxt->SrcPeri = 0; // Memory (Don't Care)
pCtxt->DstPeri = DMAC1_AC97_PCMOUT; // AC97_PCMOUT
pCtxt->FlowCtrl = MEM_TO_PERI; // Memory -> Peripheral
break;
case DMA_AC97_PCMIN:
pCtxt->SrcAHBM = AHB_M2; // Peripheral
pCtxt->DstAHBM = AHB_M1; // Memory
pCtxt->SrcPeri = DMAC1_AC97_PCMIN; // AC97_PCMIN
pCtxt->DstPeri = 0; // Memory (Don't Care)
pCtxt->FlowCtrl = PERI_TO_MEM; // Peripheral -> Memory
break;
case DMA_AC97_MICIN:
pCtxt->SrcAHBM = AHB_M2; // Peripheral
pCtxt->DstAHBM = AHB_M1; // Memory
pCtxt->SrcPeri = DMAC1_AC97_MICIN; // AC97_MICIN
pCtxt->DstPeri = 0; // Memory (Don't Care)
pCtxt->FlowCtrl = PERI_TO_MEM; // Peripheral -> Memory
break;
case DMA_PWM:
case DMA_IRDA:
case DMA_EXTERNAL:
DMA_ERR((_T("[DMA:ERR] DMA_initialize_channel() : Not Implemented\n\r")));
error = DMA_ERROR_NOT_IMPLEMENTED;
goto CleanUp;
break;
//------------------------
// DMA Source in MEM to MEM
//------------------------
case DMA_MEM:
pCtxt->SrcAHBM = AHB_M1; // Memory
pCtxt->DstAHBM = AHB_M1; // Memory
pCtxt->SrcPeri = 0; // Memory (Don't Care)
pCtxt->DstPeri = 0; // Memory (Don't Care)
pCtxt->FlowCtrl = MEM_TO_MEM; // Memory -> Memory
break;
default:
DMA_ERR((_T("[DMA:ERR] DMA_initialize_channel() : Unknown DMA Source [%d]\n\r"), pCtxt->DMASrc));
error = DMA_ERROR_ILLEGAL_PARAMETER;
goto CleanUp;
break;
}
#if 0
if (pCtxt->Controller == DMAC0) // channel in DMAC0
{
// Lock DMA Access
DMA_lock();
if (bSync)
{
// Synchronization Logic Enable (Default Value)
g_pDMAC0Reg->DMACSync &= ~(1<<(pCtxt->DMASrc));
}
else
{
// Synchronization Logic Disable
g_pDMAC0Reg->DMACSync |= (1<<(pCtxt->DMASrc));
}
// Unlock DMA Access
DMA_unlock();
}
else if (pCtxt->Controller == DMAC1) // channel in DMAC1
{
// Lock DMA Access
DMA_lock();
if (bSync)
{
// Synchronization Logic Enable (Default Value)
g_pDMAC1Reg->DMACSync &= ~(1<<(pCtxt->DMASrc-16));
}
else
{
// Synchronization Logic Disable
g_pDMAC1Reg->DMACSync |= (1<<(pCtxt->DMASrc-16));
}
// Unlock DMA Access
DMA_unlock();
}
#endif
pDMACHReg = (S3C6400_DMA_CH_REG *)pCtxt->pCHReg;
pDMACHReg->LLI = 0; // Disable LLI
pDMACHReg->Configuration = ALLOW_REQUEST | UNLOCK | FLOWCTRL(pCtxt->FlowCtrl)
| DEST_PERI(pCtxt->DstPeri) | SRC_PERI(pCtxt->SrcPeri);
CleanUp:
DMA_MSG((_T("[DMA]--DMA_initialize_channel() : %d\n\r"), error));
return error;
}
DMA_ERROR DMA_set_channel_source(DMA_CH_CONTEXT *pCtxt, unsigned int uiSrcAddr, TRANSFER_UNIT Unit, BURST_SIZE Burst, ADDRESS_UPDATE Update)
{
volatile S3C6400_DMA_CH_REG *pDMACHReg;
DMA_ERROR error = DMA_SUCCESS;
DMA_MSG((_T("[DMA]++DMA_set_channel_source() : Ch%d in DMAC%d (0x%08x, %d, %d, %d)\n\r"), pCtxt->Channel, pCtxt->Controller, uiSrcAddr, Unit, Burst, Update));
if (pCtxt->bValid == FALSE)
{
DMA_ERR((_T("[DMA:ERR] DMA_set_channel_source() : Invalid DMA_CH_CONTEXT\n\r")));
error = DMA_ERROR_ILLEGAL_PARAMETER;
goto CleanUp;
}
switch(Unit)
{
case BYTE_UNIT: case HWORD_UNIT: case WORD_UNIT:
pCtxt->SrcUnit = Unit;
break;
default:
DMA_ERR((_T("[DMA:ERR] DMA_set_channel_source() : Unknown Transfer Unit [%d]\n\r"), Unit));
error = DMA_ERROR_ILLEGAL_PARAMETER;
goto CleanUp;
break;
}
switch(Burst)
{
case BURST_1: case BURST_4: case BURST_8: case BURST_16:
case BURST_32: case BURST_64: case BURST_128: case BURST_256:
pCtxt->SrcBurst = Burst;
break;
default:
DMA_ERR((_T("[DMA:ERR] DMA_set_channel_source() : Unknown Burst Size [%d]\n\r"), Burst));
error = DMA_ERROR_ILLEGAL_PARAMETER;
goto CleanUp;
break;
}
switch(Update)
{
case INCREASE: case FIXED:
pCtxt->SrcUpdate = Update;
break;
default:
DMA_ERR((_T("[DMA:ERR] DMA_set_channel_source() : Unknown Address Update [%d]\n\r"), Update));
error = DMA_ERROR_ILLEGAL_PARAMETER;
goto CleanUp;
break;
}
pDMACHReg = (S3C6400_DMA_CH_REG *)pCtxt->pCHReg;
pDMACHReg->SrcAddr = uiSrcAddr;
pDMACHReg->Control0 = (pDMACHReg->Control0 & ~((1<<26)|(1<<24)|SRC_UNIT_MASK|SRC_BURST_MASK))
|(pCtxt->SrcUpdate<<26) |(pCtxt->SrcAHBM<<24)|(pCtxt->SrcUnit<<18)|(pCtxt->SrcBurst<<12);
CleanUp:
DMA_MSG((_T("[DMA]--DMA_initialize_channel() : %d\n\r"), error));
return error;
}
DMA_ERROR DMA_set_channel_destination(DMA_CH_CONTEXT *pCtxt, unsigned int uiDstAddr, TRANSFER_UNIT Unit, BURST_SIZE Burst, ADDRESS_UPDATE Update)
{
volatile S3C6400_DMA_CH_REG *pDMACHReg;
DMA_ERROR error = DMA_SUCCESS;
DMA_MSG((_T("[DMA]++DMA_set_channel_destnation() : Ch%d in DMAC%d (0x%08x, %d, %d, %d)\n\r"), pCtxt->Channel, pCtxt->Controller, uiDstAddr, Unit, Burst, Update));
if (pCtxt->bValid == FALSE)
{
DMA_ERR((_T("[DMA:ERR] DMA_set_channel_destnation() : Invalid DMA_CH_CONTEXT\n\r")));
error = DMA_ERROR_ILLEGAL_PARAMETER;
goto CleanUp;
}
switch(Unit)
{
case BYTE_UNIT: case HWORD_UNIT: case WORD_UNIT:
pCtxt->DstUnit = Unit;
break;
default:
DMA_ERR((_T("[DMA:ERR] DMA_set_channel_destnation() : Unknown Transfer Unit [%d]\n\r"), Unit));
error = DMA_ERROR_ILLEGAL_PARAMETER;
goto CleanUp;
break;
}
switch(Burst)
{
case BURST_1: case BURST_4: case BURST_8: case BURST_16:
case BURST_32: case BURST_64: case BURST_128: case BURST_256:
pCtxt->DstBurst = Burst;
break;
default:
DMA_ERR((_T("[DMA:ERR] DMA_set_channel_destnation() : Unknown Burst Size [%d]\n\r"), Burst));
error = DMA_ERROR_ILLEGAL_PARAMETER;
goto CleanUp;
break;
}
switch(Update)
{
case INCREASE: case FIXED:
pCtxt->DstUpdate = Update;
break;
default:
DMA_ERR((_T("[DMA:ERR] DMA_set_channel_destnation() : Unknown Address Update [%d]\n\r"), Update));
error = DMA_ERROR_ILLEGAL_PARAMETER;
goto CleanUp;
break;
}
pDMACHReg = (S3C6400_DMA_CH_REG *)pCtxt->pCHReg;
pDMACHReg->DestAddr = uiDstAddr;
pDMACHReg->Control0 = (pDMACHReg->Control0 & ~((1<<27)|(1<<25)|DEST_UNIT_MASK|DEST_BURST_MASK))
|(pCtxt->DstUpdate<<27) |(pCtxt->DstAHBM<<25)|(pCtxt->DstUnit<<21)|(pCtxt->DstBurst<<15);
CleanUp:
DMA_MSG((_T("[DMA]--DMA_set_channel_destnation() : %d\n\r"), error));
return error;
}
DMA_ERROR DMA_set_channel_transfer_size(DMA_CH_CONTEXT *pCtxt, unsigned int uiByteCount)
{
volatile S3C6400_DMA_CH_REG *pDMACHReg;
DMA_ERROR error = DMA_SUCCESS;
DMA_MSG((_T("[DMA]++DMA_set_channel_transfer_size() : Ch%d in DMAC%d (ByteCount : %d)\n\r"), pCtxt->Channel, pCtxt->Controller, uiByteCount));
if (pCtxt->bValid == FALSE)
{
DMA_ERR((_T("[DMA:ERR] DMA_set_channel_transfer_size() : Invalid DMA_CH_CONTEXT\n\r")));
error = DMA_ERROR_ILLEGAL_PARAMETER;
goto CleanUp;
}
pDMACHReg = (S3C6400_DMA_CH_REG *)pCtxt->pCHReg;
switch(pCtxt->SrcUnit)
{
case BYTE_UNIT:
pDMACHReg->Control1 = TRANSFERCOUNT(uiByteCount);
break;
case HWORD_UNIT:
pDMACHReg->Control1 = TRANSFERCOUNT(uiByteCount/2);
break;
case WORD_UNIT:
pDMACHReg->Control1 = TRANSFERCOUNT(uiByteCount/4);
break;
}
CleanUp:
DMA_MSG((_T("[DMA]--DMA_initialize_channel() : %d\n\r"), error));
return error;
}
DMA_ERROR DMA_initialize_LLI(DMA_CH_CONTEXT *pCtxt, int iLLICount)
{
DMA_ERROR error = DMA_SUCCESS;
DMA_MSG((_T("[DMA]++DMA_initialize_LLI() : Ch%d in DMAC%d (%d)\n\r"), pCtxt->Channel, pCtxt->Controller, iLLICount));
if (pCtxt->bValid == FALSE)
{
DMA_ERR((_T("[DMA:ERR] DMA_initialize_LLI() : Invalid DMA_CH_CONTEXT\n\r")));
error = DMA_ERROR_ILLEGAL_PARAMETER;
goto CleanUp;
}
if (iLLICount == 0 || iLLICount > MAX_LLI_ENTRY)
{
DMA_ERR((_T("[DMA] DMA_initialize_LLI() : LLICount [%d] Out of Range \n\r"), pCtxt->LLICount));
error = DMA_ERROR_ILLEGAL_PARAMETER;
goto CleanUp;
}
pCtxt->LLICount = iLLICount;
if (DMA_allocate_LLI_context(pCtxt) == FALSE)
{
DMA_ERR((_T("[DMA:ERR] DMA_initialize_LLI() : LLI Context Allocation Failed\n\r")));
error = DMA_ERROR_NOT_INITIALIZED;
goto CleanUp;
}
CleanUp:
DMA_MSG((_T("[DMA]--DMA_initialize_LLI() : %d\n\r"), error));
return error;
}
DMA_ERROR DMA_set_initial_LLI(DMA_CH_CONTEXT *pCtxt, int iIntialLLIEntryNumber)
{
volatile S3C6400_DMA_CH_REG *pDMACHReg;
DMA_ERROR error = DMA_SUCCESS;
DMA_MSG((_T("[DMA]++DMA_initialize_LLI() : Ch%d in DMAC%d (%d)\n\r"), pCtxt->Channel, pCtxt->Controller, iIntialLLIEntryNumber));
if (pCtxt->bValid == FALSE)
{
DMA_ERR((_T("[DMA:ERR] DMA_initialize_LLI() : Invalid DMA_CH_CONTEXT\n\r")));
error = DMA_ERROR_ILLEGAL_PARAMETER;
goto CleanUp;
}
if (pCtxt->LLICount == 0)
{
DMA_ERR((_T("[DMA] DMA_initialize_LLI() : LLI Not Initialized\n\r")));
error = DMA_ERROR_NOT_INITIALIZED;
goto CleanUp;
}
if (iIntialLLIEntryNumber > pCtxt->LLICount-1)
{
DMA_ERR((_T("[DMA:ERR] DMA_initialize_LLI() : Initial Entry Number exceed Maximum Entry Number (%d > %d)\n\r"), iIntialLLIEntryNumber, pCtxt->LLICount-1));
error = DMA_ERROR_ILLEGAL_PARAMETER;
goto CleanUp;
}
pDMACHReg = (S3C6400_DMA_CH_REG *)pCtxt->pCHReg;
pDMACHReg->LLI = NEXT_LLI_ITEM(pCtxt->LLIPhyAddr+sizeof(DMA_LLI_ENTRY)*iIntialLLIEntryNumber) |pCtxt->LLIAHBM;
CleanUp:
DMA_MSG((_T("[DMA]--DMA_initialize_LLI() : %d\n\r"), error));
return error;
}
DMA_ERROR DMA_set_LLI_entry(DMA_CH_CONTEXT *pCtxt, int iEntryNumber, LLI_NEXT_ITEM NextItem, unsigned int uiSrcAddr, unsigned int uiDstAddr, unsigned int uiByteCount)
{
DMA_LLI_ENTRY *pLLIEntry;
DMA_ERROR error = DMA_SUCCESS;
DMA_MSG((_T("[DMA]++DMA_initialize_LLI() : Ch%d in DMAC%d (%d, %d, 0x%08x, 0x%08x, %d)\n\r"), pCtxt->Channel, pCtxt->Controller, iEntryNumber, NextItem, uiSrcAddr, uiDstAddr, uiByteCount));
if (pCtxt->bValid == FALSE)
{
DMA_ERR((_T("[DMA:ERR] DMA_initialize_LLI() : Invalid DMA_CH_CONTEXT\n\r")));
error = DMA_ERROR_ILLEGAL_PARAMETER;
goto CleanUp;
}
if (iEntryNumber > pCtxt->LLICount-1)
{
DMA_ERR((_T("[DMA:ERR] DMA_initialize_LLI() : LLI Entry exceed Maximum Entry Number (%d > %d)\n\r"), iEntryNumber, pCtxt->LLICount-1));
error = DMA_ERROR_ILLEGAL_PARAMETER;
goto CleanUp;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -