⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sm5.c

📁 基于S3C2410和SM501的彩屏控制器程序
💻 C
📖 第 1 页 / 共 3 页
字号:
	long blank_width, sync_start, sync_width;	clock_select_t clock;	// Calculate the VESA line and screen frequencies.	vesaMode->horizontal_frequency = roundDiv(vesaMode->pixel_clock, vesaMode->horizontal_total);	vesaMode->vertical_frequency = roundDiv(vesaMode->horizontal_frequency, vesaMode->vertical_total);	// Calculate the sync percentages of the VESA mode.	blank_width = vesaMode->horizontal_total - vesaMode->horizontal_display_end;	sync_start = roundDiv((vesaMode->horizontal_sync_start - vesaMode->horizontal_display_end) * 100, blank_width);	sync_width = roundDiv(vesaMode->horizontal_sync_width * 100, blank_width);	// Copy VESA mode into Voyager mode.	*mode = *vesaMode;	// Find the best pixel clock.	mode->pixel_clock = findClock(vesaMode->pixel_clock * 2, &clock, display) / 2;	// Calculate the horizontal total based on the pixel clock and VESA line	// frequency.	mode->horizontal_total = roundDiv(mode->pixel_clock, vesaMode->horizontal_frequency);	// Calculate the sync start and width based on the VESA percentages.	blank_width = mode->horizontal_total - mode->horizontal_display_end;	mode->horizontal_sync_start = mode->horizontal_display_end + roundDiv(blank_width * sync_start, 100);	mode->horizontal_sync_width = roundDiv(blank_width * sync_width, 100);	// Calculate the line and screen frequencies.	mode->horizontal_frequency = roundDiv(mode->pixel_clock, mode->horizontal_total);	mode->vertical_frequency = roundDiv(mode->horizontal_frequency, mode->vertical_total);}*/// Fill the register structure.void setModeRegisters(reg_table_t *register_table, mode_table_t *mode, display_t display, int bpp){	clock_select_t clock;	memset(&clock, 0, sizeof(clock));	// Calculate the clock register values.	findClock(mode->pixel_clock * 2, &clock, display);	if (display == PANEL)	{		// Set clock value for panel.		register_table->clock			= (clock.mclk == 288000000				? FIELD_SET(0, CURRENT_POWER_CLOCK, P2XCLK_SELECT, 288)				: FIELD_SET(0, CURRENT_POWER_CLOCK, P2XCLK_SELECT, 336))			| (clock.divider == 1				? FIELD_SET(0, CURRENT_POWER_CLOCK, P2XCLK_DIVIDER, 1)				: (clock.divider == 3					? FIELD_SET(0, CURRENT_POWER_CLOCK, P2XCLK_DIVIDER, 3)					: FIELD_SET(0, CURRENT_POWER_CLOCK, P2XCLK_DIVIDER, 5)))			| FIELD_VALUE(0, CURRENT_POWER_CLOCK, P2XCLK_SHIFT, clock.shift);		// Set control register value.		register_table->control			= (mode->vertical_sync_polarity == POSITIVE				? FIELD_SET(0, PANEL_DISPLAY_CTRL, VSYNC_PHASE, ACTIVE_HIGH)				: FIELD_SET(0, PANEL_DISPLAY_CTRL, VSYNC_PHASE, ACTIVE_LOW))			| (mode->horizontal_sync_polarity == POSITIVE				? FIELD_SET(0, PANEL_DISPLAY_CTRL, HSYNC_PHASE, ACTIVE_HIGH)				: FIELD_SET(0, PANEL_DISPLAY_CTRL, HSYNC_PHASE, ACTIVE_LOW))			| FIELD_SET(0, PANEL_DISPLAY_CTRL, TIMING, ENABLE)			| FIELD_SET(0, PANEL_DISPLAY_CTRL, PLANE, ENABLE)			| (bpp == 8				? FIELD_SET(0, PANEL_DISPLAY_CTRL, FORMAT, 8)				: (bpp == 16					? FIELD_SET(0, PANEL_DISPLAY_CTRL, FORMAT, 16)					: FIELD_SET(0, PANEL_DISPLAY_CTRL, FORMAT, 32)));		// Set timing registers.		register_table->horizontal_total			= FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, TOTAL,						  mode->horizontal_total - 1)			| FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, DISPLAY_END, 						  mode->horizontal_display_end - 1);		register_table->horizontal_sync			= FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, WIDTH,						  mode->horizontal_sync_width)			| FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, START, 						  mode->horizontal_sync_start - 1);		register_table->vertical_total  			= FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, TOTAL, 						  mode->vertical_total - 1)			| FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, DISPLAY_END, 						  mode->vertical_display_end - 1);		register_table->vertical_sync    			= FIELD_VALUE(0, PANEL_VERTICAL_SYNC, HEIGHT, 						  mode->vertical_sync_height)			| FIELD_VALUE(0, PANEL_VERTICAL_SYNC, START, 						  mode->vertical_sync_start - 1);	}	else	{		// Set clock value for CRT.		register_table->clock			= (clock.mclk == 288000000				? FIELD_SET(0, CURRENT_POWER_CLOCK, V2XCLK_SELECT, 288)				: FIELD_SET(0, CURRENT_POWER_CLOCK, V2XCLK_SELECT, 336))			| (clock.divider == 1				? FIELD_SET(0, CURRENT_POWER_CLOCK, V2XCLK_DIVIDER, 1)				: FIELD_SET(0, CURRENT_POWER_CLOCK, V2XCLK_DIVIDER, 3))			| FIELD_VALUE(0, CURRENT_POWER_CLOCK, V2XCLK_SHIFT, clock.shift);		// Set control register value.		register_table->control 			= (mode->vertical_sync_polarity == POSITIVE				? FIELD_SET(0, CRT_DISPLAY_CTRL, VSYNC_PHASE, ACTIVE_HIGH)				: FIELD_SET(0, CRT_DISPLAY_CTRL, VSYNC_PHASE, ACTIVE_LOW))			| (mode->horizontal_sync_polarity == POSITIVE				? FIELD_SET(0, CRT_DISPLAY_CTRL, HSYNC_PHASE, ACTIVE_HIGH)				: FIELD_SET(0, CRT_DISPLAY_CTRL, HSYNC_PHASE, ACTIVE_LOW))			| FIELD_SET(0, CRT_DISPLAY_CTRL, SELECT, CRT)			| FIELD_SET(0, CRT_DISPLAY_CTRL, TIMING, ENABLE)			| FIELD_SET(0, CRT_DISPLAY_CTRL, PLANE, ENABLE)			| (bpp == 8				? FIELD_SET(0, CRT_DISPLAY_CTRL, FORMAT, 8)				: (bpp == 16					? FIELD_SET(0, CRT_DISPLAY_CTRL, FORMAT, 16)					: FIELD_SET(0, CRT_DISPLAY_CTRL, FORMAT, 32)));		// Set timing registers.		register_table->horizontal_total			= FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, TOTAL, 						  mode->horizontal_total - 1)			| FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, DISPLAY_END, 						  mode->horizontal_display_end - 1);		register_table->horizontal_sync  			= FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, WIDTH, 						  mode->horizontal_sync_width)			| FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, START, 						  mode->horizontal_sync_start - 1);		register_table->vertical_total   			= FIELD_VALUE(0, CRT_VERTICAL_TOTAL, TOTAL, 						  mode->vertical_total - 1)			| FIELD_VALUE(0, CRT_VERTICAL_TOTAL, DISPLAY_END, 						  mode->vertical_display_end - 1);		register_table->vertical_sync    			= FIELD_VALUE(0, CRT_VERTICAL_SYNC, HEIGHT, 						  mode->vertical_sync_height)			| FIELD_VALUE(0, CRT_VERTICAL_SYNC, START, 						  mode->vertical_sync_start - 1);	}	// Calculate frame buffer width and height.	register_table->fb_width = mode->horizontal_display_end * (bpp / 8);	register_table->width = mode->horizontal_display_end;	register_table->height = mode->vertical_display_end;	// Save display type.	register_table->display = display;}/*void setModeRegisters(reg_table_t *register_table, mode_table_t *mode, display_t display, int bpp){	clock_select_t clock;	memset(&clock, 0, sizeof(clock));	// Calculate the clock register values.	findClock(mode->pixel_clock * 2, &clock, display);	{		// Set clock value for CRT	 register_table->clock			= (clock.mclk == 288000000				? FIELD_SET(0, CURRENT_POWER_CLOCK, V2XCLK_SELECT, 288)				: FIELD_SET(0, CURRENT_POWER_CLOCK, V2XCLK_SELECT, 336))			| (clock.divider == 1				? FIELD_SET(0, CURRENT_POWER_CLOCK, V2XCLK_DIVIDER, 1)				: FIELD_SET(0, CURRENT_POWER_CLOCK, V2XCLK_DIVIDER, 3))			| FIELD_VALUE(0, CURRENT_POWER_CLOCK, V2XCLK_SHIFT, clock.shift);		// Set control register value.		register_table->control 			= (mode->vertical_sync_polarity == POSITIVE				? FIELD_SET(0, CRT_DISPLAY_CTRL, VSYNC_PHASE, ACTIVE_HIGH)				: FIELD_SET(0, CRT_DISPLAY_CTRL, VSYNC_PHASE, ACTIVE_LOW))			| (mode->horizontal_sync_polarity == POSITIVE				? FIELD_SET(0, CRT_DISPLAY_CTRL, HSYNC_PHASE, ACTIVE_HIGH)				: FIELD_SET(0, CRT_DISPLAY_CTRL, HSYNC_PHASE, ACTIVE_LOW))			| FIELD_SET(0, CRT_DISPLAY_CTRL, SELECT, CRT)			| FIELD_SET(0, CRT_DISPLAY_CTRL, TIMING, ENABLE)			| FIELD_SET(0, CRT_DISPLAY_CTRL, PLANE, ENABLE)			| (bpp == 8				? FIELD_SET(0, CRT_DISPLAY_CTRL, FORMAT, 8)				: (bpp == 16					? FIELD_SET(0, CRT_DISPLAY_CTRL, FORMAT, 16)					: FIELD_SET(0, CRT_DISPLAY_CTRL, FORMAT, 32)));		// Set timing registers.		register_table->horizontal_total			= FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, TOTAL, 						  mode->horizontal_total - 1)			| FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, DISPLAY_END, 						  mode->horizontal_display_end - 1);		register_table->horizontal_sync  			= FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, WIDTH, 						  mode->horizontal_sync_width)			| FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, START, 						  mode->horizontal_sync_start - 1);		register_table->vertical_total   			= FIELD_VALUE(0, CRT_VERTICAL_TOTAL, TOTAL, 						  mode->vertical_total - 1)			| FIELD_VALUE(0, CRT_VERTICAL_TOTAL, DISPLAY_END, 						  mode->vertical_display_end - 1);		register_table->vertical_sync    			= FIELD_VALUE(0, CRT_VERTICAL_SYNC, HEIGHT, 						  mode->vertical_sync_height)			| FIELD_VALUE(0, CRT_VERTICAL_SYNC, START, 						  mode->vertical_sync_start - 1);	}	// Calculate frame buffer width and height.	register_table->fb_width = mode->horizontal_display_end * (bpp / 8);		register_table->width = mode->horizontal_display_end;			register_table->height = mode->vertical_display_end;	// Save display type.	register_table->display = display;}*/mode_table_t *findMode(mode_table_t *mode_table, int width, int height, long refresh_rate){	// Walk the entire mode table.	while (mode_table->pixel_clock != 0)	{		// If this mode matches the requested mode, return it!		if ((mode_table->horizontal_display_end == width)		&& (mode_table->vertical_display_end == height)		&& (mode_table->vertical_frequency == refresh_rate))		{			return(mode_table);		}		// Next entry in the mode table.		mode_table++;	}	// No mode found.	return(NULL);}void SetMode(int nWidth, int nHeight, long nHertz, display_t display, int bpp){	mode_table_t 	mode;	pmode_table_t 	vesaMode;	reg_table_t		register_table;	// Locate the mode	vesaMode = findMode(mode_table, nWidth, nHeight, nHertz);	if (vesaMode != NULL)	{		//正常vesaMode为非空		// Convert VESA timing into Voyager timing		adjustMode(vesaMode, &mode, display);   		// Fill the register structure		setModeRegisters(&register_table, &mode, display, bpp);		// Program the registers		programMode(&register_table);	}}//显存软件配置void dram_config(unsigned char size){		switch(size)		{			case 2:				regWrite32(DRAM_CTRL, FIELD_SET(0, DRAM_CTRL, SIZE, 2));				break;			case 4:				regWrite32(DRAM_CTRL, FIELD_SET(0, DRAM_CTRL, SIZE, 4));				break;			case 8:				regWrite32(DRAM_CTRL, FIELD_SET(0, DRAM_CTRL, SIZE, 8));				break;			case 16:				regWrite32(DRAM_CTRL, FIELD_SET(0, DRAM_CTRL, SIZE, 16));				break;			case 32:				regWrite32(DRAM_CTRL, FIELD_SET(0, DRAM_CTRL, SIZE, 32));				break;			case 64:			 // regWrite32(DRAM_CTRL, FIELD_SET(0, DRAM_CTRL, CPU_SIZE, 64));				regWrite32(DRAM_CTRL, FIELD_SET(0, DRAM_CTRL, SIZE, 64));				break;			}	}//改变显存的起始地址void set_frame_fbinfo(int x, int y, int fb_type, display_t display){    static unsigned int gdfTab[] = { 1, 2, 2, 4, 3, 1 };	u_long				fb_address;	sm501.winSizeX = x;	sm501.winSizeY = y;	sm501.gdfBytesPP = gdfTab[fb_type];	sm501.gdfIndex = fb_type;	if (display == PANEL) 		fb_address = FIELD_GET(regRead32(PANEL_FB_ADDRESS), PANEL_FB_ADDRESS, ADDRESS);	else		fb_address = FIELD_GET(regRead32(CRT_FB_ADDRESS), CRT_FB_ADDRESS, ADDRESS);	sm501.frameAdrs = fb_address + CONFIG_SM501_MEM_BASE;	printf("sm501 frame address start = 0x%x\n", sm501.frameAdrs);}void dram_addrss(unsigned long addressoffset){	CONFIG_SM501_MEM_BASE = 0x20000000+addressoffset;	regWrite32(CRT_FB_ADDRESS,FIELD_VALUE(0, CRT_FB_ADDRESS, ADDRESS, addressoffset));}static void sm501_disable_controller(display_t display){	ulong		panel_ctrl;//if (display == CRT)	 {		panel_ctrl = regRead32(CRT_DISPLAY_CTRL);		panel_ctrl = FIELD_SET(panel_ctrl, CRT_DISPLAY_CTRL, PLANE, DISABLE);		panel_ctrl = FIELD_SET(panel_ctrl, CRT_DISPLAY_CTRL, BLANK, ON);		regWrite32(CRT_DISPLAY_CTRL, panel_ctrl);	}}static void sm501_enable_controller(display_t display){	u_long panel_ctrl = 0;		if (display == CRT)	{		panel_ctrl = regRead32(CRT_DISPLAY_CTRL);		printf("Enabling CRT controller\n");		panel_ctrl = FIELD_SET(panel_ctrl, CRT_DISPLAY_CTRL, PLANE, ENABLE);		panel_ctrl = FIELD_SET(panel_ctrl, CRT_DISPLAY_CTRL, BLANK, OFF);		regWrite32(CRT_DISPLAY_CTRL, panel_ctrl);	}	else if(display == PANEL)	{		//regWrite32(PANEL_DISPLAY_CTRL,0x410305);			    panel_ctrl = regRead32(PANEL_DISPLAY_CTRL);	    panel_ctrl = FIELD_SET(panel_ctrl, PANEL_DISPLAY_CTRL, PLANE, ENABLE);	    regWrite32(PANEL_DISPLAY_CTRL, panel_ctrl);	}	}//设置显示分辨率void *video_hw_init (void){ 	int		i;	int 	detect;	int		XRES;	int 	YRES;	int 	BPP;	int		HZ;		int		DEVICE;	sm501Reg = (char *)CONFIG_SM501_REG_BASE;  	sm501Mem = (char *)CONFIG_SM501_MEM_BASE;	if((detect = sm501_detect()) == -1)  		//Detect SM501 ID		return NULL;	XRES = mode_table[sm501mode - 1].horizontal_display_end;	YRES = mode_table[sm501mode - 1].vertical_display_end;	HZ = mode_table[sm501mode - 1].vertical_frequency;	BPP = sm501bpp;	if(!sm501out)		DEVICE = CRT;	else		DEVICE = PANEL;	error = 0;	for(i = 0;i < 10; i++)	{		SetMode(XRES, YRES, HZ, DEVICE, BPP);		if(!error)			break;		else			error = 0;	}	dram_config(16);	set_frame_fbinfo(XRES, YRES, FBTYPE_16BIT_565RGB, PANEL);//..	sm501_enable_controller(DEVICE);//..	sm501info.Bpp = 2;	sm501info.bitsPerPixel = 16;	sm501info.width = XRES;	sm501info.height = YRES;	return &sm501;}void video_set_lut ( unsigned int index,unsigned char r, unsigned char g, unsigned char b){	regWrite32(index * 4 + CRT_PALETTE_RAM, RGB(r, g , b ));}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -