1241 lines
24 KiB
C
1241 lines
24 KiB
C
/*
|
|
lcd.c - lcd control & graphics primitives
|
|
Copyright (C) 2007 Ch. Klippel <ck@mamalala.net>
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "global.h"
|
|
#include "lpc2220.h"
|
|
#include "lcd.h"
|
|
#include "fonty.h"
|
|
#include "boop_logo"
|
|
#include "adc.h"
|
|
#include "timerfuncs.h"
|
|
|
|
unsigned int is_drawing;
|
|
volatile unsigned char symbols;
|
|
volatile unsigned char oldsymbols;
|
|
|
|
void _do_rcu(unsigned char x, unsigned char y, unsigned char l, unsigned char m);
|
|
void _do_rcuAlpha (unsigned char x, unsigned char y, unsigned char l, unsigned char m,
|
|
unsigned char* alphaBuf);
|
|
void _do_rcuS(unsigned char x, unsigned char y, unsigned char m);
|
|
void _draw_block(unsigned char x, unsigned char y, unsigned char w, unsigned char h, unsigned char c, unsigned char m);
|
|
void _draw_hline(unsigned char x, unsigned char y, unsigned char l, unsigned char c, unsigned char m);
|
|
void _draw_vline(unsigned char x, unsigned char y, unsigned char l, unsigned char c, unsigned char m);
|
|
|
|
// Function pointer to section (".text.fastcode")
|
|
rcu_fn do_rcu;
|
|
|
|
rcuAlpha_fn do_rcuAlpha;
|
|
|
|
rcus_fn do_rcuS;
|
|
bl_fn draw_block;
|
|
ln_fn draw_hline;
|
|
ln_fn draw_vline;
|
|
|
|
|
|
void pause(unsigned int ptime)
|
|
{
|
|
unsigned long xx;
|
|
xx = ptime * 1500;
|
|
while(xx)
|
|
{
|
|
xx--;
|
|
};
|
|
}
|
|
|
|
|
|
void lcd_set(unsigned char s)
|
|
{
|
|
is_drawing++;
|
|
if(s == 0)
|
|
{
|
|
LCD_CMD = 0xA0; // set segment remap (00H mapped to seg0)
|
|
LCD_CMD = 0xC8; // set com output scan direction (remapped mode)
|
|
}
|
|
else
|
|
{
|
|
LCD_CMD = 0xA1; // set segment remap (7FH mapped to seg0)
|
|
LCD_CMD = 0xC0; // set com output scan direction (normal mode)
|
|
}
|
|
is_drawing--;
|
|
}
|
|
|
|
|
|
// initialise LCD controller SSD1854
|
|
//
|
|
// sequence and values disassembled from original firmware
|
|
// see http://bettyhacks.com/wiki/index.php/Betty_init
|
|
void lcd_init(unsigned char s)
|
|
{
|
|
is_drawing = 1;
|
|
LCD_CMD = LCD_WAKEUP; // exit power save mode
|
|
LCD_CMD = LCD_RESET; // software reset
|
|
pause(0x32);
|
|
LCD_CMD = LCD_OSC_START; // start internal oscillator
|
|
LCD_CMD = LCD_IRRR_8; // set internal regulator resistor ratio (8.1)
|
|
LCD_CMD = 0x81; // volume cmd
|
|
LCD_CMD = LCD_CONTRAST; // volume cmd value original 0x3F
|
|
LCD_CMD = LCD_DCDCx4; // set DC-DC converter factor (4x)
|
|
|
|
LCD_CMD = 0x60; // set upper window corner ax cmd
|
|
LCD_CMD = 0x1C; // set upper window corner ax value
|
|
LCD_CMD = 0x61; // set upper window corner ay cmd
|
|
LCD_CMD = 0x0A; // set upper window corner ay value
|
|
LCD_CMD = 0x62; // set lower window corner bx cmd
|
|
LCD_CMD = 0x75; // set lower window corner bx value
|
|
LCD_CMD = 0x63; // set lower window corner by cmd
|
|
LCD_CMD = 0x81; // set lower window corner by value
|
|
LCD_CMD = 0x90; // set PWM and FRC (4-frames)
|
|
|
|
LCD_CMD = 0x88; // set white mode frame 2nd and 1st cmd
|
|
LCD_CMD = LCD_GRAYMODE_88; // set white mode frame 2nd and 1st value
|
|
LCD_CMD = 0x89; // set white mode frame 4th and 3rd cmd
|
|
LCD_CMD = LCD_GRAYMODE_89; // set white mode frame 4th and 3rd value
|
|
LCD_CMD = 0x8A; // set light gray mode frame 2nd and 1st cmd
|
|
LCD_CMD = LCD_GRAYMODE_8A; // set light gray mode frame 2nd and 1st value // originally 33
|
|
LCD_CMD = 0x8B; // set light gray mode frame 4th and 3rd cmd
|
|
LCD_CMD = LCD_GRAYMODE_8B; // set light gray mode frame 4th and 3rd value // originally 33
|
|
LCD_CMD = 0x8C; // set dark gray mode frame 2nd and 1st cmd
|
|
LCD_CMD = LCD_GRAYMODE_8C; // set dark gray mode frame 2nd and 1st value // originally 66
|
|
LCD_CMD = 0x8D; // set dark gray mode frame 4th and 3rd cmd
|
|
LCD_CMD = LCD_GRAYMODE_8D; // set dark gray mode frame 4th and 3rd vakue // originally 66
|
|
LCD_CMD = 0x8E; // set black mode frame 2nd and 1st cmd
|
|
LCD_CMD = LCD_GRAYMODE_8E; // set black mode frame 2nd and 1st value // originally 99
|
|
LCD_CMD = 0x8F; // set black mode frame 4th and 3rd cmd
|
|
LCD_CMD = LCD_GRAYMODE_8F; // set black mode frame 4th and 3rd value // originally 99
|
|
|
|
LCD_CMD = LCD_DCDCx5; // set DC-DC converter factor (5x)
|
|
|
|
lcd_set(s);
|
|
|
|
//~ LCD_CMD = 0x2E; // set power control register (boost on, reg on, buffer off) // original
|
|
|
|
//~ pause(0x32); // original
|
|
|
|
LCD_CMD = 0x2F; // set power control register (boost on, reg on, buffer on)
|
|
LCD_CMD = LCD_ALLON; // all black
|
|
LCD_CMD = LCD_NORMAL; // set normal display mode, inverse = 0xA7
|
|
|
|
// Function pointer to section (".text.fastcode")
|
|
do_rcu = _do_rcu;
|
|
do_rcuAlpha = _do_rcuAlpha;
|
|
do_rcuS = _do_rcuS;
|
|
draw_block = _draw_block;
|
|
draw_hline = _draw_hline;
|
|
draw_vline = _draw_vline;
|
|
|
|
lcd_fill (LCD_COLOR_W); // blank display
|
|
|
|
LCD_CMD = LCD_ON; // turn display on
|
|
|
|
set_font(SMALLFONT);
|
|
|
|
is_drawing--;
|
|
} // lcd_init
|
|
|
|
|
|
void lcd_enable(unsigned char e)
|
|
{
|
|
is_drawing++;
|
|
if(e)
|
|
LCD_CMD = LCD_ON; // set display on
|
|
else
|
|
LCD_CMD = LCD_OFF; // set display off
|
|
is_drawing--;
|
|
}
|
|
|
|
|
|
/// \brief set lcd contrast
|
|
///
|
|
/// SSD1854 datasheet p.33
|
|
/// Set Contrast Control Register [81]
|
|
/// This command adjusts the contrast of the LCD panel by changing VL7 of the LCD drive voltage
|
|
/// provided by the On-Chip power circuits. VL7 is set with 64 steps (6-bit) contrast control register.
|
|
/// Default value after software reset [E2]: 20H = 32
|
|
void lcd_set_contrast(unsigned char c)
|
|
{
|
|
if (c < 64)
|
|
{
|
|
is_drawing++;
|
|
LCD_CMD = 0x81; // volume cmd
|
|
LCD_CMD = c; // volume cmd value
|
|
is_drawing--;
|
|
}
|
|
}
|
|
|
|
|
|
// set all pixels
|
|
// show symbols TODO: those should not be here!
|
|
void lcd_fill(unsigned char f)
|
|
{
|
|
unsigned char x,y;
|
|
|
|
is_drawing++;
|
|
//~
|
|
//~ if (f == 0xFF)
|
|
//~ {
|
|
//~ LCD_CMD = LCD_ALLOFF;
|
|
//~ }
|
|
//~ else if (f == 0)
|
|
//~ {
|
|
//~ LCD_CMD = LCD_ALLON;
|
|
//~ }
|
|
//~ else
|
|
//~ {
|
|
for(y=0;y<20;y++)
|
|
{
|
|
LCD_CMD = 0xB0; // Set Page Address
|
|
LCD_CMD = y;
|
|
LCD_CMD = 0x10; // Set Higher Column Address
|
|
LCD_CMD = 0x00;
|
|
for(x=0;x<128;x++)
|
|
{
|
|
LCD_DATA = f; // 4 pixels
|
|
LCD_DATA = f; // 4 pixels
|
|
}
|
|
}
|
|
//~ }
|
|
is_drawing--;
|
|
|
|
showBat(0xff);
|
|
refresh_symbols(0xff);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
/** Draw pixel data from boop_logo.
|
|
(use bmp2b to generate from 24 bit BMP)
|
|
New tool display/GrayScaler.exe for WinXP/Win7
|
|
generate icon files. The data array has the same
|
|
format and can be copied in the file boop_logo.
|
|
You can also use the new icons instead of the logo.
|
|
*/
|
|
void draw_logo(void)
|
|
{
|
|
unsigned short f;
|
|
unsigned char x,y;
|
|
is_drawing++;
|
|
f=0;
|
|
for(y=0; y<b_h>>3; y++)
|
|
{
|
|
LCD_CMD = 0xB0;
|
|
LCD_CMD = y;
|
|
LCD_CMD = 0x10;
|
|
LCD_CMD = 0x00;
|
|
for(x=0;x<b_w;x++)
|
|
{
|
|
LCD_DATA = b_data[f++];
|
|
LCD_DATA = b_data[f++];
|
|
}
|
|
}
|
|
is_drawing--;
|
|
} // draw_logo
|
|
//-----------------------------------------------------------------------------
|
|
|
|
unsigned char rcubuf[2][LCD_SIZE_X];
|
|
unsigned char drawbuf[2][LCD_SIZE_X];
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void __attribute__ ((section (".text.fastcode"))) _do_rcu (
|
|
unsigned char x, unsigned char y, unsigned char l, unsigned char m)
|
|
{
|
|
_do_rcuAlpha(x,y,l,m,NULL);
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void __attribute__ ((section (".text.fastcode"))) _do_rcuAlpha (
|
|
unsigned char x, unsigned char y, unsigned char l, unsigned char m, unsigned char* alphaBuf)
|
|
{
|
|
unsigned char q;
|
|
|
|
if ((x > BORDER_RIGHT))// || (x+l < BORDER_LEFT))
|
|
return;
|
|
|
|
if (x+l > BORDER_RIGHT + 1) {
|
|
unsigned char i;
|
|
unsigned char cut;
|
|
|
|
cut = x + l - (BORDER_RIGHT + 1);
|
|
for(i=0;i<l;i++) {
|
|
drawbuf[0][i] = drawbuf[0][i + cut];
|
|
drawbuf[1][i] = drawbuf[1][i + cut];
|
|
}
|
|
l -= cut;
|
|
}
|
|
/*
|
|
if (x < BORDER_LEFT) {
|
|
l -= (BORDER_LEFT-x);
|
|
x = BORDER_LEFT;
|
|
}
|
|
*/
|
|
is_drawing++;
|
|
|
|
if(m != DRAW_NORCU)
|
|
{
|
|
LCD_CMD = 0xB0;
|
|
LCD_CMD = (y >> 3);
|
|
LCD_CMD = (0x10 + (x >> 4));
|
|
LCD_CMD = (x & 0x0F);
|
|
|
|
q = LCD_DATA;
|
|
q = l;
|
|
|
|
while(q--)
|
|
{
|
|
rcubuf[0][q] = LCD_DATA;
|
|
rcubuf[1][q] = LCD_DATA;
|
|
}
|
|
|
|
q = LCD_DATA;
|
|
}
|
|
|
|
LCD_CMD = 0xB0;
|
|
LCD_CMD = (y >> 3);
|
|
LCD_CMD = (0x10 + (x >> 4));
|
|
LCD_CMD = (x & 0x0F);
|
|
|
|
if(alphaBuf)
|
|
{
|
|
q = l;
|
|
while(q--)
|
|
{
|
|
drawbuf[0][q] &= alphaBuf[q];
|
|
drawbuf[1][q] &= alphaBuf[q];
|
|
}
|
|
if(m==DRAW_ALPHA)
|
|
{
|
|
q = l;
|
|
while(q--)
|
|
{
|
|
rcubuf[0][q] &= ~alphaBuf[q];
|
|
rcubuf[1][q] &= ~alphaBuf[q];
|
|
}
|
|
}
|
|
}
|
|
|
|
q = l;
|
|
|
|
switch(m)
|
|
{
|
|
case DRAW_ALPHA: // draw with alpha buffer
|
|
case DRAW_PUT: // draw put
|
|
while(q--)
|
|
{
|
|
LCD_DATA = rcubuf[0][q] | drawbuf[0][q];
|
|
LCD_DATA = rcubuf[1][q] | drawbuf[1][q];
|
|
}
|
|
break;
|
|
case DRAW_XOR: // draw xor
|
|
while(q--)
|
|
{
|
|
LCD_DATA = rcubuf[0][q] ^ drawbuf[0][q];
|
|
LCD_DATA = rcubuf[1][q] ^ drawbuf[1][q];
|
|
}
|
|
break;
|
|
case DRAW_ERASE: // draw erase
|
|
while(q--)
|
|
{
|
|
LCD_DATA = rcubuf[0][q] & ~drawbuf[0][q];
|
|
LCD_DATA = rcubuf[1][q] & ~drawbuf[1][q];
|
|
}
|
|
break;
|
|
case DRAW_NORCU: // draw without rcu
|
|
while(q--)
|
|
{
|
|
LCD_DATA = drawbuf[0][q];
|
|
LCD_DATA = drawbuf[1][q];
|
|
}
|
|
break;
|
|
}
|
|
is_drawing--;
|
|
} // _do_rcu
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void __attribute__ ((section (".text.fastcode"))) _do_rcuS (
|
|
unsigned char x, unsigned char y, unsigned char m)
|
|
{
|
|
volatile unsigned char q=0;
|
|
|
|
(void)(q);
|
|
|
|
if((x > BORDER_RIGHT))// | (x < BORDER_LEFT))
|
|
return;
|
|
|
|
is_drawing++;
|
|
|
|
if(m != DRAW_NORCU)
|
|
{
|
|
LCD_CMD = 0xB0;
|
|
LCD_CMD = (y >> 3);
|
|
LCD_CMD = (0x10 + (x >> 4));
|
|
LCD_CMD = (x & 0x0F);
|
|
|
|
q = LCD_DATA;
|
|
rcubuf[0][0] = LCD_DATA;
|
|
rcubuf[1][0] = LCD_DATA;
|
|
|
|
q = LCD_DATA;
|
|
}
|
|
|
|
LCD_CMD = 0xB0;
|
|
LCD_CMD = (y >> 3);
|
|
LCD_CMD = (0x10 + (x >> 4));
|
|
LCD_CMD = (x & 0x0F);
|
|
|
|
switch(m)
|
|
{
|
|
case DRAW_ALPHA:
|
|
case DRAW_PUT: // draw put
|
|
LCD_DATA = rcubuf[0][0] | drawbuf[0][0];
|
|
LCD_DATA = rcubuf[1][0] | drawbuf[1][0];
|
|
break;
|
|
case DRAW_XOR: // draw xor
|
|
LCD_DATA = rcubuf[0][0] ^ drawbuf[0][0];
|
|
LCD_DATA = rcubuf[1][0] ^ drawbuf[1][0];
|
|
break;
|
|
case DRAW_ERASE: // draw erase
|
|
LCD_DATA = rcubuf[0][0] & ~drawbuf[0][0];
|
|
LCD_DATA = rcubuf[1][0] & ~drawbuf[1][0];
|
|
break;
|
|
case DRAW_NORCU: // draw erase
|
|
LCD_DATA = drawbuf[0][0];
|
|
LCD_DATA = drawbuf[1][0];
|
|
break;
|
|
}
|
|
is_drawing--;
|
|
} // _do_rcuS
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void __attribute__ ((section(".text.fastcode"))) _draw_block(unsigned char x, unsigned char y, unsigned char w, unsigned char h, unsigned char c, unsigned char m)
|
|
{
|
|
unsigned char q,s;
|
|
unsigned char yy,vv,ww,xx;
|
|
unsigned char segm;
|
|
is_drawing++;
|
|
|
|
if (x + w > LCD_SIZE_X)
|
|
w = LCD_SIZE_X - x;
|
|
|
|
s = y;
|
|
|
|
if(h)
|
|
{
|
|
yy = h;
|
|
vv = y & 0x07;
|
|
|
|
ww = yy & 0x07;
|
|
|
|
segm = 0xFF;
|
|
|
|
xx = 8;
|
|
if(yy < 8)
|
|
{
|
|
segm >>= (8-ww);
|
|
xx -= (8-ww);
|
|
if(vv > (8-xx))
|
|
{
|
|
xx = yy -(vv-(8-xx));
|
|
}
|
|
else
|
|
{
|
|
xx = yy;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
xx -= vv;
|
|
}
|
|
|
|
segm <<= vv;
|
|
|
|
q = w;
|
|
while(q--)
|
|
{
|
|
if(c & 0x02)
|
|
drawbuf[0][q] = segm;
|
|
else
|
|
drawbuf[0][q] = 0;
|
|
|
|
if(c & 0x01)
|
|
drawbuf[1][q] = segm;
|
|
else
|
|
drawbuf[1][q] = 0;
|
|
}
|
|
do_rcu(x,s,w,m);
|
|
|
|
yy -= xx;
|
|
|
|
while(yy > 8)
|
|
{
|
|
s += 8;
|
|
yy -= 8;
|
|
q = w;
|
|
while(q--)
|
|
{
|
|
if(c & 0x02)
|
|
drawbuf[0][q] = 0xFF;
|
|
else
|
|
drawbuf[0][q] = 0;
|
|
|
|
if(c & 0x01)
|
|
drawbuf[1][q] = 0xFF;
|
|
else
|
|
drawbuf[1][q] = 0;
|
|
}
|
|
do_rcu(x,s,w,m);
|
|
}
|
|
|
|
if(yy)
|
|
{
|
|
s += 8;
|
|
q = w;
|
|
while(q--)
|
|
{
|
|
if(c & 0x02)
|
|
drawbuf[0][q] = 0xFF >> (8-yy);
|
|
else
|
|
drawbuf[0][q] = 0;
|
|
|
|
if(c & 0x01)
|
|
drawbuf[1][q] = 0xFF >> (8-yy);
|
|
else
|
|
drawbuf[1][q] = 0;
|
|
}
|
|
do_rcu(x,s,w,m);
|
|
}
|
|
}
|
|
is_drawing--;
|
|
}
|
|
|
|
void __attribute__ ((section(".text.fastcode"))) _draw_hline(unsigned char x, unsigned char y, unsigned char l, unsigned char c, unsigned char m)
|
|
{
|
|
unsigned char p,q;
|
|
is_drawing++;
|
|
|
|
q = l;
|
|
p = 0x01 << (y & 0x07);
|
|
|
|
while(q--)
|
|
{
|
|
if(c & 0x02)
|
|
drawbuf[0][q] = p;
|
|
else
|
|
drawbuf[0][q] = 0;
|
|
|
|
if(c & 0x01)
|
|
drawbuf[1][q] = p;
|
|
else
|
|
drawbuf[1][q] = 0;
|
|
}
|
|
do_rcu(x,y,l,m);
|
|
is_drawing--;
|
|
}
|
|
|
|
void __attribute__ ((section(".text.fastcode"))) _draw_vline(unsigned char x, unsigned char y, unsigned char l, unsigned char c, unsigned char m)
|
|
{
|
|
unsigned char s;
|
|
unsigned char yy,vv,ww,xx;
|
|
unsigned char segm;
|
|
is_drawing++;
|
|
|
|
s = y;
|
|
|
|
if(l)
|
|
{
|
|
|
|
|
|
|
|
yy = l;
|
|
vv = y & 0x07;
|
|
|
|
ww = yy & 0x07;
|
|
|
|
segm = 0xFF;
|
|
|
|
xx = 8;
|
|
if(yy < 8)
|
|
{
|
|
segm >>= (8-ww);
|
|
xx -= (8-ww);
|
|
if(vv > (8-xx))
|
|
{
|
|
xx = yy -(vv-(8-xx));
|
|
}
|
|
else
|
|
{
|
|
xx = yy;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
xx -= vv;
|
|
}
|
|
|
|
segm <<= vv;
|
|
|
|
if(c & 0x02)
|
|
drawbuf[0][0] = segm;
|
|
else
|
|
drawbuf[0][0] = 0;
|
|
|
|
if(c & 0x01)
|
|
drawbuf[1][0] = segm;
|
|
else
|
|
drawbuf[1][0] = 0;
|
|
|
|
do_rcuS(x,s,m);
|
|
|
|
yy -= xx;
|
|
|
|
while(yy > 8)
|
|
{
|
|
s += 8;
|
|
yy -= 8;
|
|
if(c & 0x02)
|
|
drawbuf[0][0] = 0xFF;
|
|
else
|
|
drawbuf[0][0] = 0;
|
|
|
|
if(c & 0x01)
|
|
drawbuf[1][0] = 0xFF;
|
|
else
|
|
drawbuf[1][0] = 0;
|
|
do_rcuS(x,s,m);
|
|
}
|
|
|
|
if(yy)
|
|
{
|
|
s += 8;
|
|
if(c & 0x02)
|
|
drawbuf[0][0] = 0xFF >> (8-yy);
|
|
else
|
|
drawbuf[0][0] = 0;
|
|
|
|
if(c & 0x01)
|
|
drawbuf[1][0] = 0xFF >> (8-yy);
|
|
else
|
|
drawbuf[1][0] = 0;
|
|
do_rcuS(x,s,m);
|
|
}
|
|
}
|
|
is_drawing--;
|
|
}
|
|
|
|
void draw_rect(unsigned char x, unsigned char y, unsigned char w, unsigned char h, unsigned char lw, unsigned char c, unsigned char m)
|
|
{
|
|
is_drawing++;
|
|
if(lw)
|
|
{
|
|
if(lw == 1)
|
|
{
|
|
draw_hline(x, y, w, c, m);
|
|
draw_hline(x, y+h-1, w, c, m);
|
|
|
|
draw_vline(x, y+1, h-2, c, m);
|
|
draw_vline(x+w-1, y+1, h-2, c, m);
|
|
}
|
|
else
|
|
{
|
|
draw_block(x, y, w, lw, c, m);
|
|
draw_block(x, y+h-lw, w, lw, c, m);
|
|
draw_block(x, y+lw, lw, h-(2*lw), c, m);
|
|
draw_block(x+w-lw, y+lw, lw, h-(2*lw), c, m);
|
|
}
|
|
}
|
|
is_drawing--;
|
|
}
|
|
|
|
void draw_pixel(unsigned char x, unsigned char y, unsigned char c, unsigned char m)
|
|
{
|
|
unsigned char p;
|
|
is_drawing++;
|
|
|
|
p = 0x01 << (y & 0x07);
|
|
|
|
if(c & 0x02)
|
|
drawbuf[0][0] = p;
|
|
else
|
|
drawbuf[0][0] = 0;
|
|
|
|
if(c & 0x01)
|
|
drawbuf[1][0] = p;
|
|
else
|
|
drawbuf[1][0] = 0;
|
|
|
|
do_rcuS(x,y,m);
|
|
is_drawing--;
|
|
}
|
|
|
|
void draw_line(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, unsigned char c, unsigned char m)
|
|
{
|
|
unsigned char i,dx,dy,px,py;
|
|
unsigned int x,y;
|
|
is_drawing++;
|
|
|
|
if (y2 > y1) // incl. POSITIVE
|
|
{
|
|
dx=x2-x1;
|
|
dy=y2-y1;
|
|
px=x1;
|
|
py=y1;
|
|
draw_pixel(x1, y1, c, m); // first pixel
|
|
if (dx>=dy) // incl. is more horizontal than vertical
|
|
{
|
|
y = y1;
|
|
for(i=0;i<dx;i++)
|
|
{
|
|
y+=dy;
|
|
if (y>=dx)
|
|
{
|
|
y-=dx;
|
|
py+=1;
|
|
}
|
|
px+=1;
|
|
draw_pixel(px, py, c, m);
|
|
}
|
|
}
|
|
else // incl. is more vertical than horizontal
|
|
{
|
|
x = x1;
|
|
for(i=0;i<dy;i++)
|
|
{
|
|
x+=dx;
|
|
if (x>=dy)
|
|
{
|
|
x-=dy;
|
|
px+=1;
|
|
}
|
|
py+=1;
|
|
draw_pixel(px, py, c, m); //??????
|
|
}
|
|
};
|
|
}
|
|
else if (y2 < y1) // incl. NEGATIVE
|
|
{
|
|
dx=x2-x1;
|
|
dy=y1-y2; // inverted to produce a positive value
|
|
dx=dx;
|
|
dy=dy;
|
|
px=x1;
|
|
py=y2; // Note: due to inverted "dy",
|
|
draw_pixel(x2, y2, c, m); // the first pixel became the last one
|
|
if (dx>=dy) // incl. is more horizontal than vertical
|
|
{
|
|
y = y1;
|
|
py=y1;
|
|
for(i=0;i<dx;i++)
|
|
{
|
|
y+=dy;
|
|
if (y>=dx)
|
|
{
|
|
y-=dx;
|
|
py-=1;
|
|
}
|
|
px+=1;
|
|
draw_pixel(px, py, c, m);
|
|
}
|
|
}
|
|
else // incl. is more vertical than horizontal
|
|
{
|
|
x = x1;
|
|
px=x2;
|
|
for(i=0;i<dy;i++)
|
|
{
|
|
x+=dx;
|
|
if (x>=dy)
|
|
{
|
|
x-=dy;
|
|
px-=1;
|
|
}
|
|
py+=1;
|
|
draw_pixel(px, py, c, m);
|
|
}
|
|
};
|
|
}
|
|
is_drawing--;
|
|
}
|
|
|
|
void draw_circle(unsigned char cx, unsigned char cy, unsigned char radius, unsigned char c, unsigned char m)
|
|
{
|
|
signed int tswitch;
|
|
unsigned char y, x = 0;
|
|
unsigned char d;
|
|
is_drawing++;
|
|
|
|
d = cy - cx;
|
|
y = radius;
|
|
tswitch = 3 - 2 * radius;
|
|
while (x <= y)
|
|
{
|
|
if(x != 0)
|
|
{
|
|
draw_pixel(cx + x, cy + y, c, m);
|
|
draw_pixel(cx + x, cy - y, c, m);
|
|
}
|
|
draw_pixel(cx - x, cy + y, c, m);
|
|
draw_pixel(cx - x, cy - y, c, m);
|
|
|
|
if(x != y)
|
|
{
|
|
if(x != 0)
|
|
{
|
|
draw_pixel(cy + y - d, cy + x, c, m);
|
|
draw_pixel(cy - y - d, cy + x, c, m);
|
|
}
|
|
draw_pixel(cy + y - d, cy - x, c, m);
|
|
draw_pixel(cy - y - d, cy - x, c, m);
|
|
}
|
|
|
|
if (tswitch < 0)
|
|
{
|
|
tswitch += (4 * x + 6);
|
|
}
|
|
else
|
|
{
|
|
tswitch += (4 * (x - y) + 10);
|
|
y--;
|
|
}
|
|
x++;
|
|
}
|
|
is_drawing--;
|
|
}
|
|
|
|
void draw_qcircle(unsigned char cx, unsigned char cy, unsigned char radius, unsigned char quarter, unsigned char c, unsigned char m)
|
|
{
|
|
signed int tswitch;
|
|
unsigned char y, x = 0;
|
|
unsigned char d;
|
|
is_drawing++;
|
|
|
|
d = cy - cx;
|
|
y = radius;
|
|
tswitch = 3 - 2 * radius;
|
|
|
|
switch(quarter)
|
|
{
|
|
case TOP_LEFT:
|
|
while (x <= y)
|
|
{
|
|
draw_pixel(cx - x, cy - y, c, m);
|
|
|
|
if(x != y)
|
|
{
|
|
draw_pixel(cy - y - d, cy - x, c, m);
|
|
}
|
|
|
|
if (tswitch < 0)
|
|
{
|
|
tswitch += (4 * x + 6);
|
|
}
|
|
else
|
|
{
|
|
tswitch += (4 * (x - y) + 10);
|
|
y--;
|
|
}
|
|
x++;
|
|
}
|
|
break;
|
|
|
|
case TOP_RIGHT:
|
|
while (x <= y)
|
|
{
|
|
draw_pixel(cx + x, cy - y, c, m);
|
|
|
|
if(x != y)
|
|
{
|
|
draw_pixel(cy + y - d, cy - x, c, m);
|
|
}
|
|
|
|
if (tswitch < 0)
|
|
{
|
|
tswitch += (4 * x + 6);
|
|
}
|
|
else
|
|
{
|
|
tswitch += (4 * (x - y) + 10);
|
|
y--;
|
|
}
|
|
x++;
|
|
}
|
|
break;
|
|
|
|
case BOTTOM_LEFT:
|
|
while (x <= y)
|
|
{
|
|
draw_pixel(cx - x, cy + y, c, m);
|
|
|
|
if(x != y)
|
|
{
|
|
draw_pixel(cy - y - d, cy + x, c, m);
|
|
}
|
|
|
|
if (tswitch < 0)
|
|
{
|
|
tswitch += (4 * x + 6);
|
|
}
|
|
else
|
|
{
|
|
tswitch += (4 * (x - y) + 10);
|
|
y--;
|
|
}
|
|
x++;
|
|
}
|
|
break;
|
|
|
|
case BOTTOM_RIGHT:
|
|
while (x <= y)
|
|
{
|
|
draw_pixel(cx + x, cy + y, c, m);
|
|
|
|
if(x != y)
|
|
{
|
|
draw_pixel(cy + y - d, cy + x, c, m);
|
|
}
|
|
|
|
if (tswitch < 0)
|
|
{
|
|
tswitch += (4 * x + 6);
|
|
}
|
|
else
|
|
{
|
|
tswitch += (4 * (x - y) + 10);
|
|
y--;
|
|
}
|
|
x++;
|
|
}
|
|
break;
|
|
}
|
|
is_drawing--;
|
|
}
|
|
|
|
void draw_disc(unsigned char cx, unsigned char cy, unsigned char radius, unsigned char c, unsigned char m)
|
|
{
|
|
signed int tswitch;
|
|
unsigned char y, x = 0;
|
|
unsigned char d;
|
|
is_drawing++;
|
|
|
|
d = cy - cx;
|
|
y = radius;
|
|
tswitch = 3 - 2 * radius;
|
|
while (x <= y)
|
|
{
|
|
if(x != y)
|
|
{
|
|
if(x != 0)
|
|
{
|
|
draw_hline(cy - y - d, cy + x, (y<<1)+1, c, m);
|
|
}
|
|
draw_hline(cy - y - d, cy - x, (y<<1)+1, c, m);
|
|
}
|
|
|
|
if (tswitch < 0)
|
|
{
|
|
tswitch += (4 * x + 6);
|
|
}
|
|
else
|
|
{
|
|
draw_hline(cx-x, cy + y, (x<<1)+1, c, m);
|
|
draw_hline(cx-x, cy - y, (x<<1)+1, c, m);
|
|
tswitch += (4 * (x - y) + 10);
|
|
y--;
|
|
}
|
|
x++;
|
|
}
|
|
is_drawing--;
|
|
}
|
|
|
|
void draw_qdisc(unsigned char cx, unsigned char cy, unsigned char radius, unsigned char quarter, unsigned char c, unsigned char m)
|
|
{
|
|
signed int tswitch;
|
|
unsigned char y, x = 0;
|
|
unsigned char d;
|
|
is_drawing++;
|
|
|
|
d = cy - cx;
|
|
y = radius;
|
|
tswitch = 3 - 2 * radius;
|
|
switch(quarter)
|
|
{
|
|
case TOP_LEFT:
|
|
while (x <= y)
|
|
{
|
|
if(x != y)
|
|
{
|
|
draw_hline(cy - y - d, cy - x, y+1, c, m);
|
|
}
|
|
|
|
if (tswitch < 0)
|
|
{
|
|
tswitch += (4 * x + 6);
|
|
}
|
|
else
|
|
{
|
|
draw_hline(cx-x, cy - y, x+1, c, m);
|
|
tswitch += (4 * (x - y) + 10);
|
|
y--;
|
|
}
|
|
x++;
|
|
}
|
|
break;
|
|
|
|
case TOP_RIGHT:
|
|
while (x <= y)
|
|
{
|
|
if(x != y)
|
|
{
|
|
draw_hline(cx, cy - x, y+1, c, m);
|
|
}
|
|
|
|
if (tswitch < 0)
|
|
{
|
|
tswitch += (4 * x + 6);
|
|
}
|
|
else
|
|
{
|
|
draw_hline(cx, cy - y, x+1, c, m);
|
|
tswitch += (4 * (x - y) + 10);
|
|
y--;
|
|
}
|
|
x++;
|
|
}
|
|
break;
|
|
|
|
case BOTTOM_LEFT:
|
|
while (x <= y)
|
|
{
|
|
if(x != y)
|
|
{
|
|
draw_hline(cy - y - d, cy + x, y+1, c, m);
|
|
}
|
|
|
|
if (tswitch < 0)
|
|
{
|
|
tswitch += (4 * x + 6);
|
|
}
|
|
else
|
|
{
|
|
draw_hline(cx-x, cy + y, x+1, c, m);
|
|
tswitch += (4 * (x - y) + 10);
|
|
y--;
|
|
}
|
|
x++;
|
|
}
|
|
break;
|
|
|
|
case BOTTOM_RIGHT:
|
|
while (x <= y)
|
|
{
|
|
if(x != y)
|
|
{
|
|
draw_hline(cx, cy + x, y+1, c, m);
|
|
}
|
|
|
|
if (tswitch < 0)
|
|
{
|
|
tswitch += (4 * x + 6);
|
|
}
|
|
else
|
|
{
|
|
draw_hline(cx, cy + y, x+1, c, m);
|
|
tswitch += (4 * (x - y) + 10);
|
|
y--;
|
|
}
|
|
x++;
|
|
}
|
|
break;
|
|
}
|
|
is_drawing--;
|
|
}
|
|
|
|
|
|
unsigned char draw_arrow(int x, int y, unsigned char ArrowDir, int ArrowLen, unsigned char Color, unsigned char Mode)
|
|
{
|
|
int i;
|
|
int Len;
|
|
is_drawing++;
|
|
|
|
switch(ArrowDir)
|
|
{
|
|
case ARROW_UP:
|
|
for(i=0; i<ArrowLen; i++)
|
|
{
|
|
Len = 1 + (i*2);
|
|
draw_hline(x + ((ArrowLen-1)-i), y + i, Len, Color, Mode);
|
|
}
|
|
break;
|
|
case ARROW_DOWN:
|
|
for(i=0; i<ArrowLen; i++)
|
|
{
|
|
Len = 1 + (i*2);
|
|
draw_hline(x + ((ArrowLen-1)-i), y + ((ArrowLen-1)-i), Len, Color, Mode);
|
|
}
|
|
break;
|
|
case ARROW_LEFT:
|
|
for(i=0; i<ArrowLen; i++)
|
|
{
|
|
Len = 1 + (i*2);
|
|
draw_vline(x + i, y + ((ArrowLen-1)-i), Len, Color, Mode);
|
|
}
|
|
break;
|
|
case ARROW_RIGHT:
|
|
for(i=0; i<ArrowLen; i++)
|
|
{
|
|
Len = 1 + (i*2);
|
|
draw_vline(x + ((ArrowLen-1)-i), y + ((ArrowLen-1)-i), Len, Color, Mode);
|
|
}
|
|
break;
|
|
default:
|
|
is_drawing--;
|
|
return 0;//Error
|
|
break;
|
|
}
|
|
is_drawing--;
|
|
|
|
return 1;//OK
|
|
}
|
|
|
|
void draw_frame(unsigned char x, unsigned char y, unsigned char w, unsigned char h, unsigned char t, unsigned char r, unsigned char c, unsigned char m)
|
|
{
|
|
is_drawing++;
|
|
|
|
if(r == 0)
|
|
{
|
|
draw_rect(x,y,w,h,t,c,m);
|
|
}
|
|
else
|
|
{
|
|
if(t == 1)
|
|
{
|
|
draw_qcircle(x+r, y+r, r, TOP_LEFT, c, m);
|
|
draw_qcircle(x+w-r-1, y+r, r, TOP_RIGHT, c, m);
|
|
draw_qcircle(x+r, y+h-r-1, r, BOTTOM_LEFT, c, m);
|
|
draw_qcircle(x+w-r-1, y+h-r-1, r, BOTTOM_RIGHT, c, m);
|
|
|
|
draw_hline(x+r+1,y,w-(r<<1)-2,c,m);
|
|
draw_hline(x+r+1,y+h-1,w-(r<<1)-2,c,m);
|
|
|
|
draw_vline(x, y+r+1, h-(r<<1)-2,c,m);
|
|
draw_vline(x+w-1, y+r+1, h-(r<<1)-2,c,m);
|
|
}
|
|
else
|
|
{
|
|
draw_qdisc(x+r, y+r, r, TOP_LEFT, c, m);
|
|
draw_qdisc(x+w-r-1, y+r, r, TOP_RIGHT, c, m);
|
|
draw_qdisc(x+r, y+h-r-1, r, BOTTOM_LEFT, c, m);
|
|
draw_qdisc(x+w-r-1, y+h-r-1, r, BOTTOM_RIGHT, c, m);
|
|
|
|
if(t > r)
|
|
{
|
|
draw_block(x, y+r+1, r+1, h-(r<<1)-2,c,m);
|
|
draw_block(x+r+1, y+t, t-r-1, h-(t<<1),c,m);
|
|
draw_block(x+w-r-1, y+r+1, r+1, h-(r<<1)-2,c,m);
|
|
draw_block(x+w-t, y+t, t-r-1, h-(t<<1),c,m);
|
|
}
|
|
else
|
|
{
|
|
if(r > t)
|
|
{
|
|
draw_qdisc(x+r, y+r, r-t, TOP_LEFT, c, DRAW_XOR);
|
|
draw_qdisc(x+w-r-1, y+r, r-t, TOP_RIGHT, c, DRAW_XOR);
|
|
draw_qdisc(x+r, y+h-r-1, r-t, BOTTOM_LEFT, c, DRAW_XOR);
|
|
draw_qdisc(x+w-r-1, y+h-r-1, r-t, BOTTOM_RIGHT, c, DRAW_XOR);
|
|
}
|
|
draw_block(x, y+r+1, t, h-(r<<1)-2,c,m);
|
|
draw_block(x+w-t, y+r+1, t, h-(r<<1)-2,c,m);
|
|
}
|
|
draw_block(x+r+1, y, w-(r<<1)-2, t, c, m);
|
|
draw_block(x+r+1, y+h-t, w-(r<<1)-2, t, c, m);
|
|
}
|
|
}
|
|
is_drawing--;
|
|
}
|
|
|
|
void draw_symbol (unsigned char x, unsigned char y, unsigned char l, unsigned char* data, unsigned char c, unsigned char m)
|
|
{
|
|
unsigned char p;
|
|
unsigned int cnt;
|
|
is_drawing++;
|
|
|
|
|
|
for(cnt=0;cnt<l;cnt++)
|
|
{
|
|
p = data[cnt];
|
|
|
|
if(c & 0x02)
|
|
drawbuf[0][cnt] = p;
|
|
else
|
|
drawbuf[0][cnt] = 0;
|
|
|
|
if(c & 0x01)
|
|
drawbuf[1][cnt] = p;
|
|
else
|
|
drawbuf[1][cnt] = 0;
|
|
|
|
}
|
|
do_rcu(x,y,l,m);
|
|
|
|
is_drawing--;
|
|
}
|
|
|
|
|
|
// symbols
|
|
// 1 bpp
|
|
// 1 byte per column
|
|
// lsb is first pixel in column
|
|
const unsigned char symRF[7] = {0x01,0x02,0x04,0xff,0x04,0x02,0x01}; // antenna
|
|
const unsigned char symIR[ ] = {0x02,0x49,0x65,0x65,0x65,0x49,0x02}; // IR radiation
|
|
|
|
void refresh_symbols (unsigned int cb)
|
|
{
|
|
unsigned char c;
|
|
|
|
if (! (is_drawing))
|
|
{
|
|
if(symbols & symbolRF)
|
|
c = LCD_COLOR_B;
|
|
else
|
|
c = LCD_COLOR_W;
|
|
draw_symbol(100,0,7,(unsigned char*)symRF,c,DRAW_NORCU);
|
|
oldsymbols = symbols;
|
|
}
|
|
// else ? TODO?
|
|
}
|
|
|
|
void redraw_symbols (void)
|
|
{
|
|
oldsymbols = ~oldsymbols;
|
|
refresh_symbols(0);
|
|
}
|
|
|
|
|
|
volatile unsigned long sActiveIndTimer = 0;
|
|
void update_active_ind (void)
|
|
{
|
|
if (!sActiveIndTimer)
|
|
{
|
|
draw_block (LCD_SIZE_X - 5, LCD_SIZE_Y - 5, 5, 5, LCD_COLOR_B, DRAW_XOR);
|
|
addTimeout (&sActiveIndTimer, TIME_MSEC2TICKS (300));
|
|
}
|
|
} // update_active_ind
|