Atmega 1284 Reading ILI9341 GRAM

Go To Last Post
21 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, I have a problem reading the graphic RAM of a 3.2 inch display based on ILI9341. It is not quite an AVR related issue but I am not using Arduino so I have no other place to ask for help. 

I am already working on this since several days with no results and I started to think that my display is probably "write only". The only response I get back from the display is the last command I am sending before reading, in my case here I get 0x2E on lower data port and 0x00 on higher data port, no matter how many (dummy) readings I am taking.

Sending data and commands to the display works for writing so I think there is no problem with the code. I have even tried to read the display ID but it doesn't work, I get back the last command only (0x04).

I don't think it may be a random hardware problem either, I have 2 identical displays and both are doing the same. 

 

Below is a piece of simple code used only for reading tests. The response i get with this code is 0x2E 0x00 0x2E 0x00 0x2E 0x00, as I have mentioned alredy 0x2E is the memory read command. A picture with the display attached. 

 

 

glcd_pixel(10, 10, red);
	glcd_setX(10, 10);
	glcd_setY(10, 10);
	glcd_sendCmd(ILI9341_CMD_MEMORY_READ);
	//glcd_sendCmd(0x04)
	LCDPort_Input();
	lcd_cs(0);
	lcd_rs(1);
	//lcd_wr(1);
	//lcd_rd(1);
	lcd_rd(0);
	data[0] = LCD_DATA_PORT_L;
	lcd_rd(1);
	lcd_rd(0);
	data[0] = LCD_DATA_PORT_L;
	data[1] = LCD_DATA_PORT_H;
	lcd_rd(1);
	lcd_rd(0);
	data[2] = LCD_DATA_PORT_L;
	data[3] = LCD_DATA_PORT_H;
	lcd_rd(1);
	lcd_rd(0);
	data[4] = LCD_DATA_PORT_L;
	data[5] = LCD_DATA_PORT_H;
	lcd_rd(1);
	lcd_cs(1);

	LCDPort_Output();

 

 

 

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

VIO47 wrote:
I have a problem reading the graphic RAM of a 3.2 inch display based on ILI9341

Most if not all AVR's don't have the ram available to read a display that size!?

 

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi ki0bk, I know this and I do not intend to save the entire GRAM in the AVR's memory but only reading piece by piece and save them on SD card. I think I know how how to handle the data only if I would get some data from the display.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Look at library code.   It is very straightforward.

 

Are you using 8080-16 or 8080-8 interface ?

The ILI9341 can write to GRAM in 5-6-5 format.  But it can only read in 6-6-6 format.

 

Your code looks correct.  

8080-8: You should get xRxGxB in your data[6] buffer.  i.e. one pixel

8080-16: You should get RGBRGB in your data[6] buffer.  i.e. two pixels

 

You will need to convert the RGB 666 into 565 for internal use.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi David,

Thank you for your reply.

I am using 16 bit interface and I have already checked the library code and the datasheet so many time, it should be so easy indeed.  I understand how the data should come from LCD and how I should convert it but the problem is that I do not get GRAM data but only the last command I am sending before starting to read. I am always getting these pair of bytes 0x2E 0x00. If I convert them and write in a file I get a picture with a nice "navy" color background :)

It was somebody who posted a similar issue few years ago but the discussion went to another direction and there was no useful answer for this issue. I am not even sure now it is an ILI9341 since i cannot read the ID.

Last Edited: Wed. Apr 29, 2020 - 03:16 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

VIO47 wrote:
I am not even sure now it is an ILI9341 since i cannot read the ID.

 

If you see 0x003E it means you have a write-only display.

 

If you can't read the ID you will never read the GRAM.    The display is 3.3V.   The ILI9341 is 3.3V.    Most Arduino 5V Adapter shields make no attempt to enable the LCD_RD pin.

 

Yes,  it is very straightforward to use LCD_RD with LVC245A buffer chips bi-directionally as Nature intended.

But it is even better to use 3.3V GPIO as God intended.

 

There is no point in pursuing any serious operation if you can't identify the controller.    (I could give you a few tips for distinguishing different controllers on a write-only board)

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am not using Arduino. It is just a 1284 on a pcb I have made, powered at 3,3 volts. Probably the display is write-only, at least now I know there are such displays. It is a lottery with these Chinese stuff. It is just a hobby project to make my life easier during the quarantine. I have other ideas too with this display but unfortunately I have to avoid reading GRAM.

