More readable TLV320 Lib

Dependents:   TalkThrough

Revision:
0:808bb0b9cf45
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/I2SSlaveHL.cpp	Wed Oct 22 09:23:47 2014 +0000
@@ -0,0 +1,247 @@
+
+#include "I2SSlaveHL.h"
+
+FunctionPointer akjnh3489v8ncv;
+
+extern "C" void I2S_IRQHandler(void) {
+	akjnh3489v8ncv.call();
+}
+
+#undef  MBV
+#define MBV(num) (1<<num)
+
+I2SSlave::I2SSlave(PinName tx_sda, PinName tx_ws, PinName clk, PinName rx_sda, PinName rx_ws)
+{
+	storePins_(tx_sda, tx_ws, clk, rx_sda, rx_ws);
+	format(16, STEREO);
+}
+
+void I2SSlave::format(int bit, bool mode)
+{
+	bit_ = bit;
+	mode_ = mode;
+	initialize_(tx_sda_, tx_ws_, clk_, rx_sda_, rx_ws_);
+}
+
+
+void I2SSlave::Write(int32_t aLeft, int32_t aRight)
+{
+	int32_t lr = (aRight << 16) + aLeft;
+	LPC_I2S->I2STXFIFO = lr;
+}
+
+void I2SSlave::Read(int32_t* aLeft, int32_t* aRight)
+{
+	int32_t v32 = LPC_I2S->I2SRXFIFO;
+	*aLeft = (int16_t)v32;
+	*aRight = (int16_t)(v32 >> 16);
+}
+
+
+
+void I2SSlave::start(int mode)
+{
+	switch(mode){
+		case(0):
+			 LPC_I2S->I2SIRQ |= (0 << 0); //disable receive interrupt
+			 LPC_I2S->I2SIRQ |= (0 << 1); //disable transmit interrupt
+			 break;
+		case(1):
+				LPC_I2S->I2SIRQ |= (0 << 0);  //disable receive interrupt
+				LPC_I2S->I2SIRQ |= (1 << 1);  //enable transmit interrupt
+				LPC_I2S->I2SIRQ |= (0 << 16); //set I2STXFIFO depth to 0 words
+				break;
+		case(2):
+				LPC_I2S->I2SIRQ |= (1 << 0);  //enable receive interrupt
+				LPC_I2S->I2SIRQ |= (0 << 1);  //disable transmit interrupt
+				LPC_I2S->I2SIRQ |= (4 << 8);  //set I2SRXFIFO depth to 4 words
+				break;
+		case(3):
+				LPC_I2S->I2SIRQ |= (1 << 0);  //enable receive interrupt
+				LPC_I2S->I2SIRQ |= (4 << 8);  //set I2SRXFIFO depth to 4 words
+				LPC_I2S->I2SIRQ |= (1 << 1);  //enable transmit interrupt
+				LPC_I2S->I2SIRQ |= (0 << 16); //set I2STXFIFO depth to 0 words
+				break;
+		default:
+				break;
+    }
+    NVIC_SetPriority(I2S_IRQn, 0);
+    NVIC_EnableIRQ(I2S_IRQn);  //enable I2S interrupt in the NVIC 
+}
+
+void I2SSlave::Start()
+{
+	LPC_I2S->I2SIRQ = 0;
+	LPC_I2S->I2SIRQ |= MBV(0); // ena RecvIRQ
+	// LPC_I2S->I2SIRQ |= MBV(8); // Rx-Level=1
+	LPC_I2S->I2SIRQ |= MBV(11); // Rx-Level=8
+	NVIC_SetPriority(I2S_IRQn, 0);
+	NVIC_EnableIRQ(I2S_IRQn);
+}
+
+void I2SSlave::Stop()
+{
+	NVIC_DisableIRQ(I2S_IRQn);
+}
+
+int I2SSlave::status(void)
+{
+	return LPC_I2S->I2SSTATE;
+}
+
+int I2SSlave::GetRxLevel()
+{
+	int val = LPC_I2S->I2SSTATE >> 8;
+	return (0x0000000F & val);
+}
+
+int I2SSlave::GetTxLevel()
+{
+	int val = LPC_I2S->I2SSTATE >> 16;
+	return (0x0000000F & val);
+}
+
+
+int I2SSlave::initialize_(PinName tx_sda, PinName tx_ws, PinName clk, PinName rx_sda, PinName rx_ws)
+{
+	setPins_(tx_sda, tx_ws, clk, rx_sda, rx_ws); // designate pins
+	LPC_SC->PCONP |= (1 << 27);
+	//configure input/output register
+	format_(bit_, mode_);           
+	//set mbed as SLAVE  
+	LPC_I2S->I2SDAO |= (1 << 5);
+	LPC_I2S->I2SDAI |= (1 << 5);
+	//clock mode
+	setClocks_(4);
+	//set slave mode
+	modeConfig_();
+	//set receiver mode
+	LPC_I2S->I2SRXMODE |= (1 << 1);
+	//slave mode
+	LPC_I2S->I2STXRATE = 0;
+	LPC_I2S->I2SRXRATE = 0;
+	//Start
+	LPC_I2S->I2SDAO |= (0 << 3);          
+	LPC_I2S->I2SDAI |= (0 << 3);
+	LPC_I2S->I2SDAO |= (0 << 4);          
+	LPC_I2S->I2SDAI |= (0 << 4);
+	LPC_I2S->I2SDAO |= (0 << 15);          
+	return 0;
+}
+
+// Set the division setting on the internal clocks
+void I2SSlave::setClocks_(int divideBy)
+{
+	switch(divideBy){
+			case 1:
+					LPC_SC->PCLKSEL1 |= (1 << 22); 
+					LPC_SC->PCLKSEL1 |= (0 << 23);     
+					break;
+			case 2:
+					LPC_SC->PCLKSEL1 |= (0 << 22);
+					LPC_SC->PCLKSEL1 |= (1 << 23);
+					break;
+			case 4:
+					LPC_SC->PCLKSEL1 |= (0 << 22);
+					LPC_SC->PCLKSEL1 |= (0 << 23);
+					break;
+			case 8:
+					LPC_SC->PCLKSEL1 |= (1 << 22);
+					LPC_SC->PCLKSEL1 |= (1 << 23);
+					break;
+			default:
+					break;
+	}
+}
+
+void I2SSlave::setPins_(PinName tx_sda, PinName tx_ws, PinName clk, PinName rx_sda, PinName rx_ws)
+{
+	if(rx_ws == p29){
+			LPC_PINCON->PINSEL0 |= (1 << 10);   //set p29 as receive word select line
+	} else {
+			LPC_PINCON->PINSEL1 |= (2 << 16);   //set p16 as receive word select line
+	}
+	if(rx_sda == p8){
+			LPC_PINCON->PINSEL0 |= (1 << 12);   //set p8 as receive serial data line
+	} else {
+			LPC_PINCON->PINSEL1 |= (2 << 18);   //set p17 as receive serial data line
+	}
+	LPC_PINCON->PINSEL0 |= (1 << 14);       //set p7 as transmit clock line (only one of these)    
+	LPC_PINCON->PINSEL0 |= (1 << 16);       //set p6 as word select line (only one of these)   
+	LPC_PINCON->PINSEL0 |= (1 << 18);       //set p5 as transmit serial data line (only one of these)
+	LPC_PINCON->PINSEL0 |= (0 << 8);        //clear rx_clk
+}
+
+
+void I2SSlave::format_(int bit, bool mode)
+{
+	uint32_t bps= ((bit+1)*8)-1;
+	LPC_I2S->I2SDAO &= (0x00 << 6);
+	LPC_I2S->I2SDAO |= (bps << 6);
+	//set bit length
+	switch(bit){
+			case 8:
+					LPC_I2S->I2SDAO &= 0xfffffffc;
+					break;
+			case 16:
+					LPC_I2S->I2SDAO &= (0 << 1);
+					LPC_I2S->I2SDAO |= (1 << 0);           
+					break;
+			case 32:
+					LPC_I2S->I2SDAO &= (0 << 1);
+					LPC_I2S->I2SDAO |= (3 << 0);
+					break;
+			default:
+					break;
+	}
+	//set audio mode
+	if(mode == STEREO){
+			LPC_I2S->I2SDAO |= (0 << 2);
+	} else {
+			LPC_I2S->I2SDAO |= (1 << 2);
+	}
+	//set transmitter and receiver setting to be the same
+	LPC_I2S->I2SDAI &= (0x00 << 6);
+	LPC_I2S->I2SDAI |= (bps << 6);
+	//set bit length
+	switch(bit){
+			case 8:
+					LPC_I2S->I2SDAI &= 0xfffffffc;
+					break;
+			case 16:
+					LPC_I2S->I2SDAI &= (0 << 1);
+					LPC_I2S->I2SDAI |= (1 << 0);
+					break;
+			case 32:
+					LPC_I2S->I2SDAI &= (0 << 1);
+					LPC_I2S->I2SDAI |= (3 << 0);
+					break;
+			default:
+					break;
+	}
+	//set audio mode
+	if(mode == STEREO){
+			LPC_I2S->I2SDAI |= (0 << 2);
+	} else {
+			LPC_I2S->I2SDAI |= (1 << 2);
+	}
+}
+
+
+void I2SSlave::modeConfig_(void)
+{
+	LPC_I2S->I2STXMODE |= (0x0 << 0);
+	LPC_I2S->I2SRXMODE |= (0x0 << 0);
+}
+
+
+void I2SSlave::storePins_(PinName tx_sda, PinName tx_ws, PinName clk, PinName rx_sda, PinName rx_ws)
+{
+	tx_sda_ = tx_sda;
+	tx_ws_ = tx_ws;
+	clk_ = clk;
+	rx_sda_ = rx_sda;
+	rx_ws_ = rx_ws;
+}
+
+