sdk例程:AXI QuadSPI LVGL驱动 st77916 - minichao9901/TangNano-20k-Zynq-7020 GitHub Wiki

说明

  • AXI QuadSPI是没有问题的,虽然速度慢一点,但可以放心使用
  • 最关键的是要实现填充函数
void lcdqspi_fill_pcolor(uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint16_t *pcolor)
{
    open_window(x0,y0,x1-x0+1,y1-y0+1);

	u32 length=(x1-x0)*(y1-y0);
    send_color_data(0x2C, (u8 *)pcolor, 2*length);

//	send_color_data(0x2C, (u8 *)pcolor, BURST_SIZE);
//	send_color_array(0x3C, (u8 *)pcolor+BURST_SIZE, 2*length-BURST_SIZE, BURST_SIZE);
}
  • 工程的名字:st77916_qspi_lvgl
  • 目前暂时没有移植touch,淘宝买的屏touch调不通,看起来没有烧录固件

注意事项

lv_conf.h文件

image image image image image

程序

main.c

#include "ACZ702_Lib/COMMON.h"
#include "xil_cache.h"
#include "xil_mmu.h"

#include "lvgl/lvgl.h"
#include "lvgl/examples/porting/lv_port_disp_template.h"
#include "lvgl/examples/porting/lv_port_indev_template.h"
#include "lvgl/demos/lv_demos.h"

typedef struct{
	u8 txbuf[50];
	u8 rxbuf[50];
	u8 length;
}t_buf;

t_buf WriteBuffer[]={
	{{0x3A,0x55},{0x00},2},
	{{0xF0,0x08},{0x00},2},
	{{0xF2,0x08},{0x00},2},
	{{0x9B,0x51},{0x00},2},
	{{0x86,0x53},{0x00},2},
	{{0xF2,0x80},{0x00},2},
	{{0xF0,0x00},{0x00},2},
	{{0xF0,0x01},{0x00},2},
	{{0xF1,0x01},{0x00},2},
	{{0xB0,0x54},{0x00},2},
	{{0xB1,0x3F},{0x00},2},
	{{0xB2,0x2A},{0x00},2},
	{{0xB4,0x46},{0x00},2},
	{{0xB5,0x34},{0x00},2},
	{{0xB6,0xD5},{0x00},2},
	{{0xB7,0x30},{0x00},2},
	{{0xBA,0x00},{0x00},2},
	{{0xBB,0x08},{0x00},2},
	{{0xBC,0x08},{0x00},2},
	{{0xBD,0x00},{0x00},2},
	{{0xC0,0x80},{0x00},2},
	{{0xC1,0x10},{0x00},2},
	{{0xC2,0x37},{0x00},2},
	{{0xC3,0x80},{0x00},2},
	{{0xC4,0x10},{0x00},2},
	{{0xC5,0x37},{0x00},2},
	{{0xC6,0xA9},{0x00},2},
	{{0xC7,0x41},{0x00},2},
	{{0xC8,0x51},{0x00},2},
	{{0xC9,0xA9},{0x00},2},
	{{0xCA,0x41},{0x00},2},
	{{0xCB,0x51},{0x00},2},
	{{0xD0,0x91},{0x00},2},
	{{0xD1,0x68},{0x00},2},
	{{0xD2,0x69},{0x00},2},
	{{0xF5,0x00,0xA5},{0x00},3},
	{{0xDD,0x3F},{0x00},2},
	{{0xDE,0x3F},{0x00},2},
	{{0xF1,0x10},{0x00},2},
	{{0xF0,0x00},{0x00},2},
	{{0xF0,0x02},{0x00},2},
	{{0xE0,0xF0,0x06,0x0B,0x09,0x09,0x16,0x32,0x44,0x4A,0x37,0x13,0x13,0x2E,0x34},{0x00},15},
	{{0xE1,0xF0,0x06,0x0B,0x09,0x08,0x05,0x32,0x33,0x49,0x17,0x13,0x13,0x2E,0x34},{0x00},15},
	{{0xF0,0x10},{0x00},2},
	{{0xF3,0x10},{0x00},2},
	{{0xE0,0x0A},{0x00},2},
	{{0xE1,0x00},{0x00},2},
	{{0xE2,0x00},{0x00},2},
	{{0xE3,0x00},{0x00},2},
	{{0xE4,0xE0},{0x00},2},
	{{0xE5,0x06},{0x00},2},
	{{0xE6,0x21},{0x00},2},
	{{0xE7,0x00},{0x00},2},
	{{0xE8,0x05},{0x00},2},
	{{0xE9,0x82},{0x00},2},
	{{0xEA,0xDF},{0x00},2},
	{{0xEB,0x89},{0x00},2},
	{{0xEC,0x20},{0x00},2},
	{{0xED,0x14},{0x00},2},
	{{0xEE,0xFF},{0x00},2},
	{{0xEF,0x00},{0x00},2},
	{{0xF8,0xFF},{0x00},2},
	{{0xF9,0x00},{0x00},2},
	{{0xFA,0x00},{0x00},2},
	{{0xFB,0x30},{0x00},2},
	{{0xFC,0x00},{0x00},2},
	{{0xFD,0x00},{0x00},2},
	{{0xFE,0x00},{0x00},2},
	{{0xFF,0x00},{0x00},2},
	{{0x60,0x42},{0x00},2},
	{{0x61,0xE0},{0x00},2},
	{{0x62,0x40},{0x00},2},
	{{0x63,0x40},{0x00},2},
	{{0x64,0x02},{0x00},2},
	{{0x65,0x00},{0x00},2},
	{{0x66,0x40},{0x00},2},
	{{0x67,0x03},{0x00},2},
	{{0x68,0x00},{0x00},2},
	{{0x69,0x00},{0x00},2},
	{{0x6A,0x00},{0x00},2},
	{{0x6B,0x00},{0x00},2},
	{{0x70,0x42},{0x00},2},
	{{0x71,0xE0},{0x00},2},
	{{0x72,0x40},{0x00},2},
	{{0x73,0x40},{0x00},2},
	{{0x74,0x02},{0x00},2},
	{{0x75,0x00},{0x00},2},
	{{0x76,0x40},{0x00},2},
	{{0x77,0x03},{0x00},2},
	{{0x78,0x00},{0x00},2},
	{{0x79,0x00},{0x00},2},
	{{0x7A,0x00},{0x00},2},
	{{0x7B,0x00},{0x00},2},
	{{0x80,0x48},{0x00},2},
	{{0x81,0x00},{0x00},2},
	{{0x82,0x05},{0x00},2},
	{{0x83,0x02},{0x00},2},
	{{0x84,0xDD},{0x00},2},
	{{0x85,0x00},{0x00},2},
	{{0x86,0x00},{0x00},2},
	{{0x87,0x00},{0x00},2},
	{{0x88,0x48},{0x00},2},
	{{0x89,0x00},{0x00},2},
	{{0x8A,0x07},{0x00},2},
	{{0x8B,0x02},{0x00},2},
	{{0x8C,0xDF},{0x00},2},
	{{0x8D,0x00},{0x00},2},
	{{0x8E,0x00},{0x00},2},
	{{0x8F,0x00},{0x00},2},
	{{0x90,0x48},{0x00},2},
	{{0x91,0x00},{0x00},2},
	{{0x92,0x09},{0x00},2},
	{{0x93,0x02},{0x00},2},
	{{0x94,0xE1},{0x00},2},
	{{0x95,0x00},{0x00},2},
	{{0x96,0x00},{0x00},2},
	{{0x97,0x00},{0x00},2},
	{{0x98,0x48},{0x00},2},
	{{0x99,0x00},{0x00},2},
	{{0x9A,0x0B},{0x00},2},
	{{0x9B,0x02},{0x00},2},
	{{0x9C,0xE3},{0x00},2},
	{{0x9D,0x00},{0x00},2},
	{{0x9E,0x00},{0x00},2},
	{{0x9F,0x00},{0x00},2},
	{{0xA0,0x48},{0x00},2},
	{{0xA1,0x00},{0x00},2},
	{{0xA2,0x04},{0x00},2},
	{{0xA3,0x02},{0x00},2},
	{{0xA4,0xDC},{0x00},2},
	{{0xA5,0x00},{0x00},2},
	{{0xA6,0x00},{0x00},2},
	{{0xA7,0x00},{0x00},2},
	{{0xA8,0x48},{0x00},2},
	{{0xA9,0x00},{0x00},2},
	{{0xAA,0x06},{0x00},2},
	{{0xAB,0x02},{0x00},2},
	{{0xAC,0xDE},{0x00},2},
	{{0xAD,0x00},{0x00},2},
	{{0xAE,0x00},{0x00},2},
	{{0xAF,0x00},{0x00},2},
	{{0xB0,0x48},{0x00},2},
	{{0xB1,0x00},{0x00},2},
	{{0xB2,0x08},{0x00},2},
	{{0xB3,0x02},{0x00},2},
	{{0xB4,0xE0},{0x00},2},
	{{0xB5,0x00},{0x00},2},
	{{0xB6,0x00},{0x00},2},
	{{0xB7,0x00},{0x00},2},
	{{0xB8,0x48},{0x00},2},
	{{0xB9,0x00},{0x00},2},
	{{0xBA,0x0A},{0x00},2},
	{{0xBB,0x02},{0x00},2},
	{{0xBC,0xE2},{0x00},2},
	{{0xBD,0x00},{0x00},2},
	{{0xBE,0x00},{0x00},2},
	{{0xBF,0x00},{0x00},2},
	{{0xC0,0x12},{0x00},2},
	{{0xC1,0xAA},{0x00},2},
	{{0xC2,0x65},{0x00},2},
	{{0xC3,0x74},{0x00},2},
	{{0xC4,0x47},{0x00},2},
	{{0xC5,0x56},{0x00},2},
	{{0xC6,0x00},{0x00},2},
	{{0xC7,0x88},{0x00},2},
	{{0xC8,0x99},{0x00},2},
	{{0xC9,0x33},{0x00},2},
	{{0xD0,0x21},{0x00},2},
	{{0xD1,0xAA},{0x00},2},
	{{0xD2,0x65},{0x00},2},
	{{0xD3,0x74},{0x00},2},
	{{0xD4,0x47},{0x00},2},
	{{0xD5,0x56},{0x00},2},
	{{0xD6,0x00},{0x00},2},
	{{0xD7,0x88},{0x00},2},
	{{0xD8,0x99},{0x00},2},
	{{0xD9,0x33},{0x00},2},
	{{0xF3,0x01},{0x00},2},
	{{0xF0,0x00},{0x00},2},
	{{0xF0,0x01},{0x00},2},
	{{0xF1,0x01},{0x00},2},
	{{0xA0,0x0B},{0x00},2},
	{{0xA3,0x2A},{0x00},2},
	{{0xA5,0xC3},{0x00},2},
	{{0xA3,0x2B},{0x00},2},
	{{0xA5,0xC3},{0x00},2},
	{{0xA3,0x2C},{0x00},2},
	{{0xA5,0xC3},{0x00},2},
	{{0xA3,0x2D},{0x00},2},
	{{0xA5,0xC3},{0x00},2},
	{{0xA3,0x2E},{0x00},2},
	{{0xA5,0xC3},{0x00},2},
	{{0xA3,0x2F},{0x00},2},
	{{0xA5,0xC3},{0x00},2},
	{{0xA3,0x30},{0x00},2},
	{{0xA5,0xC3},{0x00},2},
	{{0xA3,0x31},{0x00},2},
	{{0xA5,0xC3},{0x00},2},
	{{0xA3,0x32},{0x00},2},
	{{0xA5,0xC3},{0x00},2},
	{{0xA3,0x33},{0x00},2},
	{{0xA5,0xC3},{0x00},2},
	{{0xA0,0x09},{0x00},2},
	{{0xF1,0x10},{0x00},2},
	{{0xF0,0x00},{0x00},2},
	{{0x2A,0x00,0x00,0x01,0x67},{0x00},5},
	{{0x2B,0x00,0x00,0x01,0x68},{0x00},5},
	{{0x4D,0x00},{0x00},2},
	{{0x4E,0x00},{0x00},2},
	{{0x4F,0x00},{0x00},2},
	{{0x4C,0x01},{0x00},2},
	{{0x4C,0x00},{0x00},2},
	{{0x2A,0x00,0x00,0x01,0x67},{0x00},5},
	{{0x2B,0x00,0x00,0x01,0x67},{0x00},5},
	{{0x21},{0x00},1},
	{{0x11},{0x00},1},
	{{0xff},{0x00},0},
	{{0x29},{0x00},1},
	{{0x2c},{0x00},1},
};

#define LCD_RST_PIN (54+0)
#define LCD_NSS_PIN (54+5)
#define USE_SOFT_NSS 0

void do_reset()
{
    PS_GPIO_SetPort(LCD_RST_PIN,0);
	usleep(1000);
    PS_GPIO_SetPort(LCD_RST_PIN,1);
	usleep(1000);
}

void set_nss()
{
	#if(USE_SOFT_NSS==1)
		PS_GPIO_SetPort(LCD_NSS_PIN,1);
	#endif
}

void clear_nss()
{
	#if(USE_SOFT_NSS==1)	
		PS_GPIO_SetPort(LCD_NSS_PIN,0);
	#endif
}


void print_buffer(u8 *pdata, int length)
{
	for(int i=0; i<length; i++){
		xil_printf("pdata[%d]=%x\r\n", i, pdata[i]);
	}
	xil_printf("********************\r\n");
}

#define CMD_INST    0x02
#define DATA_INST   0x32

void send_command(u8 cmd)
{
	/* data_structure: (0x02)+(0x00,cmd,0x00)+(data)*/

	u8 tmp[64]={CMD_INST/*page grogram*/, 0x00,cmd,0x00/*addr*/};
	clear_nss();
	AXI_SPI_Transfer(&AXI_SPI0, 0, NULL, tmp, 4);
	set_nss();
}

