⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s3c6400_dma_controller.c

📁 Samsung公司S3C6400芯片的BSP源码包
💻 C
📖 第 1 页 / 共 3 页
字号:
		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 + -