Subversion Repositories HomeAutomation

Rev

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
}