Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2136 - 1
/*****************************************************************************
2
 *   Copyright (C) 2009 Peter "woggle" Mack, mac@denich.net                  *
3
 *   - original LCD control by Thomas "thkais" Kaiser                        *
4
 *   - special number formating routines taken from C-OSD                    *
5
 *      from Claas Anders "CaScAdE" Rathje                                   *
6
 *   - some extension, ellipse and circ_line by Peter "woggle" Mack          *
7
 *                                                                           *
8
 *   This program is free software; you can redistribute it and/or modify    *
9
 *   it under the terms of the GNU General Public License as published by    *
10
 *   the Free Software Foundation; either version 2 of the License.          *
11
 *                                                                           *
12
 *   This program is distributed in the hope that it will be useful,         *
13
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
14
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
15
 *   GNU General Public License for more details.                            *
16
 *                                                                           *
17
 *   You should have received a copy of the GNU General Public License       *
18
 *   along with this program; if not, write to the                           *
19
 *   Free Software Foundation, Inc.,                                         *
20
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.               *
21
 *                                                                           *
22
 *****************************************************************************/
23
 
24
//############################################################################
25
//# HISTORY  lcd.c
26
//#
27
//# 10.11.2014 cebra
28
//# - fix: lcd_init() weiter Helligkeitseinstellungen korrigiert (OCR2A)
29
//#
30
//# 28.06.2014 OG
31
//# - chg: lcdx_cls_rowwidth() kompatibel zu mode MINVERSX und MNORMALX
32
//# - chg: lcdx_cls_row() auf lcdx_cls_rowwidth() umgestellt
33
//# - fix: lcdx_printp() umgestellt auf strlen_P() statt strlen()
34
//#
35
//# 27.06.2014 OG
36
//# - add: die lcd-print Funktionen wurden um MINVERSX und MNORMALX erweitert
37
//#        um einen zusaetzlichen Rand links und oben als Linie zu zeichnen
38
//#        (wird z.B. in followme.c verwendet)
39
//#
40
//# 11.06.2014 OG
41
//# - add: lcd_set_contrast()
42
//# - add: include <avr/interrupt.h>
43
//#
44
//# 04.06.2014 OG
45
//# - add: lcdx_cls_rowwidth()
46
//#
47
//# 26.05.2014 OG
48
//# - chg: LCD_Init() - LCD-Modus nur noch normal (kein Invers mehr)
49
//#
50
//# 02.05.2014 OG
51
//# - add: Popup_Draw() (ehemals in osd.c)
52
//#
53
//# 13.04.2014 OG
54
//# - add: lcd_print_LF()
55
//#
56
//# 11.04.2014 OG
57
//# - add: lcdx_cls_row()
58
//#
59
//# 10.04.2014 OG
60
//# - add: include: lipo.h
61
//#
62
//# 08.04.2014 OG
63
//# - add: lcdx_printf_center(), lcdx_printf_center_P()
64
//#
65
//# 07.04.2014 OG
66
//# - add: lcd_setpos(), lcd_print_char()
67
//#
68
//# 04.04.2014 OG
69
//# - add: ShowTitle_P()
70
//#
71
//# 28.02.2014 OG
72
//# - del: show_baudrate()
73
//# - chg: PRINTF_BUFFER_SIZE von 80 auf 40
74
//#
75
//# 16.02.2014 OG
76
//# - add: lcdx_printp_center(), lcdx_print_center()
77
//#
78
//# 13.02.2014 OG
79
//# - add: lcd_frect_round()
80
//# - chg: lcd_rect_round() um R2 ergaenzt
81
//#
82
//# 12.02.2014 OG
83
//# - add: lcd_rect_round()
84
//#
85
//# 04.02.2014 OG
86
//# - fix: writex_ndigit_number_u_100th() Aufbau der Formatmaske
87
//#
88
//# 03.02.2014 OG
89
//# - fix: writex_ndigit_number_u_100th() Berechnung Formatstring korrigiert
90
//# - fix: writex_ndigit_number_u_100th() Parameter 'mode' fehlte
91
//#
92
//# 16.06.2013 OG
93
//# - chg: LCD_ORIENTATION festgesetzt auf 0 (Normal)
94
//#
95
//# 04.05.2013 OG
96
//# - chg: angepasst auf xutils.c
97
//# - chg: writex_datetime_time(), writex_datetime_date() Lokalzeitberechnung
98
//#        via UTCdatetime2local()
99
//#
100
//# 03.05.2013 OG
101
//# - fix: writex_gpspos() - Anzeige negativer GPS-Koordinaten
102
//# - fix: Anzeigefehler writex_datetime_time()
103
//# - chg: writex_datetime_date() & writex_datetime_time() Parameter
104
//#        'timeoffset' entfernt da das durch PKT-Config geregelt werden soll
105
//#
106
//# 29.04.2013 OG
107
//# - chg: lcd_cls() geaendert auf memset
108
//#
109
//# 28.04.2013 OG
110
//# - chg: high-level Funktionen wie writex_ndigit... auf xprintf umgebaut
111
//# - add: lcdx_printf_at(), lcdx_printf_at_P()
112
//#        lcd_printf_at(), lcd_printf_at_P()
113
//#        siehe dazu: Doku in utils/xstring.h fuer xprintf
114
//#
115
//# 27.03.2013 OG
116
//# - add: writex_datetime_time()
117
//# - add: writex_datetime_date()
118
//# - add: Show_PKTError_NoRAM()
119
//#
120
//# 22.03.2013 OG
121
//# - add: writex_gpspos()
122
//#
123
//# 11.03.2013 OG
124
//# - fix: writex_time() Ausgabe Doppelpunkt ":" ergaenzt um mode,xoffs,yoffs
125
//#
126
//# 07.03.2013 OG
127
//# - del: Kompatibilitaetsfunktion lcd_printpj_at() entfernt
128
//#
129
//# 06.03.2013 OG
130
//# - lcdx_putc() wurde erweitert mit Unterstuetzung des 8x8 Font (alte Jeti
131
//#   Funktionen) und Pixel-Verschiebung (xoffs,yoffs)
132
//# - etliche Char basierte Funktionen wurden erweitert um Parameter xoffs,yoffs
133
//#   um die Ausgabe um +/- Pixel zu verschieben. Fuer Pixelgenaue Positionierung
134
//#   von OSD-Screen Elementen.
135
//#   Die neuen Funktionen mit Pixel-Verschiebung beginnen mit lcdx_, writex_ ...
136
//# - add: Kompatibilitaet gewaehrleistet durch Mapper-Funktionen
137
//# - add: defines fuer Char-Drawmode's (MNORMAL, MINVERS, MBIG, MBIGINVERS)
138
//# - del: Jeti-Funktionen (teilweise ersetzt durch Kompatibilitaetsfunktionen)
139
//############################################################################
140
 
141
 
142
#include "../cpu.h"
143
#include <avr/io.h>
144
#include <avr/interrupt.h>
145
#include <avr/pgmspace.h>
146
#include <util/delay.h>
147
#include <stdlib.h>
148
#include <string.h>
149
#include <math.h>
150
#include <stdarg.h>
151
 
152
#include "../eeprom/eeprom.h"
153
#include "../timer/timer.h"
154
#include "lcd.h"
155
#include "../main.h"
156
#include "../HAL_HW3_9.h"
157
#include "../utils/xutils.h"            // xprintf, UTCdatetime2local
158
#include "../lipo/lipo.h"            // show_Lipo()
159
 
160
 
161
#include "font8x6.h"
162
#ifdef USE_FONT_BIG
163
  #include "Font8x8.h"
164
#endif
165
 
166
 
167
#define DISP_W 128
168
#define DISP_H 64
169
 
170
#define DISP_BUFFER ((DISP_H * DISP_W) / 8)
171
#define LINE_BUFFER (((DISP_H/8) * DISP_W) / 8)
172
 
173
#define Jeti 1  // Jeti Routinen
174
 
175
volatile uint8_t display_buffer[DISP_BUFFER];   // Display-Puffer, weil nicht zurückgelesen werden kann
176
volatile uint8_t line_buffer[LINE_BUFFER];      // Zeilen-Puffer, weil nicht zurückgelesen werden kann
177
 
178
volatile uint16_t display_buffer_pointer;       // Pointer auf das aktuell übertragene Byte
179
volatile uint8_t display_buffer_counter;        // Hilfszähler zur Selektierung der Page
180
volatile uint8_t display_page_counter;          // aktuelle Page-Nummer
181
volatile uint8_t display_mode;                  // Modus für State-Machine
182
volatile uint8_t LCD_ORIENTATION = 0;           // 0=Normal / 1=reversed
183
 
184
// DOG: 128 x 64 with 6x8 Font => 21 x 8
185
// MAX7456: 30 x 16
186
 
187
uint8_t lcd_xpos;
188
uint8_t lcd_ypos;
189
 
190
char s[7];
191
 
192
#define PRINTF_BUFFER_SIZE  40                  // max. 40 Chars fuer den Buffer fuer lcdx_printf_at() / lcdx_printf_at_P()
193
char printf_buffer[PRINTF_BUFFER_SIZE];
194
 
195
char format_buffer[20];
196
 
197
//-----------------------------------------------------------
198
void send_byte( uint8_t data )
199
{
200
    clr_cs ();
201
    SPDR = data;
202
    while (!(SPSR & (1<<SPIF)));
203
    //SPSR = SPSR;
204
    set_cs ();
205
}
206
 
207
 
208
//-----------------------------------------------------------
209
// * Writes one command byte
210
// * cmd           - the command byte
211
//
212
void lcd_command( uint8_t cmd )
213
{
214
//  LCD_SELECT();
215
//  LCD_CMD();
216
//  spi_write(cmd);
217
//  LCD_UNSELECT();
218
    clr_cs ();
219
    SPDR = cmd;
220
    while (!(SPSR & (1<<SPIF)));
221
    //SPSR = SPSR;
222
    set_cs ();
223
}
224
 
