bakup - minichao9901/TangNano-20k-Zynq-7020 GitHub Wiki

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xil_io.h"
#include "sleep.h"
//#include "ff.h"
#include "xil_cache.h"
#include "xtime_l.h"


#define  RED        0xF800
#define  ORANGE     0xFC00
#define  YELLOW     0xFFE0
#define  GREEN      0x07E0
#define  CYAN       0x07FF
#define  BLUE       0x001F
#define  PURPPLE    0xF81F
#define  BLACK      0x0000
#define  WHITE      0xFFFF
#define  GRAY       0xD69A

const u16 colors[] = {
	RED,
	GREEN,
	BLUE,
	ORANGE,
	YELLOW,
	CYAN,
	PURPPLE,
	BLACK,
	WHITE,
	GRAY
};

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

//#define BIST_MODE
t_buf WriteBuffer[]={
		{{0xf0, 0xc3}, {0x00},2},
		{{0xf0, 0x96}, {0x00},2},
		{{0xf0, 0xa5}, {0x00},2},
		{{0xe9, 0x20}, {0x00},2},
		{{0xe7,  0x80, 0x77, 0x1f, 0xcc}, {0x00}, 5},
		{{0xc1,  0x77, 0x07, 0xcf, 0x16}, {0x00},5},//Normal:VGHS/VGLS/VSP/VSN电压
		{{0xc2,  0x77, 0x07, 0xcf, 0x16}, {0x00},5},//Idle: VGHS/VGLS/VSP/VSN电压
		{{0xc3,  0x22, 0x02, 0x22, 0x04}, {0x00},5},//Normal: VGH/VGL/VSP/VSN Clk
		{{0xc4,  0x22, 0x02, 0x22, 0x04}, {0x00},5},//Idle: VGH/VGL/VSP/VSN Clk
		{{0xc5,  0xed},{0x00},2}, //VCOM
		{{0xe0, 0x87, 0x09, 0x0c, 0x06, 0x05, 0x03, 0x29, 0x32, 0x49, 0x0f, 0x1b, 0x17, 0x2a, 0x2f},{0x00},15},
		{{0xe1, 0x87, 0x09, 0x0c, 0x06, 0x05, 0x03, 0x29, 0x32, 0x49, 0x0f, 0x1b, 0x17, 0x2a, 0x2f},{0x00},15},
		{{0xe5, 0xbe, 0xf5, 0xb1, 0x22, 0x22, 0x25, 0x10, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22},{0x00},15},
		{{0xe6, 0xbe, 0xf5, 0xb1, 0x22, 0x22, 0x25, 0x10, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22},{0x00},15},
		{{0xec, 0x40, 0x03},{0x00},3},
		{{0x36,  0x0c},{0x00},2},
		{{0x3a,  0x07},{0x00},2},
		{{0xb2,  0x00},{0x00},2},//GIP pattern
		{{0xb3,  0x01},{0x00},2},//video mode dot-inversion
		{{0xb4,  0x01},{0x00},2},
		{{0xb5,  0x00, 0x08, 0x00, 0x08},{0x00},5}, //vfp
		{{0xb6,  0xc7, 0x31},{0x00},3},
		{{0xa5,  0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x2a, 0x8a, 0x02},{0x00},10},
		{{0xa6,  0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x2a, 0x8a, 0x02},{0x00},10},
		{{0xba,  0x0a, 0x5a, 0x23, 0x10, 0x25, 0x02, 0x00},{0x00},8},
		{{0xbb,  0x00, 0x30, 0x00, 0x2c, 0x82, 0x87, 0x18, 0x00},{0x00},9},
		{{0xbc,  0x00, 0x30, 0x00, 0x2c, 0x82, 0x87, 0x18, 0x00},{0x00},9},
		{{0xbd, 0xa1, 0xb2, 0x2b, 0x1a, 0x56, 0x43, 0x34, 0x65, 0xff, 0xff, 0x0f},{0x00},12},
		{{0x35,  0x00},{0x00},2},
		{{0x21},{0x00},1},
		{{0x11},{0x00},1},
		{{0xff},{0x00},0},
		{{0x29},{0x00},1},
		{{0xff},{0x00},0},
		#ifdef BIST_MODE
		{{0xb0,  0xa5},{0x00},2},
		{{0xcc,  0x40, 0x00, 0x3f, 0x00, 0x14, 0x14, 0x20, 0x20, 0x03},{0x00},10},
		#endif
};

/*************************************************
 * reg rw functions
 ************************************************/
#define DMA_BASE_ADRR  0x40000000
#define DDR_BASE_ADDR  0x10000000

void wait_for_idle()
{
	u32 tmp;
	while(1){
		tmp=Xil_In32(DMA_BASE_ADRR+04);
		if(((tmp>>1)&0x1) == 1){
			break;
		}
	}
}

void dma_xfer(u32 mem_addr, u32 length)
{
	Xil_Out32(DMA_BASE_ADRR,  0x00010003);
	Xil_Out32(DMA_BASE_ADRR+0x30,  0x00010003);
	Xil_Out32(DMA_BASE_ADRR+0x18,  mem_addr);
	Xil_Out32(DMA_BASE_ADRR+0x28,  length);	 /*length is bytes*/
	wait_for_idle();
	//usleep(10);
}

void set_cfg(u32 mem_addr, u8 cmd, u8 addr, u8 mode, u8 work_mode, u16 length)
{
	u32 tmp=cmd;
	tmp|=addr<<8;
	tmp|=mode<<16;
	tmp|=length<<20;
	tmp|=work_mode<<30;
	Xil_Out32(mem_addr,  tmp);
}

u32 get_cfg(u8 cmd, u8 addr, u8 mode, u16 length)
{
	u32 tmp=cmd;
	tmp|=addr<<8;
	tmp|=mode<<16;
	tmp|=length<<20;
	return tmp;
}

void set_npdata8(u32 mem_addr, u8 *pdata, u32 length){
	u32 addr=mem_addr;
	while(length--){
		Xil_Out8(addr++, *pdata++);
	}
}

//void set_npdata16_fast(u32 mem_addr, u16 *pdata, u32 length){
//	/*每次传一个u32,数量减半*/
//	u16 *ptmp=pdata;
//	u32 addr=mem_addr;
//	while(length){
////		u16 tmp=((*ptmp&0xff)<<8)+(*ptmp>>8); /*msb&lsb swap*/
//		u16 tmp1=*ptmp;
//		u16 tmp2=*(ptmp+1);
//		u32 tmp=(tmp2<<16)+tmp1;
//		Xil_Out32(addr, tmp);
//		addr+=4;
//		ptmp+=2;
//		length-=2;
//	}
//}


/*************************************************
 * basic xfer functions
 ************************************************/
void xfer_cmd_pdata8(u32 mem_addr, u8 cmd, u8* pdata, u32 length){
	if(length==0)
		set_cfg(mem_addr, 0xde, cmd, 0b0101, 0b00, length);  /*byte_mode=0, cs_mode=1, data_mode=0b01*/
	else
		set_cfg(mem_addr, 0xde, cmd, 0b0110, 0b00, length); /*byte_mode=0, cs_mode=1, data_mode=0b10*/

	set_npdata8(mem_addr+4, pdata,length);
	dma_xfer(mem_addr, 4+length);
}

void xfer_cmd_enter_stream(u32 mem_addr){
	set_cfg(mem_addr, 0xde, 0x00, 0b0111, 0b00, 0);
	dma_xfer(mem_addr, 4);
}

//void xfer_cmd_pdata16(u32 mem_addr, u8 cmd, u16* pdata, u32 length /*w16 counts*/){
//	u32 remain=length;
//	u32 mem_addr_keep=mem_addr;
//	u32 max_burst_w16=30;
//	u32 burst_cnt=0;
//
//	while(remain>=max_burst_w16){
//		if(remain>max_burst_w16)
//			set_cfg(mem_addr, 0xde, cmd, 0b0011, 2*max_burst_w16);  /*byte_mode=0, cs_mode=0, data_mode=0b11*/
//		else
//			set_cfg(mem_addr, 0xde, cmd, 0b0111, 2*max_burst_w16);  /*byte_mode=0, cs_mode=1, data_mode=0b11*/
//
//		set_npdata16_fast(mem_addr+4, pdata, max_burst_w16);
//		pdata+=max_burst_w16;
//		remain-=max_burst_w16;
//		mem_addr+=4+2*max_burst_w16;
//		burst_cnt++;
//	}
//
//	//last part
//	if(remain>0){
//		set_cfg(mem_addr, 0xde, cmd, 0b1111, 2*remain);  /*byte_mode=1, cs_mode=1, data_mode=0b11*/
//		set_npdata16_fast(mem_addr+4, pdata, remain);
//		burst_cnt++;
//	}
//
//	dma_xfer(mem_addr_keep, 64*burst_cnt);
//}

