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

📄 dma.c

📁 i2s usb audio demo lpc2138
💻 C
字号:
/*****************************************************************************
 *   dma.c:  DMA module file for NXP LPC23xx/24xx Family Microprocessors
 *
 *   Copyright(C) 2006, NXP Semiconductor
 *   All rights reserved.
 *
 *   History
 *   2006.07.20  ver 1.00    Prelimnary version, first Release
 *
******************************************************************************/
#include "LPC23xx.h"                        /* LPC23xx/24xx definitions */
#include "type.h"
#include "irq.h"
#include "dma.h"

DWORD DMA_Init(void);

#if MCI_DMA_ENABLED
DWORD DMACount;
/******************************************************************************
** Function name:		DMAHandler
**
** Descriptions:		DMA interrupt handler
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void IRQ_DMAHandler (void) __irq 
{
    DWORD regVal, forever =1;
	static DWORD DMATCCount, DMAErrCount ;
	DMACount++;
//    IENABLE;				/* handles nested interrupt */
	regVal = GPDMA_INT_TCSTAT;
	if ( regVal )
	{
		DMATCCount++;
		GPDMA_INT_TCCLR |= regVal;
	} 

	regVal = GPDMA_INT_ERR_STAT;
	if ( regVal )
	{
		DMAErrCount++;
		GPDMA_INT_ERR_CLR |= regVal;
	} 
//    IDISABLE;
    while(forever ); /* dma interrupts dont happen in this sample code */
    VICVectAddr = 0;		/* Acknowledge Interrupt */

}

/******************************************************************************
** Function name:		DMA_Init
**
** Descriptions:		
**
** parameters:			
** Returned value:		
** 
******************************************************************************/
DWORD DMA_Init(void)
{
	/* USB RAM is used for test.
	Please note, Ethernet has its own SRAM, but GPDMA can't access
	that. GPDMA can access USB SRAM and IRAM. Ethernet DMA controller can 
	access both IRAM and Ethernet SRAM. */
	PCONP |= (1 << 29);	/* Enable GPDMA clock */

	/* clear all interrupts on channel 0 and 1 */
	GPDMA_INT_TCCLR = 0x03;
	GPDMA_INT_ERR_CLR = 0x03;

	GPDMA_CONFIG = 0x01;	/* Enable DMA channels, little endian */
	while ( !(GPDMA_CONFIG & 0x01) );    
		
    return (TRUE);
}   

/******************************************************************************
** Function name:		DMA_M2M
**
** Descriptions:		
**
** parameters:			
** Returned value:		
** 
******************************************************************************/
void DMA_Transfer_M2M( DWORD ChannelNum, DWORD DMASrc, DWORD DMADst ,DWORD DMASize )
{
	/* USB RAM is used for test.
	Please note, Ethernet has its own SRAM, but GPDMA can't access
	that. GPDMA can access USB SRAM and IRAM. Ethernet DMA controller can 
	access both IRAM and Ethernet SRAM. */
	DWORD Ch_Ctrl;

	Ch_Ctrl = (DMASize & 0x0FFF) /* Transfer Count */
              | (0x04 << 12)     /* Src Burst Size */
              | (0x04 << 15)     /* Dest Burst Size */
              | (0x02 << 18)     /* Src Transfer Width */
              | (0x02 << 21)     /* Dest Transfer Width */
              | (0x01 << 26) 	 /* Src Increment */
              | (0x01 << 27) 	 /* Dest Increment */
              | 0x80000000;	     /* Interrupt when complete */

	if ( ChannelNum == 0 )
	{
		GPDMA_INT_TCCLR = 0x01;   
	    GPDMA_INT_ERR_CLR = 0x01;
		GPDMA_CH0_SRC = DMASrc;
		GPDMA_CH0_DEST = DMADst;
		GPDMA_CH0_CTRL = Ch_Ctrl;
	}
	else if ( ChannelNum == 1 )
	{   
		GPDMA_INT_TCCLR = 0x02;   
		GPDMA_INT_ERR_CLR = 0x02;
		GPDMA_CH1_SRC = DMASrc;
		GPDMA_CH1_DEST = DMADst;
		GPDMA_CH0_CTRL = Ch_Ctrl;
	}
	GPDMA_CONFIG = 0x01;	/* Enable DMA channels, little endian */
	while ( !(GPDMA_CONFIG & 0x01) );    		
}

