之前一直使用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高清就可以正常显示了。所有工作也完成了,目前尚未发现有什么异常,不过有待进一步观察。。。。