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;
}
}
上一篇:自己写bootloader之OK6410
下一篇:OK6410裸机之LCD显
推荐阅读最新更新时间:2024-03-16 16:15
设计资源 培训 开发板 精华推荐
- 是德科技 FieldFox 手持式分析仪配合 VDI 扩频模块,实现毫米波分析功能
- 贸泽开售可精确测量CO2水平的 英飞凌PASCO2V15 XENSIV PAS CO2 5V传感器
- 玩法进阶,浩亭让您的PCB板端连接达到新高度!
- 长城汽车研发新篇章:固态电池技术引领未来
- 纳芯微提供全场景GaN驱动IC解决方案
- 解读华为固态电池新专利,2030 叫板宁德时代?
- 让纯电/插混车抓狂?中企推全球首款-40℃可放电增混电池,不怕冷
- 智驾域控知多少:中低端车型加速上车,行泊一体方案占主体
- Foresight推出六款先进立体传感器套件 彻底改变工业和汽车3D感知
- OPTIMA推出全新ORANGETOP QH6锂电池 可适应极端温度条件