bucketxp 发表于 2004-10-10 19:12:54

SkyEye模拟EP7312的问题

请问SkyEye模拟的EP7312开发板,LCD是4位色的?原来的实验箱不是12位色伪彩色的吗?

halfyear 发表于 2004-10-10 20:50:27

请看下面的回帖

halfyear 发表于 2004-10-10 21:02:41

ep7312确实比较特殊,为了简化其framebuffer驱动及SkyEye的LCD模拟模块(只支持1,2,4,8,16,24,32 packed pixel)的实现, 按照8位色处理了。(缺点是在真实的ep7312上能跑的LCD驱动在SkyEye上跑不起来,反之亦然;所以从这个角度上说,针对ep7312的LCD仿真做得不够真实,还有值得继续完善的地方)

如果要支持12位色,也是可以的。在skyeye_lcd.c中添加对12位色的处理,代码量估计也就十行左右。但是相应的framebuffer驱动写起来就有点麻烦,
如果是2.4.x内核,需要在driver/video下增加一个fbcon-cfb12.c和ep7312fb.c,
如果是2.6.x内核,需要在driver/video/console/fbcon.c中增加对12 packed pixels的支持
不过网上有老外在ep7212的framebuffer驱动(driver/video/clps711xfb.c)基础上修改而来的针对ep7312的framebuffer驱动,有现成的patch。

如果需要,我可以直接发邮件给你,欢迎加入SkyEye的开发!

bucketxp 发表于 2004-10-11 12:41:33

多谢啦!我用的是skyeye-0.8.0,能不能提供一个skyeye一个skyeye_lcd.c的patch?我的邮箱是[email protected] :-D

halfyear 发表于 2004-10-11 13:11:24

我这几天还有其他的事情啊,可能下周才有时间做这个patch,
其实你可以先自己试试,这也是一个学习SkyEye的好机会啊 ^_^

bucketxp 发表于 2004-10-11 14:17:21

好的,我也正在研究,准备晚上开始动手试试^_^

chyyuu 发表于 2004-10-12 07:57:39

bucketxp, 马老师在教学实验中要用skyeye吗?

bucketxp 发表于 2004-10-12 15:47:20

是的,好像下周就开始了。
刚才把EP7312的LCD触步模拟成12位的了,现在在做进一步测试:)

halfyear 发表于 2004-10-12 15:59:21

成功了别忘了上来bg一下 :shock:

bucketxp 发表于 2004-10-12 22:26:17

EP7312的LCD帧缓冲中,每个象素是4位,可以表示16个灰度值。相邻的3个像素的灰度值组成屏幕上的一个点。
这样就形成屏幕上的一个点的颜色值由12位表示,低4位相当于红色分量,中间4位相当于绿色分量,高4位相当于蓝色分量。
不知道我理解的对不对?
我在SkyEye-0.8.0的sim/arm/skyeye_lcd.c中修改expose_event函数:
expose_event (GtkWidget *widget, GdkEventExpose *event)
{
        int loopnum;
        int i;
        guchar fbdata_low;
        guchar fbdata_medium;
        guchar fbdata_high;

        loopnum = (lcd_width * lcd_height * lcd_depth) / (8 * 3);
        fbSkyeyeADDR = rgbbuf;

        switch (lcd_depth)
        {
                case 8:
                        gdk_draw_indexed_image (widget->window, widget->style->fg_gc,
                                                0 , 0,lcd_width ,lcd_height,
                                                GDK_RGB_DITHER_NORMAL, rgbbuf,lcd_width,colormap);
                        break;
                       
                case 12:
                        for (i = 0; i < loopnum; i++)
                        {
                                fbdata_low = *(fbSkyeyeADDR++);
                                fbdata_medium = *(fbSkyeyeADDR++);
                                fbdata_high = *(fbSkyeyeADDR++);

                                *(rgbbuf_24 + i * 6 + 0) = ((fbdata_low & 0x0f) << 4);
                              *(rgbbuf_24 + i * 6 + 1) = (fbdata_low & 0xf0);
                                *(rgbbuf_24 + i * 6 + 2) = ((fbdata_medium & 0x0f) << 4);
                              *(rgbbuf_24 + i * 6 + 3) = (fbdata_medium & 0xf0);
                              *(rgbbuf_24 + i * 6 + 4) = ((fbdata_high & 0x0f) << 4);
                              *(rgbbuf_24 + i * 6 + 5) = (fbdata_high & 0xf0);
                        }
                        gdk_draw_rgb_image(widget->window, widget->style->fg_gc,
                                                0, 0, lcd_width, lcd_height,
                                                GDK_RGB_DITHER_NORMAL, rgbbuf_24, lcd_width * 3);
                        break;

                default:
                        break;
        }
        return TRUE;
}
将LCD帧缓冲区(rgbbuf)的每一个12位的颜色值转换成为一个24位的颜色值放到新申请的颜色缓冲区(rgbbuf_24)中,在调用gdk_draw_rgb_image将rgbbuf_24这个新的缓冲区影射到模拟的LCD窗口中。
目前的实现方法比较直观:
原有的缓冲区中以三个字节为一组,它存放了两个点的颜色值,第一个点的颜色值为(R1, G1, B1),第一个点的颜色值为(R2, G2, B2)。每一个颜色分量都为4位。将每一个点的各个分量都右移4位,扩展成8位,对应生成的两个点的新颜色值共占6个字节。
我现在的问题很奇怪:
在图像显示过程中,有画屏现象,但最终的显示结果是基本正确的(除了下面说的那个问题);
LCD屏幕最左上角的3像素点不能读写,总是黑色;
我不知道lcd_write这个函数是不是还要进行修改,因为这个函数的实现还不是太明白。
我觉得在读写LCD帧缓冲时,其实还是以4位为单位来做的,所以目前的修改就是把它当成4位做的:p
void lcd_write(ARMul_State *state, ARMword addr, ARMword data)
{
        ARMword offset;
        int pixnum, bit;
        guchar pix;
        guchar *pos;
       
        ARMword swapdata=0;
        int k;

        int step;

        if (lcd_depth == 12)
        {
                step = lcd_depth / 3;
        }
        else
        {
                step = lcd_depth;
        }

        if (skyeye_config.no_lcd)
                return;

        offset = (addr & ~3) - lcd_base;
        pixnum = offset * 8 / step;
        if (pixnum<lcd_width*lcd_height) {
                pos=rgbbuf+pixnum;
               
                switch(lcd_depth){
                        case 1:
                                break;
                        case 2:
                                break;
                        case 4:
                        case 12:
                                for(k=0;k<32;k+=4){
                                        if((k/4)&0x01){
                                        swapdata=swapdata | (((data>>(k-4))&0x0f)<<(k));
                                        }else{
                                        swapdata=swapdata | (((data>>(k+4))&0x0f)<<(k));
                                        }
                                }
                                data=swapdata;
                                break;
                        default:
                                break;
                }
                for(bit = 0; bit < 32; bit += step/*lcd_depth*/){
                        pix = (data >> bit)% (1 << step/*lcd_depth*/) ;
                        *pos++ = pix;
                        lcd_changed = TRUE;
                }
        }
}
还请halfyear指点一下:)

chyyuu 发表于 2004-10-14 09:33:37

如果有何问题,可同时在论坛上发贴,并给我们发email。希望skyeye能够有助于你们的教学实验!

halfyear 发表于 2004-10-14 10:18:25

bucketxp,我给你发了邮件和QQ留言,你收到了吗?

lcd_write从0.80版本开始已经被弃用了

我做了个patch,你给我发个内核测试一下吧,或者把你用到的LCD驱动和ep7312API.打个包发给我,可以吗?

halfyear 发表于 2004-10-14 15:02:36


fbdata_low = *(fbSkyeyeADDR++);
fbdata_medium = *(fbSkyeyeADDR++);
fbdata_high = *(fbSkyeyeADDR++);

问题就处在这三句上,换成下面三句试试:
fbdata_low = *(fbSkyeyeADDR+i*3);
fbdata_medium = *(fbSkyeyeADDR+i*3+1);
fbdata_high = *(fbSkyeyeADDR+i*3+2);
因为我做这个patch时,一开始也犯了这样的错误,呵呵 :-D

原来的LCD驱动可以不作任何修改的在SkyEye上跑起来。

halfyear 发表于 2004-10-14 15:25:30

demoline画了一条对角线,
demo显示一幅位图
效果截图

bucketxp 发表于 2004-10-14 21:16:22

如果有何问题,可同时在论坛上发贴,并给我们发email。希望skyeye能够有助于你们的教学实验!
多谢版主的支持,对我们的实验很有帮助。 :mrgreen:
页: [1] 2
查看完整版本: SkyEye模拟EP7312的问题