i2s parallel "PLL_D2_CLK" problem
Posted: Mon Oct 28, 2019 6:06 am
Hi,
I created the function below to set the i2s clock frequency.
I am using the example "https://github.com/espressif/esp-iot-so ... /i2s_lcd.c".
If i send a 1000 bytes of a test buffer this happens:
*Using "PLL_D2_CLK".
With 20Mhz only send 8 bytes on clock and stop. Data appear to output all without clock.
With 10Mhz only send first time the 1000 bytes buffer size and stop.
With 5Mhz works.
*Using "APLL_CLK" ( another function similar that )
With 10MHz works Ok, but data line seems to take 10us after clock stop to enter in "idle state".
esp32: 240 Mhz clock.
esp-idf.
Thank's.
I created the function below to set the i2s clock frequency.
I am using the example "https://github.com/espressif/esp-iot-so ... /i2s_lcd.c".
If i send a 1000 bytes of a test buffer this happens:
*Using "PLL_D2_CLK".
With 20Mhz only send 8 bytes on clock and stop. Data appear to output all without clock.
With 10Mhz only send first time the 1000 bytes buffer size and stop.
With 5Mhz works.
*Using "APLL_CLK" ( another function similar that )
With 10MHz works Ok, but data line seems to take 10us after clock stop to enter in "idle state".
esp32: 240 Mhz clock.
esp-idf.
Code: Select all
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief Set WR# frequency by setting i2s_clock module parameters. Select PLL_D2_CLK clock source.
* @param i2s_lcd_handle i2s_lcd_handle_t. "typedef void* i2s_lcd_handle_t." but "i2s_lcd_handle_t" are type "i2s_lcd_t". i2s_lcd_t define i/os and port "I2S_NUM_0" or "I2S_NUM_1".
* @param N i2s_clock equation calculation
* @param b i2s_clock equation calculation
* @param a i2s_clock equation calculation
* @param M i2s_clock equation calculation
*
* Clock source are PLL_D2_CLK. Not APLL_CLK.
* PLL_D2_CLK = 160 MHz fixed internal microcontroller(esp32) clock source.
* WR# clock used in LCD Mode 8080 bus.
*
* WR# frequency calculation shown below:
* f(i2s) = f(PLL_D2_CLK)/(N+(b/a)).
* N = REG_CLKM_DIV_NUM[7:0]. N >= 2.
* b = I2S_CLKM_DIV_B[5:0].
* a = I2S_CLKM_DIV_A[5:0].
*
* Bit clock BCK f(bck) = f(i2s)/M.
* M = I2S_TX_BCK_DIV_NUM[5:0]. M >= 2.
* In LCD mode, WR# freq = f(bck)/2.
*
* So,
* WR# freq = f(PLL_D2_CLK)/(N+(b/a))/M/2.
* WR# freq = f(PLL_D2_CLK)/(REG_CLKM_DIV_NUM[7:0]+(I2S_CLKM_DIV_B[5:0]/I2S_CLKM_DIV_A[5:0]))/(I2S_TX_BCK_DIV_NUM[5:0])/2.
*
* I2S Clock parameters -> N, b, a, M.
* N: the value is 2 ~ 255. N >= 2.
* b: the value is 0 ~ 63.
* a: the value is 0 ~ 63.
* M: the value is 2 ~ 63. M >= 2.
*
* Para,
* WR# freq = 20MHz.
* WR# freq = f(PLL_D2_CLK)/(N+(b/a))/M/2.
* WR# freq = ( 160MHz )/(2+(0/1))/2/2.
* WR# freq = ( 160MHz )/8.
* WR# freq = 20MHz.
*
* N = 2
* b = 0
* a = 1
* M = 2
*
* i2s_set_bck_clk_PLL_D2_CLK ( ili9341, 2, 0, 1, 2 );
*/
void i2s_set_bck_clk_PLL_D2_CLK ( i2s_lcd_handle_t i2s_lcd_handle, uint8_t N, uint8_t b, uint8_t a, uint8_t M )
{
i2s_lcd_t *i2s_lcd = (i2s_lcd_t *)i2s_lcd_handle;
i2s_port_t i2s_num = i2s_lcd->i2s_port;
if ( i2s_num >= I2S_NUM_MAX ) printf("Error: i2s_num = %u. i2s_num >= 2\n", i2s_num );
if ( N < 2 ) printf("Error: N = %u. N < 2\n", N );
if ( b > 63 ) printf("Error: b = %u. b > 63\n", b );
if ( a > 63 ) printf("Error: a = %u. a > 63\n", a );
if ( M < 2 || M > 63) printf("Error: M = %u. range allowed for M are: 2 =< M <= 63\n", M );
I2S[i2s_num]->clkm_conf.clk_en = 0; // Disable i2s module clock ????
I2S[i2s_num]->clkm_conf.clkm_div_num = N;
I2S[i2s_num]->clkm_conf.clkm_div_b = b;
I2S[i2s_num]->clkm_conf.clkm_div_a = a;
I2S[i2s_num]->sample_rate_conf.tx_bck_div_num = M;
I2S[i2s_num]->clkm_conf.clka_en = 0; // select PLL_D2_CLK. Digital Multiplexer that select between APLL_CLK or PLL_D2_CLK.
I2S[i2s_num]->clkm_conf.clk_en = 1; // Enable i2s module clock ????
}
Thank's.