225
 
226
 
227
//-----------------------------------------------------------
228
//-----------------------------------------------------------
229
void lcd_set_contrast( uint8_t value )
230
{
231
    cli();
232
    clr_A0();
233
    send_byte( 0x81 );
234
    send_byte( value );      // Daten zum LCD senden
235
    set_A0();
236
    sei();
237
}
238
 
239
 
240
 
241
//-----------------------------------------------------------
242
void lcd_cls( void )
243
{
244
    uint16_t i, j;
245
 
246
    memset( (void *)display_buffer, 0, 1024);
247
 
248
//  for (i = 0; i < DISP_BUFFER; i++)
249
//      display_buffer[i] = 0x00;
250
 
251
    for (i = 0; i < 8; i++)
252
    {
253
        clr_A0 ();
254
        send_byte (0xB0 + i);           //1011xxxx
255
        send_byte (0x10);               //00010000
256
//      send_byte(0x04);                //00000100 gedreht plus 4 Byte
257
//      send_byte(0x00);                //00000000
258
        send_byte (LCD_ORIENTATION);    //00000000
259
 
260
        set_A0 ();
261
        for (j = 0; j < 128; j++)
262
            send_byte (0x00);
263
    }
264
 
265
    lcd_xpos = 0;
266
    lcd_ypos = 0;
267
}
268
 
269
 
270
//-----------------------------------------------------------
271
void set_adress (uint16_t adress, uint8_t data)
272
{
273
    uint8_t page;
274
    uint8_t column;
275
 
276
    page = adress >> 7;
277
 
278
    clr_A0 ();
279
    send_byte (0xB0 + page);
280
 
281
    column = (adress & 0x7F) + LCD_ORIENTATION;
282
 
283
    send_byte (0x10 + (column >> 4));
284
    send_byte (column & 0x0F);
285
 
286
    set_A0 ();
287
    send_byte (data);
288
}
289
 
290
 
291
//-----------------------------------------------------------
292
void scroll (void)
293
{
294
    uint16_t adress;
295
 
296
    for (adress = 0; adress < 896; adress++)
297
    {
298
        display_buffer[adress] = display_buffer[adress + 128];
299
        set_adress (adress, display_buffer[adress]);
300
    }
301
 
302
    for (adress = 896; adress < 1024; adress++)
303
    {
304
        display_buffer[adress] = 0;
305
        set_adress (adress, 0);
306
    }
307
}
308
 
309
//####################################################################################
310
//####################################################################################
311
 
312
//-----------------------------------------------------------
313
// + Plot (set one Pixel)
314
//-----------------------------------------------------------
315
// mode:
316
// 0=Clear, 1=Set, 2=XOR
317
void lcd_plot (uint8_t xpos, uint8_t ypos, uint8_t mode)
318
{
319
    uint16_t adress;
320
    uint8_t mask;
321
 
322
    if ((xpos < DISP_W) && (ypos < DISP_H))
323
    {
324
        adress = (ypos / 8) * DISP_W + xpos;        // adress = 0/8 * 128 + 0   = 0
325
        mask = 1 << (ypos & 0x07);                  // mask = 1<<0 = 1
326
        adress &= DISP_BUFFER - 1;
327
        switch (mode)
328
        {
329
 
330
        case 0:
331
            display_buffer[adress] &= ~mask;
332
            break;
333
 
334
        case 1:
335
            display_buffer[adress] |= mask;
336
            break;
337
 
338
        case 2:
339
            display_buffer[adress] ^= mask;
340
            break;
341
        }
342
        set_adress (adress, display_buffer[adress]);
343
    }
344
}
345
 
346
 
347
 
348
//-----------------------------------------------------------
349
//-----------------------------------------------------------
350
void lcdx_putc( uint8_t x, uint8_t y, uint8_t c, uint8_t mode, int8_t xoffs, int8_t yoffs )
351
{
352
    uint8_t ch;
353
    uint16_t adress;
354
 
355
    uint8_t x1,y1;
356
    uint8_t x0,y0;
357
    uint8_t xw;
358
    uint8_t mask;
359
    uint8_t bit;
360
 
361
    uint8_t *font;
362
 
363
    //------------------------
364
    // char translate
365
    //------------------------
366
    switch (c)
367
    {   // ISO 8859-1
368
 
369
        case 0xc4: c = 0x01; break;     // Ä
370
        case 0xe4: c = 0x02; break;     // ä
371
        case 0xd6: c = 0x03; break;     // Ö
372
        case 0xf6: c = 0x04; break;     // ö
373
        case 0xdc: c = 0x05; break;     // Ãœ
374
        case 0xfc: c = 0x06; break;     // ü
375
        case 0xdf: c = 0x1e; break;     // ß   c = 0x07;  Â° (used by Jeti)
376
    }
377
 
378
    c &= 0x7f;
379
 
380
    //------------------------
381
    // Font Parameter setzen
382
    //------------------------
383
    #ifdef USE_FONT_BIG
384
    if( mode <=2 )      // normaler font (8x6)
385
    {
386
        font = (uint8_t *) &font8x6[0][0];
387
        xw   = 6;
388
    }
389
    else                // grosser font (8x8)
390
    {
391
        font = (uint8_t *) &Font8x8[0][0];
392
        xw   = 8;
393
    }
394
    #else
395
    font = (uint8_t *) &font8x6[0][0];
396
    xw   = 6;
397
    #endif
398
 
399
 
400
    //------------------------
401
    //------------------------
402
    x0 = (x*xw) + xoffs;
403
    y0 = (y*8)  + yoffs;
404
 
405
 
406
    if( yoffs == 0)
407
    {
408
        //----------------------------------------------------------
409
        // orginaler Character Algo
410
        //
411
        // funktioniert auch mit x Verschiebung aber nicht
412
        // mit y Verschiebung.
413
        //
414
        // Da 8 Bit aufeinmal gesetzt werden ist dieser Algo
415
        // bzgl. Geschwindigkeit effektiver als der Y-Algo.
416
        //----------------------------------------------------------
417
 
418
        if( mode==MINVERS || mode==MBIGINVERS )
419
            lcd_frect( (x*xw)+xoffs, (y*8), xw-1, 7, 1); // invertierte Darstellung
420
 
421
        adress = y * 128 + x * xw + xoffs;
422
        adress &= 0x3FF;
423
 
424
        for( x1 = 0; x1 < xw; x1++)
425
        {
426
            ch = pgm_read_byte (font + x1 + c * xw);
427
 
428
            if( mode==MINVERS || mode==MBIGINVERS )
429
                display_buffer[adress + x1] ^= ch;
430
            else
431
                display_buffer[adress + x1] = ch;
432
 
433
            set_adress (adress + x1, display_buffer[adress + x1]);
434
        }
435
    }
436
    else
437
    {
438
        //----------------------------------------------------------
439
        // Y-Algo
440
        // neuer Character Algo (nur wenn Pixel y-Verschiebung)
441
        //----------------------------------------------------------
442
        for( x1 = 0; x1 < xw; x1++ )
443
        {
444
            ch = pgm_read_byte (font + x1 + c * xw);
445
 
446
            mask = 1;
447
 
448
            for( y1 = 0; y1 < 8; y1++ )
449
            {
450
                bit = (ch & mask);
451
 
452
                if( bit )
453
                    lcd_plot( x0+x1, y0+y1, ( (mode==MINVERS || mode==MBIGINVERS) ? 0 : 1) );
454
                else
455
                    lcd_plot( x0+x1, y0+y1, ( (mode==MINVERS || mode==MBIGINVERS) ? 1 : 0) );
456
 
457
                mask = (mask << 1);
458
            }
459
        }
460
    }
461
}
462
 
463
 
464
//-----------------------------------------------------------
465
//--- Kompatibilitaet
466
//-----------------------------------------------------------
467
void lcd_putc( uint8_t x, uint8_t y, uint8_t c, uint8_t mode )
468
{
469
    lcdx_putc( x, y, c, mode, 0,0 );
470
}
471
 
472
 
473
 
474
//####################################################################################
475
//####################################################################################
476
 
477
 
478
//-----------------------------------------------------------
479
void lcd_cls_line (uint8_t x, uint8_t y, uint8_t w)
480
{
481
    uint8_t lcd_width;
482
    uint8_t lcd_zpos;
483
    uint8_t i;
484
    uint8_t max = 21;
485
    lcd_width = w;
486
    lcd_xpos = x;
487
    lcd_ypos = y;
488
 
489
    if ((lcd_xpos + lcd_width) > max)
490
        lcd_width = max - lcd_xpos;
491
 
492
    lcd_zpos = lcd_xpos + lcd_width;
493
 
494
    for (i = lcd_xpos; i < lcd_zpos; i++)
495
        lcd_putc (i, lcd_ypos, 0x20, 0);
496
}
497
 
498
 
499
//-----------------------------------------------------------
500
void wait_1ms (void)
501
{
502
    _delay_ms (1);
503
}
504
 
505
 
506
//-----------------------------------------------------------
507
void wait_ms (uint16_t time)
508
{
509
    uint16_t i;
510
 
511
    for (i = 0; i < time; i++)
512
        wait_1ms ();
513
}
514
 
515
 
