@@ -212,15 +212,43 @@ static uint32_t _i2s_sample_rate;
212212void ICACHE_FLASH_ATTR i2s_set_rate (uint32_t rate ){ //Rate in HZ
213213 if (rate == _i2s_sample_rate ) return ;
214214 _i2s_sample_rate = rate ;
215- uint32_t i2s_clock_div = (I2SBASEFREQ /(_i2s_sample_rate * 32 )) & I2SCDM ;
216- uint8_t i2s_bck_div = (I2SBASEFREQ /(_i2s_sample_rate * i2s_clock_div * 2 )) & I2SBDM ;
215+
216+ uint32_t scaled_base_freq = I2SBASEFREQ /32 ;
217+ float delta_best = scaled_base_freq ;
218+
219+ uint8_t sbd_div_best = 1 ;
220+ uint8_t scd_div_best = 1 ;
221+ for (uint8_t i = 1 ; i < 64 ; i ++ ){
222+ for (uint8_t j = i ; j < 64 ; j ++ ){
223+ float new_delta = fabs (((float )scaled_base_freq /i /j ) - rate );
224+ if (new_delta < delta_best ){
225+ delta_best = new_delta ;
226+ sbd_div_best = i ;
227+ scd_div_best = j ;
228+ }
229+ }
230+ }
231+
217232 //os_printf("Rate %u Div %u Bck %u Frq %u\n", _i2s_sample_rate, i2s_clock_div, i2s_bck_div, I2SBASEFREQ/(i2s_clock_div*i2s_bck_div*2));
218233
219234 //!trans master, !bits mod, rece slave mod, rece msb shift, right first, msb right
220235 I2SC &= ~(I2STSM | (I2SBMM << I2SBM ) | (I2SBDM << I2SBD ) | (I2SCDM << I2SCD ));
221- I2SC |= I2SRF | I2SMR | I2SRSM | I2SRMS | ((i2s_bck_div - 1 ) << I2SBD ) | ((i2s_clock_div - 1 ) << I2SCD );
236+ I2SC |= I2SRF | I2SMR | I2SRSM | I2SRMS | ((sbd_div_best ) << I2SBD ) | ((scd_div_best ) << I2SCD );
237+ }
238+
239+ void ICACHE_FLASH_ATTR i2s_set_dividers (uint8_t div1 , uint8_t div2 ){
240+ div1 &= I2SBDM ;
241+ div2 &= I2SCDM ;
242+
243+ I2SC &= ~(I2STSM | (I2SBMM << I2SBM ) | (I2SBDM << I2SBD ) | (I2SCDM << I2SCD ));
244+ I2SC |= I2SRF | I2SMR | I2SRSM | I2SRMS | (div1 << I2SBD ) | (div2 << I2SCD );
222245}
223246
247+ float ICACHE_FLASH_ATTR i2s_get_real_rate (){
248+ return (float )I2SBASEFREQ /32 /((I2SC >>I2SBD ) & I2SBDM )/((I2SC >> I2SCD ) & I2SCDM );
249+ }
250+
251+
224252void ICACHE_FLASH_ATTR i2s_begin (){
225253 _i2s_sample_rate = 0 ;
226254 i2s_slc_begin ();
0 commit comments