void xfer_cmd_pdata16_dma(u32 mem_addr, u32 length){
	//dma_xfer(mem_addr, 20*64);
	dma_xfer(mem_addr, length);
}


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;

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

/*************************************************
 * application functions
 ************************************************/

#define LCD_BPP             (24)

#define LCD_X_SIZE          (400U)                      /* available x pixel size */
#define LCD_Y_SIZE          (400U)		                /* available y pixle size */
#define LCD_PBYTE           ((LCD_BPP + 0) / 8)         /* bytes in pixel unit */
#define LCD_HBYTE           (LCD_X_SIZE * LCD_PBYTE)    /* bytes in horizontal line */

#define LCD_VSW             (1U)
#define LCD_HFP             (8U)
#define LCD_HBP             (8U)

#define LCD_TE_OFT          (25U)


typedef u8 (*ArrayPtr)[400][20 * 64];
ArrayPtr ptr1=(ArrayPtr)0x10100000;
ArrayPtr ptr2=(ArrayPtr)0x10200000;
ArrayPtr ptr3=(ArrayPtr)0x10300000;
ArrayPtr ptr4=(ArrayPtr)0x10400000;
ArrayPtr ptr5=(ArrayPtr)0x10500000;
ArrayPtr ptr6=(ArrayPtr)0x10600000;
ArrayPtr ptr7=(ArrayPtr)0x10700000;
ArrayPtr ptr8=(ArrayPtr)0x10800000;

void fill_data(ArrayPtr ptr, u8 r, u8 g, u8 b) {
    u32 cmd1 = get_cfg(0xde, 0x60, 0b0011, 60);
    u32 cmd2 = get_cfg(0xde, 0x60, 0b0111, 60);

    // 遍历数组的每一行
    for (int i = 0; i < 400; ++i) {
        // 遍历每一行的每一个packet
        for (int j = 0; j < 20; ++j) {
            // 计算当前packet的起始地址
        	u8 *packet = (u8 *)(ptr + i) + j * 64; // ptr指向整个二维数组,ptr+i指向第i行,然后加上j个packet的偏移

            // 填充cmd部分
            u32 *cmd_ptr = (u32 *)packet;
            *cmd_ptr = (j == 19) ? cmd2 : cmd1; // 第20个packet使用cmd2,其余使用cmd1

            // 移动到color数据部分的起始地址
            //packet += sizeof(cmd1);

            // 填充color数据部分
            for (int k = 0; k < 60; k += 3) {
                packet[k] = r;
                packet[k + 1] = g;
                packet[k + 2] = b;
            }
        }
    }
}

void fill_color()
{
	for(int i=0; i<8; i++){
			switch(i){
			case 0: fill_data(ptr1, 0xff,0x00,0x00); break;
			case 1: fill_data(ptr2, 0x00,0xff,0x00); break;
			case 2: fill_data(ptr3, 0x00,0x00,0xff); break;
			case 3: fill_data(ptr4, 0xff,0xff,0x00); break;
			case 4: fill_data(ptr5, 0xff,0x00,0xff); break;
			case 5: fill_data(ptr6, 0x00,0xff,0xff); break;
			case 6: fill_data(ptr7, 0xff,0xff,0xff); break;
			case 7: fill_data(ptr8, 0x00,0x00,0x00); break;
			}
	}
}

ArrayPtr get_color_ptr(u32 index)
{
	ArrayPtr tmp;
	switch(index){
		case 0: tmp=ptr1; break;
		case 1: tmp=ptr2; break;
		case 2: tmp=ptr3; break;
		case 3: tmp=ptr4; break;
		case 4: tmp=ptr5; break;
		case 5: tmp=ptr6; break;
		case 6: tmp=ptr7; break;
		case 7: tmp=ptr8; break;
	}

	return tmp;
}

void dram_eight_colors()
{
	u32 loop_cnt=0;
	u8 color_index=0;
	fill_color();

    while (1)
    {
    	ArrayPtr my_ptr=get_color_ptr(color_index);

        /* vs(0x61) packet */
        for (int i = 0; i < LCD_VSW; i++)
        {
        	xfer_cmd_pdata8(DDR_BASE_ADDR, 0x61,NULL,0);
            usleep(40);
        }

        /* hbp(0x60) packet */
        for (int i = 0; i < LCD_HBP; i++)
        {
        	xfer_cmd_pdata8(DDR_BASE_ADDR, 0x60,NULL,0);
            usleep(40);
        }

        /* transmit display cache data to lcd line by line */
        for (int i = 0; i < LCD_Y_SIZE; i+=1)
        {
            //xfer_cmd_enter_stream(DDR_BASE_ADDR);
        	xfer_cmd_pdata16_dma((u32)my_ptr[i],20*64);
            //usleep(35);
        }


        /* hfp(0x60) packet */
        for (int i = 0; i < LCD_HFP; i++)
        {
        	xfer_cmd_pdata8(DDR_BASE_ADDR, 0x60,NULL,0);
            usleep(40);
        }

        loop_cnt++;
        if(loop_cnt%60==0){
			color_index++;
			if(color_index==8)
				color_index=0;
        }
    }

}

int main()
{
    init_platform();
    //cmda_init();
    //Xil_Disable_Cache_On_OCM();
    Xil_DCacheDisable();

    print("Hello World\n\r");

    //MY_QSPI_IP_Reg_SelfTest((void *)QSPI_BASE);

	seqs_init();
	dram_eight_colors();

    //draw_bmp();
    //draw_movie();

    cleanup_platform();
    return 0;
}

image image

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xil_io.h"
#include "sleep.h"
#include "ff.h"
#include "xil_cache.h"
#include "xtime_l.h"
#include <string.h>


#define  RED        0xF800
#define  ORANGE     0xFC00
#define  YELLOW     0xFFE0
#define  GREEN      0x07E0
#define  CYAN       0x07FF
#define  BLUE       0x001F
#define  PURPPLE    0xF81F
#define  BLACK      0x0000
#define  WHITE      0xFFFF
#define  GRAY       0xD69A

const u16 colors[] = {
	RED,
	GREEN,
	BLUE,
	ORANGE,
	YELLOW,
	CYAN,
	PURPPLE,
	BLACK,
	WHITE,
	GRAY
};

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

//#define BIST_MODE
t_buf WriteBuffer[]={
		{{0xf0, 0xc3}, {0x00},2},
		{{0xf0, 0x96}, {0x00},2},
		{{0xf0, 0xa5}, {0x00},2},
		{{0xe9, 0x20}, {0x00},2},
		{{0xe7,  0x80, 0x77, 0x1f, 0xcc}, {0x00}, 5},
		{{0xc1,  0x77, 0x07, 0xcf, 0x16}, {0x00},5},//Normal:VGHS/VGLS/VSP/VSN电压
		{{0xc2,  0x77, 0x07, 0xcf, 0x16}, {0x00},5},//Idle: VGHS/VGLS/VSP/VSN电压
		{{0xc3,  0x22, 0x02, 0x22, 0x04}, {0x00},5},//Normal: VGH/VGL/VSP/VSN Clk
		{{0xc4,  0x22, 0x02, 0x22, 0x04}, {0x00},5},//Idle: VGH/VGL/VSP/VSN Clk
		{{0xc5,  0xed},{0x00},2}, //VCOM
		{{0xe0, 0x87, 0x09, 0x0c, 0x06, 0x05, 0x03, 0x29, 0x32, 0x49, 0x0f, 0x1b, 0x17, 0x2a, 0x2f},{0x00},15},
		{{0xe1, 0x87, 0x09, 0x0c, 0x06, 0x05, 0x03, 0x29, 0x32, 0x49, 0x0f, 0x1b, 0x17, 0x2a, 0x2f},{0x00},15},
		{{0xe5, 0xbe, 0xf5, 0xb1, 0x22, 0x22, 0x25, 0x10, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22},{0x00},15},
		{{0xe6, 0xbe, 0xf5, 0xb1, 0x22, 0x22, 0x25, 0x10, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22},{0x00},15},
		{{0xec, 0x40, 0x03},{0x00},3},
		{{0x36,  0x0c},{0x00},2},
		{{0x3a,  0x07},{0x00},2},
		{{0xb2,  0x00},{0x00},2},//GIP pattern
		{{0xb3,  0x01},{0x00},2},//video mode dot-inversion
		{{0xb4,  0x01},{0x00},2},
		{{0xb5,  0x00, 0x08, 0x00, 0x08},{0x00},5}, //vfp
		{{0xb6,  0xc7, 0x31},{0x00},3},
		{{0xa5,  0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x2a, 0x8a, 0x02},{0x00},10},
		{{0xa6,  0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x2a, 0x8a, 0x02},{0x00},10},
		{{0xba,  0x0a, 0x5a, 0x23, 0x10, 0x25, 0x02, 0x00},{0x00},8},
		{{0xbb,  0x00, 0x30, 0x00, 0x2c, 0x82, 0x87, 0x18, 0x00},{0x00},9},
		{{0xbc,  0x00, 0x30, 0x00, 0x2c, 0x82, 0x87, 0x18, 0x00},{0x00},9},
		{{0xbd, 0xa1, 0xb2, 0x2b, 0x1a, 0x56, 0x43, 0x34, 0x65, 0xff, 0xff, 0x0f},{0x00},12},
		{{0x35,  0x00},{0x00},2},
		{{0x21},{0x00},1},
		{{0x11},{0x00},1},
		{{0xff},{0x00},0},
		{{0x29},{0x00},1},
		{{0xff},{0x00},0},
		#ifdef BIST_MODE
		{{0xb0,  0xa5},{0x00},2},
		{{0xcc,  0x40, 0x00, 0x3f, 0x00, 0x14, 0x14, 0x20, 0x20, 0x03},{0x00},10},
		#endif
};