void send_command_data(u8 cmd, u8 *p, u32 length)
{
	/* data_structure: (0x02)+(0x00,cmd,0x00)+(data)*/
	u8 tmp[64]={CMD_INST/*page grogram*/, 0x00,cmd,0x00/*addr*/};
	memcpy(tmp+4, p, length);
	clear_nss();
	AXI_SPI_Transfer(&AXI_SPI0, 0, NULL, tmp, 4+length);
	set_nss();
}


u8 frame_buffer[360*360*2+4];
void send_color_data(u8 cmd, u8 *p, u32 length)
{
	/* data_structure: (0x02)+(0x00,cmd,0x00)+(data)*/
	frame_buffer[0]=DATA_INST;
	frame_buffer[1]=0x00;
	frame_buffer[2]=cmd;
	frame_buffer[3]=0x00;
	memcpy(frame_buffer+4, p, length);

	clear_nss();
	AXI_SPI_Transfer(&AXI_SPI0, 0, NULL, frame_buffer, 4+length);
	set_nss();
}

// void send_color_array(u8 cmd, u8 *data, u32 total_length, u32 batch_size) {
//     for (u32 offset = 0; offset < total_length; offset += batch_size) {
//         u32 remaining_length = total_length - offset;
//         u32 current_batch_size = (remaining_length < batch_size) ? remaining_length : batch_size;

//         send_color_data(cmd, data + offset, current_batch_size);
//     }
// }

void seqs_init() {
	for (int i = 0; i < sizeof(WriteBuffer) / sizeof(*WriteBuffer); i++) {
		if (WriteBuffer[i].length == 0) {
			usleep(WriteBuffer[i].txbuf[0] * 1000);
			continue;
		}

		u8 cmd=WriteBuffer[i].txbuf[0];
		u8 *pdata=WriteBuffer[i].txbuf+1;
		u16 length=WriteBuffer[i].length-1;

		send_command_data(cmd, pdata, length);
		usleep(1000); //this delay is need
		xil_printf("Exec CMD=%x\r\n\r\n", cmd);
	}
}


// u8 frame[360*360*2];
#define BURST_SIZE 8  /*AXI QSPI: min_burst=2x2x2=8, max_burst=4x4x2=32*/

void open_window(u16 x0, u16 y0, u16 width, u16 height){
    // Assuming color is in RGB565 format
    u8 xdata[]={(x0 >> 8) & 0xFF, x0 & 0xFF, ((x0 + width - 1) >> 8) & 0xFF, (x0 + width - 1) & 0xFF};
    send_command_data(0x2A, xdata, 4);

    u8 ydata[]={(y0 >> 8) & 0xFF, y0 & 0xFF, ((y0 + height - 1) >> 8) & 0xFF, (y0 + height - 1) & 0xFF};
    send_command_data(0x2B, ydata, 4);
}

//void send_color(u16 color, u16 width, u16 height){
//
//    // Calculate the 16-bit RGB565 color
//    u8 color_high = (color >> 8) & 0xFF;
//    u8 color_low = color & 0xFF;
//
//    // Create the data array for the specified color and dimensions
//	for(int i=0; i<width*height; i++){
//		frame[2*i]=color_high;
//		frame[2*i+1]=color_low;
//	}
//
//	send_color_data(0x2C, frame, BURST_SIZE);
//	send_color_array(0x3C, frame+BURST_SIZE, 2*width*height-BURST_SIZE, BURST_SIZE);
//}


//void draw_single_color_rect(u16 x0, u16 y0, u16 width, u16 height, u16 color){
//	open_window(x0,y0,width,height);
//	send_color(color,width,height);
//}
//
//
//void send_pic(u16 width, u16 height){
//	send_color_data(0x2C, frame, BURST_SIZE);
//	send_color_array(0x3C, frame+BURST_SIZE, 2*width*height-BURST_SIZE, BURST_SIZE);
//}
//
//void draw_pic(u16 x0, u16 y0, u16 width, u16 height){
//	open_window(x0,y0,width,height);
//	send_pic(width,height);
//}

//void draw_eight_colors(){
//		u16 colors[] = {
//		    0xF800,  // Red
//		    0x07E0,  // Green
//		    0x001F,  // Blue
//		    0x07FF,  // Cyan
//		    0xFFE0,  // Yellow
//		    0xF81F,  // Magenta
//		    0x0000,  // Black
//		    0xFFFF   // White
//		};
//
//
//    for(int i=0; i<sizeof(colors)/sizeof(*colors);i++){
//        draw_single_color_rect(0, 0, 360, 360, colors[i]);
//        usleep(100*1000);
//    }
//}


void lcdqspi_fill_pcolor(uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint16_t *pcolor)
{
    open_window(x0,y0,x1-x0+1,y1-y0+1);

	u32 length=(x1-x0)*(y1-y0);
    send_color_data(0x2C, (u8 *)pcolor, 2*length);

//	send_color_data(0x2C, (u8 *)pcolor, BURST_SIZE);
//	send_color_array(0x3C, (u8 *)pcolor+BURST_SIZE, 2*length-BURST_SIZE, BURST_SIZE);
}

void ScuTimer_IRQ_Handler(void *CallBackRef)
{
	/* ↓↓↓用户处理↓↓↓ */
	lv_tick_inc(1);
	/* ↑↑↑结束处理↑↑↑ */
    XScuTimer_ClearInterruptStatus(&ScuTimer);
}

LV_IMG_DECLARE(bb);

 void run_picture()
 {
     lv_obj_t *img = lv_img_create(lv_scr_act());
     lv_img_set_src(img, &bb);
}


int main(void)
{
	//Xil_DCacheDisable();
	Xil_MemMap(0x10500000, 48U * 1024U, NORM_NONCACHE);


    PS_GPIO_Init();
    PS_GPIO_SetMode(LCD_RST_PIN, OUTPUT, 1);
	PS_GPIO_SetMode(LCD_NSS_PIN, OUTPUT, 1);
    AXI_SPI_Init(&AXI_SPI0, XPAR_SPI_0_DEVICE_ID, XSP_MASTER_OPTION);

	do_reset();
	seqs_init();

	usleep(100*1000);

	/* lvgl??? */
	lv_init();
	lv_port_disp_init();
//	lv_port_indev_init();
//	lv_log_register_print_cb(xil_printf);


	/* 私有定时器初始化 */
	ScuGic_Init();
	ScuTimer_Int_Init(1000);

	/* ??demo */
	//lv_demo_printer();
	//lv_demo_keypad_encoder();
	//lv_demo_widgets();
	lv_demo_stress();
	//lv_demo_benchmark();
	//run_picture();

	/* ??? */
	for ( ; ; ) {
		lv_task_handler();
		usleep(5 * 1000);
	}

	while(1) {
	}

}

lv_port_disp_template.c/h

/**
 * @file lv_port_disp_templ.c
 *
 */

 /*Copy this file as "lv_port_disp.c" and set this value to "1" to enable content*/
#if 1

/*********************
 *      INCLUDES
 *********************/
#include "lv_port_disp_template.h"
#include "../../lvgl.h"

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static void disp_init(void);

static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
//static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
//        const lv_area_t * fill_area, lv_color_t color);

/**********************
 *  STATIC VARIABLES
 **********************/

/**********************
 *      MACROS
 **********************/
#define MY_DISP_HOR_RES 360
#define MY_DISP_VER_RES 360
#define LV_VER_RES_MAX 360
/**********************
 *   GLOBAL FUNCTIONS
 **********************/

