Hi,
I am working on a EVE library for the mbed (ARM Cortex) platform in combination with the EVE ME813A-WH50C display.
It is now working, displaying images from the displays GRAM, after a lot of trying.
I have edited this post when I discovered more about the cause of the problem.
After loading images into RAM (only once), they display correctly, in gray color.
The below code loads and shows 4 bitmaps on the correct place and in the correct gray color (On and Off buttons, in narrow and wide versions):
TFT.DLstart(); // start a new display command list
TFT.DL(CLEAR_COLOR_RGB(0x25, 0x25, 0x25)); // set the clear color to white
TFT.DL(CLEAR(1, 1, 1)); // clear buffers -> color buffer,stencil buffer, tag buffer
TFT.SetLoadAddress(0);
// Narrow On button, 100x132, Address 0-26400
TFT.DL(BITMAP_HANDLE(0));
TFT.Png("/fs/SWITCH_BUTTON_SMALL_ON_100x131.png", 20, 20);
// Narrow Off button, 100x132, Address 26400-52800
TFT.DL(BITMAP_HANDLE(1));
TFT.Png("/fs/SWITCH_BUTTON_SMALL_OFF_100x131.png", 125, 20);
// Wide On button, 182x132, Address 52800-100848
TFT.DL(BITMAP_HANDLE(2));
TFT.Png("/fs/SWITCH_BUTTON_LARGE_ON_181x131.png", 230, 20);
// Wide Off button, 182x132, Address 100848-148896
TFT.DL(BITMAP_HANDLE(3));
TFT.Png("/fs/SWITCH_BUTTON_LARGE_OFF_181x131.png", 416, 20);
TFT.DL(DISPLAY()); // Display the image
TFT.Swap(); // Swap the current display list
TFT.Flush_Co_Buffer(); // Download the command list into fifo
TFT.WaitCmdfifo_empty(); // Wait till coprocessor completes the operation
In TFT.png, the image was loaded using below code, which seems to work fine:
// In short
// WrCmd32(CMD_LOADIMAGE);
// WrCmd32(_address); //destination address of png decode
// WrCmd32(0); // Output format of the bitmap OPT_RGB565
// WrCmdBuf((uint8_t *)pbuff, blocklen); //alignment is already taken care by this api
ft_uint8_t FT813::LoadPng(char* filename, ft_int16_t* x_size, ft_int16_t* y_size)
{
int bufferSize = 8192;
uint32_t marker1;
uint32_t marker2;
unsigned short length;
unsigned char data[32];
ft_uint16_t blocklen;
FILE *fp = fopen(filename, "rb");
if(fp == NULL) {
printf("LoadPng: Cannot open file \"%s\".\n", filename);
return (-1); // cannot open file
}
// Get file size
fseek(fp, 0, SEEK_END);
unsigned int Fsize = ftell(fp);
// search for 0x89504E47 and 0x0D0A1A0A markers "‰PNG...."
fseek(fp, 2, SEEK_SET); // Beginning of file
fread(data, 32, 1, fp); // Read first 32 bytes
printf("LoadPng: Filesize %d\n", Fsize);
// Check that this is indeed a PNG file
unsigned char png_header[] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
if (memcmp(data, png_header, 8)) {
printf("LoadPng: Not a PNG file.\n");
return (-2); // No FFC0 Marker, wrong format no baseline DCT-based JPEG
}
// Make sure you have an IHDR
unsigned char ihdr_name[] = "IHDR";
if (memcmp(data+8+4, ihdr_name, 4)) {
// not an IHDR chunk, invalid PNG file
printf("LoadPng: Not an IHDR chunk, invalid PNG file.\n");
return (-3); // No FFC0 Marker, wrong format no baseline DCT-based JPEG
}
// PNG actually stores integers in big-endian.
*x_size = ReadBigInt32(data, 24 - 8);
*y_size = ReadBigInt32(data, 24 - 4);
uint16_t size_x = ReadBigInt32(data, 24 - 8);
uint16_t size_y = ReadBigInt32(data, 24 - 4);
if(*x_size > DispWidth || *y_size > DispHeight)
{
printf("LoadPng: Too big to fit on screen\n");
printf("LoadPng: PNG (%dx%d) does not fit on TFT (%dx%d)\n", *x_size, *y_size, DispWidth, DispHeight);
return (-3); // Too big to fit on screen
}
fseek(fp, 0, SEEK_SET); // Beginning of file
// http://www.ftdichip.com/Support/Documents/AppNotes/AN_339%20Using%20JPEGs%20with%20the%20FT800%20series.pdf
// CMD_LOADIMAGE: This function will decode the JPEG file, produce
// either RGB565 or L8 bitmap data and store this in graphics RAM.
// It also writes commands to the display list to set the source, layout and size of the
// image (BITMAP_SOURCE, BITMAP_LAYOUT and BITMAP_SIZE).
// Note that only a BEGIN and VERTEX2F (or VERTEX2II) display list commands are then
// required to complete the display list needed to render the image.
WrCmd32(CMD_LOADIMAGE);
WrCmd32(_address); //destination address of png decode
// Increment _address
_addresses[_bitmap_count] = _address;
_bitmap_count++;
_address += (uint32_t) (size_x * size_y * 2);
_addresses[_bitmap_count] = _address;
// 0 OPT_RGB565
// 1 OPT_MONO
// 2 OPT_NODL
// 256 OPT_FLAT
// 256 OPT_SIGNED
// 512 OPT_CENTERX
// 1024 OPT_CENTERY
// 1536 OPT_CENTER
// 2048 OPT_RIGHTX
// 4096 OPT_NOBACK
// 8192 OPT_NOTICKS
// By default, option OPT_RGB565 means the loaded bitmap is in RGB565 format.
WrCmd32(0); // Output format of the bitmap OPT_RGB565
char* pbuff = (char*)malloc(bufferSize);
unsigned int FsizeCounter = Fsize;
while(FsizeCounter > 0) {
/* download the data into the command buffer by 8kb one shot */
blocklen = FsizeCounter > bufferSize ? bufferSize : FsizeCounter;
/* copy the data into pbuff and then transfter it to command buffer */
int size = fread(pbuff, 1, blocklen, fp);
FsizeCounter -= blocklen;
/* copy data continuously into command memory */
WrCmdBuf((uint8_t *)pbuff, blocklen); //alignment is already taken care by this api
}
fclose(fp);
// If the number of bytes in the JPEG file to be written to the command buffer is not a multiple of
// four, then one, two or three bytes (of any value) should be added to ensure four-byte alignment of
// the next command.
blocklen = Fsize % 4;
memset(pbuff, 0, bufferSize);
WrCmdBuf((uint8_t *)pbuff, blocklen); //alignment is already taken care by this api
free(pbuff);
printf("LoadPng: Done.\n");
return(0);
}
And the shown correctly with following code:
DL(BEGIN(BITMAPS));
DL(VERTEX2F(x * 16, y * 16));
Then, it should display several of the pre-loaded images from the displays GRAM at different locations on the screen.
It turnes out this works fine if I specify ARGB4 for the format in GRAM (trial and error). Why does it not match the RGB565 layout?
TFT.DLstart(); // start a new display command list
TFT.DL(CLEAR_COLOR_RGB(0x25, 0x25, 0x25)); // set the clear color to white
TFT.DL(CLEAR(1, 1, 1)); // clear buffers -> color buffer,stencil buffer, tag buffer
// Narrow On button, 100x132, Address 0-26400
TFT.DL(BITMAP_SOURCE(TFT.GetBitmapAddress(0)));
TFT.DL(BITMAP_LAYOUT(ARGB4, 100*2, 132)); // <------- Why ARGB4 instead of RGB565?
TFT.DL(BITMAP_SIZE(NEAREST, BORDER, BORDER, 100, 132));
TFT.DL(BEGIN(BITMAPS));
TFT.DL(VERTEX2II(125, 190, 0, 0));
// Narrow Off button, 100x132, Address 26400-52800
TFT.DL(BITMAP_SOURCE(TFT.GetBitmapAddress(1)));
TFT.DL(BITMAP_LAYOUT(ARGB4, 100*2, 132)); // <------- Why ARGB4 instead of RGB565?
TFT.DL(BITMAP_SIZE(NEAREST, BORDER, BORDER, 100, 132));
TFT.DL(BEGIN(BITMAPS));
TFT.DL(VERTEX2II(20, 190, 0, 0));
// Wide On button, 182x132, Address 52800-100848
TFT.DL(BITMAP_SOURCE(TFT.GetBitmapAddress(2)));
TFT.DL(BITMAP_LAYOUT(ARGB4, 182*2, 132)); // <------- Why ARGB4 instead of RGB565?
TFT.DL(BITMAP_SIZE(NEAREST, BORDER, BORDER, 182, 132));
TFT.DL(BEGIN(BITMAPS));
TFT.DL(VERTEX2II(416, 190, 0, 0));
// Wide Off button, 182x132, Address 100848-148896
TFT.DL(BITMAP_SOURCE(TFT.GetBitmapAddress(3)));
TFT.DL(BITMAP_LAYOUT(ARGB4, 182*2, 132)); // <------- Why ARGB4 instead of RGB565?
TFT.DL(BITMAP_SIZE(NEAREST, BORDER, BORDER, 182, 132));
TFT.DL(BEGIN(BITMAPS));
TFT.DL(VERTEX2II(230, 190, 0, 0));
TFT.DL(END());
TFT.DL(DISPLAY()); // Display the image (erases the other images!)
TFT.Swap(); // Swap the current display list
TFT.Flush_Co_Buffer(); // Download the command list into fifo
TFT.WaitCmdfifo_empty(); // Wait till coprocessor completes the operation
Definitions of RGB565, BITMAP_LAYOUT and BITMAP_SIZE_H:
#define RGB565 7UL
#define BITMAP_LAYOUT(format,linestride,height) ((7UL<<24)|(((format)&31UL)<<19)|(((linestride)&1023UL)<<9)|(((height)&511UL)<<0))
#define BITMAP_SIZE_H(width,height) ((41UL<<24)|(((width)&3UL)<<2)|(((height)&3UL)<<0))
I have added photos of the screen.
How can I define this upfront, if I'd like to try L8 format, using CMD_LOADIMAGE?
Is that possible?
I try to contribute in a positive way, and update posts with code that finally works.
Despite this seems useful and helpful information for others, this message still is awaiting approval by a moderator, for many days.
Is my contribution (as a new user) not appreciated?
I hope somebody can help me in the right direction.
Kind regards,
Jack.