历史上的今天
返回首页

历史上的今天

今天是:2024年10月11日(星期五)

正在发生

2018年10月11日 | OK6410裸机之LCD调色板

2018-10-11 来源:eefocus

lcd.c源码:

#define GPECON  (*((volatile unsigned long *)0x7F008080))

#define GPEDAT  (*((volatile unsigned long *)0x7F008084))

#define GPFCON  (*((volatile unsigned long *)0x7F0080A0))

#define GPFDAT  (*((volatile unsigned long *)0x7F0080A4))

#define GPICON  (*((volatile unsigned long *)0x7F008100))

#define GPJCON  (*((volatile unsigned long *)0x7F008120))

// display controller 

#define MIFPCON     (*((volatile unsigned long *)0x7410800C))

#define SPCON         (*((volatile unsigned long *)0x7F0081A0))

#define VIDCON0      (*((volatile unsigned long *)0x77100000))

#define VIDCON1      (*((volatile unsigned long *)0x77100004))

#define VIDTCON0     (*((volatile unsigned long *)0x77100010))

#define VIDTCON1     (*((volatile unsigned long *)0x77100014))

#define VIDTCON2     (*((volatile unsigned long *)0x77100018))

#define WINCON0      (*((volatile unsigned long *)0x77100020))

#define VIDOSD0A      (*((volatile unsigned long *)0x77100040))

#define VIDOSD0B      (*((volatile unsigned long *)0x77100044))

#define VIDOSD0C      (*((volatile unsigned long *)0x77100048))

#define VIDW00ADD0B0      (*((volatile unsigned long *)0x771000A0))

#define VIDW00ADD1B0      (*((volatile unsigned long *)0x771000D0))

#define VIDW00ADD2          (*((volatile unsigned long *)0x77100100))

#define WPALCON                (*((volatile unsigned long *)0x771001A0))

#define WIN0_PALENTRY0      0x77100400

#define  VSPW         9

#define  VBPD          1

#define  LINEVAL     271

#define  VFPD          1

#define  HSPW         40    

#define  HBPD          1

#define  HOZVAL      479

#define  HFPD          1

#define LeftTopX     0

#define LeftTopY     0

#define RightBotX   479

#define RightBotY   271

#define FRAME_BUFFER   0x54000000

unsigned int fb_base_addr;

unsigned int bpp;

unsigned int xsize;

unsigned int ysize;

void palette_init(void)

{

    int i;

    volatile unsigned long *p = (volatile unsigned long *)WIN0_PALENTRY0; //调色板地址

    

    WPALCON |= (1<<9);   // 允许CPU修改调色板 

    WPALCON &= ~(0x7);   

    WPALCON |= 1;            // 调色板的数据格式: 24-bit ( 8:8:8 ) 

    p[0] = 0x000000;          //只初始化了调色板的前五格的颜色值

    p[1] = 0x00ff00;

    p[2] = 0xff0000;

    p[3] = 0x0000ff;

    p[4] = 0xffffff;

    for (i = 0; i <256; i++)  //用调色板以后显存的bpp=8,8最大能表示256个地址,也就是调色板最大有256项

    {

        //p[i] = ;

    }

    

    WPALCON &= ~(1<<9);   // 禁止CPU访问调色板 

}

void clean_screem(void)

{

    int x;

    int y;

    int cnt = 0;

    

    volatile unsigned char *p = (volatile unsigned char *)fb_base_addr;

    for (x = 0; x <=HOZVAL; x++)

        for (y = 0; y <= LINEVAL; y++)

            p[cnt++] = 0;

}

void lcd_init(void)

