//***************************************************************************** | |
// +--+ | |
// | ++----+ | |
// +-++ | | |
// | | | |
// +-+--+ | | |
// | +--+--+ | |
// +----+ Copyright (c) 2009 Code Red Technologies Ltd. | |
// | |
// lcd.c contains various routines to plot to the LCD display on the RDB1768 | |
// development board. | |
// | |
// Software License Agreement | |
// | |
// The software is owned by Code Red Technologies and/or its suppliers, and is | |
// protected under applicable copyright laws. All rights are reserved. Any | |
// use in violation of the foregoing restrictions may subject the user to criminal | |
// sanctions under applicable laws, as well as to civil liability for the breach | |
// of the terms and conditions of this license. | |
// | |
// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED | |
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF | |
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. | |
// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT | |
// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH | |
// CODE RED TECHNOLOGIES LTD. | |
#include "lcd_commands.h" | |
#include "lcd.h" | |
#include "lcd_driver.h" | |
#include "font.h" | |
#include <stdlib.h> // to provice abs() function | |
// Routine to draw a filled rectangle to the LCD. | |
// Two corners of rectangle are at (xmin,ymin) and (xmax,ymax). | |
// The Rectangle is filled with the RGB565 color specified | |
void LCD_FilledRect(int xmin,int xmax,int ymin,int ymax,int color) | |
{ | |
int i; | |
// Specify to LCD controller coordinates we are writing to... | |
LCDdriver_WriteCom(DD_CASET); // Set the column address | |
LCDdriver_WriteData(xmin); // min address | |
LCDdriver_WriteData(xmax); // max address | |
LCDdriver_WriteCom(DD_RASET); // Set the row address | |
LCDdriver_WriteData(ymin + 1); // min address | |
LCDdriver_WriteData(ymax + 1); // max address | |
LCDdriver_WriteCom(DD_RAMWR); // RAM Write command | |
// Plot the color data to the LCD buffer | |
for(i = ((xmax - xmin + 1) * (ymax - ymin + 1)); i > 0; i--) | |
{ | |
LCDdriver_WriteData(color >> 8); // top 8 bits of RGB565 color | |
LCDdriver_WriteData(color); // bottom 8 bits of RGB565 color | |
} | |
} | |
// Routine to draw an unfilled rectangle to the LCD. | |
// Two corners of rectangle are at (xmin,ymin) and (xmax,ymax). | |
// The Rectangle is drawn in the RGB565 color specified | |
void LCD_Rect(int xmin,int xmax,int ymin,int ymax,int color) | |
{ | |
// Draw 4 lines of rectange as 4 filled rectanges, each of 1 pixel wide | |
LCD_FilledRect(xmin,xmin,ymin,ymax,color); | |
LCD_FilledRect(xmax,xmax,ymin,ymax,color); | |
LCD_FilledRect(xmin,xmax,ymin,ymin,color); | |
LCD_FilledRect(xmin,xmax,ymax,ymax,color); | |
} | |
// Plot a point on the screen in the 6:5:6 color format | |
void LCD_PlotPoint(int x,int y,int color) | |
{ | |
LCDdriver_WriteCom(DD_CASET); // Set the column address | |
LCDdriver_WriteData(x); // min address | |
LCDdriver_WriteData(x); // max address | |
LCDdriver_WriteCom(DD_RASET); // Set the row address | |
LCDdriver_WriteData(y + 1); // min address | |
LCDdriver_WriteData(y + 1); // max address | |
LCDdriver_WriteCom(DD_RAMWR); // RAM Write command | |
LCDdriver_WriteData(color >> 8); // top 8 bits of RGB565 color | |
LCDdriver_WriteData(color); // top 8 bits of RGB565 color | |
} | |
// Routine to draw a filled circle to the LCD. | |
// The centre of the circle is at (x0,y0) and the circle has the | |
// specifed radius. The circle is filled with the RGB565 color | |
// The circle is drawn using the "Midpoint circle algorithm", | |
// also known as "Bresenham's circle algorithm". In order to fill | |
// the circle, the algorithm has been modifed to draw a line between | |
// each two points, rather than plotting the two points individually. | |
void LCD_FilledCircle (int x0, int y0, int radius, int color) | |
{ | |
int f = 1 - radius; | |
int ddF_x = 1; | |
int ddF_y = -2 * radius; | |
int x = 0; | |
int y = radius; | |
LCD_FilledRect(x0, x0 ,y0 - radius,y0 + radius, color); | |
LCD_FilledRect(x0 - radius, x0 + radius ,y0,y0, color); | |
while(x < y) | |
{ | |
if(f >= 0) | |
{ | |
y--; | |
ddF_y += 2; | |
f += ddF_y; | |
} | |
x++; | |
ddF_x += 2; | |
f += ddF_x; | |
LCD_FilledRect(x0-x, x0+x ,y0 +y, y0 + y, color); | |
LCD_FilledRect(x0-x, x0+x ,y0 - y, y0 - y, color); | |
LCD_FilledRect(x0-y, x0+y ,y0 + x, y0 + x, color); | |
LCD_FilledRect(x0-y, x0+y ,y0 - x, y0 - x, color); | |
} | |
} | |
// Routine to draw an unfilled circle to the LCD. | |
// The centre of the circle is at (x0,y0) and the circle has the | |
// specifed radius. The circle is drawn in the RGB565 color | |
// The circle is drawn using the "Midpoint circle algorithm", | |
// also known as "Bresenham's circle algorithm". | |
void LCD_Circle (int x0, int y0, int radius, int color) | |
{ | |
int f = 1 - radius; | |
int ddF_x = 1; | |
int ddF_y = -2 * radius; | |
int x = 0; | |
int y = radius; | |
LCD_PlotPoint(x0, y0 + radius, color); | |
LCD_PlotPoint(x0, y0 - radius, color); | |
LCD_PlotPoint(x0 + radius, y0, color); | |
LCD_PlotPoint(x0 - radius, y0, color); | |
while(x < y) | |
{ | |
if(f >= 0) | |
{ | |
y--; | |
ddF_y += 2; | |
f += ddF_y; | |
} | |
x++; | |
ddF_x += 2; | |
f += ddF_x; | |
LCD_PlotPoint(x0 + x, y0 + y, color); | |
LCD_PlotPoint(x0 - x, y0 + y, color); | |
LCD_PlotPoint(x0 + x, y0 - y, color); | |
LCD_PlotPoint(x0 - x, y0 - y, color); | |
LCD_PlotPoint(x0 + y, y0 + x, color); | |
LCD_PlotPoint(x0 - y, y0 + x, color); | |
LCD_PlotPoint(x0 + y, y0 - x, color); | |
LCD_PlotPoint(x0 - y, y0 - x, color); | |
} | |
} | |
// Routine to draw a line in the RGB565 color to the LCD. | |
// The line is drawn from (xmin,ymin) to (xmax,ymax). | |
// The algorithm used to draw the line is "Bresenham's line | |
// algorithm". | |
#define SWAP(a, b) a ^= b; b ^= a; a ^= b; | |
void LCD_Line (int xmin,int xmax,int ymin,int ymax,int color) | |
{ | |
int Dx = xmax - xmin; | |
int Dy = ymax - ymin; | |
int steep = (abs(Dy) >= abs(Dx)); | |
if (steep) { | |
SWAP(xmin, ymin); | |
SWAP(xmax, ymax); | |
// recompute Dx, Dy after swap | |
Dx = xmax - xmin; | |
Dy = ymax - ymin; | |
} | |
int xstep = 1; | |
if (Dx < 0) { | |
xstep = -1; | |
Dx = -Dx; | |
} | |
int ystep = 1; | |
if (Dy < 0) { | |
ystep = -1; | |
Dy = -Dy; | |
} | |
int TwoDy = 2*Dy; | |
int TwoDyTwoDx = TwoDy - 2*Dx; // 2*Dy - 2*Dx | |
int E = TwoDy - Dx; //2*Dy - Dx | |
int y = ymin; | |
int xDraw, yDraw; | |
int x; | |
for (x = xmin; x != xmax; x += xstep) { | |
if (steep) { | |
xDraw = y; | |
yDraw = x; | |
} else { | |
xDraw = x; | |
yDraw = y; | |
} | |
// plot | |
LCD_PlotPoint(xDraw, yDraw, color); | |
// next | |
if (E > 0) { | |
E += TwoDyTwoDx; //E += 2*Dy - 2*Dx; | |
y = y + ystep; | |
} else { | |
E += TwoDy; //E += 2*Dy; | |
} | |
} | |
} | |
// Routine to clear the LCD. | |
// Implemented by drawing a black rectangle across the whole screen | |
void LCD_ClearScreen(void) | |
{ | |
LCD_FilledRect (0,LCD_MAX_X,0 , LCD_MAX_Y, COLOR_BLACK); | |
} | |
// Routine to write a single character to screen in the font pointed | |
// to by pBitMap. This routine is intended to be used via the | |
// LCD_PrintChar() and LCD_PrintString() routines, rather than called | |
// directly from user code. | |
void LCD_WriteBitMap8x15(int x, int y, int height, int width, unsigned char *pBitMap, int color) | |
{ | |
int xmax = x + width - 1; // start at zero | |
int ymax = y + height - 1; // start at zero | |
int iRow, iCol; | |
unsigned char ucRowData; | |
LCDdriver_WriteCom(DD_CASET); // Column address set | |
LCDdriver_WriteData(x); // Start column | |
LCDdriver_WriteData(xmax); // End column | |
LCDdriver_WriteCom(DD_RASET); // Row address set | |
LCDdriver_WriteData(y); // Start row | |
LCDdriver_WriteData(ymax); // End row | |
LCDdriver_WriteCom(DD_RAMWR); // Memory write | |
for(iRow=0;iRow<height;iRow++) | |
{ | |
ucRowData = *pBitMap++; | |
for(iCol=0;iCol<width;iCol++) | |
{ | |
// Look at each input bitmap bit | |
// and write as a black-pixel or | |
// a color-pixel. | |
if(ucRowData & 0x80) // 'color pixel' | |
{ | |
LCDdriver_WriteData(color >> 8); | |
LCDdriver_WriteData(color); | |
} | |
else // black pixel | |
{ | |
LCDdriver_WriteData(0x00); | |
LCDdriver_WriteData(0x00); | |
} | |
ucRowData = ucRowData<<1; | |
} | |
} | |
} | |
// Prints the character 'c' to the LCD in the appropriate color. | |
void LCD_PrintChar(int x, int y, unsigned char c, int color ) | |
{ | |
const unsigned char index = font_index_table[c]; | |
const unsigned int offset = index * 15; | |
unsigned char *pData = (unsigned char *)&font_data_table[offset]; | |
LCD_WriteBitMap8x15(x, y, 15, 8, pData, color); | |
} | |
// Prints the string to the LCD in the appropriate color. | |
void LCD_PrintString(int x, int y, char *pcString, int iStrLen, int color) | |
{ | |
unsigned char index; | |
unsigned int offset; | |
unsigned char *pData; | |
unsigned char c; | |
int i; | |
for(i=0;i<iStrLen;i++) | |
{ | |
c = pcString[i]; | |
if(c==0) | |
break; | |
index = font_index_table[c]; | |
offset = index * 15; | |
pData = (unsigned char *)&font_data_table[offset]; | |
LCD_WriteBitMap8x15(x, y, 15, 8, pData, color); | |
x += 8; | |
} | |
} |