void lv_port_disp_init(void)
{
    /*-------------------------
     * Initialize your display
     * -----------------------*/
    disp_init();

    /* Example for 1) */
    // static lv_disp_draw_buf_t draw_buf_dsc_1;
    // static lv_color_t buf_1[MY_DISP_HOR_RES * 10];                          /*A buffer for 10 rows*/
    // lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, MY_DISP_HOR_RES * 10);   /*Initialize the display buffer*/

    // /* Example for 2) */
    // static lv_disp_draw_buf_t draw_buf_dsc_2;
    // static lv_color_t buf_2_1[MY_DISP_HOR_RES * 10];                        /*A buffer for 10 rows*/
    // static lv_color_t buf_2_2[MY_DISP_HOR_RES * 10];                        /*An other buffer for 10 rows*/
    // lv_disp_draw_buf_init(&draw_buf_dsc_2, buf_2_1, buf_2_2, MY_DISP_HOR_RES * 10);   /*Initialize the display buffer*/

    /* Example for 3) also set disp_drv.full_refresh = 1 below*/
    static lv_disp_draw_buf_t draw_buf_dsc_3;
    static lv_color_t buf_3_1[MY_DISP_HOR_RES * MY_DISP_VER_RES];            /*A screen sized buffer*/
    static lv_color_t buf_3_2[MY_DISP_HOR_RES * MY_DISP_VER_RES];            /*Another screen sized buffer*/
    lv_disp_draw_buf_init(&draw_buf_dsc_3, buf_3_1, buf_3_2, MY_DISP_VER_RES * LV_VER_RES_MAX);   /*Initialize the display buffer*/

    /*-----------------------------------
     * Register the display in LVGL
     *----------------------------------*/

    static lv_disp_drv_t disp_drv;                         /*Descriptor of a display driver*/
    lv_disp_drv_init(&disp_drv);                    /*Basic initialization*/

    /*Set up the functions to access to your display*/

    /*Set the resolution of the display*/
    disp_drv.hor_res = 360;
    disp_drv.ver_res = 360;

    /*Used to copy the buffer's content to the display*/
    disp_drv.flush_cb = disp_flush;

    /*Set a display buffer*/
    disp_drv.draw_buf = &draw_buf_dsc_3;

    /*Required for Example 3)*/
    //disp_drv.full_refresh = 1

    /* Fill a memory array with a color if you have GPU.
     * Note that, in lv_conf.h you can enable GPUs that has built-in support in LVGL.
     * But if you have a different GPU you can use with this callback.*/
    //disp_drv.gpu_fill_cb = gpu_fill;

    /*Finally register the driver*/
    lv_disp_drv_register(&disp_drv);
}

/**********************
 *   STATIC FUNCTIONS
 **********************/

/*Initialize your display and the required peripherals.*/
static void disp_init(void)
{
    /*You code here*/
}

/*Flush the content of the internal buffer the specific area on the display
 *You can use DMA or any hardware acceleration to do this operation in the background but
 *'lv_disp_flush_ready()' has to be called when finished.*/
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/

    // int32_t x;
    // int32_t y;
    // for(y = area->y1; y <= area->y2; y++) {
    //     for(x = area->x1; x <= area->x2; x++) {
    //         /*Put a pixel to the display. For example:*/
    //         /*put_px(x, y, *color_p)*/
    //         color_p++;
    //     }
    // }

    xil_printf("x0=%d, x1=%d, y0=%d, y1=%d\r\n", area->x1,area->x2,area->y1,area->y2);
    extern void lcdqspi_fill_pcolor(uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint16_t *pcolor);
    lcdqspi_fill_pcolor(area->x1,area->y1,area->x2,area->y2, color_p);
    /*IMPORTANT!!!
     *Inform the graphics library that you are ready with the flushing*/
    lv_disp_flush_ready(disp_drv);
}

/*OPTIONAL: GPU INTERFACE*/

/*If your MCU has hardware accelerator (GPU) then you can use it to fill a memory with a color*/
//static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
//                    const lv_area_t * fill_area, lv_color_t color)
//{
//    /*It's an example code which should be done by your GPU*/
//    int32_t x, y;
//    dest_buf += dest_width * fill_area->y1; /*Go to the first line*/
//
//    for(y = fill_area->y1; y <= fill_area->y2; y++) {
//        for(x = fill_area->x1; x <= fill_area->x2; x++) {
//            dest_buf[x] = color;
//        }
//        dest_buf+=dest_width;    /*Go to the next line*/
//    }
//}


#else /*Enable this file at the top*/

/*This dummy typedef exists purely to silence -Wpedantic.*/
typedef int keep_pedantic_happy;
#endif

整个效果还不错

⚠️ **GitHub.com Fallback** ⚠️