Update esp32_i2s_parallel_v2.c

This commit is contained in:
mrfaptastic 2021-02-19 09:13:33 +00:00
parent f0999beb51
commit 1c88590d6e

View file

@ -1,14 +1,14 @@
/* /*
* ESP32_I2S_PARALLEL_V2 (Version 2) * ESP32_I2S_PARALLEL_V2 (Version 2)
* *
* Author: Mrfaptastic - https://github.com/mrfaptastic/ * Author: Mrfaptastic - https://github.com/mrfaptastic/
* *
* Description: Pointless reimplementation of ESP32 DMA setup for no reason than * Description: Pointless reimplementation of ESP32 DMA setup for no reason than
* to better understand the internals of the ESP32 SoC DMA. * to better understand the internals of the ESP32 SoC DMA.
* *
* Credits: Based on the merging of three ideas: * Credits: Based on the merging of three ideas:
* 1) https://www.esp32.com/viewtopic.php?f=17&t=3188 for original ref. implementation * 1) https://www.esp32.com/viewtopic.php?f=17&t=3188 for original ref. implementation
* 2) https://www.esp32.com/viewtopic.php?f=18&p=55305#p55305 for APLL overclock (no longer used) * 2) https://www.esp32.com/viewtopic.php?f=18&p=55305#p55305 for APLL overclock (no longer used)
* 3) https://github.com/TobleMiner/esp_i2s_parallel for a cleaner implementation * 3) https://github.com/TobleMiner/esp_i2s_parallel for a cleaner implementation
* *
*/ */
@ -198,7 +198,7 @@ esp_err_t i2s_parallel_driver_install(i2s_port_t port, i2s_parallel_config_t* co
// Enable "One datum will be written twice in LCD mode" - for some reason, // Enable "One datum will be written twice in LCD mode" - for some reason,
// if we don't do this in 8-bit mode, data is updated on half-clocks not clocks // if we don't do this in 8-bit mode, data is updated on half-clocks not clocks
if(conf->sample_width == I2S_PARALLEL_WIDTH_8) if(conf->sample_width == I2S_PARALLEL_WIDTH_8)
dev->conf2.lcd_tx_wrx2_en=1; dev->conf2.lcd_tx_wrx2_en=1;
// Setup i2s clock // Setup i2s clock
dev->sample_rate_conf.val = 0; dev->sample_rate_conf.val = 0;
@ -208,7 +208,7 @@ esp_err_t i2s_parallel_driver_install(i2s_port_t port, i2s_parallel_config_t* co
dev->sample_rate_conf.tx_bits_mod = bus_width; dev->sample_rate_conf.tx_bits_mod = bus_width;
dev->sample_rate_conf.rx_bck_div_num = 1; dev->sample_rate_conf.rx_bck_div_num = 1;
dev->sample_rate_conf.tx_bck_div_num = 1; // datasheet says this must be 2 or greater (but 1 seems to work) dev->sample_rate_conf.tx_bck_div_num = 1; // datasheet says this must be 2 or greater (but 1 seems to work)
// note: because it's 1 here, not 2, we need to clkm_div_num = clkm_div_num * 2 // note: because it's 1 here, not 2, we need to clkm_div_num = clkm_div_num * 2
// No support for fractional dividers (could probably be ported from official serial i2s driver though) // No support for fractional dividers (could probably be ported from official serial i2s driver though)
// //
@ -220,14 +220,14 @@ esp_err_t i2s_parallel_driver_install(i2s_port_t port, i2s_parallel_config_t* co
// 16bit parallel I2S = calculated clk_div_main (per line ~142) of 4 // 16bit parallel I2S = calculated clk_div_main (per line ~142) of 4
dev->clkm_conf.val=0; // Clear the clkm_conf struct dev->clkm_conf.val=0; // Clear the clkm_conf struct
dev->clkm_conf.clka_en=0; // Use the 160mhz system clock (PLL_D2_CLK) when '0' dev->clkm_conf.clka_en=0; // Use the 160mhz system clock (PLL_D2_CLK) when '0'
dev->clkm_conf.clkm_div_b=0; // Page 310 of Technical Reference Manual - Clock numerator dev->clkm_conf.clkm_div_b=0; // Page 310 of Technical Reference Manual - Clock numerator
dev->clkm_conf.clkm_div_a=0; // Page 310 of Technical Reference Manual - Clock denominator dev->clkm_conf.clkm_div_a=0; // Page 310 of Technical Reference Manual - Clock denominator
// //
// Final Mhz output = // Final Mhz output =
// Output = 80000000L / tx_bck_div_num / (clkm_div_num + (clkm_div_b/clkm_div_a) ) // Output = 80000000L / tx_bck_div_num / (clkm_div_num + (clkm_div_b/clkm_div_a) )
// Note: clkm_div_num must only be set AFTER clkm_div_b, clkm_div_a, etc. Or weird things happen! // Note: clkm_div_num must only be set AFTER clkm_div_b, clkm_div_a, etc. Or weird things happen!
// dev->clkm_conf.clkm_div_num = (clk_div_main*2)+1; // dev->clkm_conf.clkm_div_num = (clk_div_main*2)+1;
@ -277,20 +277,20 @@ esp_err_t i2s_parallel_driver_install(i2s_port_t port, i2s_parallel_config_t* co
assert(i2s_state[port] != NULL); assert(i2s_state[port] != NULL);
i2s_parallel_state_t *state = i2s_state[port]; i2s_parallel_state_t *state = i2s_state[port];
state->desccount_a = conf->desccount_a; state->desccount_a = conf->desccount_a;
state->desccount_b = conf->desccount_b; state->desccount_b = conf->desccount_b;
state->dmadesc_a = conf->lldesc_a; state->dmadesc_a = conf->lldesc_a;
state->dmadesc_b = conf->lldesc_b; state->dmadesc_b = conf->lldesc_b;
state->i2s_interrupt_port_arg = port; // need to keep this somewhere in static memory for the ISR state->i2s_interrupt_port_arg = port; // need to keep this somewhere in static memory for the ISR
// Get ISR setup // Get ISR setup
esp_err_t err = esp_intr_alloc(irq_source, esp_err_t err = esp_intr_alloc(irq_source,
(int)(ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_LEVEL1), (int)(ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_LEVEL1),
irq_hndlr, irq_hndlr,
&state->i2s_interrupt_port_arg, NULL); &state->i2s_interrupt_port_arg, NULL);
if(err) { if(err) {
return err; return err;
} }
// Setup interrupt handler which is focussed only on the (page 322 of Tech. Ref. Manual) // Setup interrupt handler which is focussed only on the (page 322 of Tech. Ref. Manual)