Page 1 of 2

i2s parallel interface to monochrome lcd with 4bit data bus

Posted: Sun Oct 08, 2017 5:14 am
by pataga
Thought I would post as a separate topic rather than reply to the i2s parallel led panel thread as it's a bit of a digression.

I have a few monochrome 240x160 lcds lying around that I have used with a Microchip PIC24 microcontroller with a built-in lcd controller peripheral.

The lcd interface signals are a 4bit data bus (4 horizontal 1-bit pixels are transmitted for every clock), uninterrupted clock , hsync (this is just a pulse to latch a line of pixels), a FR signal that toggles every frame, and a one line wide vsync pulse per frame. Have attached a grab of the signals ( chan0=VS, chan1=HS, chan2=FR, chan3=CLK )
vs.png
vs.png (82.01 KiB) Viewed 16573 times
xck_hs_timing.png
xck_hs_timing.png (118.59 KiB) Viewed 16573 times
I would like to try interfacing these panels with ESP32. Looking at the led panel showcase code comments, my understanding is that I should simply treat the HS, FR and VS signals encoded into the data as additional bits, so that gives me a 7bit parallel i2s interface.

If this is OK, then I would have two complete frames of pixel data, with one byte dedicated for every 4 horizontal pixels. One frame being drawn to by the application, the other frame being transmitted to the lcd panel, in ping-pong mode to avoid artifacts. Each frame would be (240/4)x160 = 9600bytes.

If all of the above is technically OK, my question is : what is the minimum parallel width supported by the ESP32 i2s lcd mode?

Can I dma a byte buffer encoded with 4bits of data plus the HS, FR, VS bits ? Just want to make sure this is possible before I tear my hair out trying to figure out the dma + i2s fifo interaction :).

Padding extra bytes for each 4bit data packet would be a huge waste.

Would appreciate any tips - I will post the code on github if I can get it working as outlined above. Thanks!

Re: i2s parallel interface to monochrome lcd with 4bit data bus

Posted: Sun Oct 08, 2017 2:34 pm
by ESP_Sprite
Yes, it can do 8-bit mode - I think it's described somewhere in the TRM, if not I may have a little something still lying around from the days the ESP32 still lived in an FPGA I may be able to crib something from. Be aware that the I2S peripheral reads in 32-bit words, and the order within those words it sends out the data is slightly weird - for instance, in 16-bit mode it sends the _high_ 16-bit of a word first. (Something I forgot while writing the LED-screen example, hence the weird assertion that my screen swaps every other row.)

Re: i2s parallel interface to monochrome lcd with 4bit data bus

Posted: Mon Oct 09, 2017 8:33 am
by pataga
ESP_Sprite, that's good news. I will go through the TRM. I did have a look a couple days ago, but at first glance did not see anything specific to 8bit bus width.

I would appreciate it if you could dig up and post your 8bit parallel test code. I will have additional questions anyway, and it would save you some additional posts if I can try to understand the code before bugging you again !

:)

Re: i2s parallel interface to monochrome lcd with 4bit data bus

Posted: Mon Oct 09, 2017 9:20 am
by pataga
Had a look at the TRM again, it mentions on pg 242 that the LCD mode databus is 24bits. I don't see any specific mention of 8bit or 16bit bus width.

Also, the two frame transmit modes "forms" don't seem to map to my scenario. Assuming D0, D1 ... are data packets, I would need one clock for each 8bit packet, that seems to map to form 2. But the TRM shows that as repeating packets D0, D1, D0, D1 etc.

Re: i2s parallel interface to monochrome lcd with 4bit data bus

Posted: Tue Oct 10, 2017 1:45 am
by ESP_Sprite
That is one option of sending things; I2S_LCD_TX_WRX2_EN and I2S_LCD_TX_SDX2_EN can be tweaked to get the non-repeating variant. I think getting 8-bits output may be as simple as setting the amount of bits in the I2S peripheral to 8, but I'd need to check that.

