Subversion Repositories Projects

Rev

Rev 112 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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