Thank you very much and be safe!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

VIO47 wrote:
I am not using Arduino. It is just a 1284 on a pcb I have made, powered at 3,3 volts.

 

That is good news.   Arduino users are obsessed with running at 5V which makes external electronics difficult.

 

Can you write graphics to your screen ?

 

Your screen should be perfectly readable.   However your photo does not show a LCD_RD pin.   You have not shown your schematic or any buildable software.

Personally,   I would select 8080-8 interface.    But the 16-bit interface is fine if you have enough port pins.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes I can write graphic on the display. That picture posted earlier is not the best but there is an RD pin, you can see better picture here  https://www.aliexpress.com/item/...

 

It is a hobby project for learning purposes, I have a main menu where I can choose different application like hand write on the screen using a pen on the touch screen, display bitmap pictures one by one or slide show from SD card, different tests to read and write SD card, display the list of the files on SD card and select/open a file, a simple classic calculator, a count down timer, application to adjust RGB values and create colors  and some other small applications I could imagine. Most of the applications are based on the touch screen. 

The part of the code for reading the GRAM,creating a bmp file and saving on SD card below, it is a mess now because I have made many changes trying to read data from the display and the conversion from RGB 666 to 565 missing, but this is not my problem now. Since I cannot read from display probably I will abandon this code.

 

Honestly I do not have a connection diagram "on paper", it is a simple project so the connection diagram is in my mind, the PCB attached. I do not use auto routing function when drawing the PCB so no need to have a connections diagram. Ports C and D are lower and higher data ports, port A used as command port (partially) and the touch screen and SD card are connected to hardware SPI on port B and still have few pins unused.

 

void screenShot(void)
{
	uint16_t k;
	uint8_t y;
	char data[6];
	UINT* bw = 0;
	uint32_t w1 = 320, h1 = 240;
	//bgcolor = navy;
	uint16_t n = 0, m = 0;
	
	glcd_bg(bgcolor);
	
	WriteString12BG(2, 222, "Screenshot test", yellow, bgcolor);
	_delay_ms(1000);
	
	//BMP header
	unsigned char bmFlHdr[14] = { 'B', 'M', 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0	};	
	unsigned char bmInHdr[40] = { 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 16, 0 };
		
	unsigned long fileSize = 2ul * h1 * w1 + 54; // pix data + 54 byte hdr
	
	bmFlHdr[2] = (unsigned char)(fileSize);		// all ints stored little-endian
	bmFlHdr[3] = (unsigned char)(fileSize >>  8);	// i.e., LSB first
	bmFlHdr[4] = (unsigned char)(fileSize >> 16);
	bmFlHdr[5] = (unsigned char)(fileSize >> 24);

	bmInHdr[4] = (unsigned char)(w1);
	bmInHdr[5] = (unsigned char)(w1 >>  8);
	bmInHdr[6] = (unsigned char)(w1 >> 16);
	bmInHdr[7] = (unsigned char)(w1 >> 24);
	bmInHdr[8] = (unsigned char)(h1);
	bmInHdr[9] = (unsigned char)(h1 >>  8);
	bmInHdr[10] = (unsigned char)(h1 >> 16);
	bmInHdr[11] = (unsigned char)(h1 >> 24);
	
	fresult = f_mount(&fs, "1:", 1);	
	sprintf(tmp, "Disk mount #%d", fresult);
	WriteString12BG(2, 22, tmp, red, bgcolor);
	
	fresult = f_open(&file, "1:/Saved/Bmp001.bmp", FA_CREATE_ALWAYS|FA_WRITE);
	sprintf(tmp, "File open #%d", fresult);
	WriteString12BG(2, 42, tmp, red, bgcolor);
	
	//for (k = 0; k < 14; k++)
		fresult = f_write(&file, bmFlHdr, 14, bw);
		sprintf(tmp, "Write 1st header #%d", fresult);
		WriteString12BG(2, 62, tmp, red, bgcolor);
		fresult = f_sync(&file);
	//for(k = 0; k < 40; k++)
		fresult = f_write(&file, bmInHdr, 40, bw);
		sprintf(tmp, "Write 2nd header #%d", fresult);
		WriteString12BG(2, 102, tmp, red, bgcolor);
		fresult = f_sync(&file);
			
	glcd_setOrientation(LANDSCAPE_180, 0);	
	glcd_setX(0, 319);
	glcd_setY(0, 239);
	
	glcd_sendCmd(ILI9341_CMD_MEMORY_READ);
	//ReadData();
	//lcd_cs(0);                  
	//lcd_rs(1);
	//lcd_wr(1);
	//lcd_rd(0);
	//data[0] = LCD_DATA_PORT_L;
	//lcd_rd(1);
	
	
	for (y = 0; y < 300; y ++)
	{
		for(k = 0; k < 256; k++)
		{
			LCDPort_Input();
			lcd_cs(0);                     
			lcd_rs(1);
			lcd_wr(1);
			lcd_rd(0);
			
			data[0] = LCD_DATA_PORT_L;
			data[1] = LCD_DATA_PORT_H;
			//data[2] = LCD_DATA_PORT_L;
			//data[3] = LCD_DATA_PORT_H;
			//data[4] = LCD_DATA_PORT_L;
			//data[5] = LCD_DATA_PORT_H;
			lcd_rd(1);
			LCDPort_Output();
			fresult = f_write(&file, data, 2, bw);						
			sprintf(tmp, "%3d-R:%02X G:%02X B:%02X", m++, data[0], data[1], data[2]);
			WriteString12BG(2, 162, tmp, yellow, bgcolor);
			sprintf(tmp, "%3d-R:%02X G:%02X B:%02X", m++, data[3], data[4], data[5]);
			WriteString12BG(2, 182, tmp, yellow, bgcolor);
			_delay_ms(1000);
		}
		m = 0;
		seconds = 0;
		f_sync(&file);
		sprintf(tmp, "%3d File write #%d", n++, fresult);
		WriteString12BG(2, 142, tmp, red, bgcolor);		
	}
	glcd_setOrientation(LANDSCAPE_0, 1);
	lcd_cs(1);
	
	f_close(&file);	
	f_mount(0, "1:", 0);
	
	....	
	
}

 

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well,  it looks like LCD_RD goes to PA5 but I don't see how you can expect a human to construct a schematic from reverse pcb traces.

 

