Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
107 mikeljo 1
 
2
#define F_CPU 7372800UL
3
#include <avr/io.h>
4
#include <inttypes.h>
5
#include <stdlib.h>
6
#include <avr/pgmspace.h>
7
#include <util/delay.h>
8
 
9
#include "font8x6.h"
10
#include "main.h"
11
#include "lcd.h"
12
 
13
#define DISP_W 128
14
#define DISP_H 64
15
// #define LCD_ORIENTATION 0 // 0 MJ Tasten unten / 4 Original Tasten oben
16
 
17
 
18
uint8_t lcd_xpos;
19
uint8_t lcd_ypos;
20
//volatile uint8_t display_buffer[1024];                                        // Display-Puffer, weil nicht zurückgelesen werden kann
21
//volatile uint16_t display_buffer_pointer;                                     // Pointer auf das aktuell übertragene Byte
22
//volatile uint8_t display_buffer_counter;                                      // Hilfszähler zur Selektierung der Page
23
//volatile uint8_t display_page_counter;                                        // aktuelle Page-Nummer
24
//volatile uint8_t display_mode;                                                        // Modus für State-Machine
25
 
26
 
27
void send_byte (uint8_t data)
28
{
29
        clr_cs();
30
        SPDR = data;
31
        while(!(SPSR & (1<<SPIF)));
32
        SPSR = SPSR;
33
        set_cs();
34
}
35
 
36
void cls (void)
37
{
38
        uint16_t i,j;
39
 
40
        for (i=0;i<1024;i++)
41
                display_buffer[i] = 0x00;
42
 
43
        for (i=0;i<8;i++)
44
        {
45
                clr_A0();
46
                send_byte(0xB0+i);  //1011xxxx
47
                send_byte(0x10);        //00010000
48
//              send_byte(0x04);        //00000100 gedreht plus 4 Byte
49
//              send_byte(0x00);        //00000000
50
                send_byte(LCD_ORIENTATION);     //00000000
51
 
52
 
53
                set_A0();
54
                for (j=0;j<128;j++)
55
                        send_byte(0x00);
56
        }
57
 
58
        lcd_xpos = 0;
59
        lcd_ypos = 0;
60
}
61
 
62
void lcd_cls (void)
63
{
64
        cls();
65
}
66
 
67
void wait_1ms(void)
68
{
69
        _delay_ms (1.0);
70
}
71
 
72
void wait_ms (uint16_t time)
73
{
74
        uint16_t i;
75
 
76
        for (i=0; i<time; i++)
77
                wait_1ms();
78
}
79
 
80
void lcd_init (void)
81
{
82
        lcd_xpos = 0;
83
        lcd_ypos = 0;
84
 
85
 
86
        DDRB = 0xFF;
87
 
88
        SPCR = (1<<SPE)|(1<<MSTR)|(1<<CPHA)|(1<<CPOL)|(1<<SPR1);
89
 
90
        set_cs();
91
        clr_reset();
92
        wait_ms(10);
93
        set_reset();
94
 
95
        clr_cs();
96
        clr_A0();
97
 
98
        send_byte(0x40);
99
 
100
        if (LCD_ORIENTATION == 0)
101
        {
102
                send_byte(0xA1); // A1 normal A0 reverse(original)
103
                send_byte(0xC0); // C0 normal C8 reverse(original)
104
        }
105
        else
106
        {
107
                send_byte(0xA0); // A1 normal A0 reverse(original)
108
                send_byte(0xC8); // C0 normal C8 reverse(original)
109
        }
110
        send_byte(0xA6);
111
        send_byte(0xA2);
112
        send_byte(0x2F);
113
        send_byte(0xF8);
114
        send_byte(0x00);
115
        send_byte(0x27);
116
        send_byte(0x81);
117
        send_byte(0x16);
118
        send_byte(0xAC);
119
        send_byte(0x00);
120
        send_byte(0xAF);
121
 
122
        cls();
123
 
124
}
125
 
126
void set_adress (uint16_t adress, uint8_t data)
127
{
128
        uint8_t page;
129
        uint8_t column;
130
 
131
        page = adress >> 7;
132
 
133
        clr_A0();
134
        send_byte(0xB0 + page);
135
 
136
//      column = (adress & 0x7F) + 4; Wenn gedreht
137
//      column = (adress & 0x7F);
138
        column = (adress & 0x7F) + LCD_ORIENTATION;
139
 
140
        send_byte(0x10 + (column >> 4));
141
        send_byte(column & 0x0F);
142
 
143
        set_A0();
144
        send_byte(data);
145
}
146
 
147
void scroll (void)
148
{
149
        uint16_t adress;
150
 
151
        for (adress=0;adress<896;adress++)
152
        {
153
                display_buffer[adress] = display_buffer[adress+128];
154
                set_adress(adress,display_buffer[adress]);
155
        }
156
        for (adress=896;adress<1024;adress++)
157
        {
158
                display_buffer[adress] = 0;
159
                set_adress(adress,0);
160
        }
161
}
162
 
163
//
164
// x,y = character-Pos. !
165
//
166
// mode: 0=Overwrite, 1 = OR, 2 = XOR, 3 = AND, 4 = Delete
167
void put_char (uint8_t x, uint8_t y, uint8_t c, uint8_t mode)
168
{
169
        uint8_t ch;
170
        uint8_t i;
171
        uint16_t adress;
172
 
173
        switch(c)
174
        {
175
                case 'ä':
176
                        c = 0x84;
177
                        break;
178
                case 'ö':
179
                        c = 0x94;
180
                        break;
181
                case 'ü':
182
                        c = 0x81;
183
                        break;
184
                case 'Ä':
185
                        c = 0x8E;
186
                        break;
187
                case 'Ö':
188
                        c = 0x99;
189
                        break;
190
                case 'Ü':
191
                        c = 0x9A;
192
                        break;
193
                case 'ß':
194
                        c = 0xE1;
195
                        break;
196
        }
197
 
198
        adress = y*128 + x*6;
199
        adress &= 0x3FF;
200
 
201
        for (i=0;i<6;i++)
202
        {
203
                ch = pgm_read_byte (&f8x6[0][0] + i + c * 6);
204
 
205
                switch (mode)
206
                {
207
                        case 0:
208
                                display_buffer[adress+i] = ch;
209
                                break;
210
                        case 1:
211
                                display_buffer[adress+i] |= ch;
212
                                break;
213
                        case 2:
214
                                display_buffer[adress+i] ^= ch;
215
                                break;
216
                        case 3:
217
                                display_buffer[adress+i] &= ch;
218
                                break;
219
                        case 4:
220
                                display_buffer[adress+i] &= ~ch;
221
                                break;
222
                }
223
 
224
                set_adress(adress+i,display_buffer[adress+i]);
225
        }
226
}
227
 
228
void new_line (void)
229
{
230
        lcd_ypos++;
231
 
232
        if (lcd_ypos > 7)
233
        {
234
                scroll();
235
                lcd_ypos = 7;
236
        }
237
}
238
 
239
 
240
void lcd_printp (const char *text, uint8_t mode)
241
{
242
        while (pgm_read_byte(text))
243
        {
244
                if (pgm_read_byte(text) > 0x1F)
245
                {
246
                        put_char(lcd_xpos,lcd_ypos,pgm_read_byte(text++),mode);
247
 
248
                        lcd_xpos++;
249
                        if (lcd_xpos > 20)
250
                        {
251
                                lcd_xpos = 0;
252
                                new_line();
253
                        }
254
                }
255
                else
256
                {
257
                        switch (pgm_read_byte(text))
258
                        {
259
                                case 0x0D:
260
                                        lcd_xpos = 0;
261
                                        break;
262
                                case 0x0A:
263
                                        new_line();
264
                                        break;
265
                        }
266
                        text++;
267
                }
268
        }
269
}
270
 
271
void lcd_print_atp (uint8_t x, uint8_t y, const char *text, uint8_t mode)
272
{
273
        lcd_xpos = x;
274
        lcd_ypos = y;
275
        lcd_printp (text, mode);
276
}
277
 
278
 
