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.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers I2S.cpp Source 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 }