[ FORK ] I2S library for FRDM 64F, forked from p07gbar/I2S
Fork of I2S by
I2S.cpp
00001 #include "I2S.h" 00002 00003 #define I2S_DF_WORDWIDTH 16 00004 #define I2S_DF_SAMPLERATE 32000 00005 #define I2S_DF_MASTERSLAVE I2S_MASTER 00006 #define I2S_DF_STEREOMONO I2S_STEREO 00007 #define I2S_DF_MUTED I2S_UNMUTED 00008 #define I2S_DF_INTERRUPT_FIFO_LEVEL 4 00009 00010 #define I2S_MAX_DENOMINATOR 256 00011 #define I2S_MAX_NUMERATOR 256 00012 #define I2S_MAX_BITRATE_DIV 64 00013 00014 #define I2S_PCLK_RATE 12288000 00015 00016 FunctionPointer I2S::I2STXISR; 00017 FunctionPointer I2S::I2SRXISR; 00018 00019 bool I2S::txisr; 00020 bool I2S::rxisr; 00021 00022 I2S::I2S(bool rxtx, PinName SerialData, PinName WordSelect, PinName BitClk) 00023 { 00024 SIM->SCGC6 &= ~(SIM_SCGC6_I2S_MASK); 00025 SIM->SCGC6 |= SIM_SCGC6_I2S_MASK; 00026 00027 NVIC_DisableIRQ (I2S0_Tx_IRQn); 00028 NVIC_DisableIRQ (I2S0_Rx_IRQn); 00029 00030 _SerialData = SerialData; 00031 _WordSelect = WordSelect; 00032 _BitClk = BitClk; 00033 _rxtx = rxtx; 00034 00035 WordSelect_d = true; 00036 BitClk_d = true; 00037 MasterClk_d = false; 00038 00039 fourwire = false; 00040 00041 reg_write_err = 0; 00042 00043 pin_setup(); 00044 00045 if (pin_setup_err != 0) { 00046 perror("I2S Pins incorrectly defined."); 00047 } 00048 00049 defaulter(); 00050 _i2s_init(); 00051 } 00052 00053 //I2S::I2S(bool rxtx, PinName SerialData) 00054 //{ 00055 // NVIC_DisableIRQ (I2S0_Tx_IRQn); 00056 // NVIC_DisableIRQ (I2S0_Rx_IRQn); 00057 // 00058 // _SerialData = SerialData; 00059 // _rxtx = rxtx; 00060 // 00061 // WordSelect_d = false; 00062 // BitClk_d = false; 00063 // MasterClk_d = false; 00064 // 00065 // fourwire = false; 00066 // 00067 // reg_write_err = 0; 00068 // 00069 // pin_setup(); 00070 // 00071 // if (pin_setup_err != 0) { 00072 // perror("I2S Pins incorrectly defined."); 00073 // } 00074 // 00075 // defaulter(); 00076 //} 00077 // 00078 //I2S::I2S(bool rxtx, PinName SerialData, bool fourwiremode) 00079 //{ 00080 // NVIC_DisableIRQ (I2S0_Tx_IRQn); 00081 // NVIC_DisableIRQ (I2S0_Rx_IRQn); 00082 // 00083 // _SerialData = SerialData; 00084 // _rxtx = rxtx; 00085 // 00086 // WordSelect_d = false; 00087 // BitClk_d = false; 00088 // MasterClk_d = false; 00089 // 00090 // reg_write_err = 0; 00091 // 00092 // fourwire = fourwiremode; 00093 // 00094 // pin_setup(); 00095 // 00096 // if (pin_setup_err != 0) { 00097 // perror("I2S Pins incorrectly defined."); 00098 // } 00099 // 00100 // defaulter(); 00101 //} 00102 // 00103 //I2S::I2S(bool rxtx, PinName SerialData, PinName WordSelect, bool fourwiremode) 00104 //{ 00105 // NVIC_DisableIRQ (I2S0_Tx_IRQn); 00106 // NVIC_DisableIRQ (I2S0_Rx_IRQn); 00107 // 00108 // _SerialData = SerialData; 00109 // _WordSelect = WordSelect; 00110 // _rxtx = rxtx; 00111 // 00112 // WordSelect_d = true; 00113 // BitClk_d = false; 00114 // MasterClk_d = false; 00115 // 00116 // reg_write_err = 0; 00117 // 00118 // fourwire = fourwiremode; 00119 // 00120 // pin_setup(); 00121 // 00122 // if (pin_setup_err != 0) { 00123 // perror("I2S Pins incorrectly defined."); 00124 // } 00125 // 00126 // defaulter(); 00127 //} 00128 // 00129 //I2S::I2S(bool rxtx, PinName SerialData, PinName WordSelect) 00130 //{ 00131 // NVIC_DisableIRQ (I2S0_Tx_IRQn); 00132 // NVIC_DisableIRQ (I2S0_Rx_IRQn); 00133 // 00134 // _SerialData = SerialData; 00135 // _WordSelect = WordSelect; 00136 // _rxtx = rxtx; 00137 // 00138 // WordSelect_d = true; 00139 // BitClk_d = false; 00140 // MasterClk_d = false; 00141 // 00142 // reg_write_err = 0; 00143 // 00144 // fourwire = false; 00145 // 00146 // pin_setup(); 00147 // 00148 // if (pin_setup_err != 0) { 00149 // perror("I2S Pins incorrectly defined."); 00150 // } 00151 // 00152 // defaulter(); 00153 //} 00154 00155 I2S::~I2S() 00156 { 00157 NVIC_DisableIRQ (I2S0_Tx_IRQn); 00158 NVIC_DisableIRQ (I2S0_Rx_IRQn); 00159 00160 deallocating = true; 00161 pin_setup(); 00162 write_registers(); 00163 } 00164 00165 void I2S::defaulter() 00166 { 00167 I2S0->TCSR |= 1u<<31; 00168 00169 stop(); 00170 master = false; 00171 deallocating = false; 00172 00173 frequency(I2S_DF_SAMPLERATE); 00174 wordsize(I2S_DF_WORDWIDTH); 00175 masterslave (I2S_DF_MASTERSLAVE); 00176 stereomono (I2S_DF_STEREOMONO); 00177 set_interrupt_fifo_level(I2S_DF_INTERRUPT_FIFO_LEVEL); 00178 mute (I2S_DF_MUTED); 00179 00180 NVIC_SetVector(I2S0_Tx_IRQn, (uint32_t) & _i2sisr); 00181 NVIC_EnableIRQ (I2S0_Tx_IRQn); 00182 } 00183 00184 void I2S::write(char buf[], int len) 00185 { 00186 if (_rxtx == I2S_TRANSMIT) { 00187 if (len > max_fifo_points()) 00188 len = max_fifo_points(); 00189 if (len <= 0) 00190 return; 00191 int temp = 0; 00192 for (int i = 0; i < len; i += 4) { 00193 temp = 0; 00194 for (int j = 0; j < 4; j++) { 00195 temp |= int(buf[i + j]) << (j * 8); 00196 } 00197 I2S0->TDR[0] = temp; 00198 } 00199 } 00200 00201 } 00202 00203 void I2S::write(int buf[], int len) 00204 { 00205 if (_rxtx == I2S_TRANSMIT && wordwidth > 0) { 00206 if (len > max_fifo_points()) { 00207 len = max_fifo_points(); 00208 printf("Trying to write too much data!\n\r"); 00209 } 00210 if (len <= 0) 00211 return; 00212 uint32_t temp = 0; 00213 int increment = 32 / wordwidth; 00214 unsigned char recast[] = 00215 { 0, 0, 0, 0 }; 00216 for (int i = 0; i < len; i += increment) { 00217 temp = 0; 00218 00219 switch (wordwidth) { 00220 00221 case 8: 00222 00223 recast[0] = (int8_t) buf[i + 0]; 00224 recast[1] = (int8_t) buf[i + 1]; 00225 recast[2] = (int8_t) buf[i + 2]; 00226 recast[3] = (int8_t) buf[i + 3]; 00227 break; 00228 case 16: 00229 recast[0] = (((int16_t) buf[i + 0]) >> 0) & 0xFF; 00230 recast[1] = (((int16_t) buf[i + 0]) >> 8) & 0xFF; 00231 recast[2] = (((int16_t) buf[i + 1]) >> 0) & 0xFF; 00232 recast[3] = (((int16_t) buf[i + 1]) >> 8) & 0xFF; 00233 break; 00234 case 32: 00235 recast[0] = (((int32_t) buf[i + 0]) >> 0) & 0xFF; 00236 recast[1] = (((int32_t) buf[i + 0]) >> 8) & 0xFF; 00237 recast[2] = (((int32_t) buf[i + 0]) >> 16) & 0xFF; 00238 recast[3] = (((int32_t) buf[i + 0]) >> 24) & 0xFF; 00239 break; 00240 00241 } 00242 for (int j = 0; j < 4; j++) { 00243 00244 temp |= recast[j] << (j * 8); 00245 } 00246 00247 //if(((temp >> 16) & 0xFFFF) == 0xFFFF) printf("Hmmm %x %x %x\n\r",temp, increment,i); //|| temp &0xFFFF == 0xFFFF 00248 //if((buf[i]-buf[i+1])>5000 || (buf[i]-buf[i+1])<-5000) printf("J:%i,%i\n\r",buf[i],buf[i+1]); 00249 //printf("%x\n",temp); 00250 I2S0->TDR[0] = temp; 00251 } 00252 } 00253 } 00254 00255 void I2S::write(int bufr[], int bufl[], int len) 00256 { 00257 //#TODO: Write this! 00258 } 00259 00260 int I2S::read() 00261 { 00262 return I2S0->RDR[0]; 00263 } 00264 00265 void I2S::read(char buf[], int len) 00266 { 00267 bool len_valid = true; 00268 if (len <= 0) 00269 return; 00270 if (len >= fifo_points()) 00271 len = fifo_points(); 00272 int temp[8]; 00273 int counter = 0; 00274 int increment = 4; //32/wordwidth; 00275 int fifo_levl = fifo_level(); 00276 while (counter < fifo_levl && len_valid) { 00277 temp[counter] = I2S0->RDR[0]; 00278 for (int j = 0; j < increment; j++) { 00279 if ((counter * 4) + j > len) { 00280 len_valid = false; 00281 break; 00282 } 00283 buf[counter + j] = temp[counter] >> (j * 8); 00284 00285 } 00286 counter++; 00287 } 00288 } 00289 00290 void I2S::read(int buf[], int len) 00291 { 00292 bool len_valid = true; 00293 if (len <= 0) 00294 return; 00295 if (len >= fifo_points()) 00296 len = fifo_points(); 00297 int temp[8]; 00298 int counter = 0; 00299 int increment = 32 / wordwidth; 00300 int fifo_levl = fifo_level(); 00301 while (counter < fifo_levl && len_valid) { 00302 temp[counter] = I2S0->RDR[0]; 00303 for (int j = 0; j < increment; j++) { 00304 if ((counter * increment) + j > len) { 00305 len_valid = false; 00306 break; 00307 } 00308 buf[counter + j] = temp[counter] >> (j * wordwidth); 00309 00310 } 00311 counter++; 00312 } 00313 } 00314 00315 void I2S::read(int bufr[], int bufl[], int len) 00316 { 00317 //#TODO: Write this 00318 } 00319 00320 int I2S::max_fifo_points() 00321 { 00322 switch (wordwidth) { 00323 case 8: 00324 return (4 * 8); 00325 case 16: 00326 return (2 * 8); 00327 case 32: 00328 return 8; 00329 default: 00330 return 0; 00331 } 00332 } 00333 00334 int I2S::fifo_points() 00335 { 00336 switch (wordwidth) { 00337 case 8: 00338 return (4 * fifo_level()); 00339 case 16: 00340 return (2 * fifo_level()); 00341 case 32: 00342 return fifo_level(); 00343 default: 00344 return 0; 00345 } 00346 } 00347 00348 void I2S::power(bool pwr) 00349 { 00350 if (pwr) { 00351 stopped = false; 00352 } else { 00353 stopped = true; 00354 } 00355 write_registers(); 00356 } 00357 00358 void I2S::masterslave(bool mastermode) 00359 { 00360 if (mastermode == I2S_MASTER) { 00361 master = true; 00362 } else { 00363 master = false; 00364 } 00365 write_registers(); 00366 } 00367 00368 void I2S::wordsize(int words) 00369 { 00370 wordwidth = 16; 00371 // write_registers(); 00372 } 00373 00374 void I2S::mclk_freq(int freq) 00375 { 00376 mclk_frequency = 12288000; 00377 // write_registers(); 00378 } 00379 00380 void I2S::frequency(int desired_freq) 00381 { 00382 freq = 32000; 00383 _i2s_set_rate(freq); 00384 //write_registers(); 00385 } 00386 00387 int I2S::fifo_level() 00388 { 00389 int level = 0; 00390 if (_rxtx == I2S_TRANSMIT) { 00391 level = I2S0->TFR[0]; 00392 level >>= 16; 00393 level &= 0xF; 00394 } else { 00395 level = I2S0->TFR[0]; 00396 level >>= 0; 00397 level &= 0xF; 00398 } 00399 return level; 00400 } 00401 00402 void I2S::stereomono(bool stereomode) 00403 { 00404 stereo = true; 00405 /* 00406 if (stereomode == I2S_STEREO) { 00407 stereo = true; 00408 } else { 00409 stereo = false; 00410 } 00411 */ 00412 } 00413 00414 void I2S::mute() 00415 { 00416 muted = true; 00417 // write_registers(); 00418 } 00419 00420 void I2S::mute(bool mute_en) 00421 { 00422 muted = mute_en; 00423 // write_registers(); 00424 } 00425 00426 void I2S::stop() 00427 { 00428 stopped = true; 00429 // write_registers(); 00430 } 00431 00432 void I2S::set_interrupt_fifo_level(int level) 00433 { 00434 interrupt_fifo_level = 4; 00435 // write_registers(); 00436 } 00437 00438 void I2S::start() 00439 { 00440 stopped = false; 00441 muted = false; 00442 // write_registers(); 00443 } 00444 00445 bool I2S::setup_ok() 00446 { 00447 if ((reg_write_err + pin_setup_err) > 0) 00448 return false; 00449 else 00450 return true; 00451 } 00452 00453 void I2S::pin_setup() 00454 { 00455 pin_setup_err = 0; 00456 00457 if (_rxtx == I2S_TRANSMIT) { 00458 printf("\n\rSetting up pins....\n\r"); 00459 if (_SerialData != PTC1) 00460 pin_setup_err++; 00461 if (_WordSelect != PTB19 && WordSelect_d == true) 00462 pin_setup_err++; 00463 if (_BitClk != PTB18 && BitClk_d == true) 00464 pin_setup_err++; 00465 printf("Hmm....%i\n\r", pin_setup_err); 00466 } else { 00467 if (_SerialData != PTC5) 00468 pin_setup_err++; 00469 if (_WordSelect != PTC7 && WordSelect_d == true) 00470 pin_setup_err++; 00471 if (_BitClk != PTC6 && BitClk_d == true) 00472 pin_setup_err++; 00473 } 00474 /* 00475 * @param SerialData The serial data pin 00476 * @param WordSelect The word select pin 00477 * @param BitClk The clock pin 00478 PORTC->PCR[8] &= PORT_PCR_MUX_MASK; 00479 PORTC->PCR[8] |= PORT_PCR_MUX(0x04); // PTC8 I2S0_MCLK 00480 00481 PORTC->PCR[5] &= PORT_PCR_MUX_MASK; 00482 PORTC->PCR[5] |= PORT_PCR_MUX(0x04); // PTC5 I2S0_RXD0 00483 00484 PORTC->PCR[7] &= PORT_PCR_MUX_MASK; 00485 PORTC->PCR[7] |= PORT_PCR_MUX(0x04); // PTC7 I2S0_RX_FS 00486 00487 PORTC->PCR[6] &= PORT_PCR_MUX_MASK; 00488 PORTC->PCR[6] |= PORT_PCR_MUX(0x04); // PTC6 I2S0_RX_BCLK 00489 00490 PORTC->PCR[1] &= PORT_PCR_MUX_MASK; 00491 PORTC->PCR[1] |= PORT_PCR_MUX(0x04); // PTC1 I2S0_TXD0 00492 00493 PORTB->PCR[19] &= PORT_PCR_MUX_MASK; 00494 PORTB->PCR[19] |= PORT_PCR_MUX(0x04); // PTB19 I2S0_TX_FS 00495 00496 PORTB->PCR[18] &= PORT_PCR_MUX_MASK; 00497 PORTB->PCR[18] |= PORT_PCR_MUX(0x04); // PTB18 I2S0_TX_BCLK 00498 */ 00499 00500 SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK; 00501 if (pin_setup_err == 0) { 00502 00503 PORTC->PCR[8] &= PORT_PCR_MUX_MASK; 00504 PORTC->PCR[8] |= PORT_PCR_MUX(0x04); // PTC8 I2S0_MCLK 00505 00506 if (_rxtx == I2S_TRANSMIT) { 00507 int val1 = 1; 00508 if (deallocating) { 00509 val1 = 0; 00510 } 00511 00512 PORTC->PCR[1] &= PORT_PCR_MUX_MASK; 00513 PORTC->PCR[1] |= PORT_PCR_MUX(0x04); // PTC1 I2S0_TXD0 00514 00515 if (WordSelect_d == true) { 00516 PORTB->PCR[18] &= PORT_PCR_MUX_MASK; 00517 PORTB->PCR[18] |= PORT_PCR_MUX(0x04); // PTB18 I2S0_TX_BCLK 00518 } 00519 if (BitClk_d == true) { 00520 PORTB->PCR[19] &= PORT_PCR_MUX_MASK; 00521 PORTB->PCR[19] |= PORT_PCR_MUX(0x04); // PTB19 I2S0_TX_FS 00522 } 00523 00524 } else { 00525 int val1 = 1; 00526 int val2 = 2; 00527 if (deallocating) { 00528 val1 = 0; 00529 val2 = 0; 00530 } 00531 00532 PORTC->PCR[5] &= PORT_PCR_MUX_MASK; 00533 PORTC->PCR[5] |= PORT_PCR_MUX(0x04); // PTC5 I2S0_RXD0 00534 00535 if (WordSelect_d == true) { 00536 PORTB->PCR[18] &= PORT_PCR_MUX_MASK; 00537 PORTB->PCR[18] |= PORT_PCR_MUX(0x04); // PTB18 I2S0_TX_BCLK 00538 } 00539 00540 if (BitClk_d == true) { 00541 PORTC->PCR[6] &= PORT_PCR_MUX_MASK; 00542 PORTC->PCR[6] |= PORT_PCR_MUX(0x04); // PTC6 I2S0_RX_BCLK 00543 } 00544 } 00545 } 00546 } 00547 00548 00549 00550 00551 00552 00553 00554 void I2S::_set_clock_112896(void) 00555 { 00556 // SIM->SCGC6 &= ~(SIM_SCGC6_I2S_MASK); 00557 00558 // output = input[(I2SFRAC+1) / (I2SDIV+1) ] = (48* (4/17)) 00559 // SIM_CLKDIV2 |= SIM_CLKDIV2_I2SDIV(16) | SIM_CLKDIV2_I2SFRAC(3); 00560 I2S0->MDR = I2S_MDR_FRACT(3) | I2S_MDR_DIVIDE(16); 00561 // SIM->SCGC6 |= SIM_SCGC6_I2S_MASK; 00562 } 00563 void I2S::_set_clock_122800(void) 00564 { 00565 // output = input [(I2SFRAC+1) / (I2SDIV+1) ] = (48M* (32/125)) 00566 // SIM_CLKDIV2 |= SIM_CLKDIV2_I2SDIV(124) | SIM_CLKDIV2_I2SFRAC(31); 00567 I2S0->MDR = I2S_MDR_FRACT(63) | I2S_MDR_DIVIDE(624); 00568 } 00569 void I2S::_i2s_init(void) 00570 { 00571 #define I2S_CONFIG_WORDS_IN_A_FRAME 2 00572 #define I2S_CONFIG_BITS_IN_A_WORD 16 00573 00574 I2S0->TCR1 = 4;// 6; // water mark 00575 I2S0->TCR2 |= (0<<30) | // master mode(Async mode) 00576 (1<<26) | // MSEL = MCLK 00577 (1<<25) | // CLK = drive on falling edge 00578 (1<<24) ; // CLK = OUTPUT 00579 00580 I2S0->TCR3 = (1<<16); // enable channel 0 00581 00582 I2S0->TCR4 = ((I2S_CONFIG_WORDS_IN_A_FRAME-1)<<16) | // words in a frame 00583 ((I2S_CONFIG_BITS_IN_A_WORD -1)<<8) | // bits in a word 00584 (1<<4) | // MSB 00585 (1<<3) | // one bit early 00586 (1<<1) | // frame active low 00587 (1<<0) ; // frame = output 00588 00589 I2S0->TCR5 = ((I2S_CONFIG_BITS_IN_A_WORD-1) <<24) | // word N width 00590 ((I2S_CONFIG_BITS_IN_A_WORD-1) <<16) | // word 0 width 00591 (0x17<<8); // right adjust, where the first bit starts 00592 00593 I2S0->TMR = 0; 00594 00595 // enable TX 00596 I2S0->TCSR = (0<<31) | // enable tx 00597 (1<<28) | // enable bit clock 00598 (0<<0); // enable DMA request 00599 } 00600 00601 void I2S::_i2s_set_rate(int smprate) 00602 { 00603 unsigned char div; 00604 // SIM->SCGC6 |= SIM_SCGC6_I2S_MASK; 00605 00606 // Select MCLK input source 00607 I2S0->MCR = (1<<30)| // MCLK = output 00608 (0<<24); // MCLK SRC = core clock = 48M 00609 00610 if((smprate == 11025)||(smprate == 22050)||(smprate == 44100)) { 00611 _set_clock_112896(); 00612 mclk_frequency = 11289600; 00613 } 00614 00615 if((smprate == 8000) || (smprate == 12000) || (smprate == 16000) || 00616 (smprate == 24000)|| (smprate == 32000) || (smprate == 48000) ) { 00617 _set_clock_122800(); 00618 mclk_frequency = 12288000; 00619 } 00620 00621 switch(smprate) { 00622 case 32000: 00623 div=3; 00624 break; // 12.288M/(32K*48) = 8, 8 = (DIV+1)*2, DIV = 3 00625 } 00626 00627 I2S0->TCR2 = div; 00628 } 00629 00630 00631 00632 00633 00634 00635 00636 00637 00638 00639 void I2S::write_registers() 00640 { 00641 reg_write_err = 0; 00642 //Clock Multiplier Calculations 00643 float pre_mult = 0; 00644 int pre_num = 0; 00645 int pre_den = 0; 00646 int bitrate_div = 0; 00647 // if (master == true) { // In the hope of not doing all this heavy lifting every configuration 00648 // //printf("Doing some clock magic..\n\r"); 00649 // int bitrate = freq * 64; 00650 // float target_div = I2S_PCLK_RATE / float(bitrate * 2);// Work out what divider is needed in the end, including the halving of rates the smoother does 00651 // if (mclk_frequency == 0) { 00652 // float rnd = fmod(target_div,1);// To make the X/Y fraction closest to 1, we set the last divider to the nearest integer to the rate divider 00653 // bitrate_div = int(target_div - rnd); 00654 // while (bitrate_div > I2S_MAX_BITRATE_DIV) { // But this might be out of range, so we right shift it into focus 00655 // bitrate_div >>= 1; 00656 // } 00657 // if (bitrate_div == 0) { // Could be zero, which would disable the the clock... 00658 // bitrate_div = 1; 00659 // } 00660 // pre_mult = float(bitrate_div) / target_div; // Work out what we have left to correct 00661 // pre_num = 0; 00662 // pre_den = 0; 00663 // fraction_estimator(pre_mult, &pre_num, &pre_den);// Get the function to work out the closest fraction, there might be some point in adding some possible multipliers of these values to add to the smoothing, the reference manual (UM10360 page 480) suggests this 00664 // 00665 // } else { 00666 // pre_mult = float(mclk_frequency * 2) / (I2S_PCLK_RATE); 00667 // pre_num = 0; 00668 // pre_den = 0; 00669 // fraction_estimator(pre_mult, &pre_num, &pre_den);// Get the function to work out the closest fraction, there might be some point in adding some possible multipliers of these values to add to the smoothing, the reference manual (UM10360 page 480) suggests this 00670 // bitrate_div = int( 00671 // I2S_PCLK_RATE * float(pre_num) / float(pre_den) 00672 // / float(bitrate)); 00673 // } 00674 // 00675 // old_freq = freq; 00676 // old_pre_num = pre_num; 00677 // old_pre_den = pre_den; 00678 // old_bitrate_div = bitrate_div; 00679 // } else { 00680 // pre_num = old_pre_num; 00681 // pre_den = old_pre_den; 00682 // bitrate_div = old_bitrate_div; 00683 // } 00684 00685 //Clock Multiplier, MCLK setup 00686 if (_rxtx == I2S_TRANSMIT) { 00687 int regvals = ((pre_num << 8) & 0xFF00) | (pre_den & 0xFF); 00688 // LPC_I2S->I2STXRATE = regvals; // Setting the X/Y fraction 00689 // LPC_I2S->I2STXBITRATE = (bitrate_div - 1) & 0x3F;// Setting up the bitrate divider, the periferal adds one to this 00690 00691 // LPC_I2S->I2STXMODE = fourwire << 2; 00692 00693 if (MasterClk_d == true) { 00694 // LPC_I2S->I2STXMODE |= (1 << 3); 00695 } 00696 } else { 00697 int regvals = ((pre_num << 8) & 0xFF00) | (pre_den & 0xFF); 00698 // LPC_I2S->I2SRXRATE = regvals; // Setting the X/Y fraction 00699 // LPC_I2S->I2SRXBITRATE = (bitrate_div - 1) & 0x3F;// Setting up the bitrate divider, the periferal adds one to this 00700 00701 // LPC_I2S->I2SRXMODE = fourwire << 2; 00702 00703 if (MasterClk_d == true) { 00704 // LPC_I2S->I2SRXMODE |= (1 << 3); 00705 } 00706 } 00707 00708 switch (wordwidth) { 00709 case 8: 00710 wordwidth_code = 0; 00711 break; 00712 case 16: 00713 wordwidth_code = 1; 00714 break; 00715 case 32: 00716 wordwidth_code = 3; 00717 break; 00718 default: 00719 reg_write_err++; 00720 break; 00721 } 00722 00723 int I2SDA_reg = (wordwidth_code & 0x3); 00724 I2SDA_reg |= ((!stereo << 2) & 0x4); 00725 I2SDA_reg |= ((stopped << 3) & 0x8); 00726 I2SDA_reg |= ((!master << 5) & 0x20); 00727 I2SDA_reg |= (0x1F << 6); 00728 I2SDA_reg |= ((muted << 15) & 0x8000); 00729 00730 if (_rxtx == I2S_TRANSMIT) { 00731 ; 00732 // LPC_I2S->I2SDAO = I2SDA_reg; 00733 } else { 00734 ; 00735 // LPC_I2S->I2SDAI = I2SDA_reg; 00736 } 00737 00738 if (_rxtx == I2S_TRANSMIT) { 00739 if (txisr) { 00740 // LPC_I2S->I2SIRQ = (LPC_I2S->I2SIRQ & 0xFF0FFFFF) 00741 // | ((interrupt_fifo_level & 0xF) << 16); 00742 // LPC_I2S->I2SIRQ |= 0x2; 00743 } else { 00744 ; 00745 // LPC_I2S->I2SIRQ &= 0xFFFFFFFD; 00746 } 00747 } else { 00748 if (rxisr) { 00749 // LPC_I2S->I2SIRQ = (LPC_I2S->I2SIRQ & 0xFFFFF0FF) 00750 // | ((interrupt_fifo_level & 0xF) << 8); 00751 // LPC_I2S->I2SIRQ |= 0x1; 00752 } 00753 00754 else { 00755 ; 00756 // LPC_I2S->I2SIRQ &= 0xFFFFFFFE; 00757 } 00758 } 00759 } 00760 00761 void I2S::_i2sisr(void) 00762 { 00763 I2STXISR.call(); 00764 I2SRXISR.call(); 00765 } 00766 00767 // A function to find the nearest fraction to that put to it, with numerator and denomnator less than 256 00768 // This is used when trying to get the clocks correct 00769 00770 //void I2S::fraction_estimator(float in, int * num, int * den) 00771 //{ 00772 // int test_num = 0; 00773 // int test_den = 0; 00774 // float least_error = 1; 00775 // int least_err_den = 0; 00776 // float genval; 00777 // float generr; 00778 // 00779 // for (test_den = 1; test_den < I2S_MAX_DENOMINATOR; test_den++) { 00780 // test_num = int(float(test_den) * in); 00781 // if (test_num < I2S_MAX_NUMERATOR && test_num > 0) { 00782 // genval = float(test_num) / float(test_den); 00783 // generr = mod(genval - in); 00784 // if (generr < least_error) { 00785 // least_error = generr; 00786 // least_err_den = test_den; 00787 // } 00788 // if (generr == 0) { 00789 // break; 00790 // } 00791 // } 00792 // } 00793 // 00794 // test_num = int(float(least_err_den) * in); 00795 // *num = test_num; 00796 // *den = least_err_den; 00797 // 00798 //} 00799 // 00800 //float I2S::mod(float in) 00801 //{ 00802 // if (in < 0) 00803 // in *= -1; 00804 // 00805 // return in; 00806 //}
Generated on Sun Jul 17 2022 00:39:12 by 1.7.2