/******************************************************************************
** Function name:		DMA_P2M
**
** Descriptions:		
**
** parameters:			
** Returned value:		
** 
******************************************************************************/
void DMA_Transfer_P2M( DWORD ChannelNum, DWORD DMASrc, DWORD DMADst ,DWORD DMASize )
{
	DWORD Ch_Ctrl;

	Ch_Ctrl = (DMASize & 0x0FFF) /* Transfer Count */
              | (0x04 << 15)     /* Dest Burst Size */
              | (0x02 << 18)     /* Src Transfer Width */
              | (0x02 << 21)     /* Dest Transfer Width */
              | (0x01 << 27) 	 /* Dest Increment */
              | 0x80000000;	     /* Interrupt when complete */
	
	if ( ChannelNum == 0 )
	{
		GPDMA_INT_TCCLR = 0x01;   
	    GPDMA_INT_ERR_CLR = 0x01;
		GPDMA_CH0_SRC = DMASrc;
		GPDMA_CH0_DEST = DMADst;
		if  ((DMASrc == DMA_SSP0_RX_FIFO) 
		  || (DMASrc == DMA_SSP1_RX_FIFO)
		  || (DMASrc == DMA_I2S_RX_FIFO))
		{
		   Ch_Ctrl |= (0x01 << 12);  /* Src Burst Size */		                      
		}
		else if (DMASrc == DMA_MCI_RX_FIFO)
		{
		   Ch_Ctrl |= (0x02 << 12);  /* Src Burst Size */		                      
		}
		GPDMA_CH0_CTRL = Ch_Ctrl;
	}
	else if ( ChannelNum == 1 )
	{   
		GPDMA_INT_TCCLR = 0x02;   
		GPDMA_INT_ERR_CLR = 0x02;
		GPDMA_CH1_SRC = DMASrc;
		GPDMA_CH1_DEST = DMADst;
		if  ((DMASrc == DMA_SSP0_RX_FIFO) 
		  || (DMASrc == DMA_SSP1_RX_FIFO)
		  || (DMASrc == DMA_I2S_RX_FIFO))
		{
		    Ch_Ctrl |= (0x01 << 12);  /* Src Burst Size */		                      
		}
		else if (DMASrc == DMA_MCI_RX_FIFO)
		{
		    Ch_Ctrl |= (0x02 << 12);  /* Src Burst Size */		                      
		}
		GPDMA_CH1_CTRL = Ch_Ctrl;
	}
	GPDMA_CONFIG = 0x01;	/* Enable DMA channels, little endian */
	while ( !(GPDMA_CONFIG & 0x01) );    

}

/******************************************************************************
** Function name:		DMA_M2P
**
** Descriptions:		
**
** parameters:			
** Returned value:		
** 
******************************************************************************/
void DMA_Transfer_M2P( DWORD ChannelNum, DWORD DMASrc, DWORD DMADst ,DWORD DMASize )
{
	DWORD Ch_Ctrl;

	Ch_Ctrl = (DMASize & 0x0FFF) /* Transfer Count */
              | (0x04 << 12)     /* Dest Burst Size */
              | (0x02 << 18)     /* Src Transfer Width */
              | (0x02 << 21)     /* Dest Transfer Width */
              | (0x01 << 26) 	 /* Dest Increment */
              | 0x80000000;	     /* Interrupt when complete */

	if ( ChannelNum == 0 )
	{
		GPDMA_INT_TCCLR = 0x01;   
	    GPDMA_INT_ERR_CLR = 0x01;
		GPDMA_CH0_SRC = DMASrc;
		GPDMA_CH0_DEST = DMADst;
		if  ((DMADst == DMA_SSP0_TX_FIFO)
		  || (DMADst == DMA_SSP1_TX_FIFO)
		  || (DMADst == DMA_I2S_TX_FIFO))
		{
		    Ch_Ctrl |= (0x01 << 15);  /* Src Burst Size */		                      
		}
		else if (DMADst == DMA_MCI_TX_FIFO)
		{
		    Ch_Ctrl |= (0x02 << 15);  /* Src Burst Size */		                      
		}
		GPDMA_CH0_CTRL = Ch_Ctrl;
	}
	else if ( ChannelNum == 1 )
	{   
		GPDMA_INT_TCCLR = 0x02;   
		GPDMA_INT_ERR_CLR = 0x02;
		GPDMA_CH1_SRC = DMASrc;
		GPDMA_CH1_DEST = DMADst;
		if  ((DMADst == DMA_SSP0_TX_FIFO) 
		  || (DMADst == DMA_SSP1_TX_FIFO)
		  || (DMADst == DMA_I2S_TX_FIFO))
		{
		    Ch_Ctrl |= (0x01 << 15);  /* Src Burst Size */		                      
		}
		else if (DMADst == DMA_MCI_TX_FIFO)
		{
		    Ch_Ctrl |= (0x02 << 15);  /* Src Burst Size */		                      
		}
        GPDMA_CH1_CTRL = Ch_Ctrl;
	}
	GPDMA_CONFIG = 0x01;	/* Enable DMA channels, little endian */
	while ( !(GPDMA_CONFIG & 0x01) );    
}
#endif

/******************************************************************************
**                            End Of File
******************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -