Anyone knows how to use I2S in Master Rx in LCD mode

huykhacnguyen
Posts: 11
Joined: Mon May 07, 2018 2:38 pm

Anyone knows how to use I2S in Master Rx in LCD mode

Postby huykhacnguyen » Wed Jun 06, 2018 1:45 pm

Hi all,

I would like to have ESP32 to read 8-bit data from external FIFO memory. Basically, ESP32 needs to provide clock to the FIFO and read 8 data lines from the FIFO. I plan to utilize I2S in LCD mode and in Master Rx mode. Does anyone know how to configure I2S in Master RX and LCD mode?

Thanks,
Huy

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: Anyone knows how to use I2S in Master Rx in LCD mode

Postby kolban » Wed Jun 06, 2018 4:32 pm

Howdy my friend,
I am working on a similar puzzle but using I2S in LCD/Camera mode to receive incoming data. I've got it working just fine but only for the first batch of data ... I haven't been able to reset it to read subsequent batches of data ... see:

https://github.com/espressif/esp-idf/issues/2027

Ive been pouring over the technical reference manual and studying the camera sample found here:

https://github.com/igrr/esp32-cam-demo

If we ignore the fact that the sample is a camera ... the principle of DMA written externally sourced parallel data still applies. Reading through the code is quite painful and one has to have a copy of the technical reference manual to one side and make LOTS and LOTS of notes. The good news is that I personally think I have it about understood. My next challenge will be how to write that down and communicate it clearly to good folks like yourself. My plan is to get as much as I can understood and then capture it in my book of notes in more detail. While I have the core understood, I wanted to get this last part done (the ability to read a second stream of DMA input) before I call it done ... at that point I'll make available a sample.

Now if you (or others) have made a good faith attempt at trying to understand how it all works, I'll be happy to make time and try and discuss details ... but at this stage I'm not ready to talk about it from the ground up ... again ... if you have studied it and get stuck, I'll be delighted to fill in any blanks I know or work with you to fill in any common blanks neither of us know.

Maybe we can encourage our friends at Espressif to make an investment in time with us to answer questions and we'll pay it forward with detailed write-ups?
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

huykhacnguyen
Posts: 11
Joined: Mon May 07, 2018 2:38 pm

Re: Anyone knows how to use I2S in Master Rx in LCD mode

Postby huykhacnguyen » Thu Jun 07, 2018 2:07 pm

Hi kolban,

Thanks for the reply. It gives hope that someone can help me out :)
Regards to using I2S in Master Rx in LCD mode, I think it is not supported yet because the datasheet says LCD Master Transmitter and Camera Slave Receiver when it mentions LCD mode of I2S. Actually, I tried to modify this demo code https://github.com/har-in-air/ESP32-LCD ... aster/docs in which I enable RX operation (eg, dev->conf.rx_start = 1;) and check clock signal output, the result is no clock output. When I re-enable TX operation (eg, dev->conf.tx_start=1) like the demo, the clock signal is avaiable. That comes to a conclusion that LCD mode does not support RX now.
Next, I tried to use Camera Slave mode, I modified the demo https://github.com/igrr/esp32-cam-demo in which I change I2S0.conf.rx_slave_mod to 0 for Master RX mode and configure clock pin to OUTPUT and map to I2S0O_WS_OUT_IDX signal.The result is that ESP32 can go to I2S interrupt when DMA transfer done as usual but when I probe the clock output signal, there are few pulses which does not make sense to me

Here is my code to init I2S:

Code: Select all

static void cam_i2s_init()
{
  // Enable and configure I2S peripheral
  periph_module_enable(PERIPH_I2S0_MODULE);
  // Toggle some reset bits in LC_CONF register
  // Toggle some reset bits in CONF register
  i2s_conf_reset();
  // Enable slave mode (sampling clock is external)
  //I2S0.conf.rx_slave_mod = 1;
  I2S0.conf.rx_slave_mod = 0;
  // Enable parallel mode
  I2S0.conf2.lcd_en = 1;
  // Use HSYNC/VSYNC/HREF to control sampling
  I2S0.conf2.camera_en = 1;
  // Configure clock divider
  I2S0.clkm_conf.val = 0;
  I2S0.clkm_conf.clka_en = 0;
  I2S0.clkm_conf.clkm_div_a = 63;
  I2S0.clkm_conf.clkm_div_b = 63;
  I2S0.clkm_conf.clkm_div_num = 80000000L/2000000L;
  // FIFO will sink data to DMA
  I2S0.fifo_conf.dscr_en = 1;
  // FIFO configuration
  I2S0.fifo_conf.rx_fifo_mod = SM_0A0B_0C0D;			//16-bit single channel
  I2S0.fifo_conf.rx_fifo_mod_force_en = 1;
  I2S0.conf_chan.rx_chan_mod = 1;			//only capture Left channel data
  // Clear flags which are used in I2S serial mode
  I2S0.sample_rate_conf.rx_bits_mod = 0;
  I2S0.conf.rx_right_first = 0;				//not skip first sample
  I2S0.conf.rx_msb_right = 0;				//LSB byte received first
  I2S0.conf.rx_msb_shift = 0;				//use MSB Alignment Standard
  I2S0.conf.rx_mono = 0;					//disable mono mode in PCM standard mode
  I2S0.conf.rx_short_sync = 0;				//disable receiver in PCM standard mode
  I2S0.timing.val = 0;

  // Allocate I2S interrupt, keep it disabled
  esp_intr_alloc(ETS_I2S0_INTR_SOURCE,
		  	  	  ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_LEVEL1 | ESP_INTR_FLAG_IRAM,
			  &i2s_isr, NULL, &CameraInfo.i2s_intr_handle);

}
And the code to init I2S pins (I fixed HSYNC, H_ENABLE signals to 1 and only connect VSYNC signal)

