cancel
Showing results for 
Search instead for 
Did you mean: 

Framebuffer being populated incorrectly?

Hafez1
Associate III

So I'm using an ST7789VI display connected to a STM32L4R9I-DISCO board. I've made some test projects in CubeIDE without using TouchGFX to ensure that the driver file and everything else was correct. However, when I try to integrate TouchGFX designs, I get misalignment and a bit of distortion. At first, I thought it was an issue with how I'm transmitting the data, but I did some debugging and I noticed that the Framebuf was being populated incorrectly i.e. the pixel "values" were incorrect in the areas I'm getting distortion- so not a transmission error. I'm still unsure what's causing the misalignment. Could someone help me out? I'll attach the flushframebuffer function, where i defined FrameBuf in TouchGFXGeneratedHAL and the dedicated memory spot in the linker files for the framebuffer.

 

EDIT: I've also tested with solid colors using the flushframebuffer function and I do get the correct output.

 

//How frameBuf is defined in TouchGFXGeneratedHAL.cpp

LOCATION_PRAGMA_NOLOAD(".TouchGFX_Framebuffer")

 

 

__attribute__((aligned(8))) uint16_t frameBuf[(320 * 240)] LOCATION_ATTRIBUTE_NOLOAD(".TouchGFX_Framebuffer");

 

//FrameBuffer in linker (memory)

/* TouchGFX Framebuffer section */

.TouchGFX_Framebuffer (NOLOAD):

{

. = ALIGN(8);

*(.TouchGFX_Framebuffer)

. = ALIGN(8);

} >RAM

 

//TouchGFXBridge.cpp

// TouchGFXBridge.cpp

#ifdef __cplusplus

extern "C" {

#endif

#include "stm32l4xx_hal.h"

#include "stm32l4xx_hal_gpio.h"

#include "ST7789VI.h"

#include "main.h"

 

#ifdef __cplusplus

}

#endif

 

#include <touchgfx/hal/HAL.hpp> // Include TouchGFX HAL header

#include <touchgfx/hal/Types.hpp> // Include TouchGFX Types header

 

#include "TouchGFXHAL.hpp"

 

extern "C" void flushFrameBufferFromISR()

{

touchgfx::Rect rect(0, 0, 320, 240); // Define the rectangle to flush; adjust as needed

touchgfx::HAL::getInstance()->flushFrameBuffer(rect);

// HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin);

 

// Example code to draw a string on the display, adjust as needed

// static int count = 0;

// count++;

// ST7789_DrawString(count, 1, ".", COLOR_WHITE, COLOR_BLACK, 1);

}

 

//Flushframebuffer in TouchGFXHAL.cpp

void TouchGFXHAL::flushFrameBuffer(const touchgfx::Rect &rect)

{

// Use the TouchGFX framebuffer

uint16_t* frameBuf = touchgfx::HAL::getInstance()->getTFTFrameBuffer();

uint16_t displayWidth = touchgfx::HAL::DISPLAY_WIDTH;

uint16_t* src=frameBuf + (rect.y * displayWidth) + rect.x;

uint16_t x0 = rect.x;

uint16_t y0 = rect.y;

uint16_t x1 = rect.x + rect.width - 1;

uint16_t y1 = rect.y + rect.height - 1;

printf("Framebuffer Content Before Flush:\n");

for (uint16_t y = rect.y; y < rect.y + rect.height; ++y)

{

for (uint16_t x = rect.x; x < rect.x + rect.width; ++x)

{

uint16_t pixel = frameBuf[y * displayWidth + x];

printf("Pixel[%d, %d] = %04x ", x, y, pixel);

}

printf("\n");

}

// Set the correct address window for the entire display

ST7789_SetAddressWindow(x0, y0, x1, y1);

ST7789_WriteCommand(ST7789_RAMWR);

 

// Calculate the total size in bytes for the framebuffer

uint32_t totalDataSize = rect.width * rect.height * 2; // Each pixel is 2 bytes

// Define a reasonable chunk size in bytes

uint16_t chunkSize = 2048;

uint8_t buffer[chunkSize];

 

HAL_GPIO_WritePin(SPI2_CS_GPIO_Port, SPI2_CS_Pin, GPIO_PIN_RESET);

HAL_GPIO_WritePin(GPIOG, LCD_WR_Pin, GPIO_PIN_SET);

 

for (uint32_t i = 0; i < totalDataSize; i += chunkSize)

{

uint16_t currentChunkSize = (totalDataSize - i) < chunkSize ? (uint16_t)(totalDataSize - i) : chunkSize;

uint32_t pixelIndex = i / 2;

 

// Copy the 16-bit pixel data into the 8-bit buffer

for (uint16_t j = 0; j < currentChunkSize / 2; ++j)

{

uint16_t pixel = src[pixelIndex + j];

buffer[2 * j] = pixel >> 8; // High byte

buffer[2 * j + 1] = pixel & 0xFF; // Low byte

 

// Debugging output

// printf("Buffer[%d] = %02x, Buffer[%d] = %02x, Pixel[%d] = %04x\n",

// 2 * j, buffer[2 * j], 2 * j + 1, buffer[2 * j + 1], pixelIndex + j, pixel);

}

 

HAL_SPI_Transmit(&hspi2, buffer, currentChunkSize, HAL_MAX_DELAY);

}

 

HAL_GPIO_WritePin(SPI2_CS_GPIO_Port, SPI2_CS_Pin, GPIO_PIN_SET);

 

// printf("Framebuffer flush complete, terminating.\n");

 

 

printf("Framebuffer flush complete, terminating.\n");

while (1)

{

// Optional: Toggle an LED to indicate termination

HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);

HAL_Delay(500); // Adjust delay as needed

}

}

0 REPLIES 0