Description
I have a display connected to an STM32H7 using the parallel port (SPI I haven’t tried yet).
The display in question is: 2.4 inch IPS TFT LCD without Touchscreen (newhavendisplay.com)
Using function to only fill the buffer with specific colors works fine.
When using LVGL it doesn’t work properly. I have managed to get it to show something logical as shown below, but it is still not functional.
Partial rendering is not working, it just spits out random data, but the spinner can be seen to change something.
I got away with just taking the whole buffer and sending it to the display, but it is not fully working as shown in the image.
What MCU/Processor/Board and compiler are you using?
STM32H745 with STM32CubeIDE.
What LVGL version are you using?
Master - Latest
What do you want to achieve?
To display correctly.
What have you tried so far?
Code to reproduce
init stuff
#define DISPLAY_WIDTH 320
#define DISPLAY_HEIGHT 240
#define BYTE_PER_PIXEL (LV_COLOR_FORMAT_GET_SIZE(LV_COLOR_FORMAT_RGB565A8)) /*will be 2 for RGB565 */
#define BUFF_SIZE (DISPLAY_WIDTH * DISPLAY_HEIGHT * BYTE_PER_PIXEL)
static uint8_t buf_1[BUFF_SIZE];
static uint8_t buf_2[BUFF_SIZE];
my_flush_cb
void my_flush_cb(lv_display_t * disp, const lv_area_t * area, lv_color_t * color_p)
{
comm_out(0x2C);
for (int i = 0; i < 38400; i++) {
uint16_t color_full = (color_p->red << 11) | (color_p->green << 5) | (color_p->blue);
data_out(color_full >> 8);
data_out(color_full & 0xff);
data_out(color_full >> 8);
data_out(color_full & 0xff);
color_p++;
}
/* IMPORTANT!!!
* Inform the graphics library that you are ready with the flushing*/
lv_display_flush_ready(disp);
}
Init Function
void Display_parallel_init(){
/* Initialize LVGL */
lv_init();
data_out(0x00);
HAL_GPIO_WritePin(RD_GPIO_Port, RD_Pin, HIGH);
HAL_GPIO_WritePin(WR_GPIO_Port, WR_Pin, LOW);
HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, LOW);
HAL_Delay(250);
HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, HIGH);
HAL_Delay(250);
comm_out(0x28); //display off
comm_out(0x11); //exit SLEEP mode
HAL_Delay(100);
comm_out(0x36); //MADCTL: memory data access control
data_out(0x88);
comm_out(0x3A); //COLMOD: Interface Pixel format *** 65K-colors in 16bit/pixel (5-6-5) format when using 16-bit interface to allow 1-byte per pixel
data_out(0x55);
comm_out(0xB2); //PORCTRK: Porch setting
data_out(0x0C);
data_out(0x0C);
data_out(0x00);
data_out(0x33);
data_out(0x33);
comm_out(0xB7); //GCTRL: Gate Control
data_out(0x35);
comm_out(0xBB); //VCOMS: VCOM setting
data_out(0x2B);
comm_out(0xC0); //LCMCTRL: LCM Control
data_out(0x2C);
comm_out(0xC2); //VDVVRHEN: VDV and VRH Command Enable
data_out(0x01);
data_out(0xFF);
comm_out(0xC3); //VRHS: VRH Set
data_out(0x11);
comm_out(0xC4); //VDVS: VDV Set
data_out(0x20);
comm_out(0xC6); //FRCTRL2: Frame Rate control in normal mode
data_out(0x0F);
comm_out(0xD0); //PWCTRL1: Power Control 1
data_out(0xA4);
data_out(0xA1);
comm_out(0xE0); //PVGAMCTRL: Positive Voltage Gamma control
data_out(0xD0);
data_out(0x00);
data_out(0x05);
data_out(0x0E);
data_out(0x15);
data_out(0x0D);
data_out(0x37);
data_out(0x43);
data_out(0x47);
data_out(0x09);
data_out(0x15);
data_out(0x12);
data_out(0x16);
data_out(0x19);
comm_out(0xE1); //NVGAMCTRL: Negative Voltage Gamma control
data_out(0xD0);
data_out(0x00);
data_out(0x05);
data_out(0x0D);
data_out(0x0C);
data_out(0x06);
data_out(0x2D);
data_out(0x44);
data_out(0x40);
data_out(0x0E);
data_out(0x1C);
data_out(0x18);
data_out(0x16);
data_out(0x19);
comm_out(0x2A); //X address set
data_out(0x00);
data_out(0x00);
data_out(0x00);
data_out(0xEF);
comm_out(0x2B); //Y address set
data_out(0x00);
data_out(0x00);
data_out(0x01);
data_out(0x3F);
HAL_Delay(10);
comm_out(0x21); //Display Inversion for 2.8" TFT
comm_out(0x29); //display ON
HAL_Delay(10);
// disp1();
// HAL_Delay(100);
disp2();
// HAL_Delay(100);
// Border_Fill();
// HAL_Delay(100);
disp3();
// pixel(320/2,240/2, 0xFFFF);
lv_display_t * disp = lv_display_create(DISPLAY_HEIGHT,DISPLAY_WIDTH); /*Basic initialization with horizontal and vertical resolution in pixels*/
lv_display_set_flush_cb(disp, my_flush_cb); /*Set a flush callback to draw to the display*/
lv_display_set_buffers(disp, buf_1, buf_2, sizeof(buf_1), LV_DISPLAY_RENDER_MODE_DIRECT); /*Set an initialized buffer*/
// lv_display_rotate_area(disp, LV_DISPLAY_ROTATION_90);
lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0x003a57), LV_PART_MAIN);
lv_obj_t * spinner = lv_spinner_create(lv_screen_active());
lv_obj_set_size(spinner, 100, 100);
lv_obj_center(spinner);
lv_spinner_set_anim_params(spinner, 10000, 200);
for(;;) {
/* The task running lv_timer_handler should have lower priority than that running `lv_tick_inc` */
lv_timer_handler();
/* raise the task priority of LVGL and/or reduce the handler period can improve the performance */
HAL_Delay(5);
}
}
Other functions to control the display
void comm_out(unsigned char c)
{
HAL_GPIO_WritePin(RS_GPIO_Port, RS_Pin, LOW);
for(uint8_t i=0; i<8; i++){
HAL_GPIO_WritePin(GPIOB, pinz[i], ((c) >> (i)) & 0x01);
}
HAL_GPIO_WritePin(WR_GPIO_Port, WR_Pin, LOW);
HAL_GPIO_WritePin(WR_GPIO_Port, WR_Pin, HIGH);
}
void data_out(unsigned char d)
{
HAL_GPIO_WritePin(RS_GPIO_Port, RS_Pin, HIGH);
for(uint8_t i=0; i<8; i++){
HAL_GPIO_WritePin(GPIOB, pinz[i], ((d) >> (i)) & 0x01);
}
HAL_GPIO_WritePin(WR_GPIO_Port, WR_Pin, LOW);
HAL_GPIO_WritePin(WR_GPIO_Port, WR_Pin, HIGH);
}