Or determine your software by guesswork.

 

Nowadays,  you can just provide a link to your GitHub repository.   Or attach a ZIP of your AS7.0 project.

 

MCUFRIEND_kbv runs out of the box on a Bobuino.

//LCD pins  |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 | |RD |WR |RS |CS |RST|
//AVR   pin |PB3|PB2|PB1|PB0|PD3|PD2|PD6|PD5| |PA7|PA6|PA5|PA4|PA3|

Of course this uses 8080-8 interface.   There are published SPECIALs for other ATmega1284 wiring schemes.

The SPECIALs that use 8080-16 interface are mostly run on write-only displays.    I think that SSD1963 is the only 8080-16 that I read GRAM from.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think there is no hardware problem in my project, all connections doubled checked and all signals checked with the oscilloscope. I have provided the pcb picture mostly FYI, I do not expect somebody to do reverse engineering, it is difficult also because the pcb picture is "in the mirror", I can provide additional information if needed. 

These are the pins used for display:

#define LCD_CMD_DDR     DDRA
#define LCD_CMD_PORT	PORTA
#define LCD_CS		PINA3
#define LCD_RS		PINA4
#define LCD_WR		PINA5
#define LCD_RD		PINA6
#define LCD_RST		PINA7

#define LCD_DATA_DDR_L	DDRC 
#define LCD_DATA_PORT_L	PORTC
#define LCD_DATA_DDR_H	DDRD
#define LCD_DATA_PORT_H	PORTD

Port C [0-7] goes to display pins DB[0-7] and Port D [0-7] goes to DB[8-15]. 

 

This display does not have the option to change on 8080-8, I know others have this option, so I can use only 8080-16. 

 

I do not understand what do you mean about my Github repository, I don't have such thing, I am just a hobbyist but seems you don't believe this :). I am not sure if reading the entire project will help, I have posted above already the part which doesn't work as I am expecting. The other parts are doing completely different things and does not attempt to read from GRAM.

It's something I have seen now, if I am doing more readings I get 0x2E on Port C at first reading and then I get only 0xE8 as you can see in the picture. But it still doesn't work.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your display has a LCD_RD pin.   Thanks for the clarification.   It connects to PA6.

 

