修改Eboot使OK6410A(128M內存+256MNand)支持HDMI高清顯示

        之前一直使用OK6410A(256M內存+2GNand)(WinCE6.0系統),買了塊HDMI高清顯示,跟飛凌技術要了資料,按照所給的資料說明,對Eboot做了修改後,就可以正常使用HDMI高清顯示了。最近爲了節省幾十塊RMB,老闆決定更換板子使用128M內存+256MNand的板子,拿到手準備把高清部分加進去,可是發現Eboot不太一樣呀,編譯出錯。問了飛凌技術,人家告訴我他們沒有準備在這個板子上使用HDMI的資料說明。那怎麼辦呢,只能按照之前的資料來自己嘗試解決了。好在現在解決了,下面來看看是怎麼做的。

      首先,應該修改main.c下的函數使其支持HDMI的選擇,因爲默認的沒有這個選項。主要是兩個函數:BOOL MainMenu(PBOOT_CFG pBootCfg)和void InitializeDisplay(void)函數。

在MainMenu函數中的下面一段switch-case中添加LCD_VGA1024_RGB選項,

switch(pBootCfg->ConfigFlags&LCD_TYPE_MASK)
{
	case LCD_HUA350_RGB:
        	EdbgOutputDebugString ( "(320x240)\r\n");
		break;
	case LCD_HUA430_RGB:
        	EdbgOutputDebugString ( "(480x272)\r\n");
		break;
	case LCD_HUA560_RGB:
        	EdbgOutputDebugString ( "(640x480)\r\n");
		break;
	case LCD_QUN700_RGB:
        	EdbgOutputDebugString ( "(800x480)\r\n");
		break;
	case LCD_VGA800_RGB:
        	EdbgOutputDebugString ( "(800x600)\r\n");
		break;

	case LCD_VGA1024_RGB:
        	EdbgOutputDebugString ( "(1024x768)\r\n");
		break;

        default:
                EdbgOutputDebugString ( "(unknown)\r\n");
                break;
}

繼續查看這個函數,當選擇'S'即選擇設置LCD時,調用了SetLcd(pBootCfg);,在 SetLcd(PBOOT_CFG pBootCfg)函數下,修改如下

static void SetLcd(PBOOT_CFG pBootCfg)
{
    USHORT InChar = 0;
	
    EdbgOutputDebugString("\r\n");
    EdbgOutputDebugString("0)3.5'LCD	320X240 \r\n");
    EdbgOutputDebugString("1)4.3'LCD	480X272 \r\n");
    EdbgOutputDebugString("2)5.6'LCD	640X480 \r\n");
    EdbgOutputDebugString("3)7.0'LCD	800X480 \r\n");
    EdbgOutputDebugString("4)VGA 		800X600 \r\n");
    EdbgOutputDebugString("5)HDMI		1024X768 \r\n");
	
    EdbgOutputDebugString("\r\nSelect Lcd Resolution [0-5]: ");
    while(!((InChar == 0x0d) || (InChar == 0x0a)))
    {
        InChar = OEMReadDebugByte();
        if (InChar != OEM_DEBUG_COM_ERROR && InChar != OEM_DEBUG_READ_NODATA)
        {
            // If it's a number or a period, add it to the string.
            //
            if ((InChar >= '0' && InChar <= '5'))
            {
            	OEMWriteDebugByte((BYTE)InChar);
            	pBootCfg->ConfigFlags&=~LCD_TYPE_MASK;
            	switch(InChar){
					case '0':
						pBootCfg->ConfigFlags|=LCD_HUA350_RGB;
						break;
					case '1':
						pBootCfg->ConfigFlags|=LCD_HUA430_RGB;
						break;
					case '2':
						pBootCfg->ConfigFlags|=LCD_HUA560_RGB;
						break;
					case '3':
						pBootCfg->ConfigFlags|=LCD_QUN700_RGB;
						break;
					case '4':
						pBootCfg->ConfigFlags|=LCD_VGA800_RGB;
						break;
					case '5':
						pBootCfg->ConfigFlags|=LCD_VGA1024_RGB;
						break;
					default:
						break;
            	}
				break;
            }
        }
    }

}

