2022-04-26 08:20 PM
Using threadx rtos, spi is written to st7796 rbg565 480*320, the interface display is normal during initialization, but it is abnormal when the widget is refreshed in handletickevent
Solved! Go to Solution.
2022-04-27 07:25 AM
I complete dont understand your code, read docu for partial mode...
For example part of my driver c file. (Note: Generated files isnt for edit then show it here is waste space
volatile uint8_t IsTransmittingBlock_;
void UNIMM_dmacallback(void)
{
IsTransmittingBlock_ = 0;
DisplayDriver_TransferCompleteCallback();
}
void Display_Bitmap(const uint16_t *bitmap, uint16_t posx, uint16_t posy, uint16_t sizex, uint16_t sizey)
{
IsTransmittingBlock_ = 1;
GC9A01A_SetWindow(posx, posy, posx+sizex-1, posy+sizey-1);
//DMA test
HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_SET);
SPI_send_dma(GC9A01A_SPI_periph, 1, (uint8_t *)bitmap, sizex*sizey, UNIMM_dmacallback);
}
2022-04-26 08:25 PM
Does anyone know the reason, thank you very much for your help
2022-04-26 10:29 PM
Maybe better is show your code for init display and refresh system.
2022-04-26 11:41 PM
A workaround method is adopted here. A global variable is judged in the timer interrupt. If the writing spi tft thread has completed the transmission, it will be executed.
if(writing == 2)
{
writing = 0;
IsTransmittingBlock_ = 0;
DisplayDriver_TransferCompleteCallback();
}
void touchgfxDisplayDriverTransmitBlock(const uint8_t* pixels, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
{
if(writing == 2 || writing == 0)
{
wr_x = x ;
wr_y = y;
wr_w = w;
wr_h = h;
pix = pixels;
writing = 1;
IsTransmittingBlock_ = 1;
//DisplayDriver_TransferCompleteCallback();
}
// IsTransmittingBlock_ = st7796_draw_rect(x , y , x + w , y + h , (void*)pixels);
// if(IsTransmittingBlock_ == 0)
// {
// DisplayDriver_TransferCompleteCallback();
// }
}
void app_user_task(unsigned long para)
{
volatile uint32_t base ,tick ,acculate;
uint32_t lcd_frame_tick;
for(;;)
{
tx_thread_sleep(1);
if(++acculate >= 100)
{
acculate = 0;
tick = HAL_GetTick() - base;
base = HAL_GetTick();
}
if((HAL_GetTick() - lcd_frame_tick ) >= 1000)
{
lcd_frame_tick = HAL_GetTick();
}
if(writing == 1 )
{
st7796_draw_rect(wr_x , wr_y , wr_x + wr_w , wr_y + wr_h , (void*)pix);
writing = 2;
uint16_t buf[256];
for(int i = 0; i < sizeof(buf) / sizeof(buf[0]); i++)
{
buf[i] = (i >> 2) << 5;
}
st7796_draw_rect(100 , 250 , 100+127 , 252 , (void*)buf);
}
}
}
extern "C"
void DisplayDriver_TransferCompleteCallback()
{
// After completed transmission start new transfer if blocks are ready.
touchgfx::startNewTransfer();
}
}
extern "C"
void touchgfxSignalVSync(void)
{
/* VSync has occurred, increment TouchGFX engine vsync counter */
touchgfx::HAL::getInstance()->vSync();
/* VSync has occurred, signal TouchGFX engine */
touchgfx::OSWrappers::signalVSync();
}
void TouchGFXGeneratedHAL::flushFrameBuffer(const touchgfx::Rect& rect)
{
HAL::flushFrameBuffer(rect);
// Once flushFrameBuffer() is called by the framework a block is already for transfer
// Mark it ready for transfer and transmit it if user defined method isTransmittingData() does not return false
// If data is not being transmitted, transfer the data with user defined method transmitFrameBufferBlock().
//PartialFrameBufferManager::tryTransmitBlock();
frameBufferAllocator->markBlockReadyForTransfer();
if (!touchgfxDisplayDriverTransmitActive())
{
touchgfx::Rect r;
// Get pointer to block buffer and coordinates of the rect
const uint8_t* pixels = frameBufferAllocator->getBlockForTransfer(r);
// Start transmission of the block
touchgfxDisplayDriverTransmitBlock((uint8_t*)pixels, r.x, r.y, r.width, r.height);
}
}
extern "C" int touchgfxDisplayDriverTransmitActive();
extern "C" void touchgfxDisplayDriverTransmitBlock(const uint8_t* pixels, uint16_t x, uint16_t y, uint16_t w, uint16_t h);
extern "C" void touchgfxSignalVSync(void);
// Block Allocator for Partial Framebuffer strategy
static ManyBlockAllocator<11520, /* block size */
3, /* number of blocks */
2 /* bytes per pixel */
> blockAllocator;
void TouchGFXGeneratedHAL::initialize()
{
HAL::initialize();
registerEventListener(*(Application::getInstance()));
// Partial framebuffer strategy
setFrameBufferAllocator(&blockAllocator);
setFrameRefreshStrategy(HAL::REFRESH_STRATEGY_PARTIAL_FRAMEBUFFER);
}
/*
* Initialize frame buffer semaphore and queue/mutex for VSYNC signal.
*/
void OSWrappers::initialize()
{
CHAR* pointer;
/* Create a byte memory pool from which to allocate the thread stacks. */
if (tx_byte_pool_create(&oswrapper_byte_pool, (CHAR*) "OSWrapper Byte Pool", oswrapper_heap_mem,
OSWRAPPER_BYTE_POOL_SIZE) != TX_SUCCESS)
{
assert(0 && "Failed to create OSWrapper Pool memory!");
}
/* Allocate the vsync_q. */
if (tx_byte_allocate(&oswrapper_byte_pool, (VOID**) &pointer,
OSWRAPPER_QUEUE_SIZE, TX_NO_WAIT) != TX_SUCCESS)
{
assert(0 && "Failed to allocate memory for the Vsync Message Queue!");
}
// Create a queue of length 1
if (tx_queue_create(&vsync_q, (CHAR*) "Vsync Message Queue", TX_1_ULONG,
pointer, OSWRAPPER_QUEUE_SIZE) != TX_SUCCESS)
{
assert(0 && "Failed to create Vsync Message Queue!");
}
// Create the Framebuffer Semaphore (Binary)
if (tx_semaphore_create(&frame_buffer_sem, (CHAR*) "FrameBuffer Semaphore", 0) != TX_SUCCESS)
{
assert(0 && "Failed to create FrameBuffer Semaphore!");
}
//giveFrameBufferSemaphore();
}
if(writing == 2)
{
writing = 0;
IsTransmittingBlock_ = 0;
DisplayDriver_TransferCompleteCallback();
}
2022-04-26 11:45 PM
From the phenomenon, it seems that the touchgfx kernel has data misalignment when rendering part of the buffer, and it has been repeatedly confirmed that the spi program written to the st7796 is correct.
2022-04-27 07:25 AM
I complete dont understand your code, read docu for partial mode...
For example part of my driver c file. (Note: Generated files isnt for edit then show it here is waste space
volatile uint8_t IsTransmittingBlock_;
void UNIMM_dmacallback(void)
{
IsTransmittingBlock_ = 0;
DisplayDriver_TransferCompleteCallback();
}
void Display_Bitmap(const uint16_t *bitmap, uint16_t posx, uint16_t posy, uint16_t sizex, uint16_t sizey)
{
IsTransmittingBlock_ = 1;
GC9A01A_SetWindow(posx, posy, posx+sizex-1, posy+sizey-1);
//DMA test
HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_SET);
SPI_send_dma(GC9A01A_SPI_periph, 1, (uint8_t *)bitmap, sizex*sizey, UNIMM_dmacallback);
}
2022-04-27 07:46 PM
Confirm that the problem lies in the setwindows function, st7796_draw_rect(wr_x , wr_y , wr_x + wr_w -1 , wr_y + wr_h -1, (void*)pix); need to set x2, y2 minus 1, so the window is dislocated, thank you very much You, the partial buffers are really nice to use, and can take advantage of graphics on a low-cost chip.