516
//-----------------------------------------------------------
517
void LCD_Init( uint8_t LCD_Mode )    // LCD_Mode 0= Default Mode 1= EEPROM-Parameter)
518
{
519
    lcd_xpos = 0;
520
    lcd_ypos = 0;
521
 
522
//  DDRB = 0xFF;
523
 
524
    // SPI max. speed
525
    // the DOGM128 lcd controller can work at 20 MHz
526
    SPCR = (1 << SPE) | (1 << MSTR) | (1 << CPHA) | (1 << CPOL);
527
    SPSR = (1 << SPI2X);
528
 
529
    set_cs();
530
    clr_reset();
531
    wait_ms(10);
532
    set_reset();
533
 
534
    clr_cs();
535
    clr_A0();
536
 
537
    send_byte( 0x40 );       //Display start line = 0
538
 
539
 
540
    //------------------------------------------------------------
541
    // 10.11.2014 cebra
542
    // Umschaltung der Displayansicht wird nicht mehr benötigt
543
    //    if (LCD_Mode == 1)
544
    //    {
545
    //        if (LCD_ORIENTATION == 0)
546
    //        {
547
    //            send_byte( 0xA1 ); // A1 normal A0 reverse(original)
548
    //            send_byte( 0xC0 ); // C0 normal C8 reverse(original)
549
    //        }
550
    //        else
551
    //        {
552
    //            send_byte( 0xA0 ); // A1 normal A0 reverse(original)
553
    //            send_byte( 0xC8 ); // C0 normal C8 reverse(original)
554
    //        }
555
    //    }
556
    //    else
557
    //    {
558
        send_byte( 0xA1 ); // A1 normal A0 reverse(original)
559
        send_byte( 0xC0 ); // C0 normal C8 reverse(original)
560
    //    }
561
 
562
    /*
563
    //------------------------------------------------------------
564
    // 26.05.2014 OG: einstellen von Normal/Invers durch den User
565
    // nicht mehr unterstuetzt, da der Modus Invers beim PKT
566
    // auf verschiedenen Display's nicht gut aussieht.
567
    // Ab jetzt nur noch LC-Modus Normal.
568
    //------------------------------------------------------------
569
    if (LCD_Mode == 1)
570
    {
571
        if (Config.LCD_DisplayMode == 0)
572
            send_byte (0xA6);       //Display normal, not mirrored
573
        else
574
            send_byte (0xA7);       //Display reverse, not mirrored
575
    }
576
    else
577
        send_byte (0xA6);
578
    */
579
 
580
    send_byte( 0xA6 );       //Display normal, not mirrored
581
 
582
    send_byte( 0xA2 );       //Set bias 1/9 (Duty 1/65)
583
    send_byte( 0x2F );       //Booster, regulator and follower on
584
    send_byte( 0xF8 );       //Set internal booster to 4x
585
    send_byte( 0x00 );       //Set internal booster to 4x
586
    send_byte( 0x27 );       //resistor ratio set
587
 
588
    if( LCD_Mode == 1 )
589
    {
590
        send_byte( 0x81 );       //Electronic volume register set
591
        send_byte( Config.LCD_Kontrast );        //Electronic volume register set
592
    }
593
    else
594
    {
595
        send_byte( 0x81 );
596
        send_byte( 0x16 );
597
    }
598
 
599
    send_byte( 0xAC );       //Cursor
600
    send_byte( 0x00 );       //No Cursor
601
    send_byte( 0xAF );       //No indicator
602
 
603
 
604
 
605
    if( Config.HWSound == 0 )
606
    {
607
        if( LCD_Mode == 1 )
608
        {
609
            //------------------------------------------------------------
610
            //10.11.2014 cebra,
611
            //Helligkeitseinstellungen werden nicht mehr genutzt
612
            // Helligkeit setzen
613
            //            OCR2A = Config.LCD_Helligkeit * 2.55;
614
 
615
            //OCR2A = 255;
616
        }
617
        else
618
        {
619
         //   OCR2A = 255;
620
        }
621
    }
622
    lcd_cls();
623
}
624
 
625
 
626
 
627
 
628
//-----------------------------------------------------------
629
// sicher eine Zeile für die Statusanzeige
630
void copy_line (uint8_t y)
631
{
632
    uint8_t i;
633
    uint16_t adress;
634
 
635
    adress = y * 128 + 0 * 6;
636
    adress &= 0x3FF;
637
 
638
    for (i = 0; i < 6*21; i++)
639
    {
640
        line_buffer[i] = display_buffer[adress+i];
641
        set_adress (adress + i, display_buffer[adress + i]);
642
    }
643
}
644
 
645
 
646
//-----------------------------------------------------------
647
// holt gesicherte Zeile wieder zurück
648
void paste_line (uint8_t y)
649
{
650
    uint8_t i;
651
    uint16_t adress;
652
 
653
    adress = y * 128 + 0 * 6;
654
    adress &= 0x3FF;
655
 
656
    for (i = 0; i < 6*21; i++)
657
    {
658
        display_buffer[adress+i] =line_buffer[i];
659
        set_adress (adress + i, display_buffer[adress + i]);
660
    }
661
}
662
 
663
 
664
//-----------------------------------------------------------
665
//-----------------------------------------------------------
666
void lcdx_puts_at( uint8_t x, uint8_t y, const char *s, uint8_t mode, int8_t xoffs, int8_t yoffs)
667
{
668
    while (*s)
669
    {
670
        lcdx_putc(x, y, *s++, mode, xoffs,yoffs);
671
        x++;
672
    }
673
}/* lcd_puts */
674
 
675
 
676
//-----------------------------------------------------------
677
//-----------------------------------------------------------
678
void lcd_puts_at( uint8_t x, uint8_t y, const char *s, uint8_t mode )
679
{
680
  lcdx_puts_at( x, y, s, mode, 0,0 );
681
}
682
 
683
 
684
//-----------------------------------------------------------
685
void new_line (void)
686
{
687
    lcd_ypos++;
688
 
689
    if (lcd_ypos > 7)
690
    {
691
        scroll ();
692
        lcd_ypos = 7;
693
    }
694
}
695
 
696
 
697
//-----------------------------------------------------------
698
void lcd_printpns (const char *text, uint8_t mode)
699
{
700
    while (pgm_read_byte(text))
701
    {
702
        switch (pgm_read_byte(text))
703
        {
704
 
705
        case 0x0D:
706
            lcd_xpos = 0;
707
            break;
708
 
709
        case 0x0A:
710
            new_line();
711
            break;
712
 
713
        default:
714
            lcd_putc (lcd_xpos, lcd_ypos, pgm_read_byte(text), mode);
715
            lcd_xpos++;
716
            if (lcd_xpos > 21)
717
            {
718
                lcd_xpos = 0;
719
//              new_line ();
720
            }
721
            break;
722
        }
723
        text++;
724
    }
725
}
726
 
727
 
728
//-----------------------------------------------------------
729
void lcd_printpns_at (uint8_t x, uint8_t y, const char *text, uint8_t mode)
730
{
731
    lcd_xpos = x;
732
    lcd_ypos = y;
733
    lcd_printpns (text, mode);
734
}
735
 
736
 
737
 
738
//--------------------------------------------------------------
739
// INTERN
740
//
741
// erweitert bei mode MINVERSX und MNORMALX links und oben den
742
// Text um jeweils einen Pixel -> der Invers-Modus sieht besser aus
743
//--------------------------------------------------------------
744
uint8_t _lcdx_print_modeextend( uint8_t progmem, uint8_t x, uint8_t y, uint8_t textlen, uint8_t mode, int8_t xoffs, int8_t yoffs )
745
{
746
    uint8_t draw = 0;
747
 
748
    if( (mode == MNORMALX) || (mode == MINVERSX) )
749
    {
750
        if( mode == MNORMALX )  mode = MNORMAL;
751
        else                    mode = MINVERS;
752
 
753
        if( mode == MINVERS )
754
            draw = 1;
755
 
756
        if( (y*8)+yoffs-1 >= 0 )
757
            lcd_line( (x*6)+xoffs, (y*8)+yoffs-1, (x*6)+xoffs+(textlen*6)-1, (y*8)+yoffs-1, draw);  // horizontale Linie ueber dem Text
758
 
759
        if( (x*6)+xoffs-1 >= 0 )
760
            lcd_line( (x*6)+xoffs-1, (y*8)+yoffs-1, (x*6)+xoffs-1, (y*8)+yoffs+7, draw);            // vertikale Linie links neben dem Text
761
    }
762
 
763
    return mode;
764
}
765
 
766
 
767
 
768
//-----------------------------------------------------------
769
//-----------------------------------------------------------
770
void _lcdx_print_outchar( unsigned char c, uint8_t mode, int8_t xoffs, int8_t yoffs)
771
{
772
    switch( c )
773
    {
774
        case 0x0D:  lcd_xpos = 0;
775
                    break;
776
 
777
        case 0x0A:  new_line();
778
                    break;
779
 
780
        default:    lcdx_putc( lcd_xpos, lcd_ypos, c, mode, xoffs,yoffs );
781
                    lcd_xpos++;
782
                    if( lcd_xpos > 21 )
783
                    {
784
                        lcd_xpos = 0;
785
                        new_line();
786
                    }
787
                    break;
788
    }
789
}
790
 
791
 
792
 
793
//-----------------------------------------------------------
794
//-----------------------------------------------------------
795
void lcdx_print( uint8_t *text, uint8_t mode, int8_t xoffs, int8_t yoffs)
796
{
797
    mode = _lcdx_print_modeextend( false, lcd_xpos, lcd_ypos, strlen( (const char *)text), mode, xoffs, yoffs );    // RAM Modus
798
 
799
    while( *text )
800
    {
801
        _lcdx_print_outchar( *text, mode, xoffs,yoffs);
802
        text++;
803
    }
804
}
805
 
806
 
807
 
808
//-----------------------------------------------------------
809
//-----------------------------------------------------------
810
void lcdx_printp( const char *text, uint8_t mode, int8_t xoffs, int8_t yoffs)
811
{
812
    char c;
813
 
814
    mode = _lcdx_print_modeextend( true, lcd_xpos, lcd_ypos, strlen_P( (const char *)text), mode, xoffs, yoffs );   // PROGMEM Modus
815
 
816
    while( (c = pgm_read_byte(text)) )
817
    {
818
        _lcdx_print_outchar( c, mode, xoffs,yoffs);
819
        text++;
820
    }
821
}
822
 
823
 
824
 
825
 
826
 
827
 
828
/*
829
//-----------------------------------------------------------
830
//-----------------------------------------------------------
831
void lcdx_print( uint8_t *text, uint8_t mode, int8_t xoffs, int8_t yoffs)
832
{
833
    mode = _lcdx_print_invers_extend( false, lcd_xpos, lcd_ypos, strlen( (const char *)text), mode, xoffs, yoffs ); // RAM Modus
834
 
835
 
836
    while( *text )
837
    {
838
        switch( *text )
839
        {
840
            case 0x0D:  lcd_xpos = 0;
841
                        break;
842
 
843
            case 0x0A:  new_line();
844
                        break;
845
 
846
            default:    lcdx_putc (lcd_xpos, lcd_ypos, *text, mode, xoffs,yoffs);
847
                        lcd_xpos++;
848
                        if( lcd_xpos > 21 )
849
                        {
850
                            lcd_xpos = 0;
851
                            new_line();
852
                        }
853
                        break;
854
        }
855
        text++;
856
    }
857
}
858
 
859
 
860
 
861
//-----------------------------------------------------------
862
//-----------------------------------------------------------
863
void lcdx_printp( const char *text, uint8_t mode, int8_t xoffs, int8_t yoffs)
864
{
865
    mode = _lcdx_print_invers_extend( true, lcd_xpos, lcd_ypos, strlen( (const char *)text), mode, xoffs, yoffs );  // PROGMEM Modus
866
 
867
 
868
    while( pgm_read_byte(text) )
869
    {
870
        switch( pgm_read_byte(text) )
871
        {
872
            case 0x0D:  lcd_xpos = 0;
873
                        break;
874
 
875
            case 0x0A:  new_line();
876
                        break;
877
 
878
            default:    lcdx_putc (lcd_xpos, lcd_ypos, pgm_read_byte(text), mode, xoffs,yoffs);
879
                        lcd_xpos++;
880
                        if( lcd_xpos > 21 )
881
                        {
882
                            lcd_xpos = 0;
883
                            new_line();
884
                        }
885
                        break;
886
        }
887
        text++;
888
    }
889
}
890
*/
891
 
892
 
893
 
894
 
895
 
896
//-----------------------------------------------------------
897
//-----------------------------------------------------------
898
void lcd_printp (const char *text, uint8_t mode)
899
{
900
    lcdx_printp ( text, mode, 0,0);
901
}
902
 
903
 
904
//-----------------------------------------------------------
905
//-----------------------------------------------------------
906
void lcdx_printp_at (uint8_t x, uint8_t y, const char *text, uint8_t mode, int8_t xoffs, int8_t yoffs)
907
{
908
    lcd_xpos = x;
909
    lcd_ypos = y;
910
    lcdx_printp (text, mode, xoffs,yoffs);
911
}
912
 
913
 
914
 
915
 
916
//-----------------------------------------------------------
917
//-----------------------------------------------------------
918
void lcd_printp_at (uint8_t x, uint8_t y, const char *text, uint8_t mode)
919
{
920
    lcdx_printp_at ( x, y, text, mode, 0,0);
921
}
922
 
923
 
924
 
925
//-----------------------------------------------------------
926
//--- lcd_print: Kompatibilitaet
927
//-----------------------------------------------------------
928
void lcd_print (uint8_t *text, uint8_t mode )
929
{
930
    lcdx_print (text, mode, 0,0 );
931
}
932
 
933
 
934
//-----------------------------------------------------------
935
void lcdx_print_at (uint8_t x, uint8_t y, uint8_t *text, uint8_t mode, int8_t xoffs, int8_t yoffs)
936
{
937
    lcd_xpos = x;
938
    lcd_ypos = y;
939
    lcdx_print (text, mode, xoffs, yoffs);
940
}
941
 
942
 
943
 
944
//-----------------------------------------------------------
945
//-----------------------------------------------------------
946
void lcdx_print_center( uint8_t y, uint8_t *text, uint8_t mode, int8_t xoffs, int8_t yoffs)
947
{
948
    xoffs = xoffs + ((uint8_t)(64 - ( (strlen((const char *)text)*6) /2)));       // Pixelgenau zentrieren (fuer 6x8 font)
949
    lcdx_print_at( 0, y, text, mode,   xoffs,yoffs);
950
}
951
 
952
 
953
//-----------------------------------------------------------
954
//-----------------------------------------------------------
955
void lcdx_printp_center( uint8_t y, const char *text, uint8_t mode, int8_t xoffs, int8_t yoffs)
956
{
957
    xoffs = xoffs + ((uint8_t)(64 - ( (strlen_P(text)*6) /2)));       // Pixelgenau zentrieren (fuer 6x8 font)
958
    lcdx_printp_at( 0, y, text, mode,   xoffs,yoffs);
959
}
960
 
961
 
962
//-----------------------------------------------------------
963
// lcdx_printf_center( y, mode, xoffs,yoffs, format, ...)
964
//
965
// Ausgabe von n-Parametern via Formattierung
966
//   mit erweitertem xoffs,yoffs
967
//
968
// Die Ausgabe wird zentriert,
969
//
970
// Parameter:
971
//  y          : Position in Char y
972
//  mode       : MNORMAL, MINVERS, ...
973
//  xoffs,yoffs: Verschiebung in Pixel
974
//  format     : String aus PROGMEM (siehe: xprintf in utils/xstring.h)
975
//  ...        : Parameter fuer 'format'
976
//-----------------------------------------------------------
977
void lcdx_printf_center( uint8_t y, uint8_t mode, int8_t xoffs, int8_t yoffs, const char *format, ... )
978
{
979
    va_list ap;
980
 
981
    va_start( ap, format );
982
    _xvsnprintf( false, printf_buffer, PRINTF_BUFFER_SIZE, format, ap );
983
    va_end(ap);
984
    lcdx_print_center( y,  (unsigned char *)printf_buffer, mode, xoffs, yoffs);
985
}
986
 
987
 
988
 
989
//-----------------------------------------------------------
990
// lcdx_printf_center_P( y, mode, xoffs,yoffs, format, ...)
991
//
992
// Ausgabe von n-Parametern via Formattierung
993
//   mit erweitertem xoffs,yoffs (PROGMEN-Version)
994
//
995
// Die Ausgabe wird zentriert,
996
//
997
// Parameter:
998
//  y          : Position in Char y
999
//  mode       : MNORMAL, MINVERS, ...
1000
//  xoffs,yoffs: Verschiebung in Pixel
1001
//  format     : String aus PROGMEM (siehe: xprintf in utils/xstring.h)
1002
//  ...        : Parameter fuer 'format'
1003
//-----------------------------------------------------------
1004
void lcdx_printf_center_P( uint8_t y, uint8_t mode, int8_t xoffs, int8_t yoffs, const char *format, ... )
1005
{
1006
    va_list ap;
1007
 
1008
    va_start( ap, format );
1009
    _xvsnprintf( true, printf_buffer, PRINTF_BUFFER_SIZE, format, ap );
1010
    va_end(ap);
1011
    lcdx_print_center( y,  (unsigned char *)printf_buffer, mode, xoffs, yoffs);
1012
}
1013
 
1014
 
1015
 
1016
//-----------------------------------------------------------
1017
//--- lcd_print_at: Kompatibilitaet
1018
//-----------------------------------------------------------
1019
void lcd_print_at (uint8_t x, uint8_t y, uint8_t *text, uint8_t mode )
1020
{
1021
    lcdx_print_at ( x, y, text, mode, 0,0);
1022
}
1023
 
1024
 
1025
//-----------------------------------------------------------
1026
void print_display (uint8_t *text)
1027
{
1028
    while (*text)
1029
    {
1030
        lcd_putc (lcd_xpos, lcd_ypos, *text, 0);
1031
        lcd_xpos++;
1032
        if (lcd_xpos >= 20)
1033
        {
1034
            lcd_xpos = 0;
1035
            new_line ();
1036
        }
1037
        text++;
1038
    }
1039
}
1040
 
1041
 
1042
//-----------------------------------------------------------
1043
void print_display_at (uint8_t x, uint8_t y, uint8_t *text)
1044
{
1045
    lcd_xpos = x;
1046
    lcd_ypos = y;
1047
    print_display (text);
1048
}
1049
 
1050
 
1051
//-----------------------------------------------------------
1052
// + Line (draws a line from x1,y1 to x2,y2
1053
// + Based on Bresenham line-Algorithm
1054
// + found in the internet, modified by thkais 2007
1055
//-----------------------------------------------------------
1056
 
1057
void lcd_line( unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, uint8_t mode)
1058
{
1059
    int x, y, count, xs, ys, xm, ym;
1060
 
1061
    x = (int) x1;
1062
    y = (int) y1;
1063
    xs = (int) x2 - (int) x1;
1064
    ys = (int) y2 - (int) y1;
1065
    if (xs < 0)
1066
        xm = -1;
1067
    else
1068
        if (xs > 0)
1069
            xm = 1;
1070
        else
1071
            xm = 0;
1072
    if (ys < 0)
1073
        ym = -1;
1074
    else
1075
        if (ys > 0)
1076
            ym = 1;
1077
        else
1078
            ym = 0;
1079
    if (xs < 0)
1080
        xs = -xs;
1081
 
1082
    if (ys < 0)
1083
        ys = -ys;
1084
 
1085
    lcd_plot ((unsigned char) x, (unsigned char) y, mode);
1086
 
1087
    if (xs > ys) // Flat Line <45 degrees
1088
    {
1089
        count = -(xs / 2);
1090
        while (x != x2)
1091
        {
1092
            count = count + ys;
1093
            x = x + xm;
1094
            if (count > 0)
1095
            {
1096
                y = y + ym;
1097
                count = count - xs;
1098
            }
1099
            lcd_plot ((unsigned char) x, (unsigned char) y, mode);
1100
        }
1101
    }
1102
    else // Line >=45 degrees
1103
    {
1104
        count =- (ys / 2);
1105
        while (y != y2)
1106
        {
1107
            count = count + xs;
1108
            y = y + ym;
1109
            if (count > 0)
1110
            {
1111
                x = x + xm;
1112
                count = count - ys;
1113
            }
1114
            lcd_plot ((unsigned char) x, (unsigned char) y, mode);
1115
        }
1116
    }
1117
}
1118
 
1119
 
1120
//-----------------------------------------------------------
1121
// + Filled rectangle
1122
// + x1, y1 = upper left corner
1123
//-----------------------------------------------------------
1124
void lcd_frect( uint8_t x1, uint8_t y1, uint8_t widthx, uint8_t widthy, uint8_t mode)
1125
{
1126
    uint16_t x2, y2;
1127
    uint16_t i;
1128
 
1129
    if (x1 >= DISP_W)
1130
        x1 = DISP_W - 1;
1131
 
1132
    if (y1 >= DISP_H)
1133
        y1 = DISP_H - 1;
1134
 
1135
    x2 = x1 + widthx;
1136
    y2 = y1 + widthy;
1137
 
1138
    if (x2 > DISP_W)
1139
        x2 = DISP_W;
1140
 
1141
    if (y2 > DISP_H)
1142
        y2 = DISP_H;
1143
 
1144
    for (i = y1; i <= y2; i++)
1145
    {
1146
        lcd_line (x1, i, x2, i, mode);
1147
    }
1148
}
1149
 
1150
 
1151
//-----------------------------------------------------------
1152
// ausgefuelltes Rechteck mit abgerundeten Ecken
1153
//
1154
// Hinweis:
1155
//  r (Radius) ist aktuell 'pseudo' und unterstuetzt
1156
//  nur R0 (=0), R1 (=1) oder R2 (=2=
1157
//-----------------------------------------------------------
1158
void lcd_frect_round( uint8_t x1, uint8_t y1, uint8_t widthx, uint8_t widthy, uint8_t mode, uint8_t r)
1159
{
1160
    lcd_frect( x1, y1, widthx, widthy, mode);
1161
 
1162
    switch(r)
1163
    {
1164
        case R0:    break;
1165
 
1166
        case R2:
1167
                    lcd_plot( x1+1       , y1         , !mode);     // Ecke links oben
1168
                    lcd_plot( x1         , y1+1       , !mode);
1169
 
1170
                    lcd_plot( x1+widthx-1, y1         , !mode);     // Ecke rechts oben
1171
                    lcd_plot( x1+widthx  , y1+1       , !mode);
1172
 
1173
                    lcd_plot( x1         , y1+widthy-1, !mode);     // Ecke links unten
1174
                    lcd_plot( x1+1       , y1+widthy  , !mode);
1175
 
1176
                    lcd_plot( x1+widthx-1, y1+widthy  , !mode);     // Ecke rechts unten
1177
                    lcd_plot( x1+widthx  , y1+widthy-1, !mode);
1178
 
1179
        case R1:
1180
                    lcd_plot( x1         , y1         , !mode);     // Ecke links oben
1181
                    lcd_plot( x1+widthx  , y1         , !mode);     // Ecke rechts oben
1182
                    lcd_plot( x1         , y1+widthy  , !mode);     // Ecke links unten
1183
                    lcd_plot( x1+widthx  , y1+widthy  , !mode);     // Ecke rechts unten
1184
    }
1185
}
1186
 
1187
 
1188
//-----------------------------------------------------------
1189
// + outline of rectangle
1190
// + x1, y1 = upper left corner
1191
//-----------------------------------------------------------
1192
void lcd_rect( uint8_t x1, uint8_t y1, uint8_t widthx, uint8_t widthy, uint8_t mode)
1193
{
1194
    uint16_t x2, y2;
1195
 
1196
    if (x1 >= DISP_W)
1197
        x1 = DISP_W - 1;
1198
    if (y1 >= DISP_H)
1199
        y1 = DISP_H - 1;
1200
    x2 = x1 + widthx;
1201
    y2 = y1 + widthy;
1202
 
1203
    if (x2 > DISP_W)
1204
        x2 = DISP_W;
1205
 
1206
    if (y2 > DISP_H)
1207
        y2 = DISP_H;
1208
 
1209
    lcd_line (x1, y1, x2, y1, mode);
1210
    lcd_line (x2, y1, x2, y2, mode);
1211
    lcd_line (x2, y2, x1, y2, mode);
1212
    lcd_line (x1, y2, x1, y1, mode);
1213
}
1214
 
1215
 
1216
//-----------------------------------------------------------
1217
// Rechteck mit mit abgerundeten Ecken
1218
//
1219
// Hinweis:
1220
//  r (Radius) ist aktuell 'pseudo' und unterstuetzt
1221
//  nur R0 (=0), R1 (=1) oder R2 (=2=
1222
//-----------------------------------------------------------
1223
void lcd_rect_round( uint8_t x1, uint8_t y1, uint8_t widthx, uint8_t widthy, uint8_t mode, uint8_t r)
1224
{
1225
    lcd_rect( x1, y1, widthx, widthy, mode);
1226
 
1227
    switch(r)
1228
    {
1229
        case R0:    break;
1230
 
1231
        case R2:
1232
                    lcd_plot( x1+1       , y1         , !mode);     // Ecke links oben
1233
                    lcd_plot( x1         , y1+1       , !mode);
1234
                    lcd_plot( x1+1       , y1+1       ,  mode);
1235
 
1236
                    lcd_plot( x1+widthx-1, y1         , !mode);     // Ecke rechts oben
1237
                    lcd_plot( x1+widthx  , y1+1       , !mode);
1238
                    lcd_plot( x1+widthx-1, y1+1       ,  mode);
1239
 
1240
                    lcd_plot( x1         , y1+widthy-1, !mode);     // Ecke links unten
1241
                    lcd_plot( x1+1       , y1+widthy  , !mode);
1242
                    lcd_plot( x1+1       , y1+widthy-1,  mode);
1243
 
1244
                    lcd_plot( x1+widthx-1, y1+widthy  , !mode);     // Ecke rechts unten
1245
                    lcd_plot( x1+widthx  , y1+widthy-1, !mode);
1246
                    lcd_plot( x1+widthx-1, y1+widthy-1,  mode);
1247
 
1248
        case R1:
1249
                    lcd_plot( x1         , y1         , !mode);     // Ecke links oben
1250
                    lcd_plot( x1+widthx  , y1         , !mode);     // Ecke rechts oben
1251
                    lcd_plot( x1         , y1+widthy  , !mode);     // Ecke links unten
1252
                    lcd_plot( x1+widthx  , y1+widthy  , !mode);     // Ecke rechts unten
1253
    }
1254
}
1255
 
1256
 
1257
//-----------------------------------------------------------
1258
// + outline of a circle
1259
// + Based on Bresenham-algorithm found in wikipedia
1260
// + modified by thkais (2007)
1261
//-----------------------------------------------------------
1262
void lcd_circle (int16_t x0, int16_t y0, int16_t radius, uint8_t mode)
1263
{
1264
    int16_t f = 1 - radius;
1265
    int16_t ddF_x = 0;
1266
    int16_t ddF_y = -2 * radius;
1267
    int16_t x = 0;
1268
    int16_t y = radius;
1269
 
1270
    lcd_plot (x0, y0 + radius, mode);
1271
    lcd_plot (x0, y0 - radius, mode);
1272
    lcd_plot (x0 + radius, y0, mode);
1273
    lcd_plot (x0 - radius, y0, mode);
1274
 
1275
    while (x < y)
1276
    {
1277
        if (f >= 0)
1278
        {
1279
            y --;
1280
            ddF_y += 2;
1281
            f += ddF_y;
1282
        }
1283
        x ++;
1284
        ddF_x += 2;
1285
        f += ddF_x + 1;
1286
 
1287
        lcd_plot (x0 + x, y0 + y, mode);
1288
        lcd_plot (x0 - x, y0 + y, mode);
1289
 
1290
        lcd_plot (x0 + x, y0 - y, mode);
1291
        lcd_plot (x0 - x, y0 - y, mode);
1292
 
1293
        lcd_plot (x0 + y, y0 + x, mode);
1294
        lcd_plot (x0 - y, y0 + x, mode);
1295
 
1296
        lcd_plot (x0 + y, y0 - x, mode);
1297
        lcd_plot (x0 - y, y0 - x, mode);
1298
    }
1299
}
1300
 
1301
 
1302
//-----------------------------------------------------------
1303
// + filled Circle
1304
// + modified circle-algorithm thkais (2007)
1305
//-----------------------------------------------------------
1306
void lcd_fcircle (int16_t x0, int16_t y0, int16_t radius,uint8_t mode)
1307
{
1308
    int16_t f = 1 - radius;
1309
    int16_t ddF_x = 0;
1310
    int16_t ddF_y = -2 * radius;
1311
    int16_t x = 0;
1312
    int16_t y = radius;
1313
 
1314
    lcd_line (x0, y0 + radius, x0, y0 - radius, mode);
1315
 
1316
    lcd_line (x0 + radius, y0, x0 - radius, y0, mode);
1317
 
1318
    while (x < y)
1319
    {
1320
        if (f >= 0)
1321
        {
1322
            y--;
1323
            ddF_y += 2;
1324
            f += ddF_y;
1325
        }
1326
        x++;
1327
        ddF_x += 2;
1328
        f += ddF_x + 1;
1329
 
1330
        lcd_line (x0 + x, y0 + y, x0 - x, y0 + y, mode);
1331
        lcd_line (x0 + x, y0 - y, x0 - x, y0 - y, mode);
1332
        lcd_line (x0 + y, y0 + x, x0 - y, y0 + x, mode);
1333
        lcd_line (x0 + y, y0 - x, x0 - y, y0 - x, mode);
1334
    }
1335
}
1336
 