Edit: Dug up some ancient email about 8-bit mode; we'll incorporate this in the TRM and whatever driver we come up with, but maybe it helps you now:
1.you should use i2s1 module not i2s0
2.the output data bits are I2S1O_DATA_OUT[7:0], (only 8bits mode is bit7~0,other mode not change )
3. as I said, the order of 8-bit bytes per 32-bit word may be weird
4.set I2S_TX_FIFO_MOD_FORCE_EN =1
tx_chan_mod = 1;
tx_fifo_mod = 1;
I2S_LCD_TX_WRX2_EN_S =1;
I2S_LCD_TX_SDX2_EN_S =0;

Re: i2s parallel interface to monochrome lcd with 4bit data bus

Posted: Tue Oct 10, 2017 10:40 am
by pataga
Thanks, I will have a go at it !

Re: i2s parallel interface to monochrome lcd with 4bit data bus

Posted: Tue Oct 10, 2017 2:13 pm
by pataga
Hey, just wanted to confirm if this piece of code from i2s_parallel.c (led_panel project)

Code: Select all

void i2s_parallel_flip_to_buffer(i2s_dev_t *dev, int bufid) {
    int no = i2snum(dev);
    if (i2s_state[no] == NULL) return;
    lldesc_t *active_dma_chain;
    if (bufid == 0) {
        active_dma_chain = (lldesc_t*)&i2s_state[no]->dmadesc_a[0];
		} 
	else {
        active_dma_chain = (lldesc_t*)&i2s_state[no]->dmadesc_b[0];
		}

    i2s_state[no]->dmadesc_a[i2s_state[no]->desccount_a-1].qe.stqe_next = active_dma_chain;
    i2s_state[no]->dmadesc_b[i2s_state[no]->desccount_b-1].qe.stqe_next = active_dma_chain;
	}
should be

Code: Select all

void i2s_parallel_flip_to_buffer(i2s_dev_t *dev, int bufid) {
    int no = i2snum(dev);
    if (i2s_state[no] == NULL) return;
    lldesc_t *active_dma_chain;
    if (bufid == 0) {
        	active_dma_chain = (lldesc_t*)&i2s_state[no]->dmadesc_a[0];
   	 	i2s_state[no]->dmadesc_a[i2s_state[no]->desccount_a-1].qe.stqe_next = active_dma_chain;
		} 
	else {
        	active_dma_chain = (lldesc_t*)&i2s_state[no]->dmadesc_b[0];
    		i2s_state[no]->dmadesc_b[i2s_state[no]->desccount_b-1].qe.stqe_next = active_dma_chain;
		}

	}
and secondly, does the DMA count max of 4096 still hold ? I dimly recollect seeing a recent discussion about this, and changes to the esp-idf but can't find the relevant thread again. Think it was something to do with lcd spi with dma.

Re: i2s parallel interface to monochrome lcd with 4bit data bus

Posted: Wed Oct 11, 2017 2:36 am
by ESP_Sprite
No, it doesn't: the I2S DMA engine will finish sending out the current buffer and when it gets to the last element, instead of restarting the chain it was on it will load the first descriptor of the new buffer and keep sending that out. No need to tweak the registers yourself.

The maximum of 4096 still holds for DMA transfers because it's a hardware limit (the length field is only 12 bit). The SPI driver used to carry the same limitation because it used to use only one DMA descriptor, but that was fixed by chaining DMA descriptors in the driver itself. The I2S code also does this, by the way; there's no maximum to the buffer size you feed into i2s_parallel_setup().

Re: i2s parallel interface to monochrome lcd with 4bit data bus

Posted: Wed Oct 11, 2017 10:26 am
by pataga
I have a stable image on the LCD, and the pixel left-to-right ordering corresponds to the byte ordering in the frame buffer. ESP_Sprite, thanks for the help !

Just have a problem with the line synchronization. col 0 of the image is offset to the right in the LCD. In my grab of the original working lcd signals, the HS and VS signals are not synchronous to the clock edge, they go high when the clock is low, and the HS line latch pulse is less than 1/2 clock period.

With this i2s setup all the signals are synchronous to the clock edge and HS pulse width is one clock period.

Hopefully can find something that the LCD will work with, fingers crossed.
IMG_20171011_152430.jpg
IMG_20171011_152430.jpg (133.92 KiB) Viewed 16476 times

Re: i2s parallel interface to monochrome lcd with 4bit data bus

Posted: Wed Oct 11, 2017 10:36 am
by pataga
Also, the clock frequency needs to be configured as twice the required clock frequency.