Description
Blurry Display with Different Color
What MCU/Processor/Board and compiler are you using?
STM32CubeIDE with GNU Compiler, I am Proteus Simulation Environment with STM32F401VE Microcontroller and ILI9341 connected with SPI Interface
What do you want to achieve?
Using LVGL
What have you tried so far?
I wrote ILI9341 drivers and they seem to work also, but when integrated with LVGL I see a strange color display.
Code to reproduce
Config file (also tried changing LV_COLOR_16_SWAP but didn’t help.
/*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/
#define LV_COLOR_DEPTH 16
/*Swap the 2 bytes of RGB565 color. Useful if the display has a 8 bit interface (e.g. SPI)*/
#define LV_COLOR_16_SWAP 0
/*Enable more complex drawing routines to manage screens transparency.
*Can be used if the UI is above an other layer, e.g. an OSD menu or video player.
*Requires `LV_COLOR_DEPTH = 32` colors and the screen's `bg_opa` should be set to non LV_OPA_COVER value*/
#define LV_COLOR_SCREEN_TRANSP 0
/*Images pixels with this color will not be drawn if they are chroma keyed)*/
#define LV_COLOR_CHROMA_KEY lv_color_hex(0x00ff00) /*pure green*/
Below is the flush function. I think there is some problem with this function, which I copied from online, anyways I am trying to analyze but in case someone has some idea, please let me know.
static void tft_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p)
{
uint32_t len = 0u;
lv_coord_t width = (area->x2 - area->x1) + 1;
/*Return if the area is out the screen*/
if(area->x2 < 0) return;
if(area->y2 < 0) return;
if(area->x1 > TFT_HOR_RES - 1) return;
if(area->y1 > TFT_VER_RES - 1) return;
/*Truncate the area to the screen*/
int32_t act_x1 = area->x1 < 0 ? 0 : area->x1;
int32_t act_y1 = area->y1 < 0 ? 0 : area->y1;
int32_t act_x2 = area->x2 > TFT_HOR_RES - 1 ? TFT_HOR_RES - 1 : area->x2;
int32_t act_y2 = area->y2 > TFT_VER_RES - 1 ? TFT_VER_RES - 1 : area->y2;
// Set Display Area
ILI9341_SetWindow( act_x1, act_y1, act_x2, act_y2 );
len = (act_x2 - act_x1 + 1u)*2u;
ILI9341_SendCommand(ILI9341_GRAM, 0u, 0u );
for( uint32_t y = act_y1; y <= act_y2; y++)
{
ILI9341_Send_16BitData( (uint16_t*)color_p, len );
color_p += width;
}
lv_disp_flush_ready(&disp_drv);
}
And some ILI related function.
void ILI9341_SendCommand( uint8_t command, uint8_t *data, uint32_t length )
{
uint32_t timeout = length*10u; // Considering timeout as 10 * length milliseconds
CS_LOW();
DC_LOW(); // Command Mode
HAL_SPI_Transmit( &hspi2, &command, 1u, 10u ); // send command byte
DC_HIGH(); // Data Mode
if( length )
{
HAL_SPI_Transmit( &hspi2, data, length, timeout );
}
CS_HIGH();
}
void ILI9341_SendData( uint8_t *data, uint32_t length )
{
uint32_t timeout = length*10u; // Considering timeout as 10 * length milliseconds
CS_LOW();
DC_HIGH();
HAL_SPI_Transmit( &hspi2, data, length, timeout );
CS_HIGH();
}
// Set the display area
void ILI9341_SetWindow( uint16_t x_start, uint16_t y_start, uint16_t x_end, uint16_t y_end )
{
uint8_t params[4] = { 0 };
// Column Address Set (2A)
params[0] = x_start >> 8u;
params[1] = 0xFF & x_start;
params[2] = x_end >> 8u;
params[3] = 0xFF & x_end;
ILI9341_SendCommand( ILI9341_CASET, params, 4u );
// Row Address Set (2B) also called as page address set
params[0] = y_start >> 8u;
params[1] = 0xFF & y_start;
params[2] = y_end >> 8u;
params[3] = 0xFF & y_end;
ILI9341_SendCommand( ILI9341_RASET, params, 4u );
}
void ILI9341_Send_16BitData( uint16_t *data, uint32_t length )
{
uint32_t idx = 0u;
uint8_t value[2] = { 0 };
CS_LOW();
DC_HIGH();
for( idx=0; idx<length; idx++ )
{
value[0] = data[idx] >> 8u;
value[1] = data[idx] && 0xFF;
HAL_SPI_Transmit( &hspi2, value, 2u, 10u );
}
CS_HIGH();
}