1337
 
1338
//-----------------------------------------------------------
1339
//
1340
void lcd_circ_line (uint8_t x, uint8_t y, uint8_t r, uint16_t deg, uint8_t mode)
1341
{
1342
    uint8_t xc, yc;
1343
    double deg_rad;
1344
 
1345
    deg_rad = (deg * M_PI) / 180.0;
1346
 
1347
    yc = y - (uint8_t) round (cos (deg_rad) * (double) r);
1348
    xc = x + (uint8_t) round (sin (deg_rad) * (double) r);
1349
    lcd_line (x, y, xc, yc, mode);
1350
}
1351
 
1352
 
1353
//-----------------------------------------------------------
1354
//
1355
void lcd_ellipse_line (uint8_t x, uint8_t y, uint8_t rx, uint8_t ry, uint16_t deg, uint8_t mode)
1356
{
1357
    uint8_t xc, yc;
1358
    double deg_rad;
1359
 
1360
    deg_rad = (deg * M_PI) / 180.0;
1361
 
1362
    yc = y - (uint8_t) round (cos (deg_rad) * (double) ry);
1363
    xc = x + (uint8_t) round (sin (deg_rad) * (double) rx);
1364
    lcd_line (x, y, xc, yc, mode);
1365
}
1366
 
1367
 
1368
//-----------------------------------------------------------
1369
//
1370
void lcd_ellipse (int16_t x0, int16_t y0, int16_t rx, int16_t ry, uint8_t mode)
1371
{
1372
    const int16_t rx2 = rx * rx;
1373
    const int16_t ry2 = ry * ry;
1374
    int16_t F = round (ry2 - rx2 * ry + 0.25 * rx2);
1375
    int16_t ddF_x = 0;
1376
    int16_t ddF_y = 2 * rx2 * ry;
1377
    int16_t x = 0;
1378
    int16_t y = ry;
1379
 
1380
    lcd_plot (x0, y0 + ry, mode);
1381
    lcd_plot (x0, y0 - ry, mode);
1382
    lcd_plot (x0 + rx, y0, mode);
1383
    lcd_plot (x0 - rx, y0, mode);
1384
    // while ( 2*ry2*x < 2*rx2*y ) {  we can use ddF_x and ddF_y
1385
    while (ddF_x < ddF_y)
1386
    {
1387
        if(F >= 0)
1388
        {
1389
            y     -= 1;     // south
1390
            ddF_y -= 2 * rx2;
1391
            F     -= ddF_y;
1392
        }
1393
        x     += 1;         // east
1394
        ddF_x += 2 * ry2;
1395
        F     += ddF_x + ry2;
1396
        lcd_plot (x0 + x, y0 + y, mode);
1397
        lcd_plot (x0 + x, y0 - y, mode);
1398
        lcd_plot (x0 - x, y0 + y, mode);
1399
        lcd_plot (x0 - x, y0 - y, mode);
1400
    }
1401
    F = round (ry2 * (x + 0.5) * (x + 0.5) + rx2 * (y - 1) * (y - 1) - rx2 * ry2);
1402
    while(y > 0)
1403
    {
1404
        if(F <= 0)
1405
        {
1406
            x     += 1;     // east
1407
            ddF_x += 2 * ry2;
1408
            F     += ddF_x;
1409
        }
1410
        y     -= 1;         // south
1411
        ddF_y -= 2 * rx2;
1412
        F     += rx2 - ddF_y;
1413
        lcd_plot (x0 + x, y0 + y, mode);
1414
        lcd_plot (x0 + x, y0 - y, mode);
1415
        lcd_plot (x0 - x, y0 + y, mode);
1416
        lcd_plot (x0 - x, y0 - y, mode);
1417
    }
1418
}
1419
 
1420
 
1421
//-----------------------------------------------------------
1422
//
1423
void lcd_ecircle (int16_t x0, int16_t y0, int16_t radius, uint8_t mode)
1424
{
1425
    lcd_ellipse (x0, y0, radius + 3, radius, mode);
1426
}
1427
 
1428
 
1429
//-----------------------------------------------------------
1430
//
1431
void lcd_ecirc_line (uint8_t x, uint8_t y, uint8_t r, uint16_t deg, uint8_t mode)
1432
{
1433
    lcd_ellipse_line(x, y, r + 3, r, deg, mode);
1434
}
1435
 
1436
 
1437
//-----------------------------------------------------------
1438
//
1439
void lcd_view_font (uint8_t page)
1440
{
1441
    int x;
1442
    int y;
1443
 
1444
    lcd_cls ();
1445
    lcd_printp (PSTR("  0123456789ABCDEF\r\n"), 0);
1446
    lcd_printpns_at (0, 7, PSTR(" \x1a    \x1b     Exit"), 0);
1447
 
1448
    lcd_ypos = 2;
1449
    for (y = page * 4 ; y < (page * 4 + 4); y++)
1450
    {
1451
        if (y < 10)
1452
        {
1453
            lcd_putc (0, lcd_ypos, '0' + y, 0);
1454
        }
1455
        else
1456
        {
1457
            lcd_putc (0, lcd_ypos, 'A' + y - 10, 0);
1458
        }
1459
        lcd_xpos = 2;
1460
        for (x = 0; x < 16; x++)
1461
        {
1462
            lcd_putc (lcd_xpos, lcd_ypos, y * 16 + x, 0);
1463
            lcd_xpos++;
1464
        }
1465
        lcd_ypos++;
1466
    }
1467
}
1468
 
1469
 
1470
//-----------------------------------------------------------
1471
uint8_t hdigit (uint8_t d)
1472
{
1473
    if (d < 10)
1474
    {
1475
        return '0' + d;
1476
    }
1477
    else
1478
    {
1479
        return 'A' + d - 10;
1480
    }
1481
}
1482
 
1483
 
1484
//-----------------------------------------------------------
1485
void lcd_print_hex_at (uint8_t x, uint8_t y, uint8_t h, uint8_t mode)
1486
{
1487
    lcd_xpos = x;
1488
    lcd_ypos = y;
1489
 
1490
    lcd_putc (lcd_xpos++, lcd_ypos, hdigit (h >> 4), mode);
1491
    lcd_putc (lcd_xpos, lcd_ypos, hdigit (h & 0x0f), mode);
1492
}
1493
 
1494
 
1495
//-----------------------------------------------------------
1496
void lcd_print_hex (uint8_t h, uint8_t mode)
1497
{
1498
//  lcd_xpos = x;
1499
//  lcd_ypos = y;
1500
 
1501
    lcd_putc (lcd_xpos++, lcd_ypos, hdigit (h >> 4), mode);
1502
    lcd_putc (lcd_xpos++, lcd_ypos, hdigit (h & 0x0f), mode);
1503
    lcd_putc (lcd_xpos++, lcd_ypos, ' ', mode);
1504
}
1505
 
1506
//##################################################################################################################################
1507
//##################################################################################################################################
1508
 
1509
//-----------------------------------------------------------
1510
// lcdx_printf_at( x,y, mode, xoffs,yoffs, format, ...)
1511
//
1512
// Ausgabe von n-Parametern via Formattierung
1513
//   mit erweitertem xoffs,yoffs (RAM-Version)
1514
//
1515
// Parameter:
1516
//  x,y        : Position in Char x,y
1517
//  mode       : MNORMAL, MINVERS, ...
1518
//  xoffs,yoffs: Verschiebung in Pixel
1519
//  format     : String aus RAM (siehe: xprintf in utils/xstring.h)
1520
//  ...        : Parameter fuer 'format'
1521
//-----------------------------------------------------------
1522
void lcdx_printf_at( uint8_t x, uint8_t y, uint8_t mode, int8_t xoffs, int8_t yoffs, const char *format, ... )
1523
{
1524
    va_list ap;
1525
 
1526
    va_start( ap, format );
1527
    // _xvsnprintf( int useprogmem, char *buffer, size_t n, const char *format, va_list ap )
1528
    _xvsnprintf( false, printf_buffer, PRINTF_BUFFER_SIZE, format, ap );
1529
    va_end(ap);
1530
    lcdx_print_at( x, y, (unsigned char *)printf_buffer, mode, xoffs, yoffs);
1531
}
1532
 
1533
 
1534
//-----------------------------------------------------------
1535
// lcdx_printf_at_P( x,y, mode, xoffs,yoffs, format, ...)
1536
//
1537
// Ausgabe von n-Parametern via Formattierung
1538
//   mit erweitertem xoffs,yoffs (PROGMEN-Version)
1539
//
1540
// Parameter:
1541
//  x,y        : Position in Char x,y
1542
//  mode       : MNORMAL, MINVERS, ...
1543
//  xoffs,yoffs: Verschiebung in Pixel
1544
//  format     : String aus PROGMEM (siehe: xprintf in utils/xstring.h)
1545
//  ...        : Parameter fuer 'format'
1546
//-----------------------------------------------------------
1547
void lcdx_printf_at_P( uint8_t x, uint8_t y, uint8_t mode, int8_t xoffs, int8_t yoffs, const char *format, ... )
1548
{
1549
    va_list ap;
1550
 
1551
    va_start( ap, format );
1552
    _xvsnprintf( true, printf_buffer, PRINTF_BUFFER_SIZE, format, ap );
1553
    va_end(ap);
1554
    lcdx_print_at( x, y, (unsigned char *)printf_buffer, mode, xoffs, yoffs);
1555
}
1556
 
