News:

Welcome to the Bridgetek Community!

Please read our Welcome Note

Technical Support enquires
please contact the team
@ Bridgetek Support

Please refer to our website for detailed information on all our products - Bridgetek - Bridging Technology

Main Menu
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - TreeOone

#1
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.
#2
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.
#3
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));



#4
Thank you for your comments.  :)

EVE_memWrite32(REG_AH_HCYCLE_MAX, EVE_HCYCLE + 500);

.....removed limits of 1200 line segments.

I was not aware of pixel engine's limitations.

So, it is possible to crash BT81x, even if you pay attention to FIFO and RAM_DL fullness. This also means when one deals with lots of elements on screen, behaviour is not fully deterministic. Anything can happen.

Another conclusion is do not use while(1) {....} to fill BT with commands :)

BTW
Rudolph, your library is great. Unfortunately for me, it is heavily dependent on SPI communication, which is not ideal for me, because I am using QSPI, which on STM32 works a little bit different, so I had to rewrite all functions in EVE_commands.c. BTW2 I still can not get it working on 4 data lines, so far only 2 lines working, but that is discussion for another thread, after I give up trying to fix it.
#5
Hi,
I am drawing lots of lines via command VERTEX2F on screen. I am trying to figure out how much I can fit inside BT817 before it crashes.
I have STM32 F4, running Rudolph Riedel's library, which is running Riverdi's 10'' display RVT101HVBNWC00-B.
To achieve that, I am writing commands to REG_CMDB_WRITE register.
At some point screen starts flickering. Now I am puzzled which limit I managed to hit.
After each new line, which is add, I am reading registers REG_CMD_DL, REG_CMD_WRITE, REG_CMD_READ, REG_CMDB_SPACE.
What I noticed so far:
1)   REG_CMDB_SPACE is always equal to 4092, no matter at which point I try to read it. From that I can conclude that every dword that is written in REG_CMDB_WRITE register, coprocessor command gets read, meaning it is not possible to overflow FIFO buffer. It will always be empty for new commands, because they are momentarily processed.
Is this correct?
2)   Flickering starts happening at rather strange moment. Writing new commands to REG_CMDB_WRITE eventually leads to large number of commands, even larger than 4096 bytes, which should overflow FIFO, but still flickering does not start.
3)   Flickering starts happening at 1200 line segments, but is dependent on line width (??!?!?), how long are lines, etc. Why?????
4)   When flickering starts, REG_CMD_DL is at approx. 6000 bytes full, so it is not overflowing.

Can someone explain this?

Code:

void demo_CoPro_8()
{
uint32_t c = 0;
uint32_t old_reg_REG_CMD_WRITE = 0;

while(1)
{
EVE_cmd_dl(CMD_COLDSTART);
EVE_cmd_dl(CMD_DLSTART);
EVE_cmd_dl(CLEAR_COLOR_RGB(0, 0, 0));
EVE_cmd_dl(CLEAR(1, 1, 1));
EVE_cmd_dl(COLOR_RGB(255, 250, 0));
EVE_cmd_dl(VERTEX_FORMAT(3)); // Set the precision of VERTEX2F coordinates.
EVE_begin(EVE_LINE_STRIP);
EVE_cmd_dl(LINE_WIDTH(2 * 16)); // Specify the width of lines to be drawn with primitive LINES in 1/16 pixel precision.

uint32_t min_X = 10;
uint32_t max_X = 1250;
uint32_t min_Y = 10;
uint32_t max_Y = 760;
uint32_t incrementor = 20;
uint32_t coordinates[] = {min_X, min_Y};
uint32_t direction[] = {1, 0};
uint32_t flag = 0;

EVE_cmd_dl(VERTEX2F(coordinates[0] * 8, coordinates[1] * 8));


for(size_t i = 0; i < c; i++)
{
uint32_t new_X = coordinates[0] + incrementor * direction[0];
uint32_t new_Y = coordinates[1] + incrementor * direction[1];

if(new_X > max_X)
{
direction[0] = 0;
direction[1] = 1;
min_X += incrementor;
}
else if (new_X < min_X)
{
direction[0] = 0;
direction[1] = -1;
max_X -= incrementor;
}
else if(new_Y > max_Y)
{
direction[0] = -1;
direction[1] = 0;
min_Y += incrementor;
}
else if (new_Y < min_Y)
{
direction[0] = 1;
direction[1] = 0;
max_Y -= incrementor;
}

coordinates[0] += incrementor * direction[0];
coordinates[1] += incrementor * direction[1];

EVE_cmd_dl(VERTEX2F(coordinates[0] * 8, coordinates[1] * 8));

}
EVE_end();
EVE_cmd_dl(DL_DISPLAY);
EVE_cmd_dl(CMD_SWAP);

uint32_t reg_RAM_ERR_REPORT = 0x309800;
uint8_t error_report[128] = {0};
EVE_memRead_sram_buffer(RAM_ERR_REPORT, error_report, 128);

uint32_t reg_REG_CMD_DL = EVE_memRead32(REG_CMD_DL);
uint32_t reg_REG_CMD_WRITE = EVE_memRead32(REG_CMD_WRITE);
uint32_t reg_REG_CMD_READ = EVE_memRead32(REG_CMD_READ);
uint32_t reg_REG_CMDB_SPACE = EVE_memRead32(REG_CMDB_SPACE);

uint32_t delta = 0;

if(reg_REG_CMD_WRITE > old_reg_REG_CMD_WRITE)
{
delta = reg_REG_CMD_WRITE - old_reg_REG_CMD_WRITE;
}
else
{
delta = 4096 - old_reg_REG_CMD_WRITE + reg_REG_CMD_WRITE;
}

old_reg_REG_CMD_WRITE = reg_REG_CMD_WRITE;

printf("\r\n------------------------------------------------------\r\n");
printf("reg_REG_CMD_WRITE = %d (max 4096 - 4 byte = 4092)  delta = +%d\r\n", reg_REG_CMD_WRITE, delta);
printf("reg_REG_CMD_READ = %d\r\n", reg_REG_CMD_READ);
printf("reg_REG_CMDB_SPACE = %d\r\n", reg_REG_CMDB_SPACE);
printf("reg_REG_CMD_DL = %d (max 8192 - 4 byte = 8188)\r\n", reg_REG_CMD_DL);
printf("c = %d\r\n", c);
printf("ERROR report = %s\r\n", error_report);
printf("------------------------------------------------------\r\n");

c++;
}
}


This code is basically drawing long line composed of small segments. See attachment.



#6
Hi!

I have Riverdy's EVE4 IPS 10.1" LCD TFT (type RVT101HVBNWC00-B), which is run by BT817Q.

I noticed that my application can not take full advantage of DL memory in BT817Q.

To further investigate the problem I wrote simple test program:

   printf("\r\n ------------------------------------------------ \r\n");
uint32_t c = 1091;
//uint32_t c = 2038;


Gpu_Copro_SendCmd(phost, CMD_COLDSTART);
Gpu_Copro_SendCmd(phost, CMD_DLSTART);
Gpu_Copro_SendCmd(phost, CLEAR_COLOR_RGB(0, 0, 0));
Gpu_Copro_SendCmd(phost, CLEAR(1, 1, 1));

for(uint32_t i = 0; i < c; i++)
{
Gpu_Copro_SendCmd(phost, NOP());
//Gpu_Copro_SendCmd(phost, TAG(1));
}

Gpu_Copro_SendCmd(phost, COLOR_RGB(255, 0, 0));
Gpu_Copro_SendCmd(phost, VERTEX_FORMAT(3));
Gpu_Copro_SendCmd(phost, BEGIN(LINE_STRIP));
Gpu_Copro_SendCmd(phost, LINE_WIDTH(5 * 16));
Gpu_Copro_SendCmd(phost, VERTEX2F(10 * 8, 10 * 8));
Gpu_Copro_SendCmd(phost, VERTEX2F(500 * 8, 500 * 8));
Gpu_Copro_SendCmd(phost, END());

Gpu_Copro_SendCmd(phost, DISPLAY());
Gpu_Copro_SendCmd(phost, CMD_SWAP);

uint32_t reg_REG_CMD_DL = Gpu_Hal_Rd32 (phost, REG_CMD_DL);

printf("reg_REG_CMD_DL = %d        c = %d \r\n", reg_REG_CMD_DL, c);



If I run this program I can go with variable “c”, which is filling up DL memory with dummy NOP command up to value 1091. If “c” becomes 1092, red line on screen starts having artifacts.

Printf command for last stable c = 1091 returns:

reg_REG_CMD_DL = 4404        c = 1091

So here we have magical upper limit of DL’s memory at 4404 bytes. 

This is strange because DL's size should be 8191, according to manual.

Further tinkering revealed that if I fill DL’s memory with another dummy command like TAG(1) behaviour changes.

For instance if I remove lines of code (comment them):

uint32_t c = 1091;
…and
Gpu_Copro_SendCmd(phost, NOP());

…and uncomment lines:
//uint32_t c = 2038;
…and
//Gpu_Copro_SendCmd(phost, TAG(1));

…my test application behaves as expected. I can go with variable “c” up to 2038.

In this case printf returns:

reg_REG_CMD_DL = 8191        c = 2038

…for last stable “c”. For c = 2039 and above, screen turns black, i.e. DL’s memory overflows.

Can somebody explain this?

I my actual application I am not filling DL’s memory with dummy code like in above example, instead I am filling it up with graphics primitives (lines, dots, circles etc), however when DL’s fullness reaches 4404, display starts displaying gibberish.