历史上的今天

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

正在发生

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

发布者:xrmilk 来源: eefocus关键字:OK6410  裸机  LCD调色板 手机看文章 扫描二维码
随时随地手机看文章

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;

    }

}


关键字:OK6410  裸机  LCD调色板 引用地址:OK6410裸机之LCD调色板

上一篇:自己写bootloader之OK6410
下一篇:OK6410裸机之LCD显

推荐阅读

用上国产“大脑”的机械臂、多功能智能化、实现混合生产的柔性生产线……在10日召开的第五届中国机器人峰会暨智能经济人才峰会上,近80家知名企业带来了一批机器人应用成果,展示了这个领域追赶世界水平的最新进展。 自去年下半年至今,沉寂两年的机器人自动化板块虽不受资本市场关注,但行业层面屡超预期。首先,2017年行业整体销量水平能达到13万台...
参考资料:王宏波老师的PPTMSP430F6638用户手册王宏波老师实验教程本章最新更新日期:2018.12.22第五章 Timer_A0寄存器5.1 TA0CTL【注意】Timer_A0有两种中断,一种是TAIFG,一种是TAxCCR0 CCIFG5.2 TA0RTA0的16位计数器,这个没啥好说的我起啦,一枪秒啦,有什么好说的5.3 TA0CCTLn(n=0~6)5.4 TA0CCRn这个就是存放比较寄存器的值,可以用来设置周期...
近年来,各大手机厂商的快充技术发展的越来越快,一加当然也不例外,旗下即将发布的新机——一加8T支持65W快充,能够很快将手机电量充满。不过4年前,一加3还“仅”支持20W快速充电。这些年一加是怎样越来越“来电”的?10月9日,一加官方梳理了一下自家的快充发展史。一加8T据官方介绍,2016年发布的一加3就已率先用上了当时先进的Dash闪充技术,在5V/4A...
汽车技术的发展促使自动驾驶汽车概念逐步成为现实,自动驾驶汽车的普及将是必然结果,在不久的将来,自动驾驶汽车将改变人们的出行方式。然而在自动驾驶技术迅速发展、产业模式不断走向成熟、车企产量计划全面提上日程的今天,我国对于自动驾驶的分类还没有统一的标准,很多车企在自动驾驶设计及宣传中,参照的是由国际自动机工程师学会(SAE-Internationa...

史海拾趣

问答坊 | AI 解惑

《我恋爱,我容易吗?〉电子书

《我恋爱,我容易吗?〉电子书…

查看全部问答∨

我国汽车电子标准概述

1、汽车电子产品概述 近年来,越来越严格的安全、环保技术法规和用户苛刻的个性化使用要求使得制造商不得不依赖电子技术不断改进其产品的性能,可以说汽车技术所取得的每一项进步都离不开电子技术在汽车上的应用。电子技术的应用几乎已经深入到汽 ...…

查看全部问答∨

使用AVR实现的频谱分析仪--DIY类型

老外做的一个频谱分析仪分享下:http://elm-chan.org/works/rsm/report_e.html…

查看全部问答∨

如何自动隐藏任务栏与开始菜单?

WINCE启动后,要求自动隐藏任务栏与开始菜单。请问通过设置哪里来实现?…

查看全部问答∨

WM 预留内存比动态分配,好处在哪里呢

好久没来这里啦,大家好哇。 最近调试一个东东,老大说要预留内存给这个驱动,以前是HalAllocateCommonBuffer动态申请连续内存空间的。 我想问下,这个预留的好处在哪里呢? 能节约内存空间吗? 谢谢啦…

查看全部问答∨

【转载】ASUS RampageII vs GENE

我整理一份比较表格,方便大家参考. RampageII vs GENE照片如下. Extreme-Vcore GENE-Vcore Extreme-IO GENE-IO PCB Layer compare …

查看全部问答∨

急求关于智能玩具车的单片机英文文献~~3000字左右

毕业设计需要~还2天就要交 希望各位能帮帮忙~~ 邮箱lanqoushaonian@163.com 万分感谢…

查看全部问答∨

isd4002

本帖最后由 paulhyde 于 2014-9-15 08:56 编辑 请问怎样将录音放到指定的地址?  …

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved