📄 lcd44b0.c
字号:
/**********************************************************
---------------------------------------------------------
File : lcd44b0.c
Purpose : S3C44B0X的lcd控制器的驱动,用于uC/GUI
Data : 2003-7-9 13:46
---------------------------------------------------------
2003-7-31 13:52------完成4,16级灰度支持
*********************************************************
*/
#include <stddef.h> /* needed for definition of NULL */
#include "LCD_Private.H" /* private modul definitions & config */
#include "GUI_Private.H"
#include "GUIDebug.h"
#include "LCD_0.h" /* Defines for first display */
//********************************************************
//
#include <string.h>
#include "..\inc\44b.h"
#include "..\inc\44blib.h"
#include "..\inc\def.h"
//********************************************************
#if (LCD_CONTROLLER == 0 ) && (!defined(WIN32) | defined(LCD_SIMCONTROLLER))
/*
*********************************************************
* *
* Compiler specific settings *
* *
*********************************************************
*/
#ifdef WIN32 /* Avoid warnings in MS-compiler */
#pragma warning(disable : 4244) // warning C4244: '=' : conversion from 'long ' to 'unsigned char ', possible loss of data
#pragma warning(disable : 4761) // warning C4761: integral size mismatch in argument; conversion supplied
#endif
/*
*********************************************************
* *
* Defaults for configuration *
* *
*********************************************************
*/
#define COLOR LCD_COLORINDEX
#ifdef LCDMONO
U32 (*frameBuffer1)[SCR_XSIZE/32];
#endif
#ifdef LCDG4
U32 (*frameBuffer4)[SCR_XSIZE/16];
#endif
#ifdef LCDG16
U32 (*frameBuffer16)[SCR_XSIZE/8];
#endif
/*
*********************************************************
* *
* Internal set pixel routines *
* *
*********************************************************
*/
static void SetPixel(int x, int y, LCD_PIXELINDEX c) {
// c=LCD_NUM_COLORS-1-c;
//黑白
#ifdef LCDMONO
if(x<SCR_XSIZE && y<SCR_YSIZE)
frameBuffer1[(y)][(x)/32]=( frameBuffer1[(y)][(x)/32] & ~(0x80000000>>((x)%32)*1) )
| ( (c)<< ((32-1-((x)%32))*1) );
#endif
//4级灰度
#ifdef LCDG4
if(x<SCR_XSIZE && y<SCR_YSIZE)
frameBuffer4[(y)][(x)/16]=( frameBuffer4[(y)][x/16] & ~(0xc0000000>>((x)%16)*2) )
| ( (c)<<((16-1-((x)%16))*2) );
#endif
//16级灰度
#ifdef LCDG16
if(x<SCR_XSIZE && y<SCR_YSIZE)
frameBuffer16[(y)][(x)/8]=( frameBuffer16[(y)][x/8] & ~(0xf0000000>>((x)%8)*4) )
| ( (c)<<((8-1-((x)%8))*4) );
#endif
}
unsigned int GetPixelIndex(int x, int y) {
LCD_PIXELINDEX col;
//黑白
#ifdef LCDMONO
col=( frameBuffer1[(y)][(x)/32] >> ( 32-1-(x%32)*1 ) ) & 0x1;
return col;
#endif
//4级灰度
#ifdef LCDG4
col=( frameBuffer4[(y)][(x)/16] >> ( 32-2-(x%16)*2 ) ) & 0x3;
return col;
#endif
//16级灰度
#ifdef LCDG16
col=( frameBuffer16[(y)][(x)/8] >> ( 32-4-(x%8)*4 ) ) & 0xf;
return col;
#endif
}
static void XorPixel (int x, int y) {
LCD_PIXELINDEX Index = GetPixelIndex(x,y);
SetPixel(x,y,LCD_NUM_COLORS-1-Index);
}
/*
*********************************************************
* *
* LCD_L0_XorPixel *
* *
*********************************************************
Purpose: This routine is called by emWin. It writes 1 pixel into the
display.
*/
void LCD_L0_XorPixel(int x, int y) {
XorPixel(x, y);
}
void LCD_L0_SetPixelIndex(int x, int y, int ColorIndex) {
SetPixel(x, y, ColorIndex);
}
/*
*********************************************************
* *
* LCD_L0_DrawHLine optimized *
* *
* 16 bit bus, Using BITBLT *
* *
*********************************************************
*/
void LCD_L0_DrawHLine (int x0, int y, int x1)
{
if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR)
{
while (x0 <= x1)
{
XorPixel(x0, y);
x0++;
}
} else
{
while (x0 <= x1)
{
SetPixel(x0, y, COLOR);
x0++;
}
}
}
/*
*********************************************************
* *
* LCD_L0_DrawVLine optimized *
* *
* 16 bit bus, using BITBLT *
* *
*********************************************************
*/
void LCD_L0_DrawVLine (int x, int y0, int y1) {
if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
while (y0 <= y1) {
XorPixel(x, y0);
y0++;
}
} else {
while (y0 <= y1) {
SetPixel(x, y0, COLOR);
y0++;
}
}
}
/*
*********************************************************
* *
* LCD_FillRect *
* *
*********************************************************
*/
void LCD_L0_FillRect(int x0, int y0, int x1, int y1) {
#if !LCD_SWAP_XY
for (; y0 <= y1; y0++) {
LCD_L0_DrawHLine(x0,y0, x1);
}
#else
for (; x0 <= x1; x0++) {
LCD_L0_DrawVLine(x0,y0, y1);
}
#endif
}
/*
**********************************************************
* *
* Draw a line *
* *
**********************************************************
*/
static void DrawBitLine1BPP(int x, int y, U8 const*p, int Diff, int xsize, const LCD_PIXELINDEX*pTrans) {
// LCD_PIXELINDEX aColor[2];
U16 Pixels = ((*p) << 8) | (*(p + 1));
U8 RemPixels;
p++;
// aColor[0] = *pTrans;
// aColor[1] = *(pTrans + 1);
x += Diff;
RemPixels = 16 - Diff;
Pixels <<= Diff;
if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
do {
if (RemPixels==0) {
Pixels = ((*(p + 1)) << 8) | (*(p + 2));
p += 2;
RemPixels = 16;
}
if (Pixels & 0x8000) {
XorPixel(x, y);
}
RemPixels--;
Pixels <<=1;
x++;
} while (--xsize);
}
else {
do {
if (RemPixels==0) {
Pixels = ((*(p + 1)) << 8) | (*(p + 2));
p += 2;
RemPixels = 16;
}
if (Pixels & 0x8000) {
SetPixel(x, y, *(pTrans+1));
}
RemPixels--;
Pixels <<=1;
x++;
} while (--xsize);
}
}
/*
*********************************************************
* *
* Universal draw Bitmap routine *
* *
*********************************************************
*/
void LCD_L0_DrawBitmap (int x0, int y0,
int xsize, int ysize,
int BitsPerPixel,
int BytesPerLine,
const U8* pData, int Diff,
const LCD_PIXELINDEX* pTrans) {
int i;
for (i=0; i<ysize; i++) {
DrawBitLine1BPP(x0, i+y0, pData, Diff, xsize, pTrans);
pData += BytesPerLine;
}
}
/********************************************************
* *
* LCD_L0_SetOrg *
* *
*********************************************************
Purpose: Sets the original position of the virtual display.
Has no function at this point with the PC-driver.
*/
int OrgX, OrgY;
void LCD_L0_SetOrg(int x, int y) {
OrgX = x;
OrgY = y;
}
/*
*********************************************************
* *
* LCD_On *
* LCD_Off *
* *
*********************************************************
*/
void LCD_Off (void) {
Delay(100);
rPDATC = ( rPDATC | (1<<8) );
Delay(100);
}
void LCD_On (void) {
Delay(100);
rPDATC = ( rPDATC & (~(1<<8)) );
Delay(100);
}
void LCD_Init_Controler() {
int i,j;
#ifdef LCDMONO
//320x240 1bit/1pixel LCD
if((U32)frameBuffer1==0)
{
frameBuffer1=(unsigned int (*)[SCR_XSIZE/32])malloc(ARRAY_SIZE_MONO);
}
for(j=0;j<240;j++)
for(i=0;i<10;i++)
{
frameBuffer1[j][i]=0x0;
}
rLCDCON1=(0)|(1<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_MONO<<12);
// disable,4B_SNGL_SCAN,WDLY=16clk,WLH=16clk,
rLCDCON2=(LINEVAL)|(HOZVAL<<10)|(10<<21);
// LINEBLANK=10
rLCDSADDR1= (0x0<<27) | ( ((U32)frameBuffer1>>22)<<21 ) | M5D((U32)frameBuffer1>>1);
// monochrome, LCDBANK, LCDBASEU
rLCDSADDR2= M5D( (((U32)frameBuffer1+(SCR_XSIZE*LCD_YSIZE/8))>>1) ) | (MVAL<<21);
// LCDBASSEL, MVAL
rLCDSADDR3= (LCD_XSIZE/16) | ( ((SCR_XSIZE-LCD_XSIZE)/16)<<9 );
// PAGEWIDTH, OFFSIZE (the number of halfwords)
// No virtual screen.
rLCDCON1=(1)|(1<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_MONO<<12);
// enable,4B_SNGL_SCAN,WDLY=16clk,WLH=16clk,
#endif
//********************************************************************************
#ifdef LCDG4
if((U32)frameBuffer4==0)
{
frameBuffer4=(unsigned int (*)[SCR_XSIZE/16])malloc(ARRAY_SIZE_G4);
}
for(j=0;j<240;j++)
for(i=0;i<20;i++)
{
frameBuffer4[j][i]=0x0;
}
rLCDCON1=(0)|(1<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_G4<<12);
// disable,4B_SNGL_SCAN,WDLY=8clk,WLH=8clk,
rLCDCON2=(LINEVAL)|(HOZVAL<<10)|(10<<21);
//LINEBLANK=10 (without any calculation)
rLCDSADDR1= (0x1<<27) | ( ((U32)frameBuffer4>>22)<<21 ) | M5D((U32)frameBuffer4>>1);
// 4-gray, LCDBANK, LCDBASEU
rLCDSADDR2= M5D((((U32)frameBuffer4+(SCR_XSIZE*LCD_YSIZE/4))>>1)) | (MVAL<<21);
rLCDSADDR3= (LCD_XSIZE/8) | ( ((SCR_XSIZE-LCD_XSIZE)/8)<<9 );
//The following value has to be changed for better display.
//Select 4 levels among 16 gray levels.
rBLUELUT=0xfa40;
rDITHMODE=0x0;
rDP1_2 =0xa5a5;
rDP4_7 =0xba5da65;
rDP3_5 =0xa5a5f;
rDP2_3 =0xd6b;
rDP5_7 =0xeb7b5ed;
rDP3_4 =0x7dbe;
rDP4_5 =0x7ebdf;
rDP6_7 =0x7fdfbfe;
rLCDCON1=(1)|(1<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_G4<<12);
// enable,4B_SNGL_SCAN,WDLY=8clk,WLH=8clk,
#endif
//********************************************************************************
#ifdef LCDG16
if((U32)frameBuffer16==0)
{
frameBuffer16=(unsigned int (*)[SCR_XSIZE/8])malloc(ARRAY_SIZE_G16);
}
for(j=0;j<480;j++)
for(i=0;i<40;i++)
{
frameBuffer16[j][i]=0x0;
}
//The following value has to be changed for better display.
/* rDITHMODE=0x1223a; //philips
rDP1_2 =0x5a5a;
rDP4_7 =0x366cd9b;
rDP3_5 =0xda5a7;
rDP2_3 =0xad7;
rDP5_7 =0xfeda5b7;
rDP3_4 =0xebd7;
rDP4_5 =0xebfd7;
rDP6_7 =0x7efdfbf;*/
rDITHMODE=0x12210;
//rDITHMODE=0x0;
rDP1_2 =0xa5a5;
rDP4_7 =0xba5da65;
rDP3_5 =0xa5a5f;
rDP2_3 =0xd6b;
rDP5_7 =0xeb7b5ed;
rDP3_4 =0x7dbe;
rDP4_5 =0x7ebdf;
rDP6_7 =0x7fdfbfe;
rLCDCON1=(0)|(0<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_G16<<12);
// disable,4B_SNGL_SCAN,WDLY=8clk,WLH=8clk,
rLCDCON2=(LINEVAL)|(HOZVAL<<10)|(10<<21);
//LINEBLANK=10 (without any calculation)
rLCDSADDR1= (0x2<<27) | ( ((U32)frameBuffer16>>22)<<21 ) | M5D((U32)frameBuffer16>>1);
// 16-gray, LCDBANK, LCDBASEU
rLCDSADDR2= M5D((((U32)frameBuffer16+(LCD_XSIZE*LCD_YSIZE/4))>>1)) | (MVAL<<21);
rLCDSADDR3= (LCD_XSIZE/4) | ( ((SCR_XSIZE-LCD_XSIZE)/4)<<9 );
rLCDCON1=(1)|(0<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_G16<<12);
// enable,4B_SNGL_SCAN,WDLY=8clk,WLH=8clk,
#endif
}
unsigned int LCD_L0_GetPixelIndex(int x, int y) {
return GetPixelIndex(x,y);
}
/*
*********************************************************
* *
* LCD_L0_SetLUTEntry *
* *
*********************************************************
*/
void LCD_L0_SetLUTEntry(U8 Pos, LCD_COLOR color) {
}
/*
*********************************************************
* *
* LCD_L0_ReInit : Re-Init the display *
* *
*********************************************************
ReInit contains all of the code that can be re-executed at any point without
changing or even disturbing what can be seen on the LCD.
Note that it is also used as a subroutine by LCD_Init().
*/
void LCD_L0_ReInit(void) {
LCD_Init_Controler(); /* macro defined in config */
}
/*
*********************************************************
* *
* LCD_Init : Init the display *
* *
*********************************************************
*/
int LCD_L0_Init(void) {
GUI_DEBUG_LOG("\nLCD_Init()");
/* Init controllers (except lookup table) */
LCD_L0_ReInit();
LCD_Off();
return 0; /* Init successfull ! */
}
/*
*********************************************************
* *
* LCD_L0_CheckInit *
* *
* Check if display controller(s) is/are still *
* properly initialized *
* *
*********************************************************
Return value: 0 => No error, init is O.K.
*/
int LCD_L0_CheckInit(void) {
return 0;
}
#else
void LCD13XX(void) { } /* avoid empty object files */
#endif /* (LCD_CONTROLLER == 0) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -