Skip to content

Nano和原子的HDMI_OUT例程,纯寄存器初始化

minichao9901 edited this page May 12, 2024 · 3 revisions

关于hdmi_out例程说明

  • 用Nano的硬件设计+程序,是可以跑的。不过Nano的例程多了个AXI4_Stream_Converter模块,这个看起来不爽
  • 用原子的硬件设计+程序,是可以跑的。原子的例程没有AXI4_Stream_Converter模块
  • 我的目的是,用原子的硬件设计+Nano的程序,是否可以跑? 结论是不行,需要修改代码。
  • 例程路径:A_hdmi_out_wi_wo_sd.rar

原子

  • 可以正常运行
//****************************************Copyright (c)***********************************//
//原子哥在线教学平台:www.yuanzige.com
//技术支持:www.openedv.com
//淘宝店铺:http://openedv.taobao.com
//关注微信公众平台微信号:"正点原子",免费获取ZYNQ & FPGA & STM32 & LINUX资料。
//版权所有,盗版必究。
//Copyright(C) 正点原子 2018-2028
//All rights reserved
//----------------------------------------------------------------------------------------
// File name:           main.c
// Last modified Date:  2019/10/21 17:58:36
// Last Version:        V1.1
// Descriptions:        从SD卡中读取BMP格式的图片,并在HDMI显示器上显示
//----------------------------------------------------------------------------------------
// Created by:          正点原子
// Created date:        2019/10/21 17:58:36
// Version:             V1.0
// Descriptions:        The original version
//
//----------------------------------------------------------------------------------------
//****************************************************************************************//

#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_hdmi/display_ctrl.h"
#include "vdma_api/vdma_api.h"
#include "ff.h"
#include "sleep.h"


void init()
{
	//配置VDMA
	Xil_Out32(0x43000000,0x4);
	Xil_Out32(0x43000000,0x10002);
	Xil_Out32(0x43000054,0x1680);
	Xil_Out32(0x43000058,0x1680);
	Xil_Out32(0x4300005c,0x1100000);
	Xil_Out32(0x43000000,0x14002);
	Xil_Out32(0x43000000,0x14003);
	Xil_Out32(0x43000050,0x438);
	usleep(1000);

	//初始化Display controller
	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,0x400041);
	Xil_Out32(0x43c1000c,0x0000069a);
	Xil_Out32(0x43c10010,0x0);
	Xil_Out32(0x43c10014,0x000020c4);
	Xil_Out32(0x43c10018,0xcfafa401);
	Xil_Out32(0x43c1001c,0x00a300ff);
	Xil_Out32(0x43c10000,0x0);
	Xil_Out32(0x43c10000,0x1);
	usleep(1000);

	 //设置VideoMode
	Xil_Out32(0x43c00000,0x2);
	Xil_Out32(0x43c0006c,0x0000007f);
	Xil_Out32(0x43c00070,0x898);
	Xil_Out32(0x43c00074,0x4650465);
	Xil_Out32(0x43c00060,0x4380780);
	Xil_Out32(0x43c00094,0x4380000);
	Xil_Out32(0x43c00078,0x080407d8);
	Xil_Out32(0x43c00080,0x0440043b);
	Xil_Out32(0x43c0008c,0x0440043b);
	Xil_Out32(0x43c00068,0x2);
	Xil_Out32(0x43c0007c,0x7800780);
	Xil_Out32(0x43c00084,0x07d807d8);
	Xil_Out32(0x43c00088,0x7800780);
	Xil_Out32(0x43c00090,0x07d807d8);
	Xil_Out32(0x43c0007c,0x7800780);
	Xil_Out32(0x43c00084,0x07d807d8);
	Xil_Out32(0x43c00088,0x7800780);
	Xil_Out32(0x43c00090,0x07d807d8);
	Xil_Out32(0x43c00000,0x03f7ef02);
	Xil_Out32(0x43c00000,0x03f7ef06);
	usleep(1000);
}

//宏定义
#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);
unsigned int lcd_id=0;        //LCD ID

