This is an I2S library to allow people to take advantage of the I2S peripheral on the LPC1768. Ideally it will be included in future releases of the mbed.h file.

Revision:
0:0408d1e354e7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/I2S.cpp	Mon Dec 06 00:05:39 2010 +0000
@@ -0,0 +1,228 @@
+#include "mbed.h"
+#include "LPC17xx.h"
+#include "core_cm3.h"
+#include "system_LPC17xx.h"
+#include "I2S.h"
+
+I2S::I2S(PinName bitTx = p7, PinName wdTx = p6, PinName daTx = p5, PinName bitRx = p30, PinName wdRx = p29, PinName daRx = p8) {
+    // assuming pins are correct
+
+    // assign pins - be nice to use mbed stuff for this
+	LPC_PINCON->PINSEL0 |= ((0x01 << 14) | (0x01 << 16) | (0x01 << 18)); // set p5,p6,p7 as I2S
+	LPC_PINCON->PINMODE0 |= ((0x02 << 14) | (0x02 << 16) | (0x02 << 18));
+	if(bitRx == p30)
+	{
+		LPC_PINCON->PINSEL0 |= (0x01 << 8);
+		LPC_PINCON->PINMODE0 |= (0x02 << 8);
+	}
+	else
+	{
+		LPC_PINCON->PINSEL1 |= (0x01 << 14);
+		LPC_PINCON->PINMODE1 |= (0x02 << 14);
+	}
+	if(wdRx == p29)
+	{
+		LPC_PINCON->PINSEL0 |= (0x01 << 10);
+		LPC_PINCON->PINMODE0 |= (0x02 << 10);
+	}
+	else
+	{
+		LPC_PINCON->PINSEL1 |= (0x01 << 16);
+		LPC_PINCON->PINMODE1 |= (0x02 << 16);
+	}
+	if(daRx == p8)
+	{
+		LPC_PINCON->PINSEL0 |= (0x01 << 12);
+		LPC_PINCON->PINMODE0 |= (0x02 << 12);
+	}
+	else
+	{
+		LPC_PINCON->PINSEL1 |= (0x01 << 18);
+		LPC_PINCON->PINMODE1 |= (0x02 << 18);
+	}
+
+    LPC_SC->PCONP |= (0x01 << 27); // turn on I2S periferal
+}
+
+I2S::~I2S() {
+    // release stuff
+    LPC_SC->PCONP &= (0 << 27); // turn off I2S periferal
+}
+
+
+void I2S::setClocks(uint8_t x, uint8_t y, uint8_t divider) {
+
+	if(divider == 1) LPC_SC->PCLKSEL1 &= (0x01 << 22);
+	else if(divider == 2) LPC_SC->PCLKSEL1 &= (0x02 << 22);
+	else if(divider == 4) LPC_SC->PCLKSEL1 &= (0x00 << 22);
+	else if(divider == 8) LPC_SC->PCLKSEL1 &= (0x03 << 22);
+
+	LPC_I2S->I2STXRATE = (x << 8) & y;
+	LPC_I2S->I2SRXRATE = (x << 8) & y;
+	
+	peripheralClock = SystemCoreClock/divider;
+	masterClock = (x * peripheralClock)/(2 * y);
+}
+
+
+void I2S::setTx(uint16_t resolution, uint16_t rate, bool stereo) {
+
+	if(resolution == 8) LPC_I2S->I2SDAO &= (0x00 << 4); // set to 00
+	else if(resolution == 16) LPC_I2S->I2SDAO |= (0x01 << 4); // set to 01
+	else if(resolution == 32) LPC_I2S->I2SDAO |= (0x03 << 4);// set to 11
+	
+    // rate limited to 16000, 22050, 32000, 44100, 48000 or 96000
+	
+	uint32_t bitClock = resolution * rate;
+	if(stereo == true) bitClock *= 2;
+	uint8_t bitDivider = masterClock / bitClock;	
+	LPC_I2S->I2STXBITRATE = bitDivider - 1;
+	
+    if(stereo == true) LPC_I2S->I2SDAO &= (0 << 2); // set to stereo
+	else LPC_I2S->I2SDAO |= (1 << 2);
+}
+
+void I2S::setRx(uint16_t resolution, uint16_t rate, bool stereo) {
+    
+	if(resolution == 8) LPC_I2S->I2SDAI &= (0x00 << 4); // set to 00
+	else if(resolution == 16) LPC_I2S->I2SDAI |= (0x01 << 4); // set to 01
+	else if(resolution == 32) LPC_I2S->I2SDAI |= (0x03 << 4);// set to 11
+	
+    // rate limited to 16000, 22050, 32000, 44100, 48000 or 96000
+	
+    uint32_t bitClock = resolution * rate;
+	if(stereo == true) bitClock *= 2;
+	uint8_t bitDivider = masterClock / bitClock;	
+	LPC_I2S->I2SRXBITRATE = bitDivider - 1;
+	
+	if(stereo == true) LPC_I2S->I2SDAI &= (0 << 2); // set to stereo
+	else LPC_I2S->I2SDAI |= (1 << 2);
+}
+
+void I2S::muteTx(void) {
+    // sets the channel into "stop" mode, TX sends zeros
+    if(LPC_I2S->I2SDAO & 0x08) LPC_I2S->I2SDAO |= (1 << 4);
+	else  LPC_I2S->I2SDAO &= (0 << 4);
+    return;
+}
+
+void I2S::muteRx(void) {
+    // sets the channel into "stop" mode, TX sends zeros
+    if(LPC_I2S->I2SDAI & 0x00008) LPC_I2S->I2SDAI |= (1 << 4);
+    else LPC_I2S->I2SDAI &= (0 << 4);
+    return;
+}
+
+void I2S::resetTx(void) {
+    // resets the channel
+    LPC_I2S->I2SDAO |= (1 << 5);
+    return;
+}
+
+void I2S::resetRx(void) {
+    // resets the channel
+    LPC_I2S->I2SDAI |= (1 << 5);
+    return;
+}
+
+void setTxMode(uint8_t mode) {
+	uint8_t modes[2][7] = {{0,0,0,0,1,1,1},{0,2,4,8,0,2,4}};
+	/*
+	0;0,0,0,0 // Typical transmitter master mode.
+	0;0,0,1,0 // Transmitter master mode sharing the receiver reference clock.
+	0;0,1,0,0 // 4-wire transmitter master mode sharing the receiver bit clock and WS.
+	0;1,0,0,0 // Transmitter master mode with TX_MCLK output.
+	1;0,0,0,0 // Typical transmitter slave mode.
+	1;0,0,1,0 // Transmitter slave mode sharing the receiver reference clock.
+	1;0,1,0,0 // 4-wire transmitter slave mode sharing the receiver bit clock and WS.
+	*/
+	LPC_I2S->I2SDAO &= (modes[0][mode] << 5);
+	LPC_I2S->I2STXMODE = modes[1][mode];
+}
+
+void setRxMode(uint8_t mode) {
+	uint8_t modes[2][7] = {{0,0,0,0,1,1,1},{0,2,4,8,0,2,4}};
+	/*
+	0;0,0,0,0 // Typical receiver master mode.
+	0;0,0,1,0 // Receiver master mode sharing the transmitter reference clock.
+	0;0,1,0,0 // 4-wire receiver master mode sharing the transmitter bit clock and WS.
+	0;1,0,0,0 // Receiver master mode with RX_MCLK output.
+	1;0,0,0,0 // Typical receiver slave mode.
+	1;0,0,1,0 // Receiver slave mode sharing the transmitter reference clock.
+	1;0,1,0,0 // 4-wire receiver slave mode sharing the transmitter bit clock and WS.
+	*/
+	LPC_I2S->I2SDAI &= (modes[0][mode] << 5);
+	LPC_I2S->I2SRXMODE = modes[1][mode];
+}
+
+void setIRQ(bool rxInterrupt, bool txInterrupt, uint8_t rxDepth, uint8_t txDepth) {
+	if(rxInterrupt == true)
+	{
+		LPC_I2S->I2SIRQ |= (0x01 << 0);
+		LPC_I2S->I2SIRQ |= (rxDepth << 8);
+	}
+	else
+	{
+		LPC_I2S->I2SIRQ &= ~(0x01 << 0);
+		LPC_I2S->I2SIRQ &= ~(0x0F << 8);
+	}
+	
+	if(rxInterrupt == true)
+	{
+		LPC_I2S->I2SIRQ |= (0x01 << 1);
+		LPC_I2S->I2SIRQ |= (txDepth << 16);
+	}
+	else
+	{
+		LPC_I2S->I2SIRQ &= ~(0x01 << 1);
+		LPC_I2S->I2SIRQ &= ~(0x0F << 16);
+	}
+}
+
+void setDMA1(bool rxDMA, bool txDMA, uint8_t rxDepth, uint8_t txDepth) {
+	if(rxDMA == true)
+	{
+		LPC_I2S->I2SDMA1 |= (0x01 << 0);
+		LPC_I2S->I2SDMA1 |= (rxDepth << 8);
+	}
+	else
+	{
+		LPC_I2S->I2SDMA1 &= ~(0x01 << 0);
+		LPC_I2S->I2SDMA1 &= ~(0x0F << 8);
+	}
+	
+	if(txDMA == true)
+	{
+		LPC_I2S->I2SDMA1 |= (0x01 << 1);
+		LPC_I2S->I2SDMA1 |= (txDepth << 16);
+	}
+	else
+	{
+		LPC_I2S->I2SDMA1 &= ~(0x01 << 1);
+		LPC_I2S->I2SDMA1 &= ~(0x0F << 16);
+	}
+}
+
+void setDMA2(bool rxDMA, bool txDMA, uint8_t rxDepth, uint8_t txDepth) {
+	if(rxDMA == true)
+	{
+		LPC_I2S->I2SDMA2 |= (0x01 << 0);
+		LPC_I2S->I2SDMA2 |= (rxDepth << 8);
+	}
+	else
+	{
+		LPC_I2S->I2SDMA2 &= ~(0x01 << 0);
+		LPC_I2S->I2SDMA2 &= ~(0x0F << 8);
+	}
+	
+	if(txDMA == true)
+	{
+		LPC_I2S->I2SDMA2 |= (0x01 << 1);
+		LPC_I2S->I2SDMA2 |= (txDepth << 16);
+	}
+	else
+	{
+		LPC_I2S->I2SDMA2 &= ~(0x01 << 1);
+		LPC_I2S->I2SDMA2 &= ~(0x0F << 16);
+	}
+}
\ No newline at end of file