279
void lcd_print (uint8_t *text, uint8_t mode)
280
{
281
        while (*text)
282
        {
283
                if (*text > 0x1F)
284
                {
285
                        put_char(lcd_xpos,lcd_ypos,*text++,mode);
286
 
287
                        lcd_xpos++;
288
                        if (lcd_xpos > 20)
289
                        {
290
                                lcd_xpos = 0;
291
                                new_line();
292
                        }
293
                }
294
                else
295
                {
296
                        switch (*text)
297
                        {
298
                                case 0x0D:
299
                                        lcd_xpos = 0;
300
                                        break;
301
                                case 0x0A:
302
                                        new_line();
303
                                        break;
304
                        }
305
                        text++;
306
                }
307
        }
308
}
309
 
310
void lcd_print_at (uint8_t x, uint8_t y, uint8_t *text, uint8_t mode)
311
{
312
        lcd_xpos = x;
313
        lcd_ypos = y;
314
        lcd_print(text, mode);
315
}
316
 
317
 
318
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
319
// + Plot (set one Pixel)
320
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
321
// mode:
322
// 0=Clear, 1=Set, 2=XOR
323
void lcd_plot (uint8_t xpos, uint8_t ypos, uint8_t mode)
324
{
325
        uint16_t adress;
326
        uint8_t mask;
327
 
328
        if ((xpos < 128) && (ypos < 64))
329
        {
330
                adress = (ypos/8) * 128 + xpos;                         // adress = 0/8 * 128 + 0   = 0
331
                mask = 1<<(ypos & 0x07);                                                // mask = 1<<0 = 1
332
 
333
                adress &= 0x3FF;
334
 
335
                switch (mode)
336
                {
337
                        case 0:
338
                                display_buffer[adress] &=~mask;
339
                                break;
340
                        case 1:
341
                                display_buffer[adress] |= mask;
342
                                break;
343
                        case 2:
344
                                display_buffer[adress] ^= mask;
345
                                break;
346
                }
347
 
348
                set_adress(adress,display_buffer[adress]);
349
        }
350
}
351
 
352
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
353
// + Line (draws a line from x1,y1 to x2,y2
354
// + Based on Bresenham line-Algorithm
355
// + found in the internet, modified by thkais 2007
356
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
357
 
358
void lcd_line(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, uint8_t mode)
359
 
360
{
361
        int x,y,count,xs,ys,xm,ym;
362
 
363
        x=(int)x1;
364
        y=(int)y1;
365
        xs=(int)x2 - (int)x1;
366
        ys=(int)y2 - (int)y1;
367
        if(xs < 0)
368
                xm= -1;
369
        else
370
                if(xs > 0)
371
                        xm= 1;
372
                else
373
                        xm= 0;
374
        if(ys < 0)
375
                ym= -1;
376
        else
377
                if(ys > 0)
378
                        ym= 1;
379
                else
380
                        ym= 0;
381
        if(xs < 0)
382
                xs= -xs;
383
        if(ys < 0)
384
                ys= -ys;
385
 
386
        lcd_plot((unsigned char)x, (unsigned char)y, mode);
387
 
388
        if(xs > ys) // Flat Line <45 degrees
389
        {
390
                count= -(xs / 2);
391
                while(x != x2)
392
                {
393
                        count= count + ys;
394
                        x= x + xm;
395
                        if(count > 0)
396
                        {
397
                                y= y + ym;
398
                                count= count - xs;
399
                        }
400
                        lcd_plot((unsigned char)x, (unsigned char)y, mode);
401
                }
402
        }
403
        else // Line >=45 degrees
404
        {
405
                count=- (ys / 2);
406
                while(y != y2)
407
                {
408
                        count= count + xs;
409
                        y= y + ym;
410
                        if(count > 0)
411
                        {
412
                                x= x + xm;
413
                                count= count - ys;
414
                        }
415
                        lcd_plot((unsigned char)x, (unsigned char)y, mode);
416
                }
417
        }
418
}
419
 
420
 
421
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
422
// + Filled rectangle
423
// + x1, y1 = upper left corner
424
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
425
 
426
void lcd_frect (uint8_t x1, uint8_t y1, uint8_t widthx, uint8_t widthy, uint8_t mode)
427
{
428
        uint16_t x2, y2;
429
        uint16_t i;
430
 
431
        if (x1 >= DISP_W)
432
                x1 = DISP_W - 1;
433
        if (y1 >= DISP_H)
434
                y1 = DISP_H - 1;
435
        x2 = x1 + widthx;
436
        y2 = y1 + widthy;
437
 
438
        if (x2 > DISP_W)
439
                x2 = DISP_W;
440
        if (y2 > DISP_H)
441
                y2 = DISP_H;
442
 
443
        for (i=y1;i<=y2;i++)
444
        {
445
                lcd_line(x1,i,x2,i,mode);
446
        }
447
 
448
}
449
 