{

    // 1. 设置相关GPIO引脚用于LCD 

    GPICON = 0xaaaaaaaa;    // gpi0~gpi15用作lcd_vd[0~15] 

    GPJCON = 0xaaaaaaa;     // gpj0~gpi11用作lcd 

    //GPFCON &= ~(0x3<<28);

    //GPFCON |=  (1<<28);    // GPF14用作背光使能信号 

    GPECON &= ~(0xf);

    GPECON |= (0x1);             // GPE0用作LCD的on/off信号 

    // 2. 初始化6410的display controller 

    // 2.1 hsync,vsync,vclk,vden的极性和时间参数

    // 2.2 行数、列数(分辨率),象素颜色的格式

    // 2.3 分配显存(frame buffer),写入display controller

    MIFPCON &= ~(1<<3);   // Normal mode 

    SPCON    &= ~(0x3);

    SPCON    |= 0x1;              // RGB I/F style 

#if 0

    VIDCON0 &= ~((3<<26) | (3<<17) | (0xff<<6));     // RGB I/F, RGB Parallel format,  

    // vclk== 27MHz Ext Clock input / (CLKVAL+1) = 27/3 = 9MHz 

    VIDCON0 |= ((2<<6) | (1<<4) | (0x3<<2));      

#else

    VIDCON0 &= ~((3<<26) | (3<<17) | (0xff<<6)  | (3<<2));     // RGB I/F, RGB Parallel format,  

    VIDCON0 |= ((14<<6) | (1<<4) );      // vclk== HCLK / (CLKVAL+1) = 133/15 = 9MHz 

#endif

    VIDCON1 &= ~(1<<7);               // 在vclk的下降沿获取数据 

    VIDCON1 |= ((1<<6) | (1<<5));  // HSYNC高电平有效, VSYNC高电平有效, 

    VIDTCON0 = (VBPD << 16) | (VFPD << 8) | (VSPW << 0);

    VIDTCON1 = (HBPD << 16) | (HFPD << 8) | (HSPW << 0);

    VIDTCON2 = (LINEVAL << 11) | (HOZVAL << 0);

    WINCON0 &= ~(0xf << 2);

    WINCON0 |= (0x3<<2) | (1<<17);    // 8 BPP (palletized), byte swap 

    VIDOSD0A = (LeftTopX<<11) | (LeftTopY << 0);

    VIDOSD0B = (RightBotX<<11) | (RightBotY << 0);

    VIDOSD0C = (LINEVAL + 1) * (HOZVAL + 1) / 4;

    VIDW00ADD0B0 = FRAME_BUFFER;

    VIDW00ADD1B0 =  (((HOZVAL + 1)*1 + 0) * (LINEVAL + 1)) & (0xffffff);

    // VBASEL = VBASEU + (LINEWIDTH+OFFSIZE) x (LINEVAL+1) 

    //        = 0 + (480*1 + 0) * 272

    //        = 

    //VIDW00ADD2 =  HOZVAL + 1;

    

    // 设置调色板 

    palette_init();    

    pwm_set(2);

                                    

    fb_base_addr = FRAME_BUFFER;

    xsize = HOZVAL + 1;

    ysize = LINEVAL + 1;

    bpp   = 8;

    clean_screem();

}

void backlight_enable(void)

{

    //GPFDAT |= (1<<14);

}

void backlight_disable(void)

{

    //GPFDAT &= ~(1<<14);

}

void lcd_on(void)

{

    GPEDAT |= (1<<0);

    // 等待10 frame 

}

void lcd_off(void)

{

    GPEDAT &= ~(1<<0);

}

void displaycon_on(void)

{

    VIDCON0 |= 0x3;

    WINCON0 |= 1;   //6410的lcd控制器有多个窗口,这里只使能了一个窗口

}

void displaycon_off(void)

{

    VIDCON0 &= ~0x3;

    WINCON0 &= ~1;   //6410的lcd控制器有多个窗口,这里只使能了一个窗口

}

void lcd_enable(void)

{

    // 使能LCD本身 

    lcd_on();

    

    // 打开背光 

    //backlight_enable();

    pwm_start();

    

    // 使能display controller 

    displaycon_on();

}

void lcd_disable(void)

{

    // 关闭背光 

    // 关闭LCD本身 

    // 关闭display controller 

}

void draw_line(void)

{

    //不用调色板的时候画线传入的是24位颜色值,用调色板以后传入的是在调色板中的颜色索引值

    DrawLine(0,0, 0,271, 0);

    DrawLine(0,0, 479,0, 1);

    DrawLine(0,0, 479,271, 2);

    DrawLine(0,271, 479,0, 3);

    DrawLine(0,271, 479,271, 1);

    DrawLine(479,271, 479,0, 2);

    DrawLine(0,136, 479,136, 3);

    DrawLine(240,0, 240,271, 1);

}

void display_red(void)

{

    volatile unsigned char *p = (volatile unsigned char *)FRAME_BUFFER;

    int x, y;

    int cnt = 0;

    unsigned char colors[] = {0, 1, 2, 3};

    static int color_idx = 0;

    

    for (y = 0; y <= LINEVAL; y++)

    {

        for (x = 0; x <= HOZVAL; x++)

        {

            p[cnt++] =colors[color_idx] ;  // red 

        }

    }

    color_idx++;

    if (color_idx == 5)

        color_idx = 0;

}

void lcd_test(void)

