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.
I2S.cpp
00001 #include "mbed.h" 00002 #include "LPC17xx.h" 00003 #include "core_cm3.h" 00004 #include "system_LPC17xx.h" 00005 #include "I2S.h" 00006 00007 I2S::I2S(PinName bitTx = p7, PinName wdTx = p6, PinName daTx = p5, PinName bitRx = p30, PinName wdRx = p29, PinName daRx = p8) { 00008 // assuming pins are correct 00009 00010 // assign pins - be nice to use mbed stuff for this 00011 LPC_PINCON->PINSEL0 |= ((0x01 << 14) | (0x01 << 16) | (0x01 << 18)); // set p5,p6,p7 as I2S 00012 LPC_PINCON->PINMODE0 |= ((0x02 << 14) | (0x02 << 16) | (0x02 << 18)); 00013 if(bitRx == p30) 00014 { 00015 LPC_PINCON->PINSEL0 |= (0x01 << 8); 00016 LPC_PINCON->PINMODE0 |= (0x02 << 8); 00017 } 00018 else 00019 { 00020 LPC_PINCON->PINSEL1 |= (0x01 << 14); 00021 LPC_PINCON->PINMODE1 |= (0x02 << 14); 00022 } 00023 if(wdRx == p29) 00024 { 00025 LPC_PINCON->PINSEL0 |= (0x01 << 10); 00026 LPC_PINCON->PINMODE0 |= (0x02 << 10); 00027 } 00028 else 00029 { 00030 LPC_PINCON->PINSEL1 |= (0x01 << 16); 00031 LPC_PINCON->PINMODE1 |= (0x02 << 16); 00032 } 00033 if(daRx == p8) 00034 { 00035 LPC_PINCON->PINSEL0 |= (0x01 << 12); 00036 LPC_PINCON->PINMODE0 |= (0x02 << 12); 00037 } 00038 else 00039 { 00040 LPC_PINCON->PINSEL1 |= (0x01 << 18); 00041 LPC_PINCON->PINMODE1 |= (0x02 << 18); 00042 } 00043 00044 LPC_SC->PCONP |= (0x01 << 27); // turn on I2S periferal 00045 } 00046 00047 I2S::~I2S() { 00048 // release stuff 00049 LPC_SC->PCONP &= (0 << 27); // turn off I2S periferal 00050 } 00051 00052 00053 void I2S::setClocks(uint8_t x, uint8_t y, uint8_t divider) { 00054 00055 if(divider == 1) LPC_SC->PCLKSEL1 &= (0x01 << 22); 00056 else if(divider == 2) LPC_SC->PCLKSEL1 &= (0x02 << 22); 00057 else if(divider == 4) LPC_SC->PCLKSEL1 &= (0x00 << 22); 00058 else if(divider == 8) LPC_SC->PCLKSEL1 &= (0x03 << 22); 00059 00060 LPC_I2S->I2STXRATE = (x << 8) & y; 00061 LPC_I2S->I2SRXRATE = (x << 8) & y; 00062 00063 peripheralClock = SystemCoreClock/divider; 00064 masterClock = (x * peripheralClock)/(2 * y); 00065 } 00066 00067 00068 void I2S::setTx(uint16_t resolution, uint16_t rate, bool stereo) { 00069 00070 if(resolution == 8) LPC_I2S->I2SDAO &= (0x00 << 4); // set to 00 00071 else if(resolution == 16) LPC_I2S->I2SDAO |= (0x01 << 4); // set to 01 00072 else if(resolution == 32) LPC_I2S->I2SDAO |= (0x03 << 4);// set to 11 00073 00074 // rate limited to 16000, 22050, 32000, 44100, 48000 or 96000 00075 00076 uint32_t bitClock = resolution * rate; 00077 if(stereo == true) bitClock *= 2; 00078 uint8_t bitDivider = masterClock / bitClock; 00079 LPC_I2S->I2STXBITRATE = bitDivider - 1; 00080 00081 if(stereo == true) LPC_I2S->I2SDAO &= (0 << 2); // set to stereo 00082 else LPC_I2S->I2SDAO |= (1 << 2); 00083 } 00084 00085 void I2S::setRx(uint16_t resolution, uint16_t rate, bool stereo) { 00086 00087 if(resolution == 8) LPC_I2S->I2SDAI &= (0x00 << 4); // set to 00 00088 else if(resolution == 16) LPC_I2S->I2SDAI |= (0x01 << 4); // set to 01 00089 else if(resolution == 32) LPC_I2S->I2SDAI |= (0x03 << 4);// set to 11 00090 00091 // rate limited to 16000, 22050, 32000, 44100, 48000 or 96000 00092 00093 uint32_t bitClock = resolution * rate; 00094 if(stereo == true) bitClock *= 2; 00095 uint8_t bitDivider = masterClock / bitClock; 00096 LPC_I2S->I2SRXBITRATE = bitDivider - 1; 00097 00098 if(stereo == true) LPC_I2S->I2SDAI &= (0 << 2); // set to stereo 00099 else LPC_I2S->I2SDAI |= (1 << 2); 00100 } 00101 00102 void I2S::muteTx(void) { 00103 // sets the channel into "stop" mode, TX sends zeros 00104 if(LPC_I2S->I2SDAO & 0x08) LPC_I2S->I2SDAO |= (1 << 4); 00105 else LPC_I2S->I2SDAO &= (0 << 4); 00106 return; 00107 } 00108 00109 void I2S::muteRx(void) { 00110 // sets the channel into "stop" mode, TX sends zeros 00111 if(LPC_I2S->I2SDAI & 0x00008) LPC_I2S->I2SDAI |= (1 << 4); 00112 else LPC_I2S->I2SDAI &= (0 << 4); 00113 return; 00114 } 00115 00116 void I2S::resetTx(void) { 00117 // resets the channel 00118 LPC_I2S->I2SDAO |= (1 << 5); 00119 return; 00120 } 00121 00122 void I2S::resetRx(void) { 00123 // resets the channel 00124 LPC_I2S->I2SDAI |= (1 << 5); 00125 return; 00126 } 00127 00128 void setTxMode(uint8_t mode) { 00129 uint8_t modes[2][7] = {{0,0,0,0,1,1,1},{0,2,4,8,0,2,4}}; 00130 /* 00131 0;0,0,0,0 // Typical transmitter master mode. 00132 0;0,0,1,0 // Transmitter master mode sharing the receiver reference clock. 00133 0;0,1,0,0 // 4-wire transmitter master mode sharing the receiver bit clock and WS. 00134 0;1,0,0,0 // Transmitter master mode with TX_MCLK output. 00135 1;0,0,0,0 // Typical transmitter slave mode. 00136 1;0,0,1,0 // Transmitter slave mode sharing the receiver reference clock. 00137 1;0,1,0,0 // 4-wire transmitter slave mode sharing the receiver bit clock and WS. 00138 */ 00139 LPC_I2S->I2SDAO &= (modes[0][mode] << 5); 00140 LPC_I2S->I2STXMODE = modes[1][mode]; 00141 } 00142 00143 void setRxMode(uint8_t mode) { 00144 uint8_t modes[2][7] = {{0,0,0,0,1,1,1},{0,2,4,8,0,2,4}}; 00145 /* 00146 0;0,0,0,0 // Typical receiver master mode. 00147 0;0,0,1,0 // Receiver master mode sharing the transmitter reference clock. 00148 0;0,1,0,0 // 4-wire receiver master mode sharing the transmitter bit clock and WS. 00149 0;1,0,0,0 // Receiver master mode with RX_MCLK output. 00150 1;0,0,0,0 // Typical receiver slave mode. 00151 1;0,0,1,0 // Receiver slave mode sharing the transmitter reference clock. 00152 1;0,1,0,0 // 4-wire receiver slave mode sharing the transmitter bit clock and WS. 00153 */ 00154 LPC_I2S->I2SDAI &= (modes[0][mode] << 5); 00155 LPC_I2S->I2SRXMODE = modes[1][mode]; 00156 } 00157 00158 void setIRQ(bool rxInterrupt, bool txInterrupt, uint8_t rxDepth, uint8_t txDepth) { 00159 if(rxInterrupt == true) 00160 { 00161 LPC_I2S->I2SIRQ |= (0x01 << 0); 00162 LPC_I2S->I2SIRQ |= (rxDepth << 8); 00163 } 00164 else 00165 { 00166 LPC_I2S->I2SIRQ &= ~(0x01 << 0); 00167 LPC_I2S->I2SIRQ &= ~(0x0F << 8); 00168 } 00169 00170 if(rxInterrupt == true) 00171 { 00172 LPC_I2S->I2SIRQ |= (0x01 << 1); 00173 LPC_I2S->I2SIRQ |= (txDepth << 16); 00174 } 00175 else 00176 { 00177 LPC_I2S->I2SIRQ &= ~(0x01 << 1); 00178 LPC_I2S->I2SIRQ &= ~(0x0F << 16); 00179 } 00180 } 00181 00182 void setDMA1(bool rxDMA, bool txDMA, uint8_t rxDepth, uint8_t txDepth) { 00183 if(rxDMA == true) 00184 { 00185 LPC_I2S->I2SDMA1 |= (0x01 << 0); 00186 LPC_I2S->I2SDMA1 |= (rxDepth << 8); 00187 } 00188 else 00189 { 00190 LPC_I2S->I2SDMA1 &= ~(0x01 << 0); 00191 LPC_I2S->I2SDMA1 &= ~(0x0F << 8); 00192 } 00193 00194 if(txDMA == true) 00195 { 00196 LPC_I2S->I2SDMA1 |= (0x01 << 1); 00197 LPC_I2S->I2SDMA1 |= (txDepth << 16); 00198 } 00199 else 00200 { 00201 LPC_I2S->I2SDMA1 &= ~(0x01 << 1); 00202 LPC_I2S->I2SDMA1 &= ~(0x0F << 16); 00203 } 00204 } 00205 00206 void setDMA2(bool rxDMA, bool txDMA, uint8_t rxDepth, uint8_t txDepth) { 00207 if(rxDMA == true) 00208 { 00209 LPC_I2S->I2SDMA2 |= (0x01 << 0); 00210 LPC_I2S->I2SDMA2 |= (rxDepth << 8); 00211 } 00212 else 00213 { 00214 LPC_I2S->I2SDMA2 &= ~(0x01 << 0); 00215 LPC_I2S->I2SDMA2 &= ~(0x0F << 8); 00216 } 00217 00218 if(txDMA == true) 00219 { 00220 LPC_I2S->I2SDMA2 |= (0x01 << 1); 00221 LPC_I2S->I2SDMA2 |= (txDepth << 16); 00222 } 00223 else 00224 { 00225 LPC_I2S->I2SDMA2 &= ~(0x01 << 1); 00226 LPC_I2S->I2SDMA2 &= ~(0x0F << 16); 00227 } 00228 }
Generated on Tue Jul 26 2022 16:19:14 by 1.7.2