Code: Select all

static void gpio_setup_out(int gpio, int sig, int inv) {
    if (gpio == -1) return;
    PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO);
    gpio_set_direction(gpio, GPIO_MODE_DEF_OUTPUT);
    gpio_matrix_out(gpio, sig, inv, false);
	}
static void cam_gpio_init()
{
  gpio_num_t pins[] = {
  			CAM_DATA7_IO, CAM_DATA6_IO, CAM_DATA5_IO,
  			CAM_DATA4_IO, CAM_DATA3_IO,	CAM_DATA2_IO,
  			CAM_DATA1_IO, CAM_DATA0_IO, CAM_VSYNC_IO,
  };

    gpio_config_t gpio_conf = {
            .mode = GPIO_MODE_INPUT,
            .pull_up_en = GPIO_PULLUP_ENABLE,
            .pull_down_en = GPIO_PULLDOWN_DISABLE,
            .intr_type = GPIO_INTR_DISABLE
    };
    for (int i = 0; i < sizeof(pins) / sizeof(gpio_num_t); ++i) {
        if (rtc_gpio_is_valid_gpio(pins[i])) {
            rtc_gpio_deinit(pins[i]);
        }
        gpio_conf.pin_bit_mask = 1LL << pins[i];
        gpio_config(&gpio_conf);
    }

    gpio_conf.pin_bit_mask = 1LL << 4;
    gpio_conf.mode = GPIO_MODE_OUTPUT;
    gpio_config(&gpio_conf);
    
    // Route input GPIOs to I2S peripheral using GPIO matrix
    gpio_matrix_in(CAM_DATA0_IO, I2S0I_DATA_IN0_IDX, false);
    gpio_matrix_in(CAM_DATA1_IO, I2S0I_DATA_IN1_IDX, false);
    gpio_matrix_in(CAM_DATA2_IO, I2S0I_DATA_IN2_IDX, false);
    gpio_matrix_in(CAM_DATA3_IO, I2S0I_DATA_IN3_IDX, false);
    gpio_matrix_in(CAM_DATA4_IO, I2S0I_DATA_IN4_IDX, false);
    gpio_matrix_in(CAM_DATA5_IO, I2S0I_DATA_IN5_IDX, false);
    gpio_matrix_in(CAM_DATA6_IO, I2S0I_DATA_IN6_IDX, false);
    gpio_matrix_in(CAM_DATA7_IO, I2S0I_DATA_IN7_IDX, false);
    gpio_matrix_in(CAM_VSYNC_IO, I2S0I_V_SYNC_IDX, true);		
    gpio_matrix_in(0x38, I2S0I_H_SYNC_IDX, false);
    gpio_matrix_in(0x38, I2S0I_H_ENABLE_IDX, false);
    gpio_setup_out(CAM_PCLK_IO, I2S0O_WS_OUT_IDX, false);
}
I also attach the waveform.

Should I miss anything?

HuyK
Attachments
I2S_Camera.png
I2S_Camera.png (22.63 KiB) Viewed 8965 times

huykhacnguyen
Posts: 11
Joined: Mon May 07, 2018 2:38 pm

Re: Anyone knows how to use I2S in Master Rx in LCD mode

Postby huykhacnguyen » Thu Jun 07, 2018 2:23 pm

I check the datasheet, it says about Camera Slave Receive mode, it seems that ESP32 could not support Camera Master Receive mode :(
If so, I need to build an external oscillator that supplies clock to both I2S's clock and FIFO data read clock.

User avatar
E.U.A.
Posts: 18
Joined: Wed Feb 05, 2020 2:24 am

Re: Anyone knows how to use I2S in Master Rx in LCD mode

Postby E.U.A. » Wed Feb 05, 2020 3:20 pm

I couldn't make it either.
But you can generate an internal clock using PORTD (LedC) and feed it.
I make it here.
https://esp32.com/viewtopic.php?f=19&t= ... c21e3e25a6
Admin of the SamyGO.tv, Samsung TV Hacking Project

embedded-creations
Posts: 13
Joined: Thu Feb 15, 2018 11:22 am

Re: Anyone knows how to use I2S in Master Rx in LCD mode

Postby embedded-creations » Thu Dec 17, 2020 11:02 am

I have an Arduino sketch that receives 1-bit serial data (received as parallel) or up to 8-bit parallel data with an external clock, and it works receiving a continuous stream of data using DMA. The details are in the i2s_in.* files, but unfortunately aren't well commented. I found a series of config values that worked through a combination trial and error and looking at some I2S camera receive code and once it worked well enough I moved onto other parts of the project and didn't complete the documentation, and have now forgotten most of the details.

https://github.com/Pixelvation/PixelvationEngine_HUB75

Some limitations: I only care about up to 8 bits of parallel data, but camera mode seems fixed at 16 bit width. There is a `lcd_tx_wrx2_en` bit that enables 8-bit operation in LCD mode, but it only seems to apply to TX mode and not RX, and there's no RX equivalent. My buffer is filled 16 bits at a time, but only 8 of those are useful. I can't set a DMA buffer size larger than 256 bytes (only 128 useful), which is much smaller than I want to store, and I'm not sure why a larger value doesn't work.

Who is online

Users browsing this forum: No registered users and 194 guests