Sparkfun's Nokia Color LCD Arduino Shield library for FRDM boards

Dependents:   ColorLCDShield_Conway

Committer:
kayekss
Date:
Thu Feb 19 23:05:23 2015 +0000
Revision:
2:f4f7b91314a0
Parent:
1:2d65bfd1218c
Replaced KL25Z-specific pin definitions with universal names for Arduino-compatible boards

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kayekss 2:f4f7b91314a0 1 // ==================================================== Nov 08 2013, kayeks ==
kayekss 0:86bb740bcaf7 2 // ColorLCDShield.cpp
kayekss 2:f4f7b91314a0 3 // ===========================================================================
kayekss 0:86bb740bcaf7 4 // Sparkfun's Color LCD Shield (LCD-09363) library for mbed FRDM-KL25Z boards.
kayekss 0:86bb740bcaf7 5 // - https://www.sparkfun.com/products/9363
kayekss 0:86bb740bcaf7 6 // This library has modified from Sparkfun's Arduino library code
kayekss 0:86bb740bcaf7 7 // - Command/data transmissions are implemented as software SPI communication
kayekss 0:86bb740bcaf7 8 // because the FRDM board's MCUs are not 9-bit SPI capable :(
kayekss 0:86bb740bcaf7 9 // - License is `CC BY-SA 3.0'
kayekss 0:86bb740bcaf7 10 // - Original descriptions are below
kayekss 0:86bb740bcaf7 11
kayekss 0:86bb740bcaf7 12 /*
kayekss 0:86bb740bcaf7 13 LCDShield.cpp - Arduino Library to control a Nokia 6100 LCD,
kayekss 0:86bb740bcaf7 14 specifically that found on SparkFun's Color LCD Shield.
kayekss 0:86bb740bcaf7 15 This code should work for both Epson and Phillips display drivers
kayekss 0:86bb740bcaf7 16 normally found on the Color LCD Shield.
kayekss 0:86bb740bcaf7 17
kayekss 0:86bb740bcaf7 18 License: CC BY-SA 3.0: Creative Commons Share-alike 3.0. Feel free
kayekss 0:86bb740bcaf7 19 to use and abuse this code however you'd like. If you find it useful
kayekss 0:86bb740bcaf7 20 please attribute, and SHARE-ALIKE!
kayekss 0:86bb740bcaf7 21
kayekss 0:86bb740bcaf7 22 This is based on code by Mark Sproul, and Peter Davenport.
kayekss 0:86bb740bcaf7 23 Thanks to Coleman Sellers and Harold Timmis for help getting it to work with the Phillips Driver 7-31-2011
kayekss 0:86bb740bcaf7 24 */
kayekss 0:86bb740bcaf7 25
kayekss 0:86bb740bcaf7 26 #include "ColorLCDShield.h"
kayekss 0:86bb740bcaf7 27
kayekss 0:86bb740bcaf7 28 /*extern "C" {
kayekss 0:86bb740bcaf7 29 #include "wiring.h"
kayekss 0:86bb740bcaf7 30 }*/
kayekss 0:86bb740bcaf7 31
kayekss 0:86bb740bcaf7 32 #include "mbed.h"
kayekss 0:86bb740bcaf7 33 // #include "Arduino.h"
kayekss 0:86bb740bcaf7 34
kayekss 1:2d65bfd1218c 35 // static char x_offset = 0;
kayekss 1:2d65bfd1218c 36 // static char y_offset = 0;
kayekss 0:86bb740bcaf7 37
kayekss 1:2d65bfd1218c 38 DigitalOut res(D8); // Arduino D8
kayekss 1:2d65bfd1218c 39 DigitalOut cs(D9); // Arduino D9
kayekss 1:2d65bfd1218c 40 DigitalOut dio(D11); // Arduino D11
kayekss 1:2d65bfd1218c 41 DigitalOut sck(D13); // Arduino D13
kayekss 0:86bb740bcaf7 42
kayekss 0:86bb740bcaf7 43 LCDShield::LCDShield()
kayekss 0:86bb740bcaf7 44 {
kayekss 0:86bb740bcaf7 45 }
kayekss 0:86bb740bcaf7 46
kayekss 0:86bb740bcaf7 47 void LCDShield::LCDCommand(unsigned char data)
kayekss 0:86bb740bcaf7 48 {
kayekss 0:86bb740bcaf7 49 char jj;
kayekss 0:86bb740bcaf7 50
kayekss 0:86bb740bcaf7 51 cs = 0; // enable chip
kayekss 0:86bb740bcaf7 52 dio = 0; // output low on data out (9th bit low = command)
kayekss 0:86bb740bcaf7 53
kayekss 0:86bb740bcaf7 54 sck = 0; // send clock pulse
kayekss 0:86bb740bcaf7 55 // wait_us(1);
kayekss 0:86bb740bcaf7 56 sck = 1;
kayekss 0:86bb740bcaf7 57
kayekss 0:86bb740bcaf7 58 for (jj = 0; jj < 8; jj++)
kayekss 0:86bb740bcaf7 59 {
kayekss 0:86bb740bcaf7 60 if ((data & 0x80) == 0x80)
kayekss 0:86bb740bcaf7 61 dio = 1;
kayekss 0:86bb740bcaf7 62 else
kayekss 0:86bb740bcaf7 63 dio = 0;
kayekss 0:86bb740bcaf7 64
kayekss 0:86bb740bcaf7 65 sck = 0; // send clock pulse
kayekss 0:86bb740bcaf7 66 // wait_us(1);
kayekss 0:86bb740bcaf7 67 sck = 1;
kayekss 0:86bb740bcaf7 68
kayekss 0:86bb740bcaf7 69 data <<= 1;
kayekss 0:86bb740bcaf7 70 }
kayekss 0:86bb740bcaf7 71
kayekss 0:86bb740bcaf7 72 cs = 1; // disable
kayekss 0:86bb740bcaf7 73 }
kayekss 0:86bb740bcaf7 74
kayekss 0:86bb740bcaf7 75 void LCDShield::LCDData(unsigned char data)
kayekss 0:86bb740bcaf7 76 {
kayekss 0:86bb740bcaf7 77 char j;
kayekss 0:86bb740bcaf7 78
kayekss 0:86bb740bcaf7 79 cs = 0; // enable chip
kayekss 0:86bb740bcaf7 80 dio = 1; // output high on data out (9th bit high = data)
kayekss 0:86bb740bcaf7 81
kayekss 0:86bb740bcaf7 82 sck = 0; // send clock pulse
kayekss 0:86bb740bcaf7 83 // wait_us(1);
kayekss 0:86bb740bcaf7 84 sck = 1; // send clock pulse
kayekss 0:86bb740bcaf7 85
kayekss 0:86bb740bcaf7 86 for (j = 0; j < 8; j++)
kayekss 0:86bb740bcaf7 87 {
kayekss 0:86bb740bcaf7 88 if ((data & 0x80) == 0x80)
kayekss 0:86bb740bcaf7 89 dio = 1;
kayekss 0:86bb740bcaf7 90 else
kayekss 0:86bb740bcaf7 91 dio = 0;
kayekss 0:86bb740bcaf7 92
kayekss 0:86bb740bcaf7 93 sck = 0; // send clock pulse
kayekss 0:86bb740bcaf7 94 // wait_us(1);
kayekss 0:86bb740bcaf7 95 sck = 1;
kayekss 0:86bb740bcaf7 96
kayekss 0:86bb740bcaf7 97 data <<= 1;
kayekss 0:86bb740bcaf7 98 }
kayekss 0:86bb740bcaf7 99
kayekss 0:86bb740bcaf7 100 cs = 1; // disable
kayekss 0:86bb740bcaf7 101 }
kayekss 0:86bb740bcaf7 102
kayekss 0:86bb740bcaf7 103 void LCDShield::init(int type, bool colorSwap)
kayekss 0:86bb740bcaf7 104 {
kayekss 0:86bb740bcaf7 105 driver = type;
kayekss 0:86bb740bcaf7 106
kayekss 0:86bb740bcaf7 107 // Initialize the control pins, and reset display:
kayekss 0:86bb740bcaf7 108 sck = 0; // CLK = LOW
kayekss 0:86bb740bcaf7 109 dio = 0; // DIO = LOW
kayekss 0:86bb740bcaf7 110 wait_us(10); // 10us delay
kayekss 0:86bb740bcaf7 111 cs = 1; // CS = HIGH
kayekss 0:86bb740bcaf7 112 wait_us(10); // 10uS Delay
kayekss 0:86bb740bcaf7 113 res = 0; // RESET = LOW
kayekss 0:86bb740bcaf7 114 wait_ms(200); // 200ms delay
kayekss 0:86bb740bcaf7 115 res = 1; // RESET = HIGH
kayekss 0:86bb740bcaf7 116 wait_ms(200); // 200ms delay
kayekss 0:86bb740bcaf7 117 sck = 1; // SCK_PIN = HIGH
kayekss 0:86bb740bcaf7 118 dio = 1; // DIO = HIGH
kayekss 0:86bb740bcaf7 119 wait_us(10); // 10us delay
kayekss 0:86bb740bcaf7 120
kayekss 0:86bb740bcaf7 121 if (driver == EPSON)
kayekss 0:86bb740bcaf7 122 {
kayekss 0:86bb740bcaf7 123 LCDCommand(DISCTL); // Display control (0xCA)
kayekss 0:86bb740bcaf7 124 LCDData(0x0C); // 12 = 1100 - CL dividing ratio [don't divide] switching period 8H (default)
kayekss 0:86bb740bcaf7 125 LCDData(0x20); // nlines/4 - 1 = 132/4 - 1 = 32 duty
kayekss 0:86bb740bcaf7 126 LCDData(0x00); // No inversely highlighted lines
kayekss 0:86bb740bcaf7 127
kayekss 0:86bb740bcaf7 128 LCDCommand(COMSCN); // common scanning direction (0xBB)
kayekss 0:86bb740bcaf7 129 LCDData(0x01); // 1->68, 132<-69 scan direction
kayekss 0:86bb740bcaf7 130
kayekss 0:86bb740bcaf7 131 LCDCommand(OSCON); // internal oscialltor ON (0xD1)
kayekss 0:86bb740bcaf7 132 LCDCommand(SLPOUT); // sleep out (0x94)
kayekss 0:86bb740bcaf7 133
kayekss 0:86bb740bcaf7 134 LCDCommand(PWRCTR); // power ctrl (0x20)
kayekss 0:86bb740bcaf7 135 LCDData(0x0F); // everything on, no external reference resistors
kayekss 0:86bb740bcaf7 136
kayekss 0:86bb740bcaf7 137 LCDCommand(DISINV); // invert display mode (0xA7)
kayekss 0:86bb740bcaf7 138
kayekss 0:86bb740bcaf7 139 LCDCommand(DATCTL); // data control (0xBC)
kayekss 0:86bb740bcaf7 140 LCDData(0x03); // Inverse page address, reverse rotation column address, column scan-direction !!! try 0x01
kayekss 0:86bb740bcaf7 141 LCDData(0x00); // normal RGB arrangement
kayekss 0:86bb740bcaf7 142 LCDData(0x02); // 16-bit Grayscale Type A (12-bit color)
kayekss 0:86bb740bcaf7 143
kayekss 0:86bb740bcaf7 144 LCDCommand(VOLCTR); // electronic volume, this is the contrast/brightness (0x81)
kayekss 0:86bb740bcaf7 145 LCDData(32); // volume (contrast) setting - fine tuning, original (0-63)
kayekss 0:86bb740bcaf7 146 LCDData(3); // internal resistor ratio - coarse adjustment (0-7)
kayekss 0:86bb740bcaf7 147
kayekss 0:86bb740bcaf7 148 LCDCommand(NOP); // nop (0x25)
kayekss 0:86bb740bcaf7 149
kayekss 0:86bb740bcaf7 150 wait_ms(100);
kayekss 0:86bb740bcaf7 151
kayekss 0:86bb740bcaf7 152 LCDCommand(DISON); // display on (0xAF)
kayekss 0:86bb740bcaf7 153 }
kayekss 0:86bb740bcaf7 154 else if (driver == PHILIPS)
kayekss 0:86bb740bcaf7 155 {
kayekss 0:86bb740bcaf7 156 LCDCommand(SLEEPOUT); // Sleep Out (0x11)
kayekss 0:86bb740bcaf7 157 LCDCommand(BSTRON); // Booster voltage on (0x03)
kayekss 0:86bb740bcaf7 158 LCDCommand(DISPON); // Display on (0x29)
kayekss 0:86bb740bcaf7 159
kayekss 0:86bb740bcaf7 160 //LCDCommand(INVON); // Inversion on (0x20)
kayekss 0:86bb740bcaf7 161
kayekss 0:86bb740bcaf7 162 // 12-bit color pixel format:
kayekss 0:86bb740bcaf7 163 LCDCommand(COLMOD); // Color interface format (0x3A)
kayekss 0:86bb740bcaf7 164 LCDData(0x03); // 0b011 is 12-bit/pixel mode
kayekss 0:86bb740bcaf7 165
kayekss 0:86bb740bcaf7 166 LCDCommand(MADCTL); // Memory Access Control(PHILLIPS)
kayekss 0:86bb740bcaf7 167 if (colorSwap)
kayekss 0:86bb740bcaf7 168 LCDData(0x08);
kayekss 0:86bb740bcaf7 169 else
kayekss 0:86bb740bcaf7 170 LCDData(0x00);
kayekss 0:86bb740bcaf7 171
kayekss 0:86bb740bcaf7 172 LCDCommand(SETCON); // Set Contrast(PHILLIPS)
kayekss 0:86bb740bcaf7 173 LCDData(0x30);
kayekss 0:86bb740bcaf7 174
kayekss 0:86bb740bcaf7 175 LCDCommand(NOPP); // nop(PHILLIPS)
kayekss 0:86bb740bcaf7 176 }
kayekss 0:86bb740bcaf7 177 }
kayekss 0:86bb740bcaf7 178
kayekss 0:86bb740bcaf7 179 void LCDShield::clear(int color)
kayekss 0:86bb740bcaf7 180 {
kayekss 0:86bb740bcaf7 181 if (driver) // if it's an Epson
kayekss 0:86bb740bcaf7 182 {
kayekss 0:86bb740bcaf7 183 LCDCommand(PASET);
kayekss 0:86bb740bcaf7 184 LCDData(0);
kayekss 0:86bb740bcaf7 185 LCDData(131);
kayekss 0:86bb740bcaf7 186
kayekss 0:86bb740bcaf7 187 LCDCommand(CASET);
kayekss 0:86bb740bcaf7 188 LCDData(0);
kayekss 0:86bb740bcaf7 189 LCDData(131);
kayekss 0:86bb740bcaf7 190
kayekss 0:86bb740bcaf7 191 LCDCommand(RAMWR);
kayekss 0:86bb740bcaf7 192 }
kayekss 0:86bb740bcaf7 193 else // otherwise it's a phillips
kayekss 0:86bb740bcaf7 194 {
kayekss 0:86bb740bcaf7 195 LCDCommand(PASETP);
kayekss 0:86bb740bcaf7 196 LCDData(0);
kayekss 0:86bb740bcaf7 197 LCDData(131);
kayekss 0:86bb740bcaf7 198
kayekss 0:86bb740bcaf7 199 LCDCommand(CASETP);
kayekss 0:86bb740bcaf7 200 LCDData(0);
kayekss 0:86bb740bcaf7 201 LCDData(131);
kayekss 0:86bb740bcaf7 202
kayekss 0:86bb740bcaf7 203 LCDCommand(RAMWRP);
kayekss 0:86bb740bcaf7 204 }
kayekss 0:86bb740bcaf7 205
kayekss 0:86bb740bcaf7 206 for(unsigned int i=0; i < (131*131)/2; i++)
kayekss 0:86bb740bcaf7 207 {
kayekss 0:86bb740bcaf7 208 LCDData((color>>4)&0x00FF);
kayekss 0:86bb740bcaf7 209 LCDData(((color&0x0F)<<4)|(color>>8));
kayekss 0:86bb740bcaf7 210 LCDData(color&0x0FF);
kayekss 0:86bb740bcaf7 211 }
kayekss 0:86bb740bcaf7 212
kayekss 1:2d65bfd1218c 213 // x_offset = 0;
kayekss 1:2d65bfd1218c 214 // y_offset = 0;
kayekss 0:86bb740bcaf7 215 }
kayekss 0:86bb740bcaf7 216
kayekss 0:86bb740bcaf7 217 void LCDShield::contrast(char setting)
kayekss 0:86bb740bcaf7 218 {
kayekss 0:86bb740bcaf7 219 if (driver == EPSON)
kayekss 0:86bb740bcaf7 220 {
kayekss 0:86bb740bcaf7 221 setting &= 0x3F; // 2 msb's not used, mask out
kayekss 0:86bb740bcaf7 222 LCDCommand(VOLCTR); // electronic volume, this is the contrast/brightness(EPSON)
kayekss 0:86bb740bcaf7 223 LCDData(setting); // volume (contrast) setting - course adjustment, -- original was 24
kayekss 0:86bb740bcaf7 224 LCDData(3); // TODO: Make this coarse adjustment variable, 3's a good place to stay
kayekss 0:86bb740bcaf7 225 }
kayekss 0:86bb740bcaf7 226 else if (driver == PHILIPS)
kayekss 0:86bb740bcaf7 227 {
kayekss 0:86bb740bcaf7 228 setting &= 0x7F; // msb is not used, mask it out
kayekss 0:86bb740bcaf7 229 LCDCommand(SETCON); // contrast command (PHILLIPS)
kayekss 0:86bb740bcaf7 230 LCDData(setting); // volume (contrast) setting - course adjustment, -- original was 24
kayekss 0:86bb740bcaf7 231 }
kayekss 0:86bb740bcaf7 232 }
kayekss 0:86bb740bcaf7 233
kayekss 0:86bb740bcaf7 234 // Added by Steve Sparks @ Big Nerd Ranch.
kayekss 0:86bb740bcaf7 235 // This swaps the Epson RGB order into the Philips RGB order. (Or, vice versa, I suppose.)
kayekss 0:86bb740bcaf7 236 uint16_t LCDShield::swapColors(uint16_t in) {
kayekss 0:86bb740bcaf7 237 return ((in & 0x000F)<<8)|(in & 0x00F0)|((in & 0x0F00)>>8);
kayekss 0:86bb740bcaf7 238 }
kayekss 0:86bb740bcaf7 239
kayekss 0:86bb740bcaf7 240 void LCDShield::setPixel(int color, unsigned char x, unsigned char y)
kayekss 0:86bb740bcaf7 241 {
kayekss 0:86bb740bcaf7 242 y = (COL_HEIGHT - 1) - y;
kayekss 0:86bb740bcaf7 243 x = (ROW_LENGTH - 1) - x;
kayekss 0:86bb740bcaf7 244
kayekss 0:86bb740bcaf7 245 if (driver == EPSON) // if it's an epson
kayekss 0:86bb740bcaf7 246 {
kayekss 0:86bb740bcaf7 247 LCDCommand(PASET); // page start/end ram
kayekss 0:86bb740bcaf7 248 LCDData(x);
kayekss 0:86bb740bcaf7 249 LCDData(ENDPAGE);
kayekss 0:86bb740bcaf7 250
kayekss 0:86bb740bcaf7 251 LCDCommand(CASET); // column start/end ram
kayekss 0:86bb740bcaf7 252 LCDData(y);
kayekss 0:86bb740bcaf7 253 LCDData(ENDCOL);
kayekss 0:86bb740bcaf7 254
kayekss 0:86bb740bcaf7 255 LCDCommand(RAMWR); // write
kayekss 0:86bb740bcaf7 256 LCDData((color>>4)&0x00FF);
kayekss 0:86bb740bcaf7 257 LCDData(((color&0x0F)<<4)|(color>>8));
kayekss 0:86bb740bcaf7 258 LCDData(color&0x0FF);
kayekss 0:86bb740bcaf7 259 }
kayekss 0:86bb740bcaf7 260 else if (driver == PHILIPS) // otherwise it's a phillips
kayekss 0:86bb740bcaf7 261 {
kayekss 0:86bb740bcaf7 262 LCDCommand(PASETP); // page start/end ram
kayekss 0:86bb740bcaf7 263 LCDData(x);
kayekss 0:86bb740bcaf7 264 LCDData(x);
kayekss 0:86bb740bcaf7 265
kayekss 0:86bb740bcaf7 266 LCDCommand(CASETP); // column start/end ram
kayekss 0:86bb740bcaf7 267 LCDData(y);
kayekss 0:86bb740bcaf7 268 LCDData(y);
kayekss 0:86bb740bcaf7 269
kayekss 0:86bb740bcaf7 270 LCDCommand(RAMWRP); // write
kayekss 0:86bb740bcaf7 271
kayekss 0:86bb740bcaf7 272 LCDData((unsigned char)((color>>4)&0x00FF));
kayekss 0:86bb740bcaf7 273 LCDData((unsigned char)(((color&0x0F)<<4)|0x00));
kayekss 0:86bb740bcaf7 274 }
kayekss 0:86bb740bcaf7 275 }
kayekss 0:86bb740bcaf7 276 // 2/18/2013 This Methos added by Tony Contrada in order to create arc segments in varied line thickness, or Filled
kayekss 0:86bb740bcaf7 277 void LCDShield::setArc(int x0, int y0, int radius, int arcSegments[], int numSegments, int lineThickness, int color)
kayekss 0:86bb740bcaf7 278 {
kayekss 0:86bb740bcaf7 279 //Line Thickness (Num Pixels)
kayekss 0:86bb740bcaf7 280 if(lineThickness == FILL) lineThickness = radius;
kayekss 0:86bb740bcaf7 281 for(int i = 0; i < lineThickness; i++)
kayekss 0:86bb740bcaf7 282 {
kayekss 0:86bb740bcaf7 283 int f = 1 - radius;
kayekss 0:86bb740bcaf7 284 int ddF_x = 0;
kayekss 0:86bb740bcaf7 285 int ddF_y = -2 * radius;
kayekss 0:86bb740bcaf7 286 int x = 0;
kayekss 0:86bb740bcaf7 287 int y = radius;
kayekss 0:86bb740bcaf7 288 while(x < y)
kayekss 0:86bb740bcaf7 289 {
kayekss 0:86bb740bcaf7 290 if(f >= 0)
kayekss 0:86bb740bcaf7 291 {
kayekss 0:86bb740bcaf7 292 y--;
kayekss 0:86bb740bcaf7 293 ddF_y += 2;
kayekss 0:86bb740bcaf7 294 f += ddF_y;
kayekss 0:86bb740bcaf7 295 }
kayekss 0:86bb740bcaf7 296 x++;
kayekss 0:86bb740bcaf7 297 ddF_x += 2;
kayekss 0:86bb740bcaf7 298 f += ddF_x + 1;
kayekss 0:86bb740bcaf7 299
kayekss 0:86bb740bcaf7 300 for(int i = 0; i < numSegments; i++)
kayekss 0:86bb740bcaf7 301 {
kayekss 0:86bb740bcaf7 302 if(arcSegments[i] == NNE) setPixel(color, x0 - y, y0 + x); //SHOW NNE
kayekss 0:86bb740bcaf7 303 if(arcSegments[i] == ENE) setPixel(color, x0 - x, y0 + y); //SHOW ENE
kayekss 0:86bb740bcaf7 304 if(arcSegments[i] == ESE) setPixel(color, x0 + x, y0 + y); //SHOW ESE
kayekss 0:86bb740bcaf7 305 if(arcSegments[i] == SSE) setPixel(color, x0 + y, y0 + x); //SHOW SSE
kayekss 0:86bb740bcaf7 306 if(arcSegments[i] == SSW) setPixel(color, x0 + y, y0 - x); //SHOW SSW
kayekss 0:86bb740bcaf7 307 if(arcSegments[i] == WSW) setPixel(color, x0 + x, y0 - y); //SHOW WSW
kayekss 0:86bb740bcaf7 308 if(arcSegments[i] == WNW) setPixel(color, x0 - x, y0 - y); //SHOW WNW
kayekss 0:86bb740bcaf7 309 if(arcSegments[i] == NNW) setPixel(color, x0 - y, y0 - x); //SHOW NNW
kayekss 0:86bb740bcaf7 310 }
kayekss 0:86bb740bcaf7 311
kayekss 0:86bb740bcaf7 312 }
kayekss 0:86bb740bcaf7 313 radius--;
kayekss 0:86bb740bcaf7 314 }
kayekss 0:86bb740bcaf7 315
kayekss 0:86bb740bcaf7 316 }
kayekss 0:86bb740bcaf7 317
kayekss 0:86bb740bcaf7 318 // 2/22/2013 - Modified by Tony Contrada to include Line Thickness (in pixels) or a Filled Circle
kayekss 0:86bb740bcaf7 319 void LCDShield::setCircle (int x0, int y0, int radius, int color, int lineThickness)
kayekss 0:86bb740bcaf7 320 {
kayekss 0:86bb740bcaf7 321 if(lineThickness == FILL) lineThickness = radius;
kayekss 0:86bb740bcaf7 322
kayekss 0:86bb740bcaf7 323 for(int r = 0; r < lineThickness; r++)
kayekss 0:86bb740bcaf7 324 {
kayekss 0:86bb740bcaf7 325 int f = 1 - radius;
kayekss 0:86bb740bcaf7 326 int ddF_x = 0;
kayekss 0:86bb740bcaf7 327 int ddF_y = -2 * radius;
kayekss 0:86bb740bcaf7 328 int x = 0;
kayekss 0:86bb740bcaf7 329 int y = radius;
kayekss 0:86bb740bcaf7 330
kayekss 0:86bb740bcaf7 331 setPixel(color, x0, y0 + radius);
kayekss 0:86bb740bcaf7 332 setPixel(color, x0, y0 - radius);
kayekss 0:86bb740bcaf7 333 setPixel(color, x0 + radius, y0);
kayekss 0:86bb740bcaf7 334 setPixel(color, x0 - radius, y0);
kayekss 0:86bb740bcaf7 335
kayekss 0:86bb740bcaf7 336 while(x < y)
kayekss 0:86bb740bcaf7 337 {
kayekss 0:86bb740bcaf7 338 if(f >= 0)
kayekss 0:86bb740bcaf7 339 {
kayekss 0:86bb740bcaf7 340 y--;
kayekss 0:86bb740bcaf7 341 ddF_y += 2;
kayekss 0:86bb740bcaf7 342 f += ddF_y;
kayekss 0:86bb740bcaf7 343 }
kayekss 0:86bb740bcaf7 344 x++;
kayekss 0:86bb740bcaf7 345 ddF_x += 2;
kayekss 0:86bb740bcaf7 346 f += ddF_x + 1;
kayekss 0:86bb740bcaf7 347
kayekss 0:86bb740bcaf7 348 setPixel(color, x0 + x, y0 + y);
kayekss 0:86bb740bcaf7 349 setPixel(color, x0 - x, y0 + y);
kayekss 0:86bb740bcaf7 350 setPixel(color, x0 + x, y0 - y);
kayekss 0:86bb740bcaf7 351 setPixel(color, x0 - x, y0 - y);
kayekss 0:86bb740bcaf7 352 setPixel(color, x0 + y, y0 + x);
kayekss 0:86bb740bcaf7 353 setPixel(color, x0 - y, y0 + x);
kayekss 0:86bb740bcaf7 354 setPixel(color, x0 + y, y0 - x);
kayekss 0:86bb740bcaf7 355 setPixel(color, x0 - y, y0 - x);
kayekss 0:86bb740bcaf7 356 }
kayekss 0:86bb740bcaf7 357 radius--;
kayekss 0:86bb740bcaf7 358 }
kayekss 0:86bb740bcaf7 359
kayekss 0:86bb740bcaf7 360 }
kayekss 0:86bb740bcaf7 361
kayekss 0:86bb740bcaf7 362 void LCDShield::setChar(char c, int x, int y, int fColor, int bColor)
kayekss 0:86bb740bcaf7 363 {
kayekss 0:86bb740bcaf7 364 y = (COL_HEIGHT - 1) - y; // make display "right" side up
kayekss 0:86bb740bcaf7 365 x = (ROW_LENGTH - 2) - x;
kayekss 0:86bb740bcaf7 366
kayekss 0:86bb740bcaf7 367 int i,j;
kayekss 0:86bb740bcaf7 368 unsigned int nCols;
kayekss 0:86bb740bcaf7 369 unsigned int nRows;
kayekss 0:86bb740bcaf7 370 unsigned int nBytes;
kayekss 0:86bb740bcaf7 371 unsigned char PixelRow;
kayekss 0:86bb740bcaf7 372 unsigned char Mask;
kayekss 0:86bb740bcaf7 373 unsigned int Word0;
kayekss 0:86bb740bcaf7 374 unsigned int Word1;
kayekss 0:86bb740bcaf7 375 const unsigned char *pFont;
kayekss 0:86bb740bcaf7 376 const unsigned char *pChar;
kayekss 0:86bb740bcaf7 377
kayekss 0:86bb740bcaf7 378 // get pointer to the beginning of the selected font table
kayekss 0:86bb740bcaf7 379 pFont = *FONT8x16;
kayekss 0:86bb740bcaf7 380 // get the nColumns, nRows and nBytes
kayekss 0:86bb740bcaf7 381 nCols = *pFont;
kayekss 0:86bb740bcaf7 382 nRows = *(pFont + 1);
kayekss 0:86bb740bcaf7 383 nBytes = *(pFont + 2);
kayekss 0:86bb740bcaf7 384 // get pointer to the last byte of the desired character
kayekss 0:86bb740bcaf7 385 pChar = pFont + (nBytes * (c - 0x1F)) + nBytes - 1;
kayekss 0:86bb740bcaf7 386
kayekss 0:86bb740bcaf7 387 if (driver) // if it's an epson
kayekss 0:86bb740bcaf7 388 {
kayekss 0:86bb740bcaf7 389 // Row address set (command 0x2B)
kayekss 0:86bb740bcaf7 390 LCDCommand(PASET);
kayekss 0:86bb740bcaf7 391 LCDData(x);
kayekss 0:86bb740bcaf7 392 LCDData(x + nRows - 1);
kayekss 0:86bb740bcaf7 393 // Column address set (command 0x2A)
kayekss 0:86bb740bcaf7 394 LCDCommand(CASET);
kayekss 0:86bb740bcaf7 395 LCDData(y);
kayekss 0:86bb740bcaf7 396 LCDData(y + nCols - 1);
kayekss 0:86bb740bcaf7 397
kayekss 0:86bb740bcaf7 398 // WRITE MEMORY
kayekss 0:86bb740bcaf7 399 LCDCommand(RAMWR);
kayekss 0:86bb740bcaf7 400 // loop on each row, working backwards from the bottom to the top
kayekss 0:86bb740bcaf7 401 for (i = nRows - 1; i >= 0; i--) {
kayekss 0:86bb740bcaf7 402 // copy pixel row from font table and then decrement row
kayekss 0:86bb740bcaf7 403 PixelRow = *(pChar++);
kayekss 0:86bb740bcaf7 404 // loop on each pixel in the row (left to right)
kayekss 0:86bb740bcaf7 405 // Note: we do two pixels each loop
kayekss 0:86bb740bcaf7 406 Mask = 0x80;
kayekss 0:86bb740bcaf7 407 for (j = 0; j < nCols; j += 2)
kayekss 0:86bb740bcaf7 408 {
kayekss 0:86bb740bcaf7 409 // if pixel bit set, use foreground color; else use the background color
kayekss 0:86bb740bcaf7 410 // now get the pixel color for two successive pixels
kayekss 0:86bb740bcaf7 411 if ((PixelRow & Mask) == 0)
kayekss 0:86bb740bcaf7 412 Word0 = bColor;
kayekss 0:86bb740bcaf7 413 else
kayekss 0:86bb740bcaf7 414 Word0 = fColor;
kayekss 0:86bb740bcaf7 415 Mask = Mask >> 1;
kayekss 0:86bb740bcaf7 416 if ((PixelRow & Mask) == 0)
kayekss 0:86bb740bcaf7 417 Word1 = bColor;
kayekss 0:86bb740bcaf7 418 else
kayekss 0:86bb740bcaf7 419 Word1 = fColor;
kayekss 0:86bb740bcaf7 420 Mask = Mask >> 1;
kayekss 0:86bb740bcaf7 421 // use this information to output three data bytes
kayekss 0:86bb740bcaf7 422 LCDData((Word0 >> 4) & 0xFF);
kayekss 0:86bb740bcaf7 423 LCDData(((Word0 & 0xF) << 4) | ((Word1 >> 8) & 0xF));
kayekss 0:86bb740bcaf7 424 LCDData(Word1 & 0xFF);
kayekss 0:86bb740bcaf7 425 }
kayekss 0:86bb740bcaf7 426 }
kayekss 0:86bb740bcaf7 427 }
kayekss 0:86bb740bcaf7 428 else
kayekss 0:86bb740bcaf7 429 {
kayekss 0:86bb740bcaf7 430 fColor = swapColors(fColor);
kayekss 0:86bb740bcaf7 431 bColor = swapColors(bColor);
kayekss 0:86bb740bcaf7 432
kayekss 0:86bb740bcaf7 433 // Row address set (command 0x2B)
kayekss 0:86bb740bcaf7 434 LCDCommand(PASETP);
kayekss 0:86bb740bcaf7 435 LCDData(x);
kayekss 0:86bb740bcaf7 436 LCDData(x + nRows - 1);
kayekss 0:86bb740bcaf7 437 // Column address set (command 0x2A)
kayekss 0:86bb740bcaf7 438 LCDCommand(CASETP);
kayekss 0:86bb740bcaf7 439 LCDData(y);
kayekss 0:86bb740bcaf7 440 LCDData(y + nCols - 1);
kayekss 0:86bb740bcaf7 441
kayekss 0:86bb740bcaf7 442 // WRITE MEMORY
kayekss 0:86bb740bcaf7 443 LCDCommand(RAMWRP);
kayekss 0:86bb740bcaf7 444 // loop on each row, working backwards from the bottom to the top
kayekss 0:86bb740bcaf7 445 pChar+=nBytes-1; // stick pChar at the end of the row - gonna reverse print on phillips
kayekss 0:86bb740bcaf7 446 for (i = nRows - 1; i >= 0; i--) {
kayekss 0:86bb740bcaf7 447 // copy pixel row from font table and then decrement row
kayekss 0:86bb740bcaf7 448 PixelRow = *(pChar--);
kayekss 0:86bb740bcaf7 449 // loop on each pixel in the row (left to right)
kayekss 0:86bb740bcaf7 450 // Note: we do two pixels each loop
kayekss 0:86bb740bcaf7 451 Mask = 0x01; // <- opposite of epson
kayekss 0:86bb740bcaf7 452 for (j = 0; j < nCols; j += 2)
kayekss 0:86bb740bcaf7 453 {
kayekss 0:86bb740bcaf7 454 // if pixel bit set, use foreground color; else use the background color
kayekss 0:86bb740bcaf7 455 // now get the pixel color for two successive pixels
kayekss 0:86bb740bcaf7 456 if ((PixelRow & Mask) == 0)
kayekss 0:86bb740bcaf7 457 Word0 = bColor;
kayekss 0:86bb740bcaf7 458 else
kayekss 0:86bb740bcaf7 459 Word0 = fColor;
kayekss 0:86bb740bcaf7 460 Mask = Mask << 1; // <- opposite of epson
kayekss 0:86bb740bcaf7 461 if ((PixelRow & Mask) == 0)
kayekss 0:86bb740bcaf7 462 Word1 = bColor;
kayekss 0:86bb740bcaf7 463 else
kayekss 0:86bb740bcaf7 464 Word1 = fColor;
kayekss 0:86bb740bcaf7 465 Mask = Mask << 1; // <- opposite of epson
kayekss 0:86bb740bcaf7 466 // use this information to output three data bytes
kayekss 0:86bb740bcaf7 467 LCDData((Word0 >> 4) & 0xFF);
kayekss 0:86bb740bcaf7 468 LCDData(((Word0 & 0xF) << 4) | ((Word1 >> 8) & 0xF));
kayekss 0:86bb740bcaf7 469 LCDData(Word1 & 0xFF);
kayekss 0:86bb740bcaf7 470 }
kayekss 0:86bb740bcaf7 471 }
kayekss 0:86bb740bcaf7 472 }
kayekss 0:86bb740bcaf7 473 }
kayekss 0:86bb740bcaf7 474
kayekss 0:86bb740bcaf7 475
kayekss 0:86bb740bcaf7 476 void LCDShield::setStr(char *pString, int x, int y, int fColor, int bColor)
kayekss 0:86bb740bcaf7 477 {
kayekss 0:86bb740bcaf7 478 x = x + 16;
kayekss 0:86bb740bcaf7 479 y = y + 8;
kayekss 0:86bb740bcaf7 480 int originalY = y;
kayekss 0:86bb740bcaf7 481
kayekss 0:86bb740bcaf7 482 // loop until null-terminator is seen
kayekss 0:86bb740bcaf7 483 while (*pString != 0x00) {
kayekss 0:86bb740bcaf7 484 // draw the character
kayekss 0:86bb740bcaf7 485 setChar(*pString++, x, y, fColor, bColor);
kayekss 0:86bb740bcaf7 486 // advance the y position
kayekss 0:86bb740bcaf7 487 y = y + 8;
kayekss 0:86bb740bcaf7 488 // bail out if y exceeds 131
kayekss 0:86bb740bcaf7 489 if (y > 131) {
kayekss 0:86bb740bcaf7 490 x = x + 16;
kayekss 0:86bb740bcaf7 491 y = originalY;
kayekss 0:86bb740bcaf7 492 }
kayekss 0:86bb740bcaf7 493 if (x > 123) break;
kayekss 0:86bb740bcaf7 494 }
kayekss 0:86bb740bcaf7 495 }
kayekss 0:86bb740bcaf7 496
kayekss 0:86bb740bcaf7 497 void LCDShield::setLine(int x0, int y0, int x1, int y1, int color)
kayekss 0:86bb740bcaf7 498 {
kayekss 0:86bb740bcaf7 499 int dy = y1 - y0; // Difference between y0 and y1
kayekss 0:86bb740bcaf7 500 int dx = x1 - x0; // Difference between x0 and x1
kayekss 0:86bb740bcaf7 501 int stepx, stepy;
kayekss 0:86bb740bcaf7 502
kayekss 0:86bb740bcaf7 503 if (dy < 0)
kayekss 0:86bb740bcaf7 504 {
kayekss 0:86bb740bcaf7 505 dy = -dy;
kayekss 0:86bb740bcaf7 506 stepy = -1;
kayekss 0:86bb740bcaf7 507 }
kayekss 0:86bb740bcaf7 508 else
kayekss 0:86bb740bcaf7 509 stepy = 1;
kayekss 0:86bb740bcaf7 510
kayekss 0:86bb740bcaf7 511 if (dx < 0)
kayekss 0:86bb740bcaf7 512 {
kayekss 0:86bb740bcaf7 513 dx = -dx;
kayekss 0:86bb740bcaf7 514 stepx = -1;
kayekss 0:86bb740bcaf7 515 }
kayekss 0:86bb740bcaf7 516 else
kayekss 0:86bb740bcaf7 517 stepx = 1;
kayekss 0:86bb740bcaf7 518
kayekss 0:86bb740bcaf7 519 dy <<= 1; // dy is now 2*dy
kayekss 0:86bb740bcaf7 520 dx <<= 1; // dx is now 2*dx
kayekss 0:86bb740bcaf7 521 setPixel(color, x0, y0);
kayekss 0:86bb740bcaf7 522
kayekss 0:86bb740bcaf7 523 if (dx > dy)
kayekss 0:86bb740bcaf7 524 {
kayekss 0:86bb740bcaf7 525 int fraction = dy - (dx >> 1);
kayekss 0:86bb740bcaf7 526 while (x0 != x1)
kayekss 0:86bb740bcaf7 527 {
kayekss 0:86bb740bcaf7 528 if (fraction >= 0)
kayekss 0:86bb740bcaf7 529 {
kayekss 0:86bb740bcaf7 530 y0 += stepy;
kayekss 0:86bb740bcaf7 531 fraction -= dx;
kayekss 0:86bb740bcaf7 532 }
kayekss 0:86bb740bcaf7 533 x0 += stepx;
kayekss 0:86bb740bcaf7 534 fraction += dy;
kayekss 0:86bb740bcaf7 535 setPixel(color, x0, y0);
kayekss 0:86bb740bcaf7 536 }
kayekss 0:86bb740bcaf7 537 }
kayekss 0:86bb740bcaf7 538 else
kayekss 0:86bb740bcaf7 539 {
kayekss 0:86bb740bcaf7 540 int fraction = dx - (dy >> 1);
kayekss 0:86bb740bcaf7 541 while (y0 != y1)
kayekss 0:86bb740bcaf7 542 {
kayekss 0:86bb740bcaf7 543 if (fraction >= 0)
kayekss 0:86bb740bcaf7 544 {
kayekss 0:86bb740bcaf7 545 x0 += stepx;
kayekss 0:86bb740bcaf7 546 fraction -= dy;
kayekss 0:86bb740bcaf7 547 }
kayekss 0:86bb740bcaf7 548 y0 += stepy;
kayekss 0:86bb740bcaf7 549 fraction += dx;
kayekss 0:86bb740bcaf7 550 setPixel(color, x0, y0);
kayekss 0:86bb740bcaf7 551 }
kayekss 0:86bb740bcaf7 552 }
kayekss 0:86bb740bcaf7 553 }
kayekss 0:86bb740bcaf7 554
kayekss 0:86bb740bcaf7 555 void LCDShield::setRect(int x0, int y0, int x1, int y1, unsigned char fill, int color)
kayekss 0:86bb740bcaf7 556 {
kayekss 0:86bb740bcaf7 557 // check if the rectangle is to be filled
kayekss 0:86bb740bcaf7 558 if (fill == 1)
kayekss 0:86bb740bcaf7 559 {
kayekss 0:86bb740bcaf7 560 int xDiff;
kayekss 0:86bb740bcaf7 561
kayekss 0:86bb740bcaf7 562 if(x0 > x1)
kayekss 0:86bb740bcaf7 563 xDiff = x0 - x1; //Find the difference between the x vars
kayekss 0:86bb740bcaf7 564 else
kayekss 0:86bb740bcaf7 565 xDiff = x1 - x0;
kayekss 0:86bb740bcaf7 566
kayekss 0:86bb740bcaf7 567 while(xDiff > 0)
kayekss 0:86bb740bcaf7 568 {
kayekss 0:86bb740bcaf7 569 setLine(x0, y0, x0, y1, color);
kayekss 0:86bb740bcaf7 570
kayekss 0:86bb740bcaf7 571 if(x0 > x1)
kayekss 0:86bb740bcaf7 572 x0--;
kayekss 0:86bb740bcaf7 573 else
kayekss 0:86bb740bcaf7 574 x0++;
kayekss 0:86bb740bcaf7 575
kayekss 0:86bb740bcaf7 576 xDiff--;
kayekss 0:86bb740bcaf7 577 }
kayekss 0:86bb740bcaf7 578
kayekss 0:86bb740bcaf7 579 }
kayekss 0:86bb740bcaf7 580 else
kayekss 0:86bb740bcaf7 581 {
kayekss 0:86bb740bcaf7 582 // best way to draw an unfilled rectangle is to draw four lines
kayekss 0:86bb740bcaf7 583 setLine(x0, y0, x1, y0, color);
kayekss 0:86bb740bcaf7 584 setLine(x0, y1, x1, y1, color);
kayekss 0:86bb740bcaf7 585 setLine(x0, y0, x0, y1, color);
kayekss 0:86bb740bcaf7 586 setLine(x1, y0, x1, y1, color);
kayekss 0:86bb740bcaf7 587 }
kayekss 0:86bb740bcaf7 588 }
kayekss 0:86bb740bcaf7 589
kayekss 0:86bb740bcaf7 590 void LCDShield::printLogo(void)
kayekss 0:86bb740bcaf7 591 {
kayekss 0:86bb740bcaf7 592 int x = 4, y = 25, logo_ix = 0, z;
kayekss 0:86bb740bcaf7 593 char logo;
kayekss 0:86bb740bcaf7 594
kayekss 0:86bb740bcaf7 595 for (logo_ix = 0; logo_ix < 1120; logo_ix++)
kayekss 0:86bb740bcaf7 596 {
kayekss 0:86bb740bcaf7 597 logo = logo_spark[logo_ix];
kayekss 0:86bb740bcaf7 598 for (z = 0; z < 8; z++)
kayekss 0:86bb740bcaf7 599 {
kayekss 0:86bb740bcaf7 600 if ((logo & 0x80) == 0x80) setPixel(RED, y, x);
kayekss 0:86bb740bcaf7 601 x++;
kayekss 0:86bb740bcaf7 602 if (x == 132)
kayekss 0:86bb740bcaf7 603 {
kayekss 0:86bb740bcaf7 604 x = 4;
kayekss 0:86bb740bcaf7 605 y++;
kayekss 0:86bb740bcaf7 606 }
kayekss 0:86bb740bcaf7 607 logo <<= 1;
kayekss 0:86bb740bcaf7 608 }
kayekss 0:86bb740bcaf7 609 }
kayekss 0:86bb740bcaf7 610 }
kayekss 0:86bb740bcaf7 611
kayekss 0:86bb740bcaf7 612 void LCDShield::off(void)
kayekss 0:86bb740bcaf7 613 {
kayekss 0:86bb740bcaf7 614 if (driver) // If it's an epson
kayekss 0:86bb740bcaf7 615 LCDCommand(DISOFF);
kayekss 0:86bb740bcaf7 616 else // otherwise it's a phillips
kayekss 0:86bb740bcaf7 617 LCDCommand(DISPOFF);
kayekss 0:86bb740bcaf7 618 }
kayekss 0:86bb740bcaf7 619
kayekss 0:86bb740bcaf7 620 void LCDShield::on(void)
kayekss 0:86bb740bcaf7 621 {
kayekss 0:86bb740bcaf7 622 if (driver) // If it's an epson
kayekss 0:86bb740bcaf7 623 LCDCommand(DISON);
kayekss 0:86bb740bcaf7 624 else // otherwise it's a phillips
kayekss 0:86bb740bcaf7 625 LCDCommand(DISPON);
kayekss 0:86bb740bcaf7 626 }