{

    unsigned char c;

    static int lcdon = 0;

    static int blon = 0;

    static int dispon = 0;

    lcd_init();

    

    while (1)

    {

        printf("********LCD TEST MENU********\n\r");

        printf("[L] enable/disable LCD\n\r");

        printf("[B] enable/disable back light\n\r");

        printf("[C] enable/disable s3c6410 display controller\n\r");

        printf("[D] display color\n\r");

        printf("[I]  draw line\n\r");

        printf("[Q] quit\n\r");

        do {

            c = getc();

            if (c == '\n' || c == '\r')

            {

                printf("\n\r");

            }

            else

            {

                putc(c);

            }

        } while (c == '\n' || c == '\r');

        switch (c) {

            case 'l':

            case 'L':

            {

                if (lcdon)

                {

                    lcd_off();

                    printf("LCD off\n\r");

                }

                else

                {

                    lcd_on();

                    printf("LCD on\n\r");

                }

                lcdon = !lcdon;

                break;

            }

            case 'b':

            case 'B':

            {

                pwm_menu();

                break;

            }

            case 'c':

            case 'C':

            {

                if (dispon)

                {

                    displaycon_off();

                    printf("Display controller off\n\r");

                }

                else

                {

                    displaycon_on();

                    printf("Display controller on\n\r");

                }

                blon = !blon;

                break;

            }

            case 'd':

            case 'D':

            {

                display_red();

                break;

            }

            case 'i':

            case 'I':

            {

                draw_line();

                break;

            }

            case 'q':

            case 'Q':

            {

                return ;

                break;

            }

        }

    }

}

=====================================================================

framebuffer.c源码:

// FILE: framebuffer.c

// 实现在framebuffer上画点、画线、画同心圆、清屏的函数

#include "types.h"

#include "framebuffer.h"

extern unsigned int fb_base_addr;

extern unsigned int bpp;

extern unsigned int xsize;

extern unsigned int ysize;

//typedef UINT32 FB_24BPP[272][480];

// 画点

// 输入参数:

//     x、y : 象素坐标

//     color: 颜色值

//         对于16BPP: color的格式为0xAARRGGBB (AA = 透明度),

//     需要转换为5:6:5格式

//         对于8BPP: color为调色板中的索引值,

//     其颜色取决于调色板中的数值

void PutPixel(UINT32 x, UINT32 y, UINT32 color)

{

    UINT8 red,green,blue;

    switch (bpp){

        case 24:

        {

            //bpp=24位,但是为了对齐会浪费一个字节,一共4字节32位

            UINT32 *addr = (UINT32 *)fb_base_addr + (y * xsize + x);

            *addr =  color;

            break;

        }

        case 16:

        {

            UINT16 *addr = (UINT16 *)fb_base_addr + (y * xsize + x);

            red   = (color >> 19) & 0x1f;

            green = (color >> 10) & 0x3f;

            blue  = (color >>  3) & 0x1f;

            color = (red << 11) | (green << 5) | blue; // 格式5:6:5

            *addr = (UINT16) color;

            break;

        }

        

        case 8:

        {

            UINT8 *addr = (UINT8 *)fb_base_addr + (y * xsize + x);

            *addr = (UINT8) color;  // 调色板的索引值 

            break;

        }

        default:

            break;

    }

}

// 画线

// 输入参数:

//     x1、y1 : 起点坐标

//     x2、y2 : 终点坐标

//     color  : 颜色值

//         对于16BPP: color的格式为0xAARRGGBB (AA = 透明度),

//     需要转换为5:6:5格式

//         对于8BPP: color为调色板中的索引值,

//     其颜色取决于调色板中的数值

void DrawLine(int x1,int y1,int x2,int y2,int color)

{

    int dx,dy,e;

    dx=x2-x1; 

    dy=y2-y1;

    

    if(dx>=0)

    {

        if(dy >= 0) // dy>=0

        {

            if(dx>=dy) // 1/8 octant

            {

                e=dy-dx/2;

                while(x1<=x2)

                {

                    PutPixel(x1,y1,color);

                    if(e>0){y1+=1;e-=dx;}   

                    x1+=1;

                    e+=dy;

                }

            }

            else        // 2/8 octant

            {

                e=dx-dy/2;

                while(y1<=y2)

                {

                    PutPixel(x1,y1,color);

                    if(e>0){x1+=1;e-=dy;}   

                    y1+=1;

                    e+=dx;

                }

            }

        }

        else           // dy<0

        {

            dy=-dy;   // dy=abs(dy)

            if(dx>=dy) // 8/8 octant

            {

                e=dy-dx/2;

                while(x1<=x2)

                {

                    PutPixel(x1,y1,color);

                    if(e>0){y1-=1;e-=dx;}   

                    x1+=1;

                    e+=dy;

                }

            }

            else        // 7/8 octant

            {

                e=dx-dy/2;

                while(y1>=y2)

                {

                    PutPixel(x1,y1,color);

                    if(e>0){x1+=1;e-=dy;}   

                    y1-=1;

                    e+=dx;

                }

            }

        }   

    }

    else //dx<0

    {

        dx=-dx;     //dx=abs(dx)

        if(dy >= 0) // dy>=0

        {

            if(dx>=dy) // 4/8 octant

            {

                e=dy-dx/2;

                while(x1>=x2)

                {

                    PutPixel(x1,y1,color);

                    if(e>0){y1+=1;e-=dx;}   

                    x1-=1;

                    e+=dy;

                }

            }

            else        // 3/8 octant

            {

                e=dx-dy/2;

                while(y1<=y2)

                {

                    PutPixel(x1,y1,color);

                    if(e>0){x1-=1;e-=dy;}   

                    y1+=1;

                    e+=dx;

                }

            }

        }

        else           // dy<0

        {

            dy=-dy;   // dy=abs(dy)

            if(dx>=dy) // 5/8 octant

            {

                e=dy-dx/2;

                while(x1>=x2)

                {

                    PutPixel(x1,y1,color);

                    if(e>0){y1-=1;e-=dx;}   

                    x1-=1;

                    e+=dy;

                }

            }

            else        // 6/8 octant

            {

                e=dx-dy/2;

                while(y1>=y2)

                {

                    PutPixel(x1,y1,color);

                    if(e>0){x1-=1;e-=dy;}   

                    y1-=1;

                    e+=dx;

                }

            }

        }   

    }

}

// 绘制同心圆

void Mire(void)

{

    UINT32 x,y;

    UINT32 color;

    UINT8 red,green,blue,alpha;

    for (y = 0; y < ysize; y++)

        for (x = 0; x < xsize; x++){

            color = ((x-xsize/2)*(x-xsize/2) + (y-ysize/2)*(y-ysize/2))/64;

            red   = (color/8) % 256;

            green = (color/4) % 256;

            blue  = (color/2) % 256;

            alpha = (color*2) % 256;

            color |= ((UINT32)alpha << 24);

            color |= ((UINT32)red   << 16);

            color |= ((UINT32)green << 8 );

            color |= ((UINT32)blue       );

            PutPixel(x,y,color);

        }

}

 

// 将屏幕清成单色

// 输入参数:

//     color: 颜色值

//         对于16BPP: color的格式为0xAARRGGBB (AA = 透明度),

//     需要转换为5:6:5格式

//         对于8BPP: color为调色板中的索引值,

//     其颜色取决于调色板中的数值

void ClearScr(UINT32 color)

{   

    UINT32 x,y;

    

    for (y = 0; y < ysize; y++)

        for (x = 0; x < xsize; x++)

            PutPixel(x, y, color);

}

#define FONTDATAMAX 2048

extern const unsigned char fontdata_8x8[FONTDATAMAX];

void lcd_putc(unsigned char c)

{

    static int x = 0;

    static int y = 0;

    int i,j;

    unsigned char line_dots;

    // 获得字模 

    unsigned char *char_dots = fontdata_8x8 + c * 8;    

    // 在framebuffer里描点 

    if (c == '\n')

    {

        //y = (y + 8) % 272;

        y += 8;

        if (y > 272)

            y = 0;

        return ;

    }

    else if (c == '\r')

    {

        x = 0;

        return;

    }

    for (i = 0; i < 8; i++)    

    {

        line_dots = char_dots[i];

        

        for (j = 0; j < 8; j++)

        {

            if (line_dots & (0x80 >> j))

            {

                PutPixel(x+j,  y+i, 1);  // 调色板里面第1个条目的颜色值 

            }

            else

            {

                PutPixel(x+j,  y+i, 0);  // 调色板里面第0个条目的颜色值 

            }

        }

    }

    //x = (x + 8) % 480;

    x += 8;

    if (x > 480)

        x = 0;

    

    if (x == 0)

    {

        //y = (y + 8) % 272;

        y += 8;

        if (y > 272)

            y = 0;

    }

}


推荐阅读

史海拾趣

DB Unlimited公司的发展小趣事

DB Unlimited始终将技术创新作为公司发展的核心驱动力。公司不断投入大量资源进行技术研发和创新,推出了多项具有行业领先水平的音频技术。这些技术的推出不仅提升了公司的竞争力,也推动了整个音频行业的发展。DB Unlimited的技术创新能力和成果得到了业界的广泛认可。

EOS POWER INDIA Pvt公司的发展小趣事

随着市场的不断发展和客户需求的变化,EOS意识到只有不断创新才能保持竞争力。因此,公司加大了对研发的投入,引进了一批高素质的研发人才。经过数年的努力,EOS成功研发出了一系列高性能、高可靠性的电源产品,如交钥匙电源解决方案、定制电源等。这些产品不仅满足了客户的多样化需求,还帮助EOS在市场上获得了更多的份额。

Cables To Go公司的发展小趣事

在电子行业的激烈竞争中,Cables To Go公司以其卓越的产品品质和创新精神脱颖而出。公司从成立之初就注重产品研发,不断推出符合市场需求的高品质线缆产品。通过严格把控原材料采购和制造工艺,Cables To Go确保了每一根线缆都具备出色的性能和稳定性。同时,公司还积极投入研发,推出了一系列具有创新性的线缆解决方案,满足了客户多样化的需求。

富之光(Fujicon)公司的发展小趣事

随着全球化进程的加速,富致科技也积极实施国际化战略。公司不仅在欧洲、北美等地设立了销售和服务网络,还通过参加国际展会、建立海外研发中心等方式,不断提升品牌影响力和市场竞争力。同时,富致科技还注重与全球顶尖企业和研究机构的合作,共同推动PPTC技术的创新与发展。

Daco Semiconductor Co Ltd公司的发展小趣事

Daco深知人才是企业发展的核心动力。因此,公司一直注重人才培养和团队建设。Daco为员工提供了良好的工作环境和发展机会,鼓励员工不断学习和创新。同时,公司也建立了完善的激励机制和福利制度,确保员工能够全身心地投入到工作中。这种注重人才培养和团队建设的做法,使得Daco能够吸引和留住一批优秀的员工,为公司的持续发展提供了有力的保障。

Delphi Connection Systems公司的发展小趣事

随着市场的不断发展,Delphi Connection Systems公司意识到单靠自身的力量难以在激烈的市场竞争中立足。于是,公司积极寻求与其他企业的战略合作,通过资源共享、优势互补,共同开拓市场。公司与一家知名的汽车制造商建立了战略合作关系,为其提供高质量的连接器产品,从而成功进入了汽车电子行业市场。

问答坊 | AI 解惑

世界上最美丽的英文(中文对照)

世界上最美丽的英文,挺好的~~^_^~~…

查看全部问答>

两点间温度控制

1.实验任务   用可调电阻调节电压值作为模拟温度的输入量,当温度低于30℃时,发出长嘀报警声和光报警,当温度高于60℃时,发出短嘀报警声和光报警。测量的温度范围在0-99℃。 2.电路原理图                 图4.29.1 ...…

查看全部问答>

ARM7内核上的 uC/OS—II嵌入式系统移植

ARM7内核上的 uC/OS—II嵌入式系统移植…

查看全部问答>

推荐一个arm学习网站

http://www.realview.com.cn/   这可是ARM公司的中国官方网站哦,具有一定的权威性,而且上面的资料也比较丰富…

查看全部问答>

铝电解电容选型参数

电路系统性能的稳定可靠,与选用的元器件参数、等级、质量等密切相关。设计师应针对产品应用环境以及电性能的要求,准确提出对元件参数的具体要求,包括标称值、精度和误差要求、稳定性要求、温度范围要求、安装尺寸以及与电路性能密切相关的其它要 ...…

查看全部问答>

3G协议的数据传输问题

现在要做一个基于3G协议的数据采集卡,不知道从何下手,想高人请教一下。 如果是自己设计硬件电路,3G网络芯片该如何选择?如果是选择usb 接口的 3G上网卡是否要自己写通信协议的驱动?还是直接写USB的驱动就可以了呢?…

查看全部问答>

ucos IO 模拟I2C程序问题

  使用atmega128 移植ucos II 在I2C 程序,移植的io口模拟时序程序,但是I2C 的程序在单片机程序跑的好好的 一点问题都没有有 ,而且波形也对。都能够完全实现通讯。    当我原封的程序移植到ucos ii 里 就不行了 ,根本没有 ...…

查看全部问答>

请问WINCE的所有者信息存储在哪里?

请问在WINCE6下如何不通过控制面板直接修改所有者?是修改注册表吗? 如果是的话具体存在那个键值?请高手解答....谢谢...…

查看全部问答>

关于在KEIL中访问16位外部RAM方法

各位兄弟姐妹大家好,最近碰到了一个很蹊跷的问题,我们使用STR91x访问外部RAM的时候由于外部RAM是16位的,在KEIL编写程序的时候如果访问数组比如说下面的代码: unsigned char pData[10]; pData[0] = 0x1234; pData是被分配到了外部RAM上, ...…

查看全部问答>