下面來修改 InitializeDisplay()函數,將其中選擇LCD模式的switch-case修改如下:

switch(g_pBootCfg->ConfigFlags&LCD_TYPE_MASK){
		case LCD_HUA350_RGB:
			LcdType = LDI_HUA350_RGB;
			g_dwLcdWidth = 320;
			g_dwLcdHeight = 240;
			g_dwLcdBpp = 16;
			break;
		case LCD_HUA430_RGB:
			LcdType = LDI_HUA430_RGB;
			g_dwLcdWidth = 480;
			g_dwLcdHeight = 272;
			g_dwLcdBpp = 16;
			break;
		case LCD_HUA560_RGB:
			LcdType = LDI_HUA560_RGB;
			g_dwLcdWidth = 640;
			g_dwLcdHeight = 480;
			g_dwLcdBpp = 16;
			break;
		case LCD_QUN700_RGB:
			LcdType = LDI_QUN700_RGB;
			g_dwLcdWidth = 800;
			g_dwLcdHeight = 480;
			g_dwLcdBpp = 16;
			break;
		case LCD_VGA800_RGB:
			LcdType = LDI_VGA800_RGB;
			g_dwLcdWidth = 800;
			g_dwLcdHeight = 600;
			g_dwLcdBpp = 16;
			break;
		case LCD_VGA1024_RGB:
			LcdType = LDI_VGA1024_RGB;
			g_dwLcdWidth = 1024;
			g_dwLcdHeight = 768;
			g_dwLcdBpp = 16;
			break;
		default:
			LcdType = LDI_HUA350_RGB;
			g_dwLcdWidth = 320;
			g_dwLcdHeight = 240;
			g_dwLcdBpp = 16;
			break;
	}

        到這裏就基本上修改完了,已經可以支持選擇HDMI了,但是僅僅是支持選擇,並不能真正實現HDMI高清顯示,考慮到在之前所給的資料中有個7033.lib還沒有使用,我比對了資料中的main.c 和 當前EBOOT中的 main.c,發現其調用了一個來自7033.lib的函數init_7033。於是仿照資料中的main.c做如下修改,主要是修改 InitializeVGA函數:

extern void init_7033(void);
//add by phantom
static void InitializeVGA(LDI_LCD_MODULE_TYPE LcdType)
{
	
    unsigned int  i;
	//EdbgOutputDebugString("[Eboot] ++InitializeVGA LcdType %d\r\n",LcdType);
    //IIC_Write   //CH7026 write address = 0xec
    if(LcdType==LDI_HUA560_RGB)	
    {
    	EdbgOutputDebugString("[Eboot] +++InitializeVGA 640X480()\r\n");
    	IIC_Open(2000);
		for (i = 0; i < CH7026_REG_NUM_VGA_640; i++) {
			
			if(!IIC_Write(0xEC, CH7026_REGS_VGA_640[i].subaddr, CH7026_REGS_VGA_640[i].value))
			{
				EdbgOutputDebugString("[Eboot] ---InitializeVGA ERROR!!!\r\n");
				IIC_Close();
				return;
			}
		}
		IIC_Write(0xEC,0x4,0x0);
		IIC_Close();
    	EdbgOutputDebugString("[Eboot] ---InitializeVGA 640X480()\r\n");
    }
	else if(LcdType==LDI_VGA800_RGB)
	{
    	EdbgOutputDebugString("[Eboot] +++InitializeVGA 800X600()\r\n");
		IIC_Open(2000);
		for (i = 0; i < CH7026_REG_NUM_VGA_800; i++) {
			if(!IIC_Write(0xEC, CH7026_REGS_VGA_800[i].subaddr, CH7026_REGS_VGA_800[i].value))
			{
				EdbgOutputDebugString("[Eboot] ---InitializeVGA ERROR!!!\r\n");
				IIC_Close();
				return;			
			}
		}
		IIC_Write(0xEC,0x4,0x0);
		IIC_Close();
    	EdbgOutputDebugString("[Eboot] ---InitializeVGA 800X600()\r\n");
	}
	else if(LcdType==LDI_VGA1024_RGB)
	{
		/* add by alexlee*/
		EdbgOutputDebugString("[Eboot] +++InitializeHDMI 1024X768()\r\n");
		init_7033();
		EdbgOutputDebugString("[Eboot] ---InitializeHDMI 1024X768()\r\n");
	}
	
}
         然後還有將7033.lib添加到Eboot的鏈接選項中,這個在資料中有說明,照做即可。完成這些工作後,還沒有最終完成,因爲此時在編譯Eboot時會出現編譯錯誤,這個主要是因爲在庫7033.lib中調用了一些函數,而這些函數還 沒有。比對了資料所給的usb.h、usb.c、ch7026.h,對當前Eboot下的文件進行了修改:

