Hi.
Can someone please take a look at my code. For some reason ASTC image is not rendered correctly. Image was created with EAB.
BT817 is initialized. FLASH is in full speed mode. Everything seems OK, however image is displayed as if someone took scissors and randomly put together little pieces of it on screen.
char file_name[] = "Image 4_500x376_COMPRESSED_RGBA_ASTC_4x4_KHR.raw";
uint32_t image_width = 500;
uint32_t image_height = 376;
float_t bits_per_pixel = 8;
uint32_t bitmap_format = EVE_ASTC_4X4;
printf("Attempting to display image %s !\r\n", file_name);
demo_CoPro_13(buffer, file_size, image_width, image_height, bitmap_format, bits_per_pixel);
/*
Use FLASH to display bitmaps in ASTC format.
*/
void demo_CoPro_13(uint8_t *image_location, uint32_t image_size, uint32_t image_width, uint32_t image_height, uint32_t bitmap_format, float_t bits_per_pixel)
{
if(EVE_memRead32(REG_FLASH_STATUS) != EVE_FLASH_STATUS_FULL)
{
printf("Error, flash is NOT in full speed status!\r\n");
return;
}
else
{
printf("EVE's flash is in full speed status!\r\n");
}
uint32_t flash_size = EVE_memRead32(REG_FLASH_SIZE);
printf("Flash size: %d Mbytes\r\n", flash_size);
write_to_EVE_flash_via_RAM_G(sizeof(bt817_blob), image_location, image_size);
uint8_t *result = read_from_EVE_flash_via_RAM_G(sizeof(bt817_blob), image_size, image_location, 0);
sdram_free(result);
uint32_t underrun_flag_status_start = EVE_memRead32(REG_UNDERRUN);
// Clear EVE's cache
EVE_cmd_clearcache();
EVE_cmd_dl(CMD_DLSTART); // tell EVE to start a new display-list
EVE_cmd_dl(DL_CLEAR_COLOR_RGB | WHITE); // sets the background color
EVE_cmd_dl(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG);
EVE_color_rgb(BLACK);
EVE_cmd_dl(BITMAP_HANDLE(0));
uint32_t source_value = (1UL << 23) | (sizeof(bt817_blob) / 32);
uint32_t command = DL_BITMAP_SOURCE | source_value;
// Source is FLASH -> can NOT use Rudolph's library
EVE_cmd_dl(command);
// Specify the source bitmap memory format and layout for the current handle.
EVE_cmd_dl(BITMAP_LAYOUT(EVE_GLFORMAT, image_width * bits_per_pixel / 8.0, image_height));
// Additional specification needed for GLFORMAT
EVE_cmd_dl(BITMAP_EXT_FORMAT(bitmap_format));
//This command is the extension command of BITMAP_SIZE for bitmap larger than 511 by 511 pixels.
EVE_cmd_dl(BITMAP_SIZE_H(image_width, image_height));
//Specify the screen drawing of bitmaps for the current handle
EVE_cmd_dl(BITMAP_SIZE(EVE_NEAREST, EVE_BORDER, EVE_BORDER, image_width, image_height));
EVE_begin(EVE_BITMAPS);
// Display image at coordinates 0, 0
EVE_cmd_dl(VERTEX2II(0, 0, 0, 0));
//To draw the graphics primitives beyond the coordinate range [(0,0), (511, 511)], use VERTEX2F instead.
EVE_end();
EVE_cmd_dl(DL_DISPLAY); // put in the display list to mark its end
EVE_cmd_dl(CMD_SWAP); // tell EVE to use the new display list
uint32_t underrun_flag_status_end = EVE_memRead32(REG_UNDERRUN);
printf("underrun_flag_status_start = %d\r\n", underrun_flag_status_start);
printf("underrun_flag_status_end = %d\r\n", underrun_flag_status_end);
}
I am not sure this is OK:
EVE_cmd_dl(BITMAP_LAYOUT(EVE_GLFORMAT, image_width * bits_per_pixel / 8.0, image_height));
Quote
I am not sure this is OK:
EVE_cmd_dl(BITMAP_LAYOUT(EVE_GLFORMAT, image_width * bits_per_pixel / 8.0, image_height));
And you are correct, this is not right.
Not that I could tell how these values are calculated, I tried this in EVE Screen Editor.
And for
CMD_SETBITMAP(0x800000 | 128, COMPRESSED_RGBA_ASTC_4x4_KHR, 500, 376)
The generated display list code is:
BITMAP_SOURCE(0x800000 | 128)
BITMAP_SIZE_H(0, 0)
BITMAP_SIZE(NEAREST, BORDER, BORDER, 500, 376)
BITMAP_EXT_FORMAT(COMPRESSED_RGBA_ASTC_4x4_KHR)
BITMAP_LAYOUT_H(1, 0)
BITMAP_LAYOUT(GLFORMAT, 976, 94)
Whatever the correct way is to calculate Stride and Height in BITMAP_LAYOUT for ASTC,
just stop using it and switch to CMD_SETBITMAP. :)
Edit: forgot to ask:
Quote
// Source is FLASH -> can NOT use Rudolph's library
Why?
Hi.
Sometimes, because of answers ,,Whatever the correct way is to calculate Stride and Height in BITMAP_LAYOUT for ASTC, just stop using it and switch to CMD_SETBITMAP", I begin to think who on earth would want to use Bridgetek's solutions.
Regarding your question, there is a function BITMAP_SOURCE in your library, but it is missing option to set FLASH as a source. One can not set bit No. 23 to 1.
//#define BITMAP_SOURCE(addr) ((DL_BITMAP_SOURCE) | ((addr) & 0x3FFFFFUL))
/**
* @brief Set the source address of bitmap data in RAM_G or flash memory.
* @return a 32 bit word for use with EVE_cmd_dl()
*/
static inline uint32_t BITMAP_SOURCE(const uint32_t addr)
{
return (DL_BITMAP_SOURCE | (addr & 0x3FFFFFUL));
}
BTW thanks for the help.
I have 2 more questions:
Q1: Can you perhaps say why EAB, when generating ASTC images, creates files with extension .astc and .raw. If .astc is given to BT817, image does not load well, whereas .raw generates image OK. What's the difference? I also tried creating ASTC images with ASTC encoder (downloaded from official ARM's GitHub page). Same problems. Results are not compressed.
Q2: I noticed some images encoded in ASTC_6x6_KHR display correctly, whereas when they are encoded in ASTC_4x4_KHR, they do not display at all. I am talking about same original image, for which EAB created two .raw files, one with 4x4 and other time with 6x6 encoding. What is the catch here? My test image has resolution 1100x700 px. The only difference which I can see is that result of 4x4 encoding has 1100x700 px, whereas if it is encoded with 6x6, resolution changes to 1104x702 px.
Quote from: TreeOone on May 30, 2025, 09:41:41 PM
Hi.
Sometimes, because of answers ,,Whatever the correct way is to calculate Stride and Height in BITMAP_LAYOUT for ASTC, just stop using it and switch to CMD_SETBITMAP", I begin to think who on earth would want to use Bridgetek's solutions.
What do you want me to say? :)
CMD_SETBITMAP
is part of Bridgetek's solution, this coprocessor command was introduced with the FT81x back in 2015.
And the only time I would not use it would be to optimize the display list, like for example when trying to display several images with
the same format and resolution.
Edit: forgot to mention, I really have no idea how to get to
BITMAP_LAYOUT(GLFORMAT, 976, 94)
from 500x376 and ASTC_4x4.
That is a factor of 1.952 for Stride and 1/4 for Height - why?
Quote
Regarding your question, there is a function BITMAP_SOURCE in your library, but it is missing option to set FLASH as a source. One can not set bit No. 23 to 1.
//#define BITMAP_SOURCE(addr) ((DL_BITMAP_SOURCE) | ((addr) & 0x3FFFFFUL))
/**
* @brief Set the source address of bitmap data in RAM_G or flash memory.
* @return a 32 bit word for use with EVE_cmd_dl()
*/
static inline uint32_t BITMAP_SOURCE(const uint32_t addr)
{
return (DL_BITMAP_SOURCE | (addr & 0x3FFFFFUL));
}
You are correct, this is a bug and I just fixed it, thank you!
Quote
I have 2 more questions:
Q1: Can you perhaps say why EAB, when generating ASTC images, creates files with extension .astc and .raw. If .astc is given to BT817, image does not load well, whereas .raw generates image OK. What's the difference? I also tried creating ASTC images with ASTC encoder (downloaded from official ARM's GitHub page). Same problems. Results are not compressed.
The .astc files have a 16 bytes header, there is software out there that can use these, like Neosis:
https://www.richwhitehouse.com/index.php?content=inc_projects.php&showproject=91
And I would prefer if the generation of the .astc, .json and .rawh files as well as the _converted file would be optional in EAB
with the default that these are not generated.
Quote
Q2: I noticed some images encoded in ASTC_6x6_KHR display correctly, whereas when they are encoded in ASTC_4x4_KHR, they do not display at all. I am talking about same original image, for which EAB created two .raw files, one with 4x4 and other time with 6x6 encoding. What is the catch here? My test image has resolution 1100x700 px. The only difference which I can see is that result of 4x4 encoding has 1100x700 px, whereas if it is encoded with 6x6, resolution changes to 1104x702 px.
I only displayed the two .astc for the 1100x700 image I converted just now with Neosys and they work both fine.
The change in X/Y is necessary for the memory layout of the format.
Regarding Q1, to give you the context of my question, I am looking for a way to generate images dynamically, which will be shown on display. To do that I need to implement in my MCU a function which will take .jpg or .png as an input, and convert it to format which BT817 can display. Image data needs to be stored in ASTC format, and stored on FLASH, because my display has 1280x800 px, and images of that size do not fit in BT817's RAM_G if stored in ARGB format. Noesis might do the job, but I need open source solution, which can be executed in MCU. That is why I asked what is the difference between ASTC format, generated by EAB, and ARM's algorithm, which is open source and available for download from Github.
Regarding Q2, yes I presume resolution 1100x700 by itself is not a problem. The problem is my image. Find attached original and converted image, encoded with ASTC 4x4 and 6x6.
My take on this was that the .raw file is just stripped of the header: https://github.com/ARM-software/astc-encoder/blob/main/Docs/FileFormat.md
But, I just found out that while this is true for EAB v3.0.0, this is not the case for EAB v2.13.0.
No idea what is going on there, but the .astc and .raw of EAB v2.13.0 are not the same when you strip the header.
The images from 2.x worked fine, but this is strange.
Both are using the same ASTC encoder which is v4.5.0 from June 2023 (why this old?)
Anyways, skipping the header when saving the file should be fine.
However, given previous experiences with ASTC encoding, especially font conversion, I wonder if running the ASTC encoder on anything that still can be called a micro-controller is even possible, even more so at 1280x800.
My desktop CPU merely blinks with the current EAB when converting stuff, but it has AVX-512 SIMD instructions and plenty of memory.
Quote
Regarding Q2, yes I presume resolution 1100x700 by itself is not a problem. The problem is my image. Find attached original and converted image, encoded with ASTC 4x4 and 6x6.
The issue really is with the memory layout of the format, the compression works in blocks of pixels.
1100 / 4 = 275
1100 / 6 = 183,333 -> needs 1104