/*************************************************
 * reg rw functions
 ************************************************/
#define DMA_BASE_ADRR  0x40000000
#define DDR_BASE_ADDR  0x10000000

void wait_for_idle()
{
	u32 tmp;
	while(1){
		tmp=Xil_In32(DMA_BASE_ADRR+04);
		if(((tmp>>1)&0x1) == 1){
			break;
		}
	}
}

void dma_xfer(u32 mem_addr, u32 length)
{
	//Xil_DCacheFlushRange(mem_addr, length);

	Xil_Out32(DMA_BASE_ADRR,  0x00010003);
	Xil_Out32(DMA_BASE_ADRR+0x30,  0x00010003);
	Xil_Out32(DMA_BASE_ADRR+0x18,  mem_addr);
	Xil_Out32(DMA_BASE_ADRR+0x28,  length);	 /*length is bytes*/
	wait_for_idle();
//	usleep(10);
//	xil_printf("%x, %d\r\n",mem_addr, length);
}

void set_cfg(u32 mem_addr, u8 cmd, u8 addr, u8 mode, u8 work_mode, u16 length)
{
	u32 tmp=cmd;
	tmp|=addr<<8;
	tmp|=mode<<16;
	tmp|=length<<20;
//	tmp|=work_mode<<30;
	Xil_Out32(mem_addr,  tmp);
}

u32 get_cfg(u8 cmd, u8 addr, u8 mode, u8 work_mode, u16 length)
{
	u32 tmp=cmd;
	tmp|=addr<<8;
	tmp|=mode<<16;
	tmp|=length<<20;
//	tmp|=work_mode<<30;
	return tmp;
}

void set_npdata8(u32 mem_addr, u8 *pdata, u32 length){
	u32 addr=mem_addr;
	while(length--){
		Xil_Out8(addr++, *pdata++);
	}
}


/*************************************************
 * basic xfer functions
 ************************************************/
void xfer_cmd_pdata8(u32 mem_addr, u8 cmd, u8* pdata, u32 length){
	if(length==0)
		set_cfg(mem_addr, 0xde, cmd, 0b0101, 0b00, length);  /*byte_mode=0, cs_mode=1, data_mode=0b01*/
	else
		set_cfg(mem_addr, 0xde, cmd, 0b0110, 0b00, length); /*byte_mode=0, cs_mode=1, data_mode=0b10*/

	set_npdata8(mem_addr+4, pdata,length);
	dma_xfer(mem_addr, 4+length);
}

void xfer_cmd_enter_stream(u32 mem_addr){
//	memset((void *)mem_addr, 0, 20*64);
	set_cfg(mem_addr, 0xde, 0x00, 0b0111, 0b11, 4);
	dma_xfer(mem_addr, 8);
}


