summaryrefslogtreecommitdiff
path: root/firmware/drivers/i2s.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/i2s.c')
-rw-r--r--firmware/drivers/i2s.c159
1 files changed, 159 insertions, 0 deletions
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
+******************************************************************************/
+