Rev 1793 | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1789 | arune | 1 | #include "graphics.h" |
| 2 | #include "font.h" |
||
| 3 | #include <avr/io.h> |
||
| 4 | #include <stdio.h> |
||
| 5 | #include <stdlib.h> |
||
| 6 | |||
| 7 | #include <avr/pgmspace.h> |
||
| 8 | |||
| 1794 | arune | 9 | #ifndef GRAPHICS_DRIVER |
| 10 | #define GRAPHICS_DRIVER KS0108 |
||
| 11 | #error Please define GRAPHICS_DRIVER in your config.inc, see config.inc.template |
||
| 1793 | arune | 12 | #endif |
| 13 | |||
| 1794 | arune | 14 | #ifndef GRAPHICS_WIDTH |
| 15 | #define GRAPHICS_WIDTH KS0108_WIDTH |
||
| 16 | #error Please define GRAPHICS_WIDTH in your config.inc, KS0108_WIDTH should be replaced |
||
| 17 | #endif |
||
| 18 | |||
| 19 | #ifndef GRAPHICS_HEIGHT |
||
| 20 | #define GRAPHICS_HEIGHT KS0108_HIGHT |
||
| 21 | #error Please define GRAPHICS_HEIGHT in your config.inc, KS0108_HIGHT should be replaced |
||
| 22 | #endif |
||
| 23 | |||
| 24 | |||
| 25 | #if GRAPHICS_DRIVER==KS0108 |
||
| 1793 | arune | 26 | #include "ks0108.h" |
| 1794 | arune | 27 | #elif GRAPHICS_DRIVER==DOTMATRIX |
| 1793 | arune | 28 | #include "dotmatrix.h" |
| 29 | #else |
||
| 30 | #error Non supported graphics driver |
||
| 31 | #endif |
||
| 32 | |||
| 33 | |||
| 1789 | arune | 34 | //Some parts of the code is from proycon avrlib written by Pascal Stang: |
| 35 | //***************************************************************************** |
||
| 36 | // |
||
| 37 | // File Name : 'glcd.c' |
||
| 38 | // Title : Graphic LCD API functions |
||
| 39 | // Author : Pascal Stang - Copyright (C) 2002 |
||
| 40 | // Date : 5/30/2002 |
||
| 41 | // Revised : 5/30/2002 |
||
| 42 | // Version : 0.5 |
||
| 43 | // Target MCU : Atmel AVR |
||
| 44 | // Editor Tabs : 4 |
||
| 45 | // |
||
| 46 | // NOTE: This code is currently below version 1.0, and therefore is considered |
||
| 47 | // to be lacking in some functionality or documentation, or may not be fully |
||
| 48 | // tested. Nonetheless, you can expect most functions to work. |
||
| 49 | // |
||
| 50 | // This code is distributed under the GNU Public License |
||
| 51 | // which can be found at http://www.gnu.org/licenses/gpl.txt |
||
| 52 | // |
||
| 53 | //***************************************************************************** |
||
| 54 | |||
| 55 | void glcdSetColor(uint8_t color){ |
||
| 1794 | arune | 56 | #if GRAPHICS_DRIVER==KS0108 |
| 1789 | arune | 57 | ks0108SetColor(color); |
| 1794 | arune | 58 | #elif GRAPHICS_DRIVER==DOTMATRIX |
| 1793 | arune | 59 | dotmatrixSetColor(color); |
| 60 | #endif |
||
| 1789 | arune | 61 | } |
| 62 | |||
| 63 | uint8_t glcdGetColor(void){ |
||
| 1794 | arune | 64 | #if GRAPHICS_DRIVER==KS0108 |
| 1789 | arune | 65 | return ks0108GetColor(); |
| 1794 | arune | 66 | #elif GRAPHICS_DRIVER==DOTMATRIX |
| 1793 | arune | 67 | return dotmatrixGetColor(); |
| 68 | #endif |
||
| 1789 | arune | 69 | } |
| 70 | |||
| 71 | void glcdWriteData(uint8_t data, uint8_t color){ |
||
| 1794 | arune | 72 | #if GRAPHICS_DRIVER==KS0108 |
| 1789 | arune | 73 | ks0108WriteData(data, color); |
| 1794 | arune | 74 | #elif GRAPHICS_DRIVER==DOTMATRIX |
| 1793 | arune | 75 | dotmatrixWriteData(data, color); |
| 76 | #endif |
||
| 1789 | arune | 77 | } |
| 78 | |||
| 79 | void glcdWriteDataTransparent(uint8_t inputdata, uint8_t color){ |
||
| 1794 | arune | 80 | #if GRAPHICS_DRIVER==KS0108 |
| 1789 | arune | 81 | ks0108WriteDataTransparent(inputdata, color); |
| 1794 | arune | 82 | #elif GRAPHICS_DRIVER==DOTMATRIX |
| 1793 | arune | 83 | dotmatrixWriteDataTransparent(inputdata, color); |
| 84 | #endif |
||
| 1789 | arune | 85 | } |
| 86 | |||
| 87 | uint8_t glcdReadData(void){ |
||
| 1794 | arune | 88 | #if GRAPHICS_DRIVER==KS0108 |
| 1789 | arune | 89 | return ks0108ReadData(); |
| 1794 | arune | 90 | #elif GRAPHICS_DRIVER==DOTMATRIX |
| 1793 | arune | 91 | return dotmatrixReadData(); |
| 92 | #endif |
||
| 1789 | arune | 93 | } |
| 94 | |||
| 95 | void glcdClear(){ |
||
| 1794 | arune | 96 | #if GRAPHICS_DRIVER==KS0108 |
| 1789 | arune | 97 | ks0108Clear(); |
| 1794 | arune | 98 | #elif GRAPHICS_DRIVER==DOTMATRIX |
| 1793 | arune | 99 | dotmatrixClear(); |
| 100 | #endif |
||
| 1789 | arune | 101 | } |
| 102 | |||
| 103 | void glcdSetXY(uint8_t x, uint8_t y){ |
||
| 1794 | arune | 104 | #if GRAPHICS_DRIVER==KS0108 |
| 1789 | arune | 105 | ks0108SetXY(x, y); |
| 1794 | arune | 106 | #elif GRAPHICS_DRIVER==DOTMATRIX |
| 1793 | arune | 107 | dotmatrixSetXY(x, y); |
| 108 | #endif |
||
| 1789 | arune | 109 | } |
| 110 | |||
| 111 | uint8_t glcdGetX(void){ |
||
| 1794 | arune | 112 | #if GRAPHICS_DRIVER==KS0108 |
| 1789 | arune | 113 | return ks0108GetX(); |
| 1794 | arune | 114 | #elif GRAPHICS_DRIVER==DOTMATRIX |
| 1793 | arune | 115 | return dotmatrixGetX(); |
| 116 | #endif |
||
| 1789 | arune | 117 | } |
| 118 | |||
| 119 | uint8_t glcdGetY(void){ |
||
| 1794 | arune | 120 | #if GRAPHICS_DRIVER==KS0108 |
| 1789 | arune | 121 | return ks0108GetY(); |
| 1794 | arune | 122 | #elif GRAPHICS_DRIVER==DOTMATRIX |
| 1793 | arune | 123 | return dotmatrixGetY(); |
| 124 | #endif |
||
| 1789 | arune | 125 | } |
| 126 | |||
| 127 | void glcdInit(void) |
||
| 128 | { |
||
| 1794 | arune | 129 | #if GRAPHICS_DRIVER==KS0108 |
| 1789 | arune | 130 | ks0108Init(); |
| 1794 | arune | 131 | #elif GRAPHICS_DRIVER==DOTMATRIX |
| 1793 | arune | 132 | dotmatrixInit(); |
| 133 | #endif |
||
| 1789 | arune | 134 | } |
| 135 | |||
| 1794 | arune | 136 | void glcdRefresh(void) |
| 137 | { |
||
| 138 | #if GRAPHICS_DRIVER==KS0108 |
||
| 139 | /* No refresh needed */ |
||
| 140 | #elif GRAPHICS_DRIVER==DOTMATRIX |
||
| 141 | dotmatrixRefresh(); |
||
| 142 | #endif |
||
| 143 | } |
||
| 144 | |||
| 1789 | arune | 145 | void glcdWriteChar(char c, uint8_t color) |
| 146 | { |
||
| 147 | uint8_t i = 0; |
||
| 1794 | arune | 148 | if (glcdGetX() > (GRAPHICS_WIDTH-5)) |
| 1789 | arune | 149 | { |
| 150 | glcdSetXY(0, glcdGetY() + 8); |
||
| 151 | } |
||
| 152 | |||
| 153 | for(i=0; i<5; i++) |
||
| 154 | { |
||
| 155 | glcdWriteData(pgm_read_byte(&Font5x7[((c - 0x20) * 5) + i]), color); //Borde snyggas till med pekare |
||
| 156 | } |
||
| 157 | glcdWriteData(0x00, color); //space between this and the next char |
||
| 158 | } |
||
| 159 | |||
| 160 | void glcdPutStr(char *data, uint8_t color){ |
||
| 161 | while (*data){ |
||
| 162 | glcdWriteChar(*data, color); |
||
| 163 | data++; |
||
| 164 | } |
||
| 165 | } |
||
| 166 | void glcdWriteCharTransparent(char c, uint8_t color) |
||
| 167 | { |
||
| 168 | uint8_t i = 0; |
||
| 1794 | arune | 169 | if (glcdGetX() > (GRAPHICS_WIDTH-5)) |
| 1789 | arune | 170 | { |
| 171 | glcdSetXY(0, glcdGetY() + 8); |
||
| 172 | } |
||
| 173 | |||
| 174 | for(i=0; i<5; i++) |
||
| 175 | { |
||
| 176 | glcdWriteDataTransparent(pgm_read_byte(&Font5x7[((c - 0x20) * 5) + i]), color); //Borde snyggas till med pekare |
||
| 177 | } |
||
| 178 | glcdWriteDataTransparent(0x00, color); //space between this and the next char |
||
| 179 | } |
||
| 180 | |||
| 181 | void glcdPutStrTransparent(char *data, uint8_t color){ |
||
| 182 | while (*data){ |
||
| 183 | glcdWriteCharTransparent(*data, color); |
||
| 184 | data++; |
||
| 185 | } |
||
| 186 | } |
||
| 187 | |||
| 188 | void glcdDrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t color) { |
||
| 189 | uint8_t length, i, y, yAlt, xTmp, yTmp; |
||
| 190 | int16_t m; |
||
| 191 | |||
| 192 | // |
||
| 193 | // vertical line |
||
| 194 | // |
||
| 195 | if(x1 == x2) { |
||
| 196 | // x1|y1 must be the upper point |
||
| 197 | if(y1 > y2) { |
||
| 198 | yTmp = y1; |
||
| 199 | y1 = y2; |
||
| 200 | y2 = yTmp; |
||
| 201 | } |
||
| 202 | glcdDrawVertLine(x1, y1, y2-y1, color); |
||
| 203 | |||
| 204 | // |
||
| 205 | // horizontal line |
||
| 206 | // |
||
| 207 | } else if(y1 == y2) { |
||
| 208 | // x1|y1 must be the left point |
||
| 209 | if(x1 > x2) { |
||
| 210 | xTmp = x1; |
||
| 211 | x1 = x2; |
||
| 212 | x2 = xTmp; |
||
| 213 | } |
||
| 214 | glcdDrawHoriLine(x1, y1, x2-x1, color); |
||
| 215 | |||
| 216 | // |
||
| 217 | // schiefe line :) |
||
| 218 | // |
||
| 219 | } else { |
||
| 220 | // angle >= 45� |
||
| 221 | if((y2-y1) >= (x2-x1) || (y1-y2) >= (x2-x1)) { |
||
| 222 | // x1 must be smaller than x2 |
||
| 223 | if(x1 > x2) { |
||
| 224 | xTmp = x1; |
||
| 225 | yTmp = y1; |
||
| 226 | x1 = x2; |
||
| 227 | y1 = y2; |
||
| 228 | x2 = xTmp; |
||
| 229 | y2 = yTmp; |
||
| 230 | } |
||
| 231 | |||
| 232 | length = x2-x1; // not really the length :) |
||
| 233 | m = ((y2-y1)*200)/length; |
||
| 234 | yAlt = y1; |
||
| 235 | |||
| 236 | for(i=0; i<=length; i++) { |
||
| 237 | y = ((m*i)/200)+y1; |
||
| 238 | |||
| 239 | if((m*i)%200 >= 100) |
||
| 240 | y++; |
||
| 241 | else if((m*i)%200 <= -100) |
||
| 242 | y--; |
||
| 243 | |||
| 244 | glcdDrawLine(x1+i, yAlt, x1+i, y, color); |
||
| 245 | |||
| 246 | if(length <= (y2-y1) && y1 < y2) |
||
| 247 | yAlt = y+1; |
||
| 248 | else if(length <= (y1-y2) && y1 > y2) |
||
| 249 | yAlt = y-1; |
||
| 250 | else |
||
| 251 | yAlt = y; |
||
| 252 | } |
||
| 253 | |||
| 254 | // angle < 45� |
||
| 255 | } else { |
||
| 256 | // y1 must be smaller than y2 |
||
| 257 | if(y1 > y2) { |
||
| 258 | xTmp = x1; |
||
| 259 | yTmp = y1; |
||
| 260 | x1 = x2; |
||
| 261 | y1 = y2; |
||
| 262 | x2 = xTmp; |
||
| 263 | y2 = yTmp; |
||
| 264 | } |
||
| 265 | |||
| 266 | length = y2-y1; |
||
| 267 | m = ((x2-x1)*200)/length; |
||
| 268 | yAlt = x1; |
||
| 269 | |||
| 270 | for(i=0; i<=length; i++) { |
||
| 271 | y = ((m*i)/200)+x1; |
||
| 272 | |||
| 273 | if((m*i)%200 >= 100) |
||
| 274 | y++; |
||
| 275 | else if((m*i)%200 <= -100) |
||
| 276 | y--; |
||
| 277 | |||
| 278 | glcdDrawLine(yAlt, y1+i, y, y1+i, color); |
||
| 279 | if(length <= (x2-x1) && x1 < x2) |
||
| 280 | yAlt = y+1; |
||
| 281 | else if(length <= (x1-x2) && x1 > x2) |
||
| 282 | yAlt = y-1; |
||
| 283 | else |
||
| 284 | yAlt = y; |
||
| 285 | } |
||
| 286 | } |
||
| 287 | } |
||
| 288 | } |
||
| 289 | |||
| 290 | void glcdDrawRect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color) { |
||
| 291 | glcdDrawHoriLine(x, y, width, color); // top |
||
| 292 | glcdDrawHoriLine(x, y+height, width, color); // bottom |
||
| 293 | glcdDrawVertLine(x, y, height, color); // left |
||
| 294 | glcdDrawVertLine(x+width, y, height, color); // right |
||
| 295 | } |
||
| 296 | |||
| 297 | |||
| 298 | void glcdFillRect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color) { |
||
| 299 | uint8_t mask, pageOffset, h, i; //, data; |
||
| 300 | height++; |
||
| 301 | |||
| 302 | pageOffset = y%8; |
||
| 303 | y -= pageOffset; |
||
| 304 | mask = 0xFF; |
||
| 305 | if(height < 8-pageOffset) { |
||
| 306 | mask >>= (8-height); |
||
| 307 | h = height; |
||
| 308 | } else { |
||
| 309 | h = 8-pageOffset; |
||
| 310 | } |
||
| 311 | mask <<= pageOffset; |
||
| 312 | |||
| 313 | glcdSetXY(x, y); |
||
| 314 | for(i=0; i<=width; i++) { |
||
| 315 | glcdWriteDataTransparent(mask, color); |
||
| 316 | } |
||
| 317 | |||
| 318 | while(h+8 <= height) { |
||
| 319 | h += 8; |
||
| 320 | y += 8; |
||
| 321 | glcdSetXY(x, y); |
||
| 322 | |||
| 323 | for(i=0; i<=width; i++) { |
||
| 324 | glcdWriteData(0xff, color); |
||
| 325 | } |
||
| 326 | } |
||
| 327 | |||
| 328 | if(h < height) { |
||
| 329 | mask = ~(0xFF << (height-h)); |
||
| 330 | glcdSetXY(x, y+8); |
||
| 331 | |||
| 332 | for(i=0; i<=width; i++) { |
||
| 333 | glcdWriteDataTransparent(mask, color); |
||
| 334 | } |
||
| 335 | } |
||
| 336 | } |
||
| 337 | |||
| 338 | void glcdInvertRect(uint8_t x, uint8_t y, uint8_t width, uint8_t height) { |
||
| 339 | uint8_t mask, pageOffset, h, i, data, tmpData; |
||
| 340 | height++; |
||
| 341 | |||
| 342 | pageOffset = y%8; |
||
| 343 | y -= pageOffset; |
||
| 344 | mask = 0xFF; |
||
| 345 | if(height < 8-pageOffset) { |
||
| 346 | mask >>= (8-height); |
||
| 347 | h = height; |
||
| 348 | } else { |
||
| 349 | h = 8-pageOffset; |
||
| 350 | } |
||
| 351 | mask <<= pageOffset; |
||
| 352 | |||
| 353 | glcdSetXY(x, y); |
||
| 354 | for(i=0; i<=width; i++) { |
||
| 355 | data = glcdReadData(); //glcdReadData(); |
||
| 356 | tmpData = ~data; |
||
| 357 | data = (tmpData & mask) | (data & ~mask); |
||
| 358 | glcdWriteData(data, GLCD_COLOR_SET); |
||
| 359 | } |
||
| 360 | |||
| 361 | while(h+8 <= height) { |
||
| 362 | h += 8; |
||
| 363 | y += 8; |
||
| 364 | glcdSetXY(x, y); |
||
| 365 | |||
| 366 | for(i=0; i<=width; i++) { |
||
| 367 | data = glcdReadData(); |
||
| 368 | glcdWriteData(~data, GLCD_COLOR_SET); |
||
| 369 | } |
||
| 370 | } |
||
| 371 | |||
| 372 | if(h < height) { |
||
| 373 | mask = ~(0xFF << (height-h)); |
||
| 374 | glcdSetXY(x, y+8); |
||
| 375 | |||
| 376 | for(i=0; i<=width; i++) { |
||
| 377 | data = glcdReadData(); //glcdReadData(); |
||
| 378 | tmpData = ~data; |
||
| 379 | data = (tmpData & mask) | (data & ~mask); |
||
| 380 | glcdWriteData(data, GLCD_COLOR_SET); |
||
| 381 | } |
||
| 382 | } |
||
| 383 | } |
||
| 384 | |||
| 385 | void glcdInvert(void) { |
||
| 386 | if(glcdGetColor() == GLCD_COLOR_BLACK) |
||
| 387 | glcdSetColor(GLCD_COLOR_WHITE); |
||
| 388 | else |
||
| 389 | glcdSetColor(GLCD_COLOR_BLACK); |
||
| 1794 | arune | 390 | glcdInvertRect(0,0,GRAPHICS_WIDTH-1,GRAPHICS_HEIGHT-1); |
| 1789 | arune | 391 | } |
| 392 | |||
| 393 | void glcdSetDot(uint8_t x, uint8_t y, uint8_t color) { |
||
| 394 | glcdSetXY(x, y-y%8); // read data from display memory |
||
| 395 | glcdWriteDataTransparent(0x01 << (y%8), GLCD_COLOR_SET); |
||
| 396 | } |
||
| 397 | |||
| 398 | void glcdDrawRoundRect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t radius, uint8_t color) { |
||
| 399 | int16_t tSwitch, x1 = 0, y1 = radius; |
||
| 400 | tSwitch = 3 - 2 * radius; |
||
| 401 | |||
| 402 | while (x1 <= y1) { |
||
| 403 | glcdSetDot(x+radius - x1, y+radius - y1, color); |
||
| 404 | glcdSetDot(x+radius - y1, y+radius - x1, color); |
||
| 405 | |||
| 406 | glcdSetDot(x+width-radius + x1, y+radius - y1, color); |
||
| 407 | glcdSetDot(x+width-radius + y1, y+radius - x1, color); |
||
| 408 | |||
| 409 | glcdSetDot(x+width-radius + x1, y+height-radius + y1, color); |
||
| 410 | glcdSetDot(x+width-radius + y1, y+height-radius + x1, color); |
||
| 411 | |||
| 412 | glcdSetDot(x+radius - x1, y+height-radius + y1, color); |
||
| 413 | glcdSetDot(x+radius - y1, y+height-radius + x1, color); |
||
| 414 | |||
| 415 | if (tSwitch < 0) { |
||
| 416 | tSwitch += (4 * x1 + 6); |
||
| 417 | } else { |
||
| 418 | tSwitch += (4 * (x1 - y1) + 10); |
||
| 419 | y1--; |
||
| 420 | } |
||
| 421 | x1++; |
||
| 422 | } |
||
| 423 | |||
| 424 | glcdDrawHoriLine(x+radius, y, width-(2*radius), color); // top |
||
| 425 | glcdDrawHoriLine(x+radius, y+height, width-(2*radius), color); // bottom |
||
| 426 | glcdDrawVertLine(x, y+radius, height-(2*radius), color); // left |
||
| 427 | glcdDrawVertLine(x+width, y+radius, height-(2*radius), color); // right |
||
| 428 | } |