diff options
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/dma.c | 189 | ||||
-rw-r--r-- | firmware/drivers/dma.h | 46 | ||||
-rw-r--r-- | firmware/drivers/i2s.c | 159 | ||||
-rw-r--r-- | firmware/drivers/i2s.h | 41 |
4 files changed, 435 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
+******************************************************************************/
diff --git a/firmware/drivers/dma.h b/firmware/drivers/dma.h new file mode 100644 index 0000000..fe75fcd --- /dev/null +++ b/firmware/drivers/dma.h @@ -0,0 +1,46 @@ +/****************************************************************************
+ * $Id:: dma.h 5797 2010-12-03 00:27:00Z usb00423 $
+ * Project: NXP LPC17xx DMA example
+ *
+ * Description:
+ * This file contains DMA code header definition.
+ *
+ ****************************************************************************
+ * 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.
+****************************************************************************/
+#ifndef __I2S_DMA_H
+#define __I2S_DMA_H
+
+#define DMA_I2S_REQ0 5
+#define DMA_I2S_REQ1 6
+
+#define DMA_SRC 0x2007C000
+#define DMA_DST 0x2007D000
+#define DMA_I2S_TX_FIFO (LPC_I2S_BASE + 0x08)
+#define DMA_I2S_RX_FIFO (LPC_I2S_BASE + 0x0C)
+
+#define DMA_SIZE 0x200
+
+/* DMA mode */
+#define M2M 0x00
+#define M2P 0x01
+#define P2M 0x02
+#define P2P 0x03
+
+extern void DMA_IRQHandler( void );
+extern void DMA_Init( void );
+extern uint32_t DMAChannel_Init( uint32_t ChannelNum, uint32_t DMAMode );
+
+#endif /* end __I2S_DMA_H */
+/****************************************************************************
+** End Of File
+****************************************************************************/
diff --git a/firmware/drivers/i2s.c b/firmware/drivers/i2s.c new file mode 100644 index 0000000..0085e1d --- /dev/null +++ b/firmware/drivers/i2s.c @@ -0,0 +1,159 @@ +/****************************************************************************
+ * $Id:: i2s.c 5797 2010-12-03 00:27:00Z usb00423 $
+ * Project: NXP LPC17xx I2S example
+ *
+ * Description:
+ * This file contains I2S code example which include I2S initialization,
+ * I2C interrupt handler, and APIs for I2S 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"
+
+/* treat I2S TX and RX as a constant address, make the code and buffer
+easier for both DMA and non-DMA test */
+volatile uint8_t *I2STXBuffer = (uint8_t *)(DMA_SRC);
+volatile uint8_t *I2SRXBuffer = (uint8_t *)(DMA_DST);
+volatile uint32_t I2SReadLength = 0;
+volatile uint32_t I2SWriteLength = 0;
+volatile uint32_t I2SRXDone = 0, I2STXDone = 0;
+
+/*****************************************************************************
+** Function name: I2S_IRQHandler
+**
+** Descriptions: I2S interrupt handler, only RX interrupt is enabled
+** for simplicity.
+**
+** parameters: None
+** Returned value: None
+**
+*****************************************************************************/
+void I2S_IRQHandler (void)
+{
+ uint32_t RxCount = 0;
+
+ if ( LPC_I2S->I2SSTATE & 0x01 )
+ {
+ RxCount = (LPC_I2S->I2SSTATE >> 8) & 0xFF;
+ if ( (RxCount != RXFIFO_EMPTY) && !I2SRXDone )
+ {
+ while ( RxCount > 0 )
+ {
+ if ( I2SReadLength == BUFSIZE )
+ {
+ LPC_I2S->I2SDAI |= ((0x01 << 3) | (0x01 << 4));
+ LPC_I2S->I2SIRQ &= ~(0x01 << 0); /* Disable RX */
+ I2SRXDone = 1;
+ break;
+ }
+ else
+ {
+ I2SRXBuffer[I2SReadLength++] = LPC_I2S->I2SRXFIFO;
+ }
+ RxCount--;
+ }
+ }
+ }
+ return;
+}
+
+/*****************************************************************************
+** Function name: I2SStart
+**
+** Descriptions: Start I2S DAI and DAO
+**
+** parameters: None
+** Returned value: None
+**
+*****************************************************************************/
+void I2SStart( void )
+{
+ uint32_t DAIValue, DAOValue;
+
+ /* Audio output is the master, audio input is the slave, */
+ /* 16 bit data, stereo, reset, master mode, not mute. */
+ DAOValue = LPC_I2S->I2SDAO;
+ DAIValue = LPC_I2S->I2SDAI;
+ LPC_I2S->I2SDAO = DAOValue & (~((0x01 << 4)|(0x01 <<3)));
+ /* 16 bit data, stereo, reset, slave mode, not mute. */
+ LPC_I2S->I2SDAI = DAIValue & (~((0x01 << 4)|(0x01 <<3)));
+ return;
+}
+
+/*****************************************************************************
+** Function name: I2SStop
+**
+** Descriptions: Stop I2S DAI and DAO
+**
+** parameters: None
+** Returned value: None
+**
+*****************************************************************************/
+void I2SStop( void )
+{
+ uint32_t DAIValue, DAOValue;
+
+ /* Stop the I2S to start. Audio output is master, audio input is the slave. */
+ /* 16 bit data, set STOP and RESET bits to reset the channels */
+ DAOValue = LPC_I2S->I2SDAO;
+ /* Switch to master mode, TX channel, no mute */
+ DAOValue &= ~((0x01 << 5)|(0x01 << 15));
+ DAIValue = LPC_I2S->I2SDAI;
+ DAIValue &= ~(0x01 << 15);
+ LPC_I2S->I2SDAO = (0x01 << 4) | (0x01 << 3) | DAOValue; /* Master */
+ LPC_I2S->I2SDAI = (0x01 << 4) | (0x01 << 3) | DAIValue; /* Slave */
+ return;
+}
+
+/*****************************************************************************
+** Function name: I2SInit
+**
+** Descriptions: Initialize I2S controller
+**
+** parameters: None
+** Returned value: true or false, return false if the I2S
+** interrupt handler was not installed correctly
+**
+*****************************************************************************/
+void I2SInit( void )
+{
+
+ /*enable I2S in the PCONP register. I2S is disabled on reset*/
+ LPC_SC->PCONP |= (1 << 27);
+
+ /*connect the I2S sigals to port pins(P0.4-P0.9)*/
+ LPC_PINCON->PINSEL0 &= ~0x000FFF00;
+ LPC_PINCON->PINSEL0 |= 0x00055500;
+
+ /* Please note, in order to generate accurate TX/RX clock rate for I2S,
+ PCLK and CCLK needs to be carefully reconsidered. For this test
+ program, the TX is looped back to RX without external I2S device,
+ clock rate is not critical in this matter. */
+ LPC_I2S->I2STXRATE = //0x241;
+ (100 << 0) | // Y
+ (49 << 8) // X
+ ;
+
+ // LPC_I2S->I2SRXRATE = 0x241;
+
+ I2SStop();
+ return;
+}
+
+/******************************************************************************
+** End Of File
+******************************************************************************/
+
diff --git a/firmware/drivers/i2s.h b/firmware/drivers/i2s.h new file mode 100644 index 0000000..dbbb6f2 --- /dev/null +++ b/firmware/drivers/i2s.h @@ -0,0 +1,41 @@ +/****************************************************************************
+ * $Id:: i2s.h 5797 2010-12-03 00:27:00Z usb00423 $
+ * Project: NXP LPC17xx I2S example
+ *
+ * Description:
+ * This file contains I2S code header definition.
+ *
+ ****************************************************************************
+ * 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.
+****************************************************************************/
+#ifndef __I2S_H
+#define __I2S_H
+
+//#include "../src/sample.h"
+
+#define I2S_DMA_ENABLED 1
+
+#define BUFSIZE 0x200
+//(1097 * sizeof(short) * 2)/*stereo*/
+//((int)(sizeof(samples) * 2/*stereo*/))
+#define RXFIFO_EMPTY 0
+#define TXFIFO_FULL 8
+
+extern void I2S_IRQHandler( void );
+extern void I2SStart( void );
+extern void I2SStop( void );
+extern void I2SInit( void );
+
+#endif /* end __I2S_H */
+/****************************************************************************
+** End Of File
+*****************************************************************************/
|