@@ -49,7 +49,7 @@ static const char* I2S_TAG = "I2S";
4949#define I2S_EXIT_CRITICAL () portEXIT_CRITICAL(&i2s_spinlock[i2s_num])
5050#define I2S_FULL_DUPLEX_SLAVE_MODE_MASK (I2S_MODE_TX | I2S_MODE_RX | I2S_MODE_SLAVE)
5151#define I2S_FULL_DUPLEX_MASTER_MODE_MASK (I2S_MODE_TX | I2S_MODE_RX | I2S_MODE_MASTER)
52- #define APLL_MIN_FREQ (350000000 )
52+ #define APLL_MIN_FREQ (250000000 )
5353#define APLL_MAX_FREQ (500000000)
5454#define APLL_I2S_MIN_RATE (10675) //in Hz, I2S Clock rate limited by hardware
5555/**
@@ -83,29 +83,16 @@ typedef struct {
8383 int bytes_per_sample ; /*!< Bytes per sample*/
8484 int bits_per_sample ; /*!< Bits per sample*/
8585 i2s_mode_t mode ; /*!< I2S Working mode*/
86- int use_apll ; /*!< I2S use APLL clock */
8786 uint32_t sample_rate ; /*!< I2S sample rate */
87+ bool use_apll ; /*!< I2S use APLL clock */
88+ int fixed_mclk ; /*!< I2S fixed MLCK clock */
8889} i2s_obj_t ;
8990
9091static i2s_obj_t * p_i2s_obj [I2S_NUM_MAX ] = {0 };
9192static i2s_dev_t * I2S [I2S_NUM_MAX ] = {& I2S0 , & I2S1 };
9293static portMUX_TYPE i2s_spinlock [I2S_NUM_MAX ] = {portMUX_INITIALIZER_UNLOCKED , portMUX_INITIALIZER_UNLOCKED };
9394static int _i2s_adc_unit = -1 ;
9495static int _i2s_adc_channel = -1 ;
95- /**
96- * @brief Pre define APLL parameters, save compute time
97- * | bits_per_sample | rate | sdm0 | sdm1 | sdm2 | odir
98- */
99- static const int apll_predefine [][6 ] = {
100- {16 , 11025 , 38 , 80 , 5 , 31 },
101- {16 , 16000 , 147 , 107 , 5 , 21 },
102- {16 , 22050 , 130 , 152 , 5 , 15 },
103- {16 , 32000 , 129 , 212 , 5 , 10 },
104- {16 , 44100 , 15 , 8 , 5 , 6 },
105- {16 , 48000 , 136 , 212 , 5 , 6 },
106- {16 , 96000 , 143 , 212 , 5 , 2 },
107- {0 , 0 , 0 , 0 , 0 , 0 }
108- };
10996
11097static i2s_dma_t * i2s_create_dma_queue (i2s_port_t i2s_num , int dma_buf_count , int dma_buf_len );
11198static esp_err_t i2s_destroy_dma_queue (i2s_port_t i2s_num , i2s_dma_t * dma );
@@ -121,16 +108,16 @@ static esp_err_t i2s_reset_fifo(i2s_port_t i2s_num)
121108 return ESP_OK ;
122109}
123110
124- inline static void gpio_matrix_out_check (uint32_t gpio , uint32_t signal_idx , bool out_inv , bool oen_inv )
111+ inline static void gpio_matrix_out_check (uint32_t gpio , uint32_t signal_idx , bool out_inv , bool oen_inv )
125112{
126113 //if pin = -1, do not need to configure
127114 if (gpio != -1 ) {
128115 PIN_FUNC_SELECT (GPIO_PIN_MUX_REG [gpio ], PIN_FUNC_GPIO );
129116 gpio_set_direction (gpio , GPIO_MODE_DEF_OUTPUT );
130117 gpio_matrix_out (gpio , signal_idx , out_inv , oen_inv );
131- }
132- }
133- inline static void gpio_matrix_in_check (uint32_t gpio , uint32_t signal_idx , bool inv )
118+ }
119+ }
120+ inline static void gpio_matrix_in_check (uint32_t gpio , uint32_t signal_idx , bool inv )
134121{
135122 if (gpio != -1 ) {
136123 PIN_FUNC_SELECT (GPIO_PIN_MUX_REG [gpio ], PIN_FUNC_GPIO );
@@ -191,7 +178,7 @@ static esp_err_t i2s_isr_register(i2s_port_t i2s_num, uint8_t intr_alloc_flags,
191178}
192179
193180
194- static float i2s_get_apll_real_rate (int bits_per_sample , int sdm0 , int sdm1 , int sdm2 , int odir )
181+ static float i2s_apll_get_fi2s (int bits_per_sample , int sdm0 , int sdm1 , int sdm2 , int odir )
195182{
196183 int f_xtal = (int )rtc_clk_xtal_freq_get () * 1000000 ;
197184 uint32_t is_rev0 = (GET_PERI_REG_BITS2 (EFUSE_BLK0_RDATA3_REG , 1 , 15 ) == 0 );
@@ -201,37 +188,37 @@ static float i2s_get_apll_real_rate(int bits_per_sample, int sdm0, int sdm1, int
201188 }
202189 float fout = f_xtal * (sdm2 + sdm1 / 256.0f + sdm0 / 65536.0f + 4 );
203190 if (fout < APLL_MIN_FREQ || fout > APLL_MAX_FREQ ) {
204- return 9999999 ;
191+ return APLL_MAX_FREQ ;
205192 }
206193 float fpll = fout / (2 * (odir + 2 )); //== fi2s (N=1, b=0, a=1)
207- return fpll /( 8 * 4 * bits_per_sample ); //fbck = fi2s/bck_div
194+ return fpll /2 ;
208195}
209196
210197/**
211198 * @brief APLL calculate function, was described by following:
212199 * APLL Output frequency is given by the formula:
213- *
200+ *
214201 * apll_freq = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536)/((o_div + 2) * 2)
215202 * apll_freq = fout / ((o_div + 2) * 2)
216- *
203+ *
217204 * The dividend in this expression should be in the range of 240 - 600 MHz.
218205 * In rev. 0 of ESP32, sdm0 and sdm1 are unused and always set to 0.
219206 * * sdm0 frequency adjustment parameter, 0..255
220207 * * sdm1 frequency adjustment parameter, 0..255
221208 * * sdm2 frequency adjustment parameter, 0..63
222209 * * o_div frequency divider, 0..31
223- *
224- * The most accurate way to find the sdm0..2 and odir parameters is to loop through them all,
225- * then apply the above formula, finding the closest frequency to the desired one.
210+ *
211+ * The most accurate way to find the sdm0..2 and odir parameters is to loop through them all,
212+ * then apply the above formula, finding the closest frequency to the desired one.
226213 * But 256*256*64*32 = 134.217.728 loops are too slow with ESP32
227214 * 1. We will choose the parameters with the highest level of change,
228- * With 350MHz<fout<500MHz, we limit the sdm2 from 4 to 9,
215+ * With 350MHz<fout<500MHz, we limit the sdm2 from 4 to 9,
229216 * Take average frequency close to the desired frequency, and select sdm2
230- * 2. Next, we look for sequences of less influential and more detailed parameters,
217+ * 2. Next, we look for sequences of less influential and more detailed parameters,
231218 * also by taking the average of the largest and smallest frequencies closer to the desired frequency.
232219 * 3. And finally, loop through all the most detailed of the parameters, finding the best desired frequency
233220 *
234- * @param[in] rate The sample rate
221+ * @param[in] rate The I2S Frequency (MCLK)
235222 * @param[in] bits_per_sample The bits per sample
236223 * @param[out] sdm0 The sdm 0
237224 * @param[out] sdm1 The sdm 1
@@ -240,75 +227,64 @@ static float i2s_get_apll_real_rate(int bits_per_sample, int sdm0, int sdm1, int
240227 *
241228 * @return ESP_FAIL or ESP_OK
242229 */
243- static esp_err_t i2s_apll_calculate (int rate , int bits_per_sample , int * sdm0 , int * sdm1 , int * sdm2 , int * odir )
230+
231+ static esp_err_t i2s_apll_calculate_fi2s (int rate , int bits_per_sample , int * sdm0 , int * sdm1 , int * sdm2 , int * odir )
244232{
245- int _odir , _sdm0 , _sdm1 , _sdm2 , i ;
233+ int _odir , _sdm0 , _sdm1 , _sdm2 ;
246234 float avg ;
247235 float min_rate , max_rate , min_diff ;
248- if (rate < APLL_I2S_MIN_RATE ) {
236+ if (rate / bits_per_sample / 2 / 8 < APLL_I2S_MIN_RATE ) {
249237 return ESP_FAIL ;
250238 }
251- //check pre-define apll parameters
252- i = 0 ;
253- while (apll_predefine [i ][0 ]) {
254- if (apll_predefine [i ][0 ] == bits_per_sample && apll_predefine [i ][0 ] == rate ) {
255- * sdm0 = apll_predefine [i ][1 ];
256- * sdm1 = apll_predefine [i ][2 ];
257- * sdm2 = apll_predefine [i ][3 ];
258- * odir = apll_predefine [i ][4 ];
259- return ESP_OK ;
260- }
261- i ++ ;
262- }
239+
263240 * sdm0 = 0 ;
264241 * sdm1 = 0 ;
265242 * sdm2 = 0 ;
266243 * odir = 0 ;
267- min_diff = 99999 ;
244+ min_diff = APLL_MAX_FREQ ;
268245
269246 for (_sdm2 = 4 ; _sdm2 < 9 ; _sdm2 ++ ) {
270- max_rate = i2s_get_apll_real_rate (bits_per_sample , 255 , 255 , _sdm2 , 0 );
271- min_rate = i2s_get_apll_real_rate (bits_per_sample , 0 , 0 , _sdm2 , 31 );
247+ max_rate = i2s_apll_get_fi2s (bits_per_sample , 255 , 255 , _sdm2 , 0 );
248+ min_rate = i2s_apll_get_fi2s (bits_per_sample , 0 , 0 , _sdm2 , 31 );
272249 avg = (max_rate + min_rate )/2 ;
273250 if (abs (avg - rate ) < min_diff ) {
274251 min_diff = abs (avg - rate );
275252 * sdm2 = _sdm2 ;
276253 }
277254 }
278- min_diff = 99999 ;
255+ min_diff = APLL_MAX_FREQ ;
279256 for (_odir = 0 ; _odir < 32 ; _odir ++ ) {
280- max_rate = i2s_get_apll_real_rate (bits_per_sample , 255 , 255 , * sdm2 , _odir );
281- min_rate = i2s_get_apll_real_rate (bits_per_sample , 0 , 0 , * sdm2 , _odir );
257+ max_rate = i2s_apll_get_fi2s (bits_per_sample , 255 , 255 , * sdm2 , _odir );
258+ min_rate = i2s_apll_get_fi2s (bits_per_sample , 0 , 0 , * sdm2 , _odir );
282259 avg = (max_rate + min_rate )/2 ;
283260 if (abs (avg - rate ) < min_diff ) {
284261 min_diff = abs (avg - rate );
285262 * odir = _odir ;
286263 }
287264 }
288265
289- min_diff = 99999 ;
266+ min_diff = APLL_MAX_FREQ ;
290267 for (_sdm1 = 0 ; _sdm1 < 256 ; _sdm1 ++ ) {
291- max_rate = i2s_get_apll_real_rate (bits_per_sample , 255 , _sdm1 , * sdm2 , * odir );
292- min_rate = i2s_get_apll_real_rate (bits_per_sample , 0 , _sdm1 , * sdm2 , * odir );
268+ max_rate = i2s_apll_get_fi2s (bits_per_sample , 255 , _sdm1 , * sdm2 , * odir );
269+ min_rate = i2s_apll_get_fi2s (bits_per_sample , 0 , _sdm1 , * sdm2 , * odir );
293270 avg = (max_rate + min_rate )/2 ;
294271 if (abs (avg - rate ) < min_diff ) {
295272 min_diff = abs (avg - rate );
296273 * sdm1 = _sdm1 ;
297274 }
298275 }
299-
300- min_diff = 99999 ;
276+
277+ min_diff = APLL_MAX_FREQ ;
301278 for (_sdm0 = 0 ; _sdm0 < 256 ; _sdm0 ++ ) {
302- avg = i2s_get_apll_real_rate (bits_per_sample , _sdm0 , * sdm1 , * sdm2 , * odir );
279+ avg = i2s_apll_get_fi2s (bits_per_sample , _sdm0 , * sdm1 , * sdm2 , * odir );
303280 if (abs (avg - rate ) < min_diff ) {
304281 min_diff = abs (avg - rate );
305282 * sdm0 = _sdm0 ;
306283 }
307284 }
308-
285+
309286 return ESP_OK ;
310287}
311-
312288esp_err_t i2s_set_clk (i2s_port_t i2s_num , uint32_t rate , i2s_bits_per_sample_t bits , i2s_channel_t ch )
313289{
314290 int factor = (256 %bits )? 384 : 256 ; // According to hardware codec requirement(supported 256fs or 384fs)
@@ -402,7 +378,7 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, i2s_bits_per_sample_t b
402378 if (p_i2s_obj [i2s_num ]-> mode & I2S_MODE_RX ) {
403379
404380 save_rx = p_i2s_obj [i2s_num ]-> rx ;
405-
381+
406382 p_i2s_obj [i2s_num ]-> rx = i2s_create_dma_queue (i2s_num , p_i2s_obj [i2s_num ]-> dma_buf_count , p_i2s_obj [i2s_num ]-> dma_buf_len );
407383 if (p_i2s_obj [i2s_num ]-> rx == NULL ){
408384 ESP_LOGE (I2S_TAG , "Failed to create rx dma buffer" );
@@ -417,7 +393,7 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, i2s_bits_per_sample_t b
417393 i2s_destroy_dma_queue (i2s_num , save_rx );
418394 }
419395 }
420-
396+
421397 }
422398
423399 double mclk ;
@@ -453,18 +429,24 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, i2s_bits_per_sample_t b
453429 mclk = clkmInteger + denom * clkmDecimals ;
454430 bck = factor /(bits * channel );
455431 }
456- int sdm0 , sdm1 , sdm2 , odir ;
457- if (p_i2s_obj [i2s_num ]-> use_apll && i2s_apll_calculate (rate , bits , & sdm0 , & sdm1 , & sdm2 , & odir ) == ESP_OK ) {
432+ int sdm0 , sdm1 , sdm2 , odir , m_scale = 8 ;
433+ int fi2s_clk = rate * channel * bits * m_scale ;
434+ if (p_i2s_obj [i2s_num ]-> use_apll && p_i2s_obj [i2s_num ]-> fixed_mclk ) {
435+ fi2s_clk = p_i2s_obj [i2s_num ]-> fixed_mclk ;
436+ m_scale = fi2s_clk /bits /rate /channel ;
437+ }
438+ if (p_i2s_obj [i2s_num ]-> use_apll && i2s_apll_calculate_fi2s (fi2s_clk , bits , & sdm0 , & sdm1 , & sdm2 , & odir ) == ESP_OK ) {
439+ ESP_LOGD (I2S_TAG , "sdm0=%d, sdm1=%d, sdm2=%d, odir=%d" , sdm0 , sdm1 , sdm2 , odir );
458440 rtc_clk_apll_enable (1 , sdm0 , sdm1 , sdm2 , odir );
459441 I2S [i2s_num ]-> clkm_conf .clkm_div_num = 1 ;
460442 I2S [i2s_num ]-> clkm_conf .clkm_div_b = 0 ;
461443 I2S [i2s_num ]-> clkm_conf .clkm_div_a = 1 ;
462- I2S [i2s_num ]-> sample_rate_conf .tx_bck_div_num = 8 ;
463- I2S [i2s_num ]-> sample_rate_conf .rx_bck_div_num = 8 ;
444+ I2S [i2s_num ]-> sample_rate_conf .tx_bck_div_num = m_scale ;
445+ I2S [i2s_num ]-> sample_rate_conf .rx_bck_div_num = m_scale ;
464446 I2S [i2s_num ]-> clkm_conf .clka_en = 1 ;
465- double real_rate = i2s_get_apll_real_rate (bits , sdm0 , sdm1 , sdm2 , odir );
466- ESP_LOGI (I2S_TAG , "APLL: Req RATE: %d, real rate: %0.3f, BITS: %u, CLKM: %u, BCK : %u, MCLK: %0.3f, SCLK: %f, diva: %d, divb: %d" ,
467- rate , real_rate , bits , 1 , 8 , ( double ) I2S_BASE_CLK / mclk , real_rate * bits * channel , 1 , 0 );
447+ double fi2s_rate = i2s_apll_get_fi2s (bits , sdm0 , sdm1 , sdm2 , odir );
448+ ESP_LOGI (I2S_TAG , "APLL: Req RATE: %d, real rate: %0.3f, BITS: %u, CLKM: %u, BCK_M : %u, MCLK: %0.3f, SCLK: %f, diva: %d, divb: %d" ,
449+ rate , fi2s_rate / bits / channel / m_scale , bits , 1 , m_scale , fi2s_rate , fi2s_rate / 8 , 1 , 0 );
468450 } else {
469451 I2S [i2s_num ]-> clkm_conf .clka_en = 0 ;
470452 I2S [i2s_num ]-> clkm_conf .clkm_div_a = 63 ;
@@ -476,10 +458,10 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, i2s_bits_per_sample_t b
476458 ESP_LOGI (I2S_TAG , "PLL_D2: Req RATE: %d, real rate: %0.3f, BITS: %u, CLKM: %u, BCK: %u, MCLK: %0.3f, SCLK: %f, diva: %d, divb: %d" ,
477459 rate , real_rate , bits , clkmInteger , bck , (double )I2S_BASE_CLK / mclk , real_rate * bits * channel , 64 , clkmDecimals );
478460 }
479-
461+
480462 I2S [i2s_num ]-> sample_rate_conf .tx_bits_mod = bits ;
481463 I2S [i2s_num ]-> sample_rate_conf .rx_bits_mod = bits ;
482-
464+
483465 // wait all writing on-going finish
484466 if ((p_i2s_obj [i2s_num ]-> mode & I2S_MODE_TX ) && p_i2s_obj [i2s_num ]-> tx ) {
485467 xSemaphoreGive (p_i2s_obj [i2s_num ]-> tx -> mux );
@@ -930,7 +912,7 @@ static esp_err_t i2s_param_config(i2s_port_t i2s_num, const i2s_config_t *i2s_co
930912 I2S [i2s_num ]-> conf .rx_right_first = 0 ;
931913 I2S [i2s_num ]-> conf .rx_slave_mod = 0 ; // Master
932914 I2S [i2s_num ]-> fifo_conf .rx_fifo_mod_force_en = 1 ;
933-
915+
934916 if (i2s_config -> mode & I2S_MODE_SLAVE ) {
935917 I2S [i2s_num ]-> conf .rx_slave_mod = 1 ;//RX Slave
936918 }
@@ -1001,6 +983,7 @@ static esp_err_t i2s_param_config(i2s_port_t i2s_num, const i2s_config_t *i2s_co
1001983 }
1002984
1003985 p_i2s_obj [i2s_num ]-> use_apll = i2s_config -> use_apll ;
986+ p_i2s_obj [i2s_num ]-> fixed_mclk = i2s_config -> fixed_mclk ;
1004987 return ESP_OK ;
1005988}
1006989
0 commit comments