Since your TFT is working fine with write commands,   I assume that lcd_wr(0), lcd_wr(1) strobes the LCD_WR signal correctly.

So I guess that your lcd_rd(0), lcd_rd(1) strobes the LCD_RD signal.

 

If the read is not working,   I would follow this signal e.g. broken pcb trace.

 

My code is:

        CS_ACTIVE;
        WriteCmd(_MR);
        setReadDir();
        READ_8(r);    //dummy
        while (n) {
                READ_8(r);
                READ_8(g);
                READ_8(b);
                ret = color565(r, g, b);
            *block++ = ret;
        }
        RD_IDLE;
        CS_IDLE;
        setWriteDir();

So I do not release CS during the sequence.   I suspect that your glcd_sendCommand() might release CS.

 

David.

 

Edit.   The MEMORY_READ() command does not care if CS is interrupted on an ILI9341.   I can only suggest that you check the physical hardware connectivity.

Last Edited: Thu. Apr 30, 2020 - 09:25 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have already checked the connection on RD pin even checked the signal going up and down with the oscilloscope. I do not know what is wrong here but reading doesn't work :(.

The only thing I cannot check is if the RD pin is indeed connected to the display on the display board but this needs to disassemble the display from the board and I can destroy it so will not do this.

By the way, can you provide a picture of the display which worked for reading the GRAM, maybe I can buy one.

Thank you for advises. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have many Mcufriend UNO shields.  These are 8080-8.  They can read GRAM

I have some MEGA2560 shields.  Both 8080-8 and 8080-16.  These are all write-only.

I have a 40-pin SSD1963 display.  This is 8080-16.   It can read GRAM.

 

I don't have any 34-pin displays.   If there was a 34-pin Adapter shield I would support them.

I might buy a 34-pin OTM8009A display.   Just to write the driver as an academic exercise.    I would have to make a ProtoShield Adapter.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Probably also these 34 pin displays are write-only too, it is just cheap stuff. Maybe somebody who knows this can confirm. Thank you!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No.   Almost certainly read-write.

 

The TFT panel contains all the signals on its ribbon.

It is the Arduino Shield makers that f*ck things up.   e.g. use bidirectional buffers but hard-wire the direction pin as write-only.

 

There are Arduino Forum Members with 34-pin displays.    I suspect that Jean-Marc Zingg owns one.   I will ask.

 

What do you intend to do?    Read the screen and save area as .BMP file on an SD ?

 

David.

 

Edit.   I have asked on Arduino Forum.   I will report back.

Last Edited: Thu. Apr 30, 2020 - 04:05 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
What do you intend to do?    Read the screen and save area as .BMP file on an SD ?

 

Yes, exactly this is want I want to do.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jean-Marc has a 34-pin ILI9341 like this

He says:

I have several 34pin displays, and as far as I remember, I could read from all of them.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you and also to Jean-Marc. I see his display has the pins exactly on the same position so it may be similar. Probably I am doing something wrong but I cannot see what is wrong.

Have a nice weekend! 

Last Edited: Mon. May 11, 2020 - 07:40 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
I have a 40-pin SSD1963 display.  This is 8080-16.   It can read GRAM.
new arrival

SSD1963 LCD Controller Graphics Card - Microchip Technology | Mouser

SSD1963 LCD Controller Graphics Card

...

The SSD1963 LCD Controller Graphics Card is designed specifically to be used with the following boards and display modules:

• SAM E54 Curiosity Ultra (DM320210)
• SAM E70 Xplained Ultra (DM320113)
• Curiosity PIC32 MZ EF 2.0 (DM320209)
• High-Performance 4.3" WQVGA Display Module with maXTouch (AC320005-4)
• High-Performance WVGA LCD Display Module with maXTouch (AC320005-5) 

...

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes,  40-pin SSD1963 displays almost always provide a RD pin.

 

The Arduino market has had 40-pin Adapter shields since the beginning of time.

However 99% of these shields have write-only 3.3V level shifters with no access to the TFT RD pin.

Even Adapter shields for the 3.3V Arduino Due hard-wire the RD pin.

 

The SAM and PIC32 have 3.3V logic.   So can interface directly to the 40-pin display.   You can use all the facilities of the SSD1963.

 

David.