usb.h中添加:

BOOL IIC_Read(u8 cSlaveAddr,u8 cAddr,u8 *cData);

usb.c中添加:

void IIC_SetRead(  u8 cSlaveAddr,  u8 *pData, u32 uDataLen)
{
	u32 uTmp2;
	u32 uTmp3;
	
	uTmp2= Input32(rIICSTAT0);
	while(uTmp2&(1<<5))		//	Wait until IIC bus is free.
		uTmp2 = Input32(rIICSTAT0);			

	g_PcIIC_BUFFER	=	pData;
	g_uIIC_PT		=	0;
	g_uIIC_DATALEN	=	uDataLen;

	uTmp3 = Input32(rIICCON0);
	uTmp3 |= (1<<7);
	Outp32(rIICCON0,uTmp3);				//	Ack generation Enable
	Outp32(rIICDS0,cSlaveAddr);
	Outp32(rIICSTAT0,0xB0);				//	Master Rx Start.
}
BOOL IIC_Read(u8 cSlaveAddr,u8 cAddr,u8 *cData)
{
	IIC_SetWrite( cSlaveAddr, &cAddr, 1);			// following EEPROM random address access procedure
	IIC_SetRead( cSlaveAddr, cData, 1);
	IIC_Wait();								//	Waiting for read complete.
}

將ch7026.h直接拷貝過來,覆蓋原有的ch7026.h文件,因爲資料中的這個文件中添加了一個CH7033_RegTable[][2]。

         至此,就完成了修改工作了,此時重新編譯,然後生成映像。但是選擇了HDMI高清後,系統啓動到中間就停下來了,DNW上打印如下:

[Eboot] ++InitializeDisplay()

就是說在這個地方無法繼續往下執行了。我查找了這個語句,其是在InitializeDisplay()函數中打印的,進一步查找發現是下面的循環導致啓動中斷的:

        for (i=0; i<g_dwLcdWidth*g_dwLcdHeight; i++)
            *pFB++ = 0x0000;//0x001F;        // Blue
這個循環是在初始LOGO中的,本身這個循環沒有什麼問題,我懷疑是否是由於越界導致的呢,看了下pFB指針,

  unsigned short *pFB;
        pFB = (unsigned short *)EBOOT_FRAMEBUFFER_UA_START;
進一步搜索EBOOT_FRAMEBUFFER_UA_START,在image_cfg.h中定義的,如下:

// Eboot Display Frame Buffer
// 2MB
#define EBOOT_FRAMEBUFFER_OFFSET        (0x07F00000) 
#define EBOOT_FRAMEBUFFER_PA_START      (DRAM_BASE_PA_START+EBOOT_FRAMEBUFFER_OFFSET)
#define EBOOT_FRAMEBUFFER_UA_START      (DRAM_BASE_UA_START+EBOOT_FRAMEBUFFER_OFFSET)
#define EBOOT_FRAMEBUFFER_SIZE          (0x00100000)
將EBOOT_FRAMEBUFFER_OFFSET的值改爲0x07E00000。

      再次重新編譯,生成映像。此時選擇HDMI高清就可以正常顯示了。所有工作也完成了,目前尚未發現有什麼異常,不過有待進一步觀察。。。。





發佈了37 篇原創文章 · 獲贊 199 · 訪問量 43萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章