#include "data_types.h"
#include "lpc2478.h"
#include "lcd_draw.h"
#include <assert.h>
#define C_GLCD_H_SIZE 800
#define C_GLCD_V_SIZE 480
#define TEXT_DEF_TAB_SIZE 5
static pFontType_t pCurrFont = NULL;
static LdcPixel_t TextColour;
static LdcPixel_t TextBackgndColour;
static INT32S TextX_Pos = 0;
static INT32S TextY_Pos = 0;
static INT32U XL_Win = 0;
static INT32U YU_Win = 0;
static INT32U XR_Win = C_GLCD_H_SIZE-1;
static INT32U YD_Win = C_GLCD_V_SIZE-1;
static INT32U TabSize = TEXT_DEF_TAB_SIZE;
static INT32U WindY_Size, WindX_Size;
static INT32U CurrY_Size, CurrX_Size;
static pINT32U pWind;
static pINT32U pPix;
/*-----------------------------------------------------------------------------
* 800 x 480 TFT LCD单个象素的显示数据输出
*/
void PutPixel(INT32S x,INT32S y,INT16S c)
{
if(x < 800 && y < 480)
*(volatile INT16U *)(SDRAM_BASE + 2*(x + 800 * y)) = c;
}
/**************************************************************
填充某一特定区块为特定颜色
**************************************************************/
void putarea(INT32S x_start,INT32S x_end,INT32S y_start,INT32S y_end,INT16S c)
{
INT32S x,y;
if(x_start<x_end && x_end<800 && y_start<y_end && y_end<480)
{
for(x=x_start;x<=x_end;x++)
{
for(y=y_start;y<=y_end;y++)
PutPixel(x,y,c);
}
}
}
/**************************************************************
填充马赛克
**************************************************************/
void fillmosaic(void)
{
INT16S color[]={0x07e0,0xf800,0x001f,0xff00,0xffff,0x0000,0x02fe};
INT32S i,j,k=0;
for(i=0;i<10;i++)
{for(j=0;j<=10;j++)
{
putarea(80*j,(80*(j+1)-1),48*i,(48*(i+1)-1),color[k]);
if(k++==6)
k=0;
}
}
}
/**************************************************************
800×480 16Bpp TFT LCD全屏填充特定颜色单元或清屏
**************************************************************/
void Lcd_ClearScr(INT32S x,INT32S y,INT32S c)
{
INT32S i = 0;
while (i < x * y)
{
*(volatile INT16U *)(SDRAM_BASE + i * 2) = c;
i += 1;
}
}
/**************************************************************
// LCD display is flipped vertically
// But, think the algorithm by mathematics point.
// 3I2
// 4 I 1
// --+-- <-8 octants mathematical cordinate
// 5 I 8
// 6I7
**************************************************************/
void Glib_Line(INT32S x1,INT32S y1,INT32S x2,INT32S y2,INT32S color)
{
INT32S 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;
}
}
}
}
}
/**************************************************************
在LCD屏幕上画一个矩形
**************************************************************/
void Glib_Rectangle(INT32S x1,INT32S y1,INT32S x2,INT32S y2,INT32S color)
{
Glib_Line(x1,y1,x2,y1,color);
Glib_Line(x2,y1,x2,y2,color);
Glib_Line(x1,y2,x2,y2,color);
Glib_Line(x1,y1,x1,y2,color);
}
/**************************************************************
在LCD屏幕上用颜色填充一个矩形
**************************************************************/
void Glib_FilledRectangle(INT32S x1,INT32S y1,INT32S x2,INT32S y2,INT32S color)
{
INT32S i;
for(i=y1;i<=y2;i++)
Glib_Line(x1,i,x2,i,color);
}
/*************************************************************************
* Function Name: GLCD_SetFont
* Parameters: pFontType_t pFont, LdcPixel_t Color
* LdcPixel_t BackgndColor
*
* Return: none
*
* Description: Set current font, font color and background color
*
*************************************************************************/
void GLCD_SetFont(pFontType_t pFont, LdcPixel_t Color, LdcPixel_t BackgndColor)
{
pCurrFont = pFont;
TextColour = Color;
TextBackgndColour = BackgndColor;
}
/*************************************************************************
* Function Name: GLCD_SetWindow
* Parameters: Int32U X_Left, Int32U Y_Up,
* Int32U X_Right, Int32U Y_Down
*
* Return: none
*
* Description: Set draw window XY coordinate in pixels
*
*************************************************************************/
void GLCD_SetWindow(INT32U X_Left, INT32U Y_Up,
INT32U X_Right, INT32U Y_Down)
{
assert(X_Right < C_GLCD_H_SIZE);
assert(Y_Down < C_GLCD_V_SIZE);
assert(X_Left < X_Right);
assert(Y_Up < Y_Down);
XL_Win = X_Left;
YU_Win = Y_Up;
XR_Win = X_Right;
YD_Win = Y_Down;
}
/*************************************************************************
* Function Name: GLCD_TextSetPos
* Parameters: Int32U X_UpLeft, Int32U Y_UpLeft,
* Int32U X_DownLeft, Int32U Y_DownLeft
*
* Return: none
*
* Description: Set text X,Y coordinate in characters
*
*************************************************************************/
void GLCD_TextSetPos(INT32U X, INT32U Y)
{
TextX_Pos = X;
TextY_Pos = Y;
}
/*************************************************************************
* Function Name: GLCD_TextSetTabSize
* Parameters: Int32U Size
*
* Return: none
*
* Description: Set text tab size in characters
*
*************************************************************************/
void GLCD_TextSetTabSize(INT32U Size)
{
TabSize = Size;
}
/*************************************************************************
* Function Name: LCD_SET_WINDOW
* Parameters: int c
*
* Return: none
*
* Description: Put char function
*
*************************************************************************/
void LCD_SET_WINDOW (INT32U X_Left, INT32U X_Right,
INT32U Y_Up, INT32U Y_Down)
{
pPix = pWind = ((pINT32U)SDRAM_BASE) + X_Left + (Y_Up*C_GLCD_H_SIZE);
WindX_Size = X_Right - X_Left;
WindY_Size = Y_Down - Y_Up;
CurrX_Size = CurrY_Size = 0;
}
/*************************************************************************
* Function Name: LCD_SET_WINDOW
* Parameters: int c
*
* Return: none
*
* Description: Put char function
*
*************************************************************************/
static
void LCD_WRITE_PIXEL (INT32U Pixel)
{
*pPix++ = Pixel;
if (++CurrX_Size> WindX_Size)
{
CurrX_Size = 0;
if(++CurrY_Size> WindY_Size)
{
CurrY_Size = 0;
}
pPix = pWind + CurrY_Size * C_GLCD_H_SIZE;
}
}
/*************************************************************************
* Function Name: GLCD_TextCalcWindow
* Parameters: pInt32U pXL, pInt32U pXR,
* pInt32U pYU, pInt32U pYD,
* pInt32U pH_Size, pInt32U pV_Size
*
* Return: Boolean
* FALSE - out of window coordinate aren't valid
* TRUE - the returned coordinate are valid
*
* Description: Calculate character window
*
*************************************************************************/
static
BOOL GLCD_TextCalcWindow (pINT32U pXL, pINT32U pXR,
pINT32U pYU, pINT32U pYD,
pINT32U pH_Size, pINT32U pV_Size)
{
*pH_Size = pCurrFont->H_Size;
*pV_Size = pCurrFont->V_Size;
*pXL = XL_Win + (TextX_Pos*pCurrFont->H_Size);
if(*pXL> XR_Win)
{
return(FALSE);
}
*pYU = YU_Win + (TextY_Pos*pCurrFont->V_Size);
if(*pYU> YD_Win)
{
return(FALSE);
}
*pXR = XL_Win + ((TextX_Pos+1)*pCurrFont->H_Size) - 1;
if(*pXR> XR_Win)
{
*pH_Size -= *pXR - XR_Win;
*pXR = XR_Win;
}
*pYD = YU_Win + ((TextY_Pos+1)*pCurrFont->V_Size) - 1;
if(*pYD> YD_Win)
{
*pV_Size -= *pYD - YD_Win;
*pYD = YD_Win;
}
return(TRUE);
}
/*************************************************************************
* Function Name: putchar
* Parameters: int c
*
* Return: none
*
* Description: Put char function
*
*************************************************************************/
int putchar (int c)
{
INT32U i,j,k;
pINT8U pSrc;
INT32U H_Line;
INT32U xl,xr,yu,yd,Temp,V_Size, H_Size, SrcInc = 1;
INT32U WhiteSpaceNumb;
if(pCurrFont == NULL)
{
return(FALSE);
}
H_Line = (pCurrFont->H_Size / 8) + ((pCurrFont->H_Size % 8)?1:0);
switch(c)
{
case '\n': // go to begin of next line (NewLine)
++TextY_Pos;
break;
case '\r': // go to begin of this line (Carriage Return)
// clear from current position to end of line
while(GLCD_TextCalcWindow(&xl,&xr,&yu,&yd,&H_Size,&V_Size))
{
LCD_SET_WINDOW(xl,xr,yu,yd);
for(i = 0; i < V_Size; ++i)
{
for(j = 0; j < H_Size; ++j)
{
LCD_WRITE_PIXEL(TextBackgndColour);
}
}
++TextX_Pos;
}
TextX_Pos = 0;
break;
case '\b': // go back one position (BackSpace)
if(TextX_Pos)
{
--TextX_Pos;
// del current position
if(GLCD_TextCalcWindow(&xl,&xr,&yu,&yd,&H_Size,&V_Size))
{
LCD_SET_WINDOW(xl,xr,yu,yd);
for(i = 0; i < V_Size; ++i)
{
for(j = 0; j < H_Size; ++j)
{
LCD_WRITE_PIXEL(TextBackgndColour);
}
}
}
}
break;
case '\t': // go to next Horizontal Tab stop
WhiteSpaceNumb = TabSize - (TextX_Pos%TabSize);
for(k = 0; k < WhiteSpaceNumb; ++k)
{
LCD_SET_WINDOW(xl,xr,yu,yd);
if(GLCD_TextCalcWindow(&xl,&xr,&yu,&yd,&H_Size,&V_Size))
{
for(i = 0; i < V_Size; ++i)
{
for(j = 0; j < H_Size; ++j)
{
LCD_WRITE_PIXEL(TextBackgndColour);
}
}
++TextX_Pos;
}
else
{
break;
}
}
break;
case '\f': // go to top of page (Form Feed)
// clear entire window
H_Size = XR_Win - XL_Win;
V_Size = YD_Win - YU_Win;
// set character window X left, Y right
LCD_SET_WINDOW(XL_Win,XR_Win,YU_Win,YD_Win);
// Fill window with background font color
for(i = 0; i <= V_Size; ++i)
{
for(j = 0; j <= H_Size; ++j)
{
LCD_WRITE_PIXEL(TextBackgndColour);
}
}
TextX_Pos = TextY_Pos = 0;
break;
case '\a': // signal an alert (BELl)
;
break;
default:
// Calculate the current character base address from stream
// and the character position
if((c < pCurrFont->CharacterOffset) &&
(c>= pCurrFont->CharactersNuber))
{
c = 0;
}
else
{
c -= pCurrFont->CharacterOffset;
}
pSrc = pCurrFont->pFontStream + (H_Line * pCurrFont->V_Size * c);
// Calculate character window and fit it in the text window
if(GLCD_TextCalcWindow(&xl,&xr,&yu,&yd,&H_Size,&V_Size))
{
// set character window X left, Y right
LCD_SET_WINDOW(xl,xr,yu,yd);
// Send char data
for(i = 0; i < V_Size; ++i)
{
SrcInc = H_Line;
for(j = 0; j < H_Size; ++j)
{
Temp = (*pSrc & (1UL << (j&0x7)))?TextColour:TextBackgndColour;
LCD_WRITE_PIXEL(Temp);
if((j&0x7) == 7)
{
++pSrc;
--SrcInc;
}
}
// next line of character
pSrc += SrcInc;
}
}
++TextX_Pos;
}
return(c);
}
void dprintf( INT8U *ptr)
{
while(*ptr)
{
putchar(*ptr);
ptr++;
}
}
/*************************************************************************
* Function Name: GLCD_LoadPic
* Parameters: Int32U X_Left, Int32U Y_Up, Bmp_t * pBmp
*
* Return: none
*
* Description: Load picture in VRAM memory area
*
*************************************************************************/
void GLCD_LoadPic (INT32U X_Left, INT32U Y_Up, Bmp_t * pBmp, INT32U Mask)
{
INT32U i,j;
pINT32U pData = ((pINT32U) SDRAM_BASE) + X_Left + (Y_Up * C_GLCD_H_SIZE);
pINT32U pSrc = pBmp->pPicStream;
INT32U X_LeftHold;
for(i = 0; i < pBmp->V_Size; i++)
{
if(Y_Up++>= C_GLCD_V_SIZE)
{
break;
}
for(j = 0; j < pBmp->H_Size; j++)
{
if(X_LeftHold++>= C_GLCD_H_SIZE)
{
pSrc += pBmp->H_Size - j;
break;
}
*(pData+j) = *pSrc++ ^ Mask;
}
X_LeftHold = X_Left;
pData += C_GLCD_H_SIZE;
}
}
/*************************************************************************
* Function Name: GLCD_SetPallet
* Parameters: const Int32U * pPallete
*
* Return: none
*
* Description: GLCD init colour pallete
*
*************************************************************************/
void GLCD_SetPallet (const INT32U * pPallete)
{
INT32U i;
pINT32U pDst = (pINT32U) SDRAM_BASE;
assert(pPallete);
for (i = 0; i < 128; i++)
{
*pDst++ = *pPallete++;
}
}
/*************************************************************************
* Function Name: GLCD_Init
* Parameters: const Int32U *pPain, const Int32U * pPallete
*
* Return: none
*
* Description: GLCD controller init
*
*************************************************************************/
void GLCD_Init (const INT32U *pPain, const INT32U * pPallete)
{
INT32U i;
pINT32U pDst = (pINT32U) SDRAM_BASE;
if(NULL != pPallete)
{
GLCD_SetPallet(pPallete);
}
if (NULL == pPain)
{
// clear display memory
for(i = 0; (C_GLCD_H_SIZE * C_GLCD_V_SIZE)> i; i++)
{
*pDst++ = 0;
}
}
else
{
// set display memory
for(i = 0; (800 * 480)> i; i++)
{
*pDst++ = *pPain++;
}
}
}
|