// --------------------------------------------------------------------
// Copyright (c) 2019 by MicroPhase Technologies Inc.
// --------------------------------------------------------------------
//
// Permission:
//
// MicroPhase grants permission to use and modify this code for use
// in synthesis for all MicroPhase Development Boards.
// Other use of this code, including the selling
// ,duplication, or modification of any portion is strictly prohibited.
//
// Disclaimer:
//
// This VHDL/Verilog or C/C++ source code is intended as a design reference
// which illustrates how these types of functions can be implemented.
// It is the user's responsibility to verify their design for
// consistency and functionality through the use of formal
// verification methods. MicroPhase provides no warranty regarding the use
// or functionality of this code.
//
// --------------------------------------------------------------------
//
// MicroPhase Technologies Inc
// Shanghai, China
//
// web: http://www.microphase.cn/
// email: [email protected]
//
// --------------------------------------------------------------------
// --------------------------------------------------------------------
//
// Major Functions:
//
// --------------------------------------------------------------------
// --------------------------------------------------------------------
//
// Revision History:
// Date By Revision Change Description
//---------------------------------------------------------------------
//2020-02-22 Wang 1.0 Original
//2020- 1.1
// --------------------------------------------------------------------
// --------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xil_types.h"
#include "xil_cache.h"
#include "xparameters.h"
#include "xaxivdma.h"
#include "xaxivdma_i.h"
#include "display_ctrl/display_ctrl.h"
#include "vdma_api/vdma_api.h"
#include "ff.h"
#include "sleep.h"
//宏定义
#define BYTES_PIXEL 3 //像素字节数,RGB888占3个字节
#define DYNCLK_BASEADDR XPAR_AXI_DYNCLK_0_BASEADDR //动态时钟基地址
#define VDMA_ID XPAR_AXIVDMA_0_DEVICE_ID //VDMA器件ID
#define DISP_VTC_ID XPAR_VTC_0_DEVICE_ID //VTC器件ID
//函数声明
void load_sd_bmp(u8 *frame);
//全局变量
XAxiVdma vdma;
DisplayCtrl dispCtrl;
VideoMode vd_mode;
//frame buffer的起始地址
unsigned int const frame_buffer_addr = (XPAR_PS7_DDR_0_S_AXI_BASEADDR + 0x1000000);
void init()
{
Xil_Out32(0x43000000,0x4);
Xil_Out32(0x43000000,0x0001000a);
Xil_Out32(0x43000054,0x960);
Xil_Out32(0x43000058,0x960);
Xil_Out32(0x4300005c,0x1100000);
Xil_Out32(0x43000000,0x0001400a);
Xil_Out32(0x43000000,0x0001400b);
Xil_Out32(0x43000050,0x1e0);
//usleep(1000);
Xil_Out32(0x43c10008,0x800083);
Xil_Out32(0x43c1000c,0x800411);
Xil_Out32(0x43c10010,0x0);
Xil_Out32(0x43c10014,0x82);
Xil_Out32(0x43c10018,0xd2cfa401);
Xil_Out32(0x43c1001c,0x006300ff);
Xil_Out32(0x43c10000,0x1);
//usleep(1000);
Xil_Out32(0x43c10008,0x800083);
Xil_Out32(0x43c1000c,0x800411);
Xil_Out32(0x43c10010,0x0);
Xil_Out32(0x43c10014,0x82);
Xil_Out32(0x43c10018,0xd2cfa401);
Xil_Out32(0x43c1001c,0x006300ff);
Xil_Out32(0x43c10000,0x0);
Xil_Out32(0x43c10000,0x1);
usleep(1000); /*这个delay是必须要有的,否则时钟配不成功(因为有个PLL要锁定)*/
Xil_Out32(0x43c00000,0x2);
Xil_Out32(0x43c0006c,0x70);
Xil_Out32(0x43c00070,0x421);
Xil_Out32(0x43c00074,0x020e020e);
Xil_Out32(0x43c00060,0x01e00320);
Xil_Out32(0x43c00094,0x1e0);
Xil_Out32(0x43c00078,0x03c80348);
Xil_Out32(0x43c00080,0x01eb01e9);
Xil_Out32(0x43c0008c,0x01eb01e9);
Xil_Out32(0x43c00068,0x2);
Xil_Out32(0x43c0007c,0x3200320);
Xil_Out32(0x43c00084,0x3480348);
Xil_Out32(0x43c00088,0x3200320);
Xil_Out32(0x43c00090,0x3480348);
Xil_Out32(0x43c0007c,0x3200320);
Xil_Out32(0x43c00084,0x3480348);
Xil_Out32(0x43c00088,0x3200320);
Xil_Out32(0x43c00090,0x3480348);
Xil_Out32(0x43c00000,0x03f7ef02);
Xil_Out32(0x43c00000,0x03f7ef06);
//usleep(1000);
}
int main(void)
{
if(0){
//设置分辨率
vd_mode = VMODE_800x480;
//配置VDMA
run_vdma_frame_buffer(&vdma, VDMA_ID, vd_mode.width, vd_mode.height,
frame_buffer_addr,0, 0,ONLY_READ);
//初始化Display controller
DisplayInitialize(&dispCtrl, DISP_VTC_ID, DYNCLK_BASEADDR);
//设置VideoMode
DisplaySetMode(&dispCtrl, &vd_mode);
DisplayStart(&dispCtrl);
}
if(1){
init();
}
//读取SD卡图片并显示
load_sd_bmp((u8*)frame_buffer_addr);
return 0;
}
//从SD卡中读取BMP图片
void load_sd_bmp(u8 *frame)
{
static FATFS fatfs;
FIL fil;
u8 bmp_head[54];
UINT *bmp_width,*bmp_height,*bmp_size;
UINT br;
int i;
f_mount(&fatfs,"",1);//挂载文件系统
f_open(&fil,"shatan_800x480.bmp",FA_READ); //打开文件
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
for(i=*bmp_height-1;i>=0;i--){
f_read(&fil,frame+i*(*bmp_width)*3,(*bmp_width)*3,&br);
}
//关闭文件
f_close(&fil);
Xil_DCacheFlush(); //刷新Cache,将数据更新至DDR3中
xil_printf("display bmp\n\r");
}