void xfer_cmd_pdata16_dma(u32 mem_addr, u32 length){
	//dma_xfer(mem_addr, 20*64);
	dma_xfer(mem_addr, length);
}


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;

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

/*************************************************
 * application functions
 ************************************************/
u8 frame_src[1920*1080*3];
u8 frame_target[400*400*3];

void load_sd_bmp(u8 *frame, const char *bmp_name);
void convertRGB888toRGB888(
		const uint8_t *input,
		uint8_t *output,
		int inputWidth, int inputHeight,
		int startX, int startY,
		int outputWidth, int outputHeight
		) ;


#define LCD_BPP             (24)

#define LCD_X_SIZE          (400U)                      /* available x pixel size */
#define LCD_Y_SIZE          (400U)		                /* available y pixle size */
#define LCD_PBYTE           ((LCD_BPP + 0) / 8)         /* bytes in pixel unit */
#define LCD_HBYTE           (LCD_X_SIZE * LCD_PBYTE)    /* bytes in horizontal line */

#define LCD_VSW             (1U)
#define LCD_HFP             (8U)
#define LCD_HBP             (8U)

#define LCD_TE_OFT          (25U)


typedef u8 (*ArrayPtr)[400][20 * 64];
ArrayPtr ptr1=(ArrayPtr)0x11000000;
ArrayPtr ptr2=(ArrayPtr)0x10200000;
ArrayPtr ptr3=(ArrayPtr)0x10300000;
ArrayPtr ptr4=(ArrayPtr)0x10400000;
ArrayPtr ptr5=(ArrayPtr)0x10500000;
ArrayPtr ptr6=(ArrayPtr)0x10600000;
ArrayPtr ptr7=(ArrayPtr)0x10700000;
ArrayPtr ptr8=(ArrayPtr)0x10800000;



void fill_pic(ArrayPtr ptr, u8 *pcolor) {
    u32 cmd1 = get_cfg(0xde, 0x60, 0b0011, 0b00, 60);
    u32 cmd2 = get_cfg(0xde, 0x60, 0b0111, 0b00, 60);

    // 遍历数组的每一行
    for (int i = 0; i < 400; ++i) {
        // 遍历每一行的每一个packet
        for (int j = 0; j < 20; ++j) {
            // 计算当前packet的起始地址
        	u8 *packet = (u8 *)(ptr + i) + j * 64; // ptr指向整个二维数组,ptr+i指向第i行,然后加上j个packet的偏移

            // 填充cmd部分
            u32 *cmd_ptr = (u32 *)packet;
            *cmd_ptr = (j == 19) ? cmd2 : cmd1; // 第20个packet使用cmd2,其余使用cmd1

            // 移动到color数据部分的起始地址
            packet += sizeof(cmd1);

            // 填充color数据部分
        	memcpy(packet, pcolor, 60);
        	pcolor+=60;
//            for (int k = 0; k < 60; k += 3) {
//            	u8 b=*pcolor++;
//            	u8 g=*pcolor++;
//            	u8 r=*pcolor++;
//
//                packet[k] = r;
//                packet[k + 1] = g;
//                packet[k + 2] = b;
//            }
        }
    }
}

u32 get_ptr(const uint8_t *input, int inputWidth, int inputHeight, int startX, int startY, int line_num, int offset_num)
{
	int lineIndex = ((startY + line_num) * inputWidth + startX+ offset_num*20) * 3;
	u32 ptr=(u32)&input[lineIndex];
	//xil_printf("%x\r\n",ptr);
	return ptr;
}

