FTDI Community
General Category => Discussion - Software => Topic started by: jberkhout on June 29, 2018, 07:33:36 PM
-
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.
-
Hello,
Can you please have a look at the following application note:
http://brtchip.com/wp-content/uploads/Support/Documentation/Application_Notes/ICs/EVE/AN_303-FT800-Image-File-Conversion.pdf (http://brtchip.com/wp-content/uploads/Support/Documentation/Application_Notes/ICs/EVE/AN_303-FT800-Image-File-Conversion.pdf)
It covers using the EVE Image Convertor, the different output formats (L8, ARGB4, etc) and how to implement these in code.
Best Regards,
FTDI Community
-
Thank yes, I was reading in it this afternoon, it is useful.
To load raw, this function is used:
hal_spi_wr8s(phost, ram_start, imbuff, blocklen);
I'm looking for the implementation of this function, so I can test it.
Is it something like:
ft_void_t FT813::Wr8s(ft_uint32_t addr, ft_uint8_t *buffer, ft_uint8_t length)
{
_ss = 0; // cs low
_spi.write(0x80 | (addr >> 16));
_spi.write(addr >> 8);
_spi.write(addr & 0xff);
while (length--) {
_spi.write(*buffer);
buffer++;
}
_ss = 1;
}
-
You can also check out my library: https://github.com/RudolphRiedel/FT800-FT813
It is plain C, cross-plattform in a sense that it uses a minimalistic set of mostly one-line functions that are target specific while almost everything else is not.
And while I have not used it with ARM myself I have reports that it has been used successfully with a whole bunch of ARM controllers: STM32, SAM3, SAM4, SAMV70, SAMC21, SAMD20.
The last platform I needed to adapt to was Infineon Aurix, with the help of the software engineer I was to provide a visualisation for it took about 20 minutes with a bit of explaining for the target specific lines and built flawlessly in the scope of his project.
Next up für me is SAME51.
A good starting point would be the "FT8xx_Test_90CAN_FT813_EVE2-35G" example I provided, it should be updated with the latest FT8_commands.c though.
You should be able to adapt it to your target quite easily and from there it should provide some ideas for your own library.
-
Hello,
In General the wr8s function would do the following:
- Bring CS low
- Write the Address
- Burst write the data buffer
- Bring CS high when the data has been written
Best Regards,
FTDI Community
-
hi, i am also working eve ft813 display using stm32f controller .as i have completed the touch calibrate, text and button keypad now i am stuglging to complete the bitmaping for many days. i dont have a idea of whether the hex value storing, or maybe something missing in configue or protocol. the image i configure only shows a plain white rectangle bar. i dont know what to do. kindly help me in it.
here i have add my code and
cmd(CMD_DLSTART);
cmd(CLEAR_COLOR_RGB(0x25, 0x25, 0x25));
cmd(CLEAR(1,1,1));
cmd(BITMAP_SOURCE(0));
cmd(BITMAP_HANDLE(0));
HOST_MEM_WR_STR(RAM_G,rawData, sizeof(*rawData));
cmd(DISPLAY());
cmd(CMD_SWAP);
cmd(CMD_DLSTART);
cmd(CLEAR_COLOR_RGB(0x25, 0x25, 0x25));
cmd(CLEAR(1,1,1));
cmd(BITMAP_SOURCE(0));
cmd(BITMAP_HANDLE(0));
cmd(BITMAP_LAYOUT(ALWAYS, 100*2, 132));
cmd(BITMAP_SIZE(NEAREST, BORDER, BORDER, 100, 132));
cmd(BEGIN(BITMAPS));
cmd(VERTEX2II(125, 190, 0, 0));
cmd(END());
cmd(DISPLAY());
cmd(CMD_SWAP);
-
Hello,
Thank you for your post.
As a note, the http://www.brtcommunity.com/ (http://www.brtcommunity.com/) forum is now available for any EVE related questions.
The image showing as a white box on the screen indicates that the bitmap is attempting to display, but the source for the image data is not being read correctly.
There are some notes on how to display images in the followi9ng application note (see section 7):
https://ftdichip.com/wp-content/uploads/2020/07/BRT_AN_014_FT81X_Simple_PIC_Library_Examples.pdf (https://ftdichip.com/wp-content/uploads/2020/07/BRT_AN_014_FT81X_Simple_PIC_Library_Examples.pdf)
Could you possibly provide the intended image to be displayed, and what settings you have utilized when converting the image?
Best Regards,
FTDI Community