450
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
451
// + outline of rectangle
452
// + x1, y1 = upper left corner
453
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
454
 
455
void lcd_rect (uint8_t x1, uint8_t y1, uint8_t widthx, uint8_t widthy, uint8_t mode)
456
{
457
        uint16_t x2, y2;
458
 
459
        if (x1 >= DISP_W)
460
                x1 = DISP_W - 1;
461
        if (y1 >= DISP_H)
462
                y1 = DISP_H - 1;
463
        x2 = x1 + widthx;
464
        y2 = y1 + widthy;
465
 
466
        if (x2 > DISP_W)
467
                x2 = DISP_W;
468
        if (y2 > DISP_H)
469
                y2 = DISP_H;
470
 
471
        lcd_line (x1, y1, x2, y1, mode);
472
        lcd_line (x2, y1, x2, y2, mode);
473
        lcd_line (x2, y2, x1, y2, mode);
474
        lcd_line (x1, y2, x1, y1, mode);
475
}
476
 
477
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
478
// + outline of a circle
479
// + Based on Bresenham-algorithm found in wikipedia
480
// + modified by thkais (2007)
481
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
482
 
483
 
484
void draw_circle(int16_t x0, int16_t y0, int16_t radius, uint8_t mode)
485
{
486
        int16_t f = 1 - radius;
487
        int16_t ddF_x = 0;
488
        int16_t ddF_y = -2 * radius;
489
        int16_t x = 0;
490
        int16_t y = radius;
491
 
492
        lcd_plot(x0, y0 + radius, mode);
493
        lcd_plot(x0, y0 - radius, mode);
494
        lcd_plot(x0 + radius, y0, mode);
495
        lcd_plot(x0 - radius, y0, mode);
496
 
497
        while(x < y)
498
        {
499
                if(f >= 0)
500
                {
501
                        y --;
502
                        ddF_y += 2;
503
                        f += ddF_y;
504
                }
505
                x ++;
506
                ddF_x += 2;
507
                f += ddF_x + 1;
508
 
509
                lcd_plot(x0 + x, y0 + y, mode);
510
                lcd_plot(x0 - x, y0 + y, mode);
511
 
512
                lcd_plot(x0 + x, y0 - y, mode);
513
                lcd_plot(x0 - x, y0 - y, mode);
514
 
515
                lcd_plot(x0 + y, y0 + x, mode);
516
                lcd_plot(x0 - y, y0 + x, mode);
517
 
518
                lcd_plot(x0 + y, y0 - x, mode);
519
                lcd_plot(x0 - y, y0 - x, mode);
520
        }
521
}
522
 
523
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
524
// + filled Circle
525
// + modified circle-algorithm thkais (2007)
526
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
527
 
528
void draw_fcircle(int16_t x0, int16_t y0, int16_t radius)
529
{
530
        int16_t f = 1 - radius;
531
        int16_t ddF_x = 0;
532
        int16_t ddF_y = -2 * radius;
533
        int16_t x = 0;
534
        int16_t y = radius;
535
 
536
        lcd_line(x0, y0 + radius,x0, y0 - radius,1);
537
 
538
        lcd_line(x0 + radius, y0,x0 - radius, y0,1);
539
 
540
        while(x < y)
541
        {
542
                if(f >= 0)
543
                {
544
                        y--;
545
                        ddF_y += 2;
546
                        f += ddF_y;
547
                }
548
                x++;
549
                ddF_x += 2;
550
                f += ddF_x + 1;
551
 
552
                lcd_line(x0 + x, y0 + y,x0 - x, y0 + y,1);
553
                lcd_line(x0 + x, y0 - y,x0 - x, y0 - y,1);
554
                lcd_line(x0 + y, y0 + x,x0 - y, y0 + x,1);
555
                lcd_line(x0 + y, y0 - x,x0 - y, y0 - x,1);
556
        }
557
 }