XTime t1,t2,t3,t4;
void draw_bmp()
{
//	XTime_GetTime(&t1);
	load_sd_bmp(frame_src, "shatan.bmp");	//1920x1080
	XTime_GetTime(&t2);
	xil_printf("%x, %x\r\n", frame_src, frame_target);
	convertRGB888toRGB888(
			frame_src,
			frame_target,
			1920,1080,
			500,500,
			400,400
			);
	XTime_GetTime(&t3);
	fill_pic(ptr1,frame_target);
	XTime_GetTime(&t4);

	XTime dt21 = ((t2-t1) * 1000000) / (COUNTS_PER_SECOND);
	XTime dt32 = ((t3-t2) * 1000000) / (COUNTS_PER_SECOND);
	XTime dt43 = ((t4-t3) * 1000000) / (COUNTS_PER_SECOND);
	xil_printf("dt21=%d, dt32=%d, dt43=%d\r\n", dt21,dt32,dt43);

    while (1)
    {

        /* vs(0x61) packet */
        for (int i = 0; i < LCD_VSW; i++)
        {
        	xfer_cmd_pdata8(DDR_BASE_ADDR, 0x61,NULL,0);
            usleep(40);
        }

        /* hbp(0x60) packet */
        for (int i = 0; i < LCD_HBP; i++)
        {
        	xfer_cmd_pdata8(DDR_BASE_ADDR, 0x60,NULL,0);
            usleep(40);
        }

        /* transmit display cache data to lcd line by line */
        for (int i = 0; i < LCD_Y_SIZE; i+=1)
        {
            //xfer_cmd_enter_stream(DDR_BASE_ADDR);
            xfer_cmd_pdata16_dma((u32)ptr1[i],20*64);
//            for(int j=0; j<20; j++){
//				u32 ptr=get_ptr(
//						frame_src,
//						1920,1080,
//						500,500,
//						i,j
//						);
//            	xfer_cmd_pdata16_dma(ptr,64);
//            }
            //usleep(35);
        }


        /* hfp(0x60) packet */
        for (int i = 0; i < LCD_HFP; i++)
        {
        	xfer_cmd_pdata8(DDR_BASE_ADDR, 0x60,NULL,0);
            usleep(40);
        }

    }
}

int main()
{
    init_platform();
    //cmda_init();
    //Xil_Disable_Cache_On_OCM();
    Xil_DCacheDisable();

    print("Hello World\n\r");

    //MY_QSPI_IP_Reg_SelfTest((void *)QSPI_BASE);

	seqs_init();
	//dram_eight_colors();

    draw_bmp();
    //draw_movie();

    cleanup_platform();
    return 0;
}


//从SD卡中读取BMP图片
void load_sd_bmp(u8 *frame, const char *bmp_name)
{
	static 	FATFS fatfs;
	FIL 	fil;
	u8		bmp_head[54];
	UINT 	bmp_width,bmp_height,bmp_size;
	UINT 	br;

	f_mount(&fatfs,"",1);//挂载文件系统

	f_open(&fil, bmp_name,FA_READ);	//打开文件, 注意是bmp_24bits格式
	xil_printf("open bmp\n\r");
	f_lseek(&fil,0);//移动文件读写指针到文件开头

	f_read(&fil,bmp_head,54,&br);//读取BMP文件头

	//BMP图片的分辨率和大小
	bmp_width  = *(UINT *)(bmp_head + 0x12);
	bmp_height = *(UINT *)(bmp_head + 0x16);
	bmp_size   = *(UINT *)(bmp_head + 0x22);
	xil_printf("bmp information:\n\r");
	xil_printf(" width  = %d,\n\r height = %d,\n\r size   = %d bytes \n\r",
			bmp_width,bmp_height,bmp_size);

	//读出图片,写入DDR
	f_read(&fil, frame, bmp_width*bmp_height*3,&br);
	xil_printf("br=%d\r\n", br);

	for(int i=0; i<20; i++){
		xil_printf("%x\r\n", frame[i]);
	}

	//关闭文件
	f_close(&fil);

	Xil_DCacheFlush();     //刷新Cache,将数据更新至DDR3中
	xil_printf("display bmp\n\r");
}


void convertRGB888toRGB888(const uint8_t *input, uint8_t *output, int inputWidth, int inputHeight, int startX, int startY, int outputWidth, int outputHeight)
{
    int i, j;

    for (i = 0; i < outputHeight; i++) {
        for (j = 0; j < outputWidth; j++) {
            // Calculate the index in the RGB888 array
            int inputIndex = ((startY + i) * inputWidth + startX + j) * 3;

            // Extract RGB888 components
            uint8_t b = input[inputIndex];
            uint8_t g = input[inputIndex + 1];
            uint8_t r = input[inputIndex + 2];

            int outputIndex=(i * outputWidth + j)*3;
            // Store in the output array
            output[outputIndex] = b;
            output[outputIndex+1] = g;
            output[outputIndex+2] = r;
        }
    }
}

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