int main(void)
{
	xil_printf("HDMI Display 1920*1080 \r\n");
	//sleep(10);

	//设置video参数,分辨率:1920*1080
	vd_mode = VMODE_1920x1080;


	//配置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);

	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.bmp",FA_READ);

	//移动文件读写指针到文件开头
	f_lseek(&fil,0);

	//读取BMP文件头
	f_read(&fil,bmp_head,54,&br);
	xil_printf("fengjing.bmp head: \n\r");
	for(i=0;i<54;i++)
		xil_printf(" %x",bmp_head[i]);

	//打印BMP图片分辨率和大小
	bmp_width  = (UINT *)(bmp_head + 0x12);
	bmp_height = (UINT *)(bmp_head + 0x16);
	bmp_size   = (UINT *)(bmp_head + 0x22);
	xil_printf("\n width = %d, height = %d, 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("show bmp\n\r");
}

Nano

  • 用原子的设计,Nano的程序,不能运行起来,需要修改。修改点有2点,在程序中有说明 image image image image

如果VDMA的Stream宽度是24,那么这里需要设置为3。 如果VDMA的Stream宽度是32,那么这里需要设置为4。

// --------------------------------------------------------------------
// 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 File Definitions						*/
/* ------------------------------------------------------------ */

#include <stdio.h>
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
#include "xil_types.h"
#include "xil_cache.h"
#include "xparameters.h"
#include "display_demo.h"
#include "display_ctrl/display_ctrl.h"
#include "display_ctrl/vga_modes.h"
#include "ff.h"
#include "sleep.h"


void init();

/*
 * XPAR redefines
 */
#define DYNCLK_BASEADDR     XPAR_AXI_DYNCLK_0_BASEADDR
#define VGA_VDMA_ID         XPAR_AXIVDMA_0_DEVICE_ID
#define DISP_VTC_ID         XPAR_VTC_0_DEVICE_ID

/* ------------------------------------------------------------ */
/*				Global Variables								*/
/* ------------------------------------------------------------ */


/*
 * Display Driver struct
 */
DisplayCtrl dispCtrl;
XAxiVdma vdma;
static FIL fil;		/* File object */
static FATFS fatfs;
/*
 * Frame buffers for video data
 */
u8 frameBuf[DISPLAY_NUM_FRAMES][DEMO_MAX_FRAME] __attribute__ ((aligned (64)));
u8 *pFrames[DISPLAY_NUM_FRAMES];  // array of pointers to the frame buffers

/* ------------------------------------------------------------ */
/*				Procedure Definitions							*/
/* ------------------------------------------------------------ */
unsigned char read_line_buf[1920 * 4];
void bmp_read(char * bmp,u8 *frame,u32 stride)
{
	short y,x;
	short Ximage;
	short Yimage;
	u32 iPixelAddr = 0;
	FRESULT res;
	unsigned char TMPBUF[64];
	unsigned int br;         // File R/W count

	res = f_open(&fil, bmp, FA_OPEN_EXISTING | FA_READ);
	if(res != FR_OK)
	{
		return ;
	}
	res = f_read(&fil, TMPBUF, 54, &br);
	if(res != FR_OK)
	{
		return ;
	}
	Ximage=(unsigned short int)TMPBUF[19]*256+TMPBUF[18];
	Yimage=(unsigned short int)TMPBUF[23]*256+TMPBUF[22];
	iPixelAddr = (Yimage-1)*stride ;

	for(y = 0; y < Yimage ; y++)
	{
		f_read(&fil, read_line_buf, Ximage * 3, &br);
		for(x = 0; x < Ximage; x++)
		{
			frame[x * BYTES_PIXEL + iPixelAddr + 0] = read_line_buf[x * 3 + 0];
			frame[x * BYTES_PIXEL + iPixelAddr + 1] = read_line_buf[x * 3 + 1];
			frame[x * BYTES_PIXEL + iPixelAddr + 2] = read_line_buf[x * 3 + 2];
		}
		iPixelAddr -= stride;
	}
	f_close(&fil);
}


int main(void)
{
	//sleep(10);

	int i;
	int Status;
	XAxiVdma_Config *vdmaConfig;
	FRESULT rc;
	/*
	 * Initialize an array of pointers to the 3 frame buffers
	 */
	for (i = 0; i < DISPLAY_NUM_FRAMES; i++)
	{
		pFrames[i] = frameBuf[i];
	}
	xil_printf("hello world!\r\n");
	/*
	 * Initialize VDMA driver, get the hardware VDMA configurations
	 */
	vdmaConfig = XAxiVdma_LookupConfig(VGA_VDMA_ID);
	if (vdmaConfig == NULL)
	{
		xil_printf("No video DMA found for ID %d\r\n", VGA_VDMA_ID);
	}

	/*
	 * Use hardware VDMA configurations to initialize the driver
	 */
	Status = XAxiVdma_CfgInitialize(&vdma, vdmaConfig, vdmaConfig->BaseAddress);
	if (Status != XST_SUCCESS)
	{
		xil_printf("VDMA Configuration Initialization failed %d\r\n", Status);
	}

	/*
	 * Initialize the Display controller and start it
	 */

	VideoMode VMODE = VMODE_1920x1080;
	Status = DisplayInitialize(&dispCtrl, &vdma, DISP_VTC_ID, DYNCLK_BASEADDR, pFrames, DEMO_STRIDE, VMODE);

	if (Status != XST_SUCCESS)
	{
		xil_printf("Display Ctrl initialization failed during demo initialization%d\r\n", Status);
	}

	Status = DisplayStart(&dispCtrl);

	if (Status != XST_SUCCESS)
	{
		xil_printf("Couldn't start display during demo initialization%d\r\n", Status);
	}

//	init();

	rc = f_mount(&fatfs, "0:/", 0);
		if (rc != FR_OK)
		{
			return 0 ;
		}

	while(0){
		char s[30];
		memset(s,0,30);
		printf("please input picture name:\r\n");
		scanf("%s", &s[0]);
		printf("%s\r\n",s);
		bmp_read(s,dispCtrl.framePtr[dispCtrl.curFrame], DEMO_STRIDE);
		Xil_DCacheFlushRange((unsigned int) dispCtrl.framePtr[dispCtrl.curFrame], DEMO_MAX_FRAME);
	}

	if(0){
		char s[30]="shatan.bmp";
		bmp_read(s,dispCtrl.framePtr[dispCtrl.curFrame], DEMO_STRIDE);
		Xil_DCacheFlushRange((unsigned int) dispCtrl.framePtr[dispCtrl.curFrame], DEMO_MAX_FRAME);
	}
	if(1){
		char s[30]="shatan.bmp";
		bmp_read(s,(u8*)0x00126d40, DEMO_STRIDE);         /*注意DEMO_STRIDE要设置成1920*3*/
		Xil_DCacheFlushRange(0x00126d40, DEMO_MAX_FRAME);
	}

	return 0;
}


void init()
{
	//初始化Display controller
	Xil_Out32(0x43000000,0x4);
	Xil_Out32(0x43c10008,0x400041);
	Xil_Out32(0x43c1000c,0x0000069a);
	Xil_Out32(0x43c10010,0x0);
	Xil_Out32(0x43c10014,0x000020c4);
	Xil_Out32(0x43c10018,0xcfafa401);
	Xil_Out32(0x43c1001c,0x00a300ff);
	Xil_Out32(0x43c10000,0x1);
	usleep(1000);

	Xil_Out32(0x43c10008,0x400041);
	Xil_Out32(0x43c1000c,0x0000069a);
	Xil_Out32(0x43c10010,0x0);
	Xil_Out32(0x43c10014,0x000020c4);
	Xil_Out32(0x43c10018,0xcfafa401);
	Xil_Out32(0x43c1001c,0x00a300ff);
	Xil_Out32(0x43c10000,0x0);
	Xil_Out32(0x43c10000,0x1);
	usleep(1000);

	//设置VideoMode
	Xil_Out32(0x43c00000,0x2);
	Xil_Out32(0x43c0006c,0x0000007f);
	Xil_Out32(0x43c00070,0x898);
	Xil_Out32(0x43c00074,0x4650465);
	Xil_Out32(0x43c00060,0x4380780);
	Xil_Out32(0x43c00094,0x4380000);
	Xil_Out32(0x43c00078,0x080407d8);
	Xil_Out32(0x43c00080,0x0440043b);
	Xil_Out32(0x43c0008c,0x0440043b);
	Xil_Out32(0x43c00068,0x2);
	Xil_Out32(0x43c0007c,0x7800780);
	Xil_Out32(0x43c00084,0x07d807d8);
	Xil_Out32(0x43c00088,0x7800780);
	Xil_Out32(0x43c00090,0x07d807d8);
	Xil_Out32(0x43c0007c,0x7800780);
	Xil_Out32(0x43c00084,0x07d807d8);
	Xil_Out32(0x43c00088,0x7800780);
	Xil_Out32(0x43c00090,0x07d807d8);
	Xil_Out32(0x43c00000,0x03f7ef02);
	Xil_Out32(0x43c00000,0x03f7ef06);
	usleep(1000);

	//配置VDMA
	Xil_Out32(0x43000000,0x10002);
//	Xil_Out32(0x43000054,0x1);   /*Nano例程的问题出在这里,不能配0x1*/
//	Xil_Out32(0x43000058,0x1);   /*Nano例程的问题出在这里,不能配0x1*/
	Xil_Out32(0x43000054,0x1680);
	Xil_Out32(0x43000058,0x1680);
	Xil_Out32(0x4300005c,0x00126d40);
	Xil_Out32(0x43000000,0x10003);
	Xil_Out32(0x43000050,0x438);
	Xil_Out32(0x43000028,0x0);
	Xil_Out32(0x43000000,0x10001);
	usleep(1000);
}
Clone this wiki locally