1557
 
1558
//-----------------------------------------------------------
1559
// lcdx_printf_at( x,y, mode, xoffs,yoffs, format, ...)
1560
//
1561
// Ausgabe von n-Parametern via Formattierung (RAM-Version)
1562
//
1563
// Parameter:
1564
//  x,y        : Position in Char x,y
1565
//  mode       : MNORMAL, MINVERS, ...
1566
//  format     : String aus RAM (siehe: xprintf in utils/xstring.h)
1567
//  ...        : Parameter fuer 'format'
1568
//-----------------------------------------------------------
1569
void lcd_printf_at( uint8_t x, uint8_t y, uint8_t mode, const char *format, ... )
1570
{
1571
    va_list ap;
1572
 
1573
    va_start( ap, format );
1574
    // _xvsnprintf( int useprogmem, char *buffer, size_t n, const char *format, va_list ap )
1575
    _xvsnprintf( false, printf_buffer, PRINTF_BUFFER_SIZE, format, ap );
1576
    va_end(ap);
1577
    lcdx_print_at( x, y, (unsigned char *)printf_buffer, mode, 0,0);
1578
}
1579
 
1580
 
1581
//-----------------------------------------------------------
1582
// lcd_printf_at_P( x,y, mode, xoffs,yoffs, format, ...)
1583
//
1584
// Ausgabe von n-Parametern via Formattierung (PROGMEN-Version)
1585
//
1586
// Parameter:
1587
//  x,y        : Position in Char x,y
1588
//  mode       : MNORMAL, MINVERS, ...
1589
//  format     : String aus PROGMEM (siehe: xprintf in utils/xstring.h)
1590
//  ...        : Parameter fuer 'format'
1591
//-----------------------------------------------------------
1592
void lcd_printf_at_P( uint8_t x, uint8_t y, uint8_t mode, const char *format, ... )
1593
{
1594
    va_list ap;
1595
 
1596
    va_start( ap, format );
1597
    _xvsnprintf( true, printf_buffer, PRINTF_BUFFER_SIZE, format, ap );
1598
    va_end(ap);
1599
    lcdx_print_at( x, y, (unsigned char *)printf_buffer, mode, 0,0);
1600
}
1601
 
1602
 
1603
 
1604
//##################################################################################################################################
1605
//##################################################################################################################################
1606
 
1607
 
1608
//-----------------------------------------------------------
1609
void lcd_write_number_u (uint8_t number)
1610
{
1611
    uint8_t num = 100;
1612
    uint8_t started = 0;
1613
 
1614
    while (num > 0)
1615
    {
1616
        uint8_t b = number / num;
1617
        if (b > 0 || started || num == 1)
1618
        {
1619
            lcd_putc (lcd_xpos++, lcd_ypos, '0' + b, 0);
1620
            started = 1;
1621
        }
1622
        number -= b * num;
1623
 
1624
        num /= 10;
1625
    }
1626
}
1627
 
1628
 
1629
//-----------------------------------------------------------
1630
void lcd_write_number_u_at (uint8_t x, uint8_t y, uint8_t number)
1631
{
1632
    lcd_xpos = x;
1633
    lcd_ypos = y;
1634
    lcd_write_number_u (number);
1635
}
1636
 
1637
 
1638
//-----------------------------------------------------------
1639
// numtype: 'd' oder 'u'
1640
//
1641
// Ergebnis: ein String in format_buffer
1642
//  -> "%4d"  "%4.2d" "%03.1d"  "%4u"  usw...
1643
//-----------------------------------------------------------
1644
void make_number_format( char numtype, int16_t length, int16_t decimals, uint8_t pad )
1645
{
1646
    register char *p;
1647
    register char *psrc;
1648
 
1649
    p = format_buffer;
1650
    *p = '%';                       p++;                // start '%'
1651
    if(pad) { *p = '0';             p++; }              // pad '0'
1652
 
1653
    itoa( length, s, 10 );
1654
    psrc = s; while(*psrc)          *p++ = *psrc++;     // vorkomma
1655
 
1656
    if( decimals > 0 )
1657
    {
1658
        *p = '.';                   p++;                // punkt '.'
1659
        itoa( decimals, s, 10 );
1660
        psrc = s; while(*psrc)      *p++ = *psrc++;     // nachkomma
1661
    }
1662
 
1663
    *p = numtype;                   p++;                // 'd' oder 'u'
1664
    *p = 0;
1665
}
1666
 
1667
 
1668
//-----------------------------------------------------------
1669
// Write only some digits of a unsigned <number> at <x>/<y> to MAX7456 display memory
1670
// <num> represents the largest multiple of 10 that will still be displayable as
1671
// the first digit, so num = 10 will be 0-99 and so on
1672
// <pad> = 1 will cause blank spaced to be filled up with zeros e.g. 007 instead of   7
1673
//
1674
void writex_ndigit_number_u (uint8_t x, uint8_t y, uint16_t number, int16_t length, uint8_t pad, uint8_t mode, int8_t xoffs, int8_t yoffs)
1675
{
1676
    make_number_format( 'u', length, 0, pad );                          // ergebnis in: format_buffer
1677
    lcdx_printf_at( x, y, mode, xoffs, yoffs, format_buffer, number );
1678
}
1679
 
1680
 
1681
//-----------------------------------------------------------
1682
//-----------------------------------------------------------
1683
void write_ndigit_number_u (uint8_t x, uint8_t y, uint16_t number, int16_t length, uint8_t pad, uint8_t mode)
1684
{
1685
    writex_ndigit_number_u( x, y, number, length, pad, mode, 0,0);
1686
}
1687
 
1688
 
1689
//-----------------------------------------------------------
1690
// Write only some digits of a signed <number> at <x>/<y> to MAX7456 display memory
1691
// <num> represents the largest multiple of 10 that will still be displayable as
1692
// the first digit, so num = 10 will be 0-99 and so on
1693
// <pad> = 1 will cause blank spaced to be filled up with zeros e.g. 007 instead of   7
1694
//
1695
void writex_ndigit_number_s (uint8_t x, uint8_t y, int16_t number, int16_t length, uint8_t pad, uint8_t mode, int8_t xoffs, int8_t yoffs)
1696
{
1697
    make_number_format( 'd', length, 0, pad );                          // ergebnis in: format_buffer
1698
    lcdx_printf_at( x, y, mode, xoffs, yoffs, format_buffer, number );
1699
}
1700
 
1701
 
1702
//-----------------------------------------------------------
1703
//-----------------------------------------------------------
1704
void write_ndigit_number_s (uint8_t x, uint8_t y, int16_t number, int16_t length, uint8_t pad, uint8_t mode)
1705
{
1706
    writex_ndigit_number_s (x, y, number, length, pad, mode, 0,0);
1707
}
1708
 
1709
 
1710
//-----------------------------------------------------------
1711
// Write only some digits of a unsigned <number> at <x>/<y> to MAX7456 display memory
1712
// as /10th of the value
1713
// <num> represents the largest multiple of 10 that will still be displayable as
1714
// the first digit, so num = 10 will be 0-99 and so on
1715
// <pad> = 1 will cause blank spaced to be filled up with zeros e.g. 007 instead of   7
1716
//
1717
void writex_ndigit_number_u_10th( uint8_t x, uint8_t y, uint16_t number, int16_t length, uint8_t pad, uint8_t mode, int8_t xoffs, int8_t yoffs)
1718
{
1719
    make_number_format( 'u', length-1, 1, pad );                        // ergebnis in: format_buffer
1720
    lcdx_printf_at( x, y, mode, xoffs, yoffs, format_buffer, number );
1721
}
1722
 
1723
 
1724
//-----------------------------------------------------------
1725
//-----------------------------------------------------------
1726
void write_ndigit_number_u_10th( uint8_t x, uint8_t y, uint16_t number, int16_t length, uint8_t pad, uint8_t mode)
1727
{
1728
  writex_ndigit_number_u_10th( x, y, number, length, pad, mode, 0,0);
1729
}
1730
 
1731
 
1732
//-----------------------------------------------------------
1733
//-----------------------------------------------------------
1734
void writex_ndigit_number_u_100th( uint8_t x, uint8_t y, uint16_t number, int16_t length, uint8_t pad, uint8_t mode, int8_t xoffs, int8_t yoffs)
1735
{
1736
    make_number_format( 'u', length-2, 2, pad );                        // ergebnis in: format_buffer
1737
    lcdx_printf_at( x, y, mode, xoffs, yoffs, format_buffer, number );
1738
}
1739
 
1740
 
1741
//-----------------------------------------------------------
1742
//-----------------------------------------------------------
1743
void write_ndigit_number_u_100th( uint8_t x, uint8_t y, uint16_t number, int16_t length, uint8_t pad)
1744
{
1745
    writex_ndigit_number_u_100th( x, y, number, length, pad, MNORMAL, 0,0);
1746
}
1747
 
1748
 
1749
//-----------------------------------------------------------
1750
// Write only some digits of a signed <number> at <x>/<y> to MAX7456 display memory
1751
// as /10th of the value
1752
// <num> represents the largest multiple of 10 that will still be displayable as
1753
// the first digit, so num = 10 will be 0-99 and so on
1754
// <pad> = 1 will cause blank spaced to be filled up with zeros e.g. 007 instead of   7
1755
//
1756
void writex_ndigit_number_s_10th (uint8_t x, uint8_t y, int16_t number, int16_t length, uint8_t pad, uint8_t mode, int8_t xoffs, int8_t yoffs)
1757
{
1758
    make_number_format( 'd', length-1, 1, pad );                        // ergebnis in: format_buffer
1759
    lcdx_printf_at( x, y, mode, xoffs, yoffs, format_buffer, number );
1760
}
1761
 
1762
 
1763
//-----------------------------------------------------------
1764
//-----------------------------------------------------------
1765
void write_ndigit_number_s_10th (uint8_t x, uint8_t y, int16_t number, int16_t length, uint8_t pad, uint8_t mode)
1766
{
1767
    writex_ndigit_number_s_10th ( x,  y,  number,  length,  pad,  mode,  0,0);
1768
 
1769
}
1770
 
1771
 
1772
//-----------------------------------------------------------
1773
// write <seconds> as human readable time at <x>/<y> to MAX7456 display mem
1774
//
1775
void writex_time( uint8_t x, uint8_t y, uint16_t seconds, uint8_t mode, int8_t xoffs, int8_t yoffs)
1776
{
1777
    uint16_t min = seconds / 60;
1778
    seconds -= min * 60;
1779
 
1780
    lcdx_printf_at( x, y, mode, xoffs, yoffs, "%02u:%02u", min, seconds);
1781
    /*
1782
    writex_ndigit_number_u (x, y, min, 2, 0,mode, xoffs,yoffs);
1783
    lcdx_putc (x + 2, y, ':', mode, xoffs,yoffs);
1784
    writex_ndigit_number_u (x + 3, y, seconds, 2, 1,mode, xoffs,yoffs);
1785
    */
1786
}
1787
 
1788
 
1789
//-----------------------------------------------------------
1790
//-----------------------------------------------------------
1791
void write_time( uint8_t x, uint8_t y, uint16_t seconds)
1792
{
1793
    writex_time( x,  y,  seconds, 0, 0,0);
1794
}
1795
 
1796
 
1797
//--------------------------------------------------------------
1798
// writex_datetime_time()
1799
//
1800
// Anzeigeformat: 'hh:mm:ss'
1801
//
1802
// datetime  : vom Typ PKTdatetime_t
1803
//--------------------------------------------------------------
1804
void writex_datetime_time( uint8_t x, uint8_t y, PKTdatetime_t datetime, uint8_t mode, int8_t xoffs, int8_t yoffs)
1805
{
1806
    PKTdatetime_t dtlocal;
1807
 
1808
    UTCdatetime2local( &dtlocal, &datetime );
1809
    lcdx_printf_at( x, y, mode, xoffs, yoffs, "%02u:%02u:%02u", (uint8_t)(dtlocal.seconds/3600), (uint8_t)((dtlocal.seconds/60)%60), (uint8_t)(dtlocal.seconds%60));
1810
}
1811
 
1812
 
1813
//--------------------------------------------------------------
1814
// writex_datetime_date()
1815
//
1816
// Anzeigeformat: 'dd.mm.yyyy'  (keine Unterstuetzung von anderen Formaten aus aller Welt)
1817
//
1818
// datetime  : vom Typ PKTdatetime_t
1819
//--------------------------------------------------------------
1820
void writex_datetime_date( uint8_t x, uint8_t y, PKTdatetime_t datetime, uint8_t mode, int8_t xoffs, int8_t yoffs)
1821
{
1822
    PKTdatetime_t dtlocal;
1823
 
1824
    if( datetime.year > 0 )
1825
    {
1826
        UTCdatetime2local( &dtlocal, &datetime );
1827
        lcdx_printf_at( x, y, mode, xoffs, yoffs, "%02u.%02u.%04u", dtlocal.day, dtlocal.month, dtlocal.year);
1828
    }
1829
    else
1830
    {
1831
        // keine UTCZeit -> keine Datumsanzeige
1832
        lcdx_printp_at( x, y, PSTR("  .  .    "), mode, xoffs,yoffs);
1833
    }
1834
}
1835
 
1836
 
1837
//-----------------------------------------------------------
1838
// writes a single gps-pos
1839
//-----------------------------------------------------------
1840
void writex_gpspos( uint8_t x, uint8_t y, int32_t GPSpos, uint8_t mode, int8_t xoffs, int8_t yoffs )
1841
{
1842
    lcdx_printf_at( x, y, mode, xoffs, yoffs, "%3.5ld", GPSpos/100);
1843
}
1844
 
1845
 
1846
 
1847
//--------------------------------------------------------------
1848
//--------------------------------------------------------------
1849
void Show_PKTError_NoRAM(void)
1850
{
1851
    lcd_cls();
1852
    lcd_rect( 8, 8, 127-16, 6*8, 1);
1853
 
1854
    //                       123456789012345678901
1855
    lcd_printp_at( 2,2 , PSTR("** OUT OF RAM **"), MINVERS);
1856
    lcd_printp_at( 2,4 , PSTR("this function is"), MNORMAL);
1857
    lcd_printp_at( 2,5 , PSTR("not available!"), MNORMAL);
1858
 
1859
    while ( !( (get_key_press (1 << KEY_ENTER)) || (get_key_press (1 << KEY_ESC))  || (get_key_press (1 << KEY_PLUS))  || (get_key_press (1 << KEY_MINUS))  ) );
1860
}
1861
 
1862
 
1863
 
1864
//--------------------------------------------------------------
1865
//--------------------------------------------------------------
1866
void ShowTitle_P( const char *title, uint8_t clearscreen )
1867
{
1868
    if( clearscreen )
1869
        lcd_cls();
1870
 
1871
    lcd_frect( 0, 0, 127, 7, 1);                                        // Titel: Invers
1872
 
1873
    if( strlen_P(title) < 17 )
1874
        show_Lipo();
1875
 
1876
    lcd_printp_at ( 1, 0, title , MINVERS);
1877
}
1878
 
1879
 
1880
 
1881
//-----------------------------------------------------------
1882
//-----------------------------------------------------------
1883
void Popup_Draw( uint8_t heigthC )
1884
{
1885
    uint8_t y, h;
1886
 
1887
    h = heigthC*8;
1888
    y = 63-h;
1889
 
1890
    //lcd_frect(     0, (hC*8)-6, 127, 63-(hC*8)+6, 1); // Box white
1891
    lcd_frect(   0, y-8, 127,   3, 0);      // Box clear
1892
    lcd_frect(   0, y-4, 127, h+4, 1);      // Box fill white
1893
    lcd_plot (   0, y-4, 0);                // Ecke links oben 1
1894
    lcd_plot ( 127, y-4, 0);                // Ecke rechts oben 1
1895
 
1896
    lcd_line (     1, y-4,   0, y-3, 0);    // Ecke links oben 2
1897
    lcd_line ( 127-1, y-4, 127, y-3, 0);    // Ecke rechts oben 2
1898
}
1899
 
1900
 
1901
 
1902
//-----------------------------------------------------------
1903
// lcdx_cls_rowwidth( y, width, mode, xoffs,yoffs )
1904
//
1905
// loescht eine Zeile auf dem Display
1906
// mode ist kompatibel zu MNORMALX, MINVERSX
1907
//
1908
//  width: in Zeichen
1909
//-----------------------------------------------------------
1910
void lcdx_cls_rowwidth( uint8_t y, uint8_t width, uint8_t mode, int8_t xoffs, int8_t yoffs )
1911
{
1912
    int8_t  xadd = 0;
1913
    int8_t  yadd = 0;
1914
 
1915
    if( mode == MNORMALX || mode == MINVERSX )
1916
    {
1917
        if( xoffs > 0 )         xadd = 1;
1918
        if( (y*8)+yoffs > 0 )   yadd = 1;
1919
 
1920
        if( mode == MNORMALX )
1921
            mode = MNORMAL;
1922
        else
1923
            mode = MINVERS;
1924
    }
1925
 
1926
    lcd_frect( xoffs-xadd, (y*8)+yoffs-yadd, (width*6)+xadd, 7+yadd, (mode == MNORMAL ? 0 : 1) );     // Zeile loeschen
1927
}
1928
 
1929
 
1930
//-----------------------------------------------------------
1931
// lcdx_cls_row( y, mode, yoffs )
1932
//
1933
// loescht eine Zeile auf dem Display
1934
// mode ist kompatibel zu MNORMALX, MINVERSX
1935
//-----------------------------------------------------------
1936
void lcdx_cls_row( uint8_t y, uint8_t mode, int8_t yoffs )
1937
{
1938
    lcdx_cls_rowwidth( y, 21, mode, 0, yoffs );
1939
}
1940
 
1941
 
1942
 
1943
//####################################################################################
1944
//####################################################################################
1945
 
1946
 
1947
 
1948
//-----------------------------------------------------------
1949
//-----------------------------------------------------------
1950
void lcd_setpos( uint8_t x, uint8_t y )
1951
{
1952
    lcd_xpos = x;
1953
    lcd_ypos = y;
1954
}
1955
 
1956
 
1957
 
1958
//-----------------------------------------------------------
1959
//-----------------------------------------------------------
1960
void lcd_print_char( uint8_t c, uint8_t mode )
1961
{
1962
    switch( c )
1963
    {
1964
        case 0x0D:  lcd_xpos = 0;
1965
                    break;
1966
 
1967
        case 0x0A:  new_line();
1968
                    break;
1969
 
1970
        default:    lcdx_putc (lcd_xpos, lcd_ypos, c, mode,  0,0);
1971
                    lcd_xpos++;
1972
                    if( lcd_xpos > 20 )
1973
                    {
1974
                        lcd_xpos = 0;
1975
                        new_line();
1976
                    }
1977
                    break;
1978
    }
1979
}
1980
 
1981
 
1982
//----------------------------------------------------
1983
// gibt einen Linefeed aus (CR+LF)
1984
//----------------------------------------------------
1985
void  lcd_print_LF( void )
1986
{
1987
    lcd_print_char( 0x0D, MNORMAL );
1988
    lcd_print_char( 0x0A, MNORMAL );
1989
}
1990