summaryrefslogtreecommitdiff
path: root/firmware/drivers/dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/dma.c')
-rw-r--r--firmware/drivers/dma.c189
1 files changed, 189 insertions, 0 deletions
diff --git a/firmware/drivers/dma.c b/firmware/drivers/dma.c
new file mode 100644
index 0000000..fb7324a
--- /dev/null
+++ b/firmware/drivers/dma.c
@@ -0,0 +1,189 @@
+/****************************************************************************
+ * $Id:: dma.c 5797 2010-12-03 00:27:00Z usb00423 $
+ * Project: NXP LPC17xx DMA for I2S example
+ *
+ * Description:
+ * This file contains DMA code example which include DMA initialization,
+ * DMA interrupt handler, and APIs for DMA access.
+ *
+ ****************************************************************************
+ * Software that is described herein is for illustrative purposes only
+ * which provides customers with programming information regarding the
+ * products. This software is supplied "AS IS" without any warranties.
+ * NXP Semiconductors assumes no responsibility or liability for the
+ * use of the software, conveys no license or title under any patent,
+ * copyright, or mask work right to the product. NXP Semiconductors
+ * reserves the right to make changes in the software without
+ * notification. NXP Semiconductors also make no representation or
+ * warranty that such application will be suitable for the specified
+ * use without further testing or modification.
+****************************************************************************/
+#include <LPC17xx.h>
+//#include "type.h"
+#include "i2s.h"
+#include "dma.h"
+
+#if I2S_DMA_ENABLED
+volatile uint32_t DMATCCount = 0;
+volatile uint32_t DMAErrCount = 0;
+volatile uint32_t I2SDMA0Done = 0;
+volatile uint32_t I2SDMA1Done = 0;
+
+#define FALSE 0
+#define TRUE 1
+
+/******************************************************************************
+** Function name: DMA_IRQHandler
+**
+** Descriptions: DMA interrupt handler
+**
+** parameters: None
+** Returned value: None
+**
+******************************************************************************/
+void DMA_IRQHandler(void)
+{
+ uint32_t regVal;
+
+ regVal = LPC_GPDMA->DMACIntTCStat;
+ if ( regVal )
+ {
+ DMATCCount++;
+ LPC_GPDMA->DMACIntTCClear |= regVal;
+ if ( regVal & 0x01 )
+ {
+ I2SDMA0Done = 1;
+ }
+ else if ( regVal & 0x02 )
+ {
+ I2SDMA1Done = 1;
+ }
+ }
+
+ regVal = LPC_GPDMA->DMACIntErrStat;
+ if ( regVal )
+ {
+ DMAErrCount++;
+ LPC_GPDMA->DMACIntErrClr |= regVal;
+ }
+
+}
+
+/******************************************************************************
+** Function name: DMA_Init
+**
+** Descriptions: clock to GPDMA in PCONP, GPDMA init before channel init
+**
+** parameters: None
+** Returned value: None
+**
+******************************************************************************/
+void DMA_Init( void )
+{
+ /* Enable CLOCK into GPDMA controller */
+ LPC_SC->PCONP |= (1 << 29);
+
+ LPC_GPDMA->DMACIntTCClear = 0x03;
+ LPC_GPDMA->DMACIntErrClr = 0x03;
+
+ LPC_GPDMA->DMACConfig = 0x01; /* Enable DMA channels, little endian */
+ while ( !(LPC_GPDMA->DMACConfig & 0x01) );
+
+ return;
+}
+
+/******************************************************************************
+** Function name: DMAChannel_Init
+**
+** Descriptions:
+**
+** parameters:
+** Returned value:
+**
+******************************************************************************/
+uint32_t DMAChannel_Init( uint32_t ChannelNum, uint32_t DMAMode )
+{
+ if ( ChannelNum == 0 )
+ {
+ I2SDMA0Done = 0;
+ LPC_GPDMA->DMACIntTCClear = 0x01;
+ if ( DMAMode == M2P )
+ {
+ /* Ch0 set for M2P transfer from mempry to I2S TX FIFO. */
+ LPC_GPDMACH0->DMACCSrcAddr = DMA_SRC;
+ LPC_GPDMACH0->DMACCDestAddr = DMA_I2S_TX_FIFO;
+ /* The burst size is set to 1. Terminal Count Int enable */
+ LPC_GPDMACH0->DMACCControl = (DMA_SIZE & 0x0FFF) | (0x00 << 12) | (0x00 << 15)
+ | (1 << 26) | 0x80000000;
+ }
+ else if ( DMAMode == P2M )
+ {
+ /* Ch0 set for P2M transfer from I2S RX FIFO to memory. */
+ LPC_GPDMACH0->DMACCSrcAddr = DMA_I2S_RX_FIFO;
+ LPC_GPDMACH0->DMACCDestAddr = DMA_DST;
+ /* The burst size is set to 1. Terminal Count Int enable. */
+ LPC_GPDMACH0->DMACCControl = (DMA_SIZE & 0x0FFF) | (0x00 << 12) | (0x00 << 15)
+ | (1 << 27) | 0x80000000;
+ }
+ else if ( DMAMode == P2P )
+ {
+ /* Ch0 set for P2P transfer from I2S DAO to I2S DAI. */
+ LPC_GPDMACH0->DMACCSrcAddr = DMA_I2S_TX_FIFO;
+ LPC_GPDMACH0->DMACCDestAddr = DMA_I2S_RX_FIFO;
+ /* The burst size is set to 32. */
+ LPC_GPDMACH0->DMACCControl = (DMA_SIZE & 0x0FFF) | (0x04 << 12) | (0x04 << 15)
+ | 0x80000000;
+ }
+ else
+ {
+ return ( FALSE );
+ }
+ }
+ else if ( ChannelNum == 1 )
+ {
+ I2SDMA1Done = 0;
+ LPC_GPDMA->DMACIntTCClear = 0x02;
+ if ( DMAMode == M2P )
+ {
+ /* Ch1 set for M2P transfer from mempry to I2S TX FIFO. */
+ LPC_GPDMACH1->DMACCSrcAddr = DMA_SRC;
+ LPC_GPDMACH1->DMACCDestAddr = DMA_I2S_TX_FIFO;
+ /* The burst size is set to 1. Terminal Count Int enable. */
+ LPC_GPDMACH1->DMACCControl = (DMA_SIZE & 0x0FFF) | (0x00 << 12) | (0x00 << 15)
+ | (1 << 26) | 0x80000000;
+ }
+ else if ( DMAMode == P2M )
+ {
+ /* Ch1 set for P2M transfer from I2S RX FIFO to memory. */
+ LPC_GPDMACH1->DMACCSrcAddr = DMA_I2S_RX_FIFO;
+ LPC_GPDMACH1->DMACCDestAddr = DMA_DST;
+ /* The burst size is set to 1. Terminal Count Int enable. */
+ LPC_GPDMACH1->DMACCControl = (DMA_SIZE & 0x0FFF) | (0x00 << 12) | (0x00 << 15)
+ | (1 << 27) | 0x80000000;
+ }
+ else if ( DMAMode == P2P )
+ {
+ /* Ch1 set for P2P transfer from I2S DAO to I2S DAI. */
+ LPC_GPDMACH1->DMACCSrcAddr = DMA_I2S_TX_FIFO;
+ LPC_GPDMACH1->DMACCDestAddr = DMA_I2S_RX_FIFO;
+ /* The burst size is set to 32. */
+ LPC_GPDMACH1->DMACCControl = (DMA_SIZE & 0x0FFF) | (0x04 << 12) | (0x04 << 15)
+ | 0x80000000;
+ }
+ else
+ {
+ return ( FALSE );
+ }
+ }
+ else
+ {
+ return ( FALSE );
+ }
+ return( TRUE );
+}
+
+#endif /* end if DMA_ENABLED */
+
+/******************************************************************************
+** End Of File
+******************************************************************************/