OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [powerpc/] [csb281/] [v2_0/] [src/] [lcd_support.c] - Blame information for rev 307

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//        Lcd_support.c
4
//
5
//        Cogent CSB281 - LCD/CRT support routines
6
//
7
//==========================================================================
8
//####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12
// Copyright (C) 2003 Gary Thomas
13
//
14
// eCos is free software; you can redistribute it and/or modify it under
15
// the terms of the GNU General Public License as published by the Free
16
// Software Foundation; either version 2 or (at your option) any later version.
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21
// for more details.
22
//
23
// You should have received a copy of the GNU General Public License along
24
// with eCos; if not, write to the Free Software Foundation, Inc.,
25
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26
//
27
// As a special exception, if other files instantiate templates or use macros
28
// or inline functions from this file, or you compile this file and link it
29
// with other works to produce a work based on this file, this file does not
30
// by itself cause the resulting work to be covered by the GNU General Public
31
// License. However the source code for this file must still be made available
32
// in accordance with section (3) of the GNU General Public License.
33
//
34
// This exception does not invalidate any other reasons why a work based on
35
// this file might be covered by the GNU General Public License.
36
//
37
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38
// at http://sources.redhat.com/ecos/ecos-license/
39
// -------------------------------------------
40
//####ECOSGPLCOPYRIGHTEND####
41
//==========================================================================
42
//#####DESCRIPTIONBEGIN####
43
//
44
// Author(s):     gthomas
45
// Contributors:  gthomas
46
// Date:          2001-11-03
47
// Description:   Simple LCD support
48
//####DESCRIPTIONEND####
49
 
50
#include <pkgconf/hal.h>
51
 
52
#include <cyg/infra/diag.h>
53
#include <cyg/hal/hal_io.h>       // IO macros
54
#include <cyg/hal/hal_if.h>       // Virtual vector support
55
#include <cyg/hal/hal_arch.h>     // Register state info
56
#include <cyg/hal/hal_intr.h>     // HAL interrupt macros
57
 
58
#include <cyg/hal/lcd_support.h>
59
#include <cyg/hal/hal_cache.h>
60
 
61
#include <string.h>
62
 
63
#ifdef CYGPKG_ISOINFRA
64
# include <pkgconf/isoinfra.h>
65
# ifdef CYGINT_ISO_STDIO_FORMATTED_IO
66
#  include <stdio.h>  // sscanf
67
# endif
68
#endif
69
 
70
#ifndef FALSE
71
#define FALSE 0
72
#define TRUE  1
73
#endif
74
 
75
// Logical layout
76
#define LCD_WIDTH  640
77
#define LCD_HEIGHT 480
78
#define LCD_DEPTH   16
79
 
80
#define RGB_RED(x)   (((x)&0x1F)<<11)
81
#define RGB_GREEN(x) (((x)&0x3F)<<5)
82
#define RGB_BLUE(x)  (((x)&0x1F)<<0)
83
 
84
// Black on light blue
85
static int bg = RGB_RED(0x1F) | RGB_GREEN(0x3F) | RGB_BLUE(0x1F);
86
static int fg = RGB_RED(0) | RGB_GREEN(0) | RGB_BLUE(0);
87
 
88
static struct lcd_info lcd;
89
 
90
int sed135x_init(int depth, struct lcd_info *info);
91
 
92
// Compute the location for a pixel within the framebuffer
93
static cyg_uint16 *
94
lcd_fb(int row, int col)
95
{
96
    cyg_uint16 *res = (cyg_uint16 *)((char *)lcd.fb+(row*lcd.rlen)+(col*lcd.stride));
97
    return res;
98
}
99
 
100
void
101
lcd_on(bool enable)
102
{
103
    static bool on = false;
104
 
105
    if (enable) {
106
        if (!on) {
107
            (*lcd.on)();
108
        }
109
        on = true;
110
    } else {
111
//        (*lcd.off)();
112
    }
113
}
114
 
115
// Initialize LCD hardware
116
 
117
void
118
lcd_init(int depth)
119
{
120
    sed135x_init(depth, &lcd);
121
}
122
 
123
// Get information about the frame buffer
124
int
125
lcd_getinfo(struct lcd_info *info)
126
{
127
    if (lcd.bpp == 0) {
128
        return 0;  // LCD not initialized
129
    }
130
    *info = lcd;
131
    return 1; // Information valid
132
}
133
 
134
// Clear screen
135
void
136
lcd_clear(void)
137
{
138
#if 0
139
    cyg_uint32 *fb_row0, *fb_rown;
140
    cyg_uint32 _bg = (bg<<16)|bg;
141
 
142
    fb_row0 = lcd_fb(0, 0);
143
    fb_rown = lcd_fb(lcd_height, 0);
144
    while (fb_row0 != fb_rown) {
145
        *fb_row0++ = _bg;
146
    }
147
#endif
148
}
149
 
150
#ifdef CYGSEM_CSB281_LCD_COMM
151
 
152
//
153
// Additional support for LCD/Keyboard as 'console' device
154
//
155
 
156
#ifdef CYGOPT_CSB281_LCD_COMM_LOGO
157
#include "banner.xpm"
158
#endif
159
#include "font.h"
160
 
161
// Virtual screen info
162
static int curX = 0;  // Last used position
163
static int curY = 0;
164
//static int width = LCD_WIDTH / (FONT_WIDTH*NIBBLES_PER_PIXEL);
165
//static int height = LCD_HEIGHT / (FONT_HEIGHT*SCREEN_SCALE);
166
 
167
#define SCREEN_PAN            20
168
#define SCREEN_WIDTH          80
169
#define SCREEN_HEIGHT         (LCD_HEIGHT/FONT_HEIGHT)
170
#define VISIBLE_SCREEN_WIDTH  (LCD_WIDTH/FONT_WIDTH)
171
#define VISIBLE_SCREEN_HEIGHT (LCD_HEIGHT/FONT_HEIGHT)
172
static char screen[SCREEN_HEIGHT][SCREEN_WIDTH];
173
static int screen_height = SCREEN_HEIGHT;
174
static int screen_width = SCREEN_WIDTH;
175
static int screen_pan = 0;
176
 
177
// Usable area on screen [logical pixel rows]
178
static int screen_start = 0;
179
static int screen_end = LCD_HEIGHT/FONT_HEIGHT;
180
 
181
static bool cursor_enable = true;
182
 
183
// Functions
184
static void lcd_drawc(cyg_int8 c, int x, int y);
185
 
186
// Note: val is a 16 bit, RGB555 value which must be mapped
187
// onto a 12 bit value.
188
#define RED(v)   ((v>>12) & 0x0F)
189
#define GREEN(v) ((v>>7) & 0x0F)
190
#define BLUE(v)  ((v>>1) & 0x0F)
191
 
192
static void
193
set_pixel(int row, int col, unsigned short val)
194
{
195
    unsigned short *pix = (unsigned short *)lcd_fb(row, col);
196
    *pix = _le16(val);
197
}
198
 
199
static int
200
_hexdigit(char c)
201
{
202
    if ((c >= '0') && (c <= '9')) {
203
        return c - '0';
204
    } else {
205
        if ((c >= 'A') && (c <= 'F')) {
206
            return (c - 'A') + 0x0A;
207
        } else {
208
            if ((c >= 'a') && (c <= 'f')) {
209
                return (c - 'a') + 0x0a;
210
            }
211
        }
212
    }
213
 
214
    return 0;
215
}
216
 
217
static int
218
_hex(char *cp)
219
{
220
    return (_hexdigit(*cp)<<4) | _hexdigit(*(cp+1));
221
}
222
 
223
static unsigned short
224
parse_color(char *cp)
225
{
226
    int red, green, blue;
227
 
228
    while (*cp && (*cp != 'c')) cp++;
229
    if (cp) {
230
        cp += 2;
231
        if (*cp == '#') {
232
            red = _hex(cp+1);
233
            green = _hex(cp+3);
234
            blue = _hex(cp+5);
235
#define USE_RGB565
236
#ifdef USE_RGB565
237
            return RGB_RED(red>>3) | RGB_GREEN(green>>2) | RGB_BLUE(blue>>3);
238
#else
239
            return RGB_RED(red>>3) | RGB_GREEN(green>>3) | RGB_BLUE(blue>>3);
240
#endif
241
        } else {
242
            // Should be "None"
243
            return 0xFFFF;
244
        }
245
    } else {
246
        return 0xFFFF;
247
    }
248
}
249
 
250
#ifndef CYGINT_ISO_STDIO_FORMATTED_IO
251
static int
252
get_int(unsigned char **_cp)
253
{
254
    char *cp = *_cp;
255
    char c;
256
    int val = 0;
257
 
258
    while ((c = *cp++) && (c != ' ')) {
259
        if ((c >= '0') && (c <= '9')) {
260
            val = val * 10 + (c - '0');
261
        } else {
262
            return -1;
263
        }
264
    }
265
    *_cp = cp;
266
    return val;
267
}
268
#endif
269
 
270
#ifdef CYGOPT_CSB281_LCD_COMM_LOGO
271
static int
272
show_xpm(char *xpm[], int screen_pos)
273
{
274
    int i, row, col, offset;
275
    unsigned char *cp;
276
    int nrows, ncols, nclrs, cwid;
277
    unsigned short colors[256];  // Mapped by character index
278
    short color_value, color_index;
279
//#define HORRIBLY_SLOW_COLOR_MAPPING
280
#ifdef HORRIBLY_SLOW_COLOR_MAPPING
281
    bool color_match;
282
    short cmap[256][2];
283
    int j;
284
#else
285
    // Caution - this is very GIMP specific
286
    short cmap[256][3];  // Enough room for 256 colors
287
    short cmap_col, cmap_row;
288
    unsigned char std_cmap[] = " .+";
289
#endif
290
 
291
    cp = xpm[0];
292
#ifdef CYGINT_ISO_STDIO_FORMATTED_IO
293
    if (sscanf(cp, "%d %d %d %d", &ncols, &nrows, &nclrs, &cwid) != 4) {
294
#else
295
    if (((ncols = get_int(&cp)) < 0) ||
296
        ((nrows = get_int(&cp)) < 0) ||
297
        ((nclrs = get_int(&cp)) < 0) ||
298
        ((cwid = get_int(&cp)) < 0)) {
299
 
300
#endif
301
        diag_printf("Can't parse XPM data, sorry\n");
302
        return 0;
303
    }
304
//    diag_printf("%d rows, %d cols, %d colors %d chars/pixel\n", nrows, ncols, nclrs, cwid);
305
    if (cwid > 2) {
306
        diag_printf("Color map is too wide - %d\n", cwid);
307
        return 0;
308
    }
309
 
310
    for (i = 0;  i < 256;  i++) {
311
        colors[i] = 0x0000;
312
#ifdef HORRIBLY_SLOW_COLOR_MAPPING
313
        cmap[i][0] = 0;  cmap[i][1] = 0;
314
#else
315
        cmap[i][0] = 0;  cmap[i][1] = 0;  cmap[i][2] = 0;
316
#endif
317
    }
318
    color_index = 0;
319
    for (i = 0;  i < nclrs;  i++) {
320
        cp = xpm[i+1];
321
#ifdef HORRIBLY_SLOW_COLOR_MAPPING
322
        for (j = 0;  j < cwid;  j++) {
323
            cmap[color_index][j] = cp[j];
324
        }
325
#else
326
        if (cwid == 1) {
327
            cmap_col = 0;
328
        } else {
329
            for (cmap_col = 0;  cmap_col < 3;  cmap_col++) {
330
                if (cp[1] == std_cmap[cmap_col]) {
331
                    break;
332
                }
333
            }
334
        }
335
        cmap_row = *cp;
336
        cmap[cmap_row][cmap_col] = color_index;
337
#endif
338
        color_value = parse_color(cp+cwid);
339
        colors[color_index++] = color_value;
340
//        diag_printf("Color[%d] = %04x\n", color_index-1, colors[color_index-1]);
341
    }
342
 
343
#ifdef CYGOPT_CSB281_LCD_COMM_LOGO_TOP
344
    offset = screen_pos;
345
#else
346
    offset = screen_pos-nrows;
347
#endif
348
    for (row = 0;  row < nrows;  row++) {
349
        cp = xpm[nclrs+1+row];
350
        for (col = 0;  col < ncols;  col++) {
351
#ifdef HORRIBLY_SLOW_COLOR_MAPPING
352
            // Horrible, but portable, way to map colors
353
            for (color_index = 0;  color_index < nclrs;  color_index++) {
354
                color_match = true;
355
                for (j = 0;  j < cwid;  j++) {
356
                    if (cmap[color_index][j] != cp[j]) {
357
                        color_match = false;
358
                    }
359
                }
360
                if (color_match) {
361
                    break;
362
                }
363
            }
364
#else
365
            if (cwid == 1) {
366
                cmap_col = 0;
367
            } else {
368
                for (cmap_col = 0;  cmap_col < 3;  cmap_col++) {
369
                    if (cp[1] == std_cmap[cmap_col]) {
370
                        break;
371
                    }
372
                }
373
            }
374
            cmap_row = *cp;
375
            color_index = cmap[cmap_row][cmap_col];
376
#endif
377
            set_pixel(row+offset, col, colors[color_index]);
378
            cp += cwid;
379
        }
380
    }
381
#ifdef CYGOPT_CSB281_LCD_COMM_LOGO_TOP
382
    screen_start = (nrows + (FONT_HEIGHT-1))/FONT_HEIGHT;
383
    screen_end = LCD_HEIGHT/FONT_HEIGHT;
384
    return offset+nrows;
385
#else    
386
    screen_start = 0;
387
    screen_height = offset / FONT_HEIGHT;
388
    screen_end = screen_height;
389
    return offset;
390
#endif
391
}
392
#endif
393
 
394
void
395
lcd_screen_clear(void)
396
{
397
    int row, col, pos;
398
 
399
    for (row = 0;  row < screen_height;  row++) {
400
        for (col = 0;  col < screen_width;  col++) {
401
            screen[row][col] = ' ';
402
            lcd_drawc(' ', col, row);
403
        }
404
    }
405
#ifdef CYGOPT_CSB281_LCD_COMM_LOGO
406
    // Note: Row 0 seems to wrap incorrectly
407
#ifdef CYGOPT_CSB281_LCD_COMM_LOGO_TOP
408
    pos = 0;
409
#else
410
    pos = (LCD_HEIGHT-1);
411
#endif
412
    show_xpm(banner_xpm, pos);
413
#endif // CYGOPT_CSB281_LCD_COMM_LOGO
414
    curX = 0;  curY = screen_start;
415
    if (cursor_enable) {
416
        lcd_drawc(CURSOR_ON, curX-screen_pan, curY);
417
    }
418
}
419
 
420
// Position cursor
421
void
422
lcd_moveto(int X, int Y)
423
{
424
    if (cursor_enable) {
425
        lcd_drawc(screen[curY][curX], curX-screen_pan, curY);
426
    }
427
    if (X < 0) X = 0;
428
    if (X >= screen_width) X = screen_width-1;
429
    curX = X;
430
    if (Y < screen_start) Y = screen_start;
431
    if (Y >= screen_height) Y = screen_height-1;
432
    curY = Y;
433
    if (cursor_enable) {
434
        lcd_drawc(CURSOR_ON, curX-screen_pan, curY);
435
    }
436
}
437
 
438
// Render a character at position (X,Y) with current background/foreground
439
static void
440
lcd_drawc(cyg_int8 c, int x, int y)
441
{
442
    cyg_uint8 bits;
443
    int l, p;
444
    int xoff, yoff;
445
 
446
    if ((x < 0) || (x >= VISIBLE_SCREEN_WIDTH) ||
447
        (y < 0) || (y >= screen_height)) return;
448
    for (l = 0;  l < FONT_HEIGHT;  l++) {
449
        bits = font_table[c-FIRST_CHAR][l];
450
        yoff = y*FONT_HEIGHT + l;
451
        xoff = x*FONT_HEIGHT;
452
        for (p = 0;  p < FONT_WIDTH;  p++) {
453
            set_pixel(yoff, xoff + p, (bits & 0x01) ? fg : bg);
454
            bits >>= 1;
455
        }
456
    }
457
}
458
 
459
static void
460
lcd_refresh(void)
461
{
462
    int row, col;
463
 
464
    for (row = screen_start;  row < screen_height;  row++) {
465
        for (col = 0;  col < VISIBLE_SCREEN_WIDTH;  col++) {
466
            if ((col+screen_pan) < screen_width) {
467
                lcd_drawc(screen[row][col+screen_pan], col, row);
468
            } else {
469
                lcd_drawc(' ', col, row);
470
            }
471
        }
472
    }
473
    if (cursor_enable) {
474
        lcd_drawc(CURSOR_ON, curX-screen_pan, curY);
475
    }
476
}
477
 
478
static void
479
lcd_scroll(void)
480
{
481
    int col;
482
    cyg_uint8 *c1;
483
    cyg_uint32 *lc0, *lc1, *lcn;
484
    cyg_uint16 *fb_row0, *fb_row1, *fb_rown;
485
 
486
    // First scroll up the virtual screen
487
#if ((SCREEN_WIDTH%4) != 0)
488
#error Scroll code optimized for screen with multiple of 4 columns
489
#endif
490
    lc0 = (cyg_uint32 *)&screen[0][0];
491
    lc1 = (cyg_uint32 *)&screen[1][0];
492
    lcn = (cyg_uint32 *)&screen[screen_height][0];
493
    while (lc1 != lcn) {
494
        *lc0++ = *lc1++;
495
    }
496
    c1 = &screen[screen_height-1][0];
497
    for (col = 0;  col < screen_width;  col++) {
498
        *c1++ = 0x20;
499
    }
500
    fb_row0 = lcd_fb(screen_start*FONT_HEIGHT, 0);
501
    fb_row1 = lcd_fb((screen_start+1)*FONT_HEIGHT, 0);
502
    fb_rown = lcd_fb(screen_end*FONT_HEIGHT, 0);
503
    while (fb_row1 != fb_rown) {
504
        *fb_row0 = *fb_row1;
505
        fb_row0 = (cyg_uint16 *)((char *)fb_row0 + lcd.stride);
506
        fb_row1 = (cyg_uint16 *)((char *)fb_row1 + lcd.stride);
507
    }
508
    // Erase bottom line
509
    for (col = 0;  col < screen_width;  col++) {
510
        lcd_drawc(' ', col, screen_end-1);
511
    }
512
}
513
 
514
// Draw one character at the current position
515
void
516
lcd_putc(cyg_int8 c)
517
{
518
// TEMP
519
    int cache_on;
520
    HAL_DCACHE_IS_ENABLED(cache_on);
521
    if (cache_on) {
522
        HAL_DCACHE_SYNC();
523
        HAL_DCACHE_DISABLE();
524
    }
525
// TEMP
526
    if (cursor_enable) {
527
        lcd_drawc(screen[curY][curX], curX-screen_pan, curY);
528
    }
529
    switch (c) {
530
    case '\r':
531
        curX = 0;
532
        break;
533
    case '\n':
534
        curY++;
535
        break;
536
    case '\b':
537
        curX--;
538
        if (curX < 0) {
539
            curY--;
540
            if (curY < 0) curY = 0;
541
            curX = screen_width-1;
542
        }
543
        break;
544
    default:
545
        if (((cyg_uint8)c < FIRST_CHAR) || ((cyg_uint8)c > LAST_CHAR)) c = '.';
546
        screen[curY][curX] = c;
547
        lcd_drawc(c, curX-screen_pan, curY);
548
        curX++;
549
        if (curX == screen_width) {
550
            curY++;
551
            curX = 0;
552
        }
553
    }
554
    if (curY >= screen_height) {
555
        lcd_scroll();
556
        curY = (screen_height-1);
557
    }
558
    if (cursor_enable) {
559
        lcd_drawc(CURSOR_ON, curX-screen_pan, curY);
560
    }
561
// TEMP
562
    if (cache_on) {
563
        HAL_DCACHE_ENABLE();
564
    }
565
// TEMP
566
}
567
 
568
// Basic LCD 'printf()' support
569
 
570
#include <stdarg.h>
571
 
572
#define is_digit(c) ((c >= '0') && (c <= '9'))
573
 
574
static int
575
_cvt(unsigned long val, char *buf, long radix, char *digits)
576
{
577
    char temp[80];
578
    char *cp = temp;
579
    int length = 0;
580
 
581
    if (val == 0) {
582
        /* Special case */
583
        *cp++ = '0';
584
    } else {
585
        while (val) {
586
            *cp++ = digits[val % radix];
587
            val /= radix;
588
        }
589
    }
590
    while (cp != temp) {
591
        *buf++ = *--cp;
592
        length++;
593
    }
594
    *buf = '\0';
595
    return (length);
596
}
597
 
598
static int
599
lcd_vprintf(void (*putc)(cyg_int8), const char *fmt0, va_list ap)
600
{
601
    char c, sign, *cp;
602
    int left_prec, right_prec, zero_fill, length, pad, pad_on_right;
603
    char buf[32];
604
    long val;
605
 
606
    while ((c = *fmt0++)) {
607
        cp = buf;
608
        length = 0;
609
        if (c == '%') {
610
            c = *fmt0++;
611
            left_prec = right_prec = pad_on_right = 0;
612
            if (c == '-') {
613
                c = *fmt0++;
614
                pad_on_right++;
615
            }
616
            if (c == '0') {
617
                zero_fill = TRUE;
618
                c = *fmt0++;
619
            } else {
620
                zero_fill = FALSE;
621
            }
622
            while (is_digit(c)) {
623
                left_prec = (left_prec * 10) + (c - '0');
624
                c = *fmt0++;
625
            }
626
            if (c == '.') {
627
                c = *fmt0++;
628
                zero_fill++;
629
                while (is_digit(c)) {
630
                    right_prec = (right_prec * 10) + (c - '0');
631
                    c = *fmt0++;
632
                }
633
            } else {
634
                right_prec = left_prec;
635
            }
636
            sign = '\0';
637
            switch (c) {
638
            case 'd':
639
            case 'x':
640
            case 'X':
641
                val = va_arg(ap, long);
642
                switch (c) {
643
                case 'd':
644
                    if (val < 0) {
645
                        sign = '-';
646
                        val = -val;
647
                    }
648
                    length = _cvt(val, buf, 10, "0123456789");
649
                    break;
650
                case 'x':
651
                    length = _cvt(val, buf, 16, "0123456789abcdef");
652
                    break;
653
                case 'X':
654
                    length = _cvt(val, buf, 16, "0123456789ABCDEF");
655
                    break;
656
                }
657
                break;
658
            case 's':
659
                cp = va_arg(ap, char *);
660
                length = strlen(cp);
661
                break;
662
            case 'c':
663
                c = va_arg(ap, long /*char*/);
664
                (*putc)(c);
665
                continue;
666
            default:
667
                (*putc)('?');
668
            }
669
            pad = left_prec - length;
670
            if (sign != '\0') {
671
                pad--;
672
            }
673
            if (zero_fill) {
674
                c = '0';
675
                if (sign != '\0') {
676
                    (*putc)(sign);
677
                    sign = '\0';
678
                }
679
            } else {
680
                c = ' ';
681
            }
682
            if (!pad_on_right) {
683
                while (pad-- > 0) {
684
                    (*putc)(c);
685
                }
686
            }
687
            if (sign != '\0') {
688
                (*putc)(sign);
689
            }
690
            while (length-- > 0) {
691
                (*putc)(c = *cp++);
692
                if (c == '\n') {
693
                    (*putc)('\r');
694
                }
695
            }
696
            if (pad_on_right) {
697
                while (pad-- > 0) {
698
                    (*putc)(' ');
699
                }
700
            }
701
        } else {
702
            (*putc)(c);
703
            if (c == '\n') {
704
                (*putc)('\r');
705
            }
706
        }
707
    }
708
 
709
    // FIXME
710
    return 0;
711
}
712
 
713
int
714
_lcd_printf(char const *fmt, ...)
715
{
716
    int ret;
717
    va_list ap;
718
 
719
    va_start(ap, fmt);
720
    ret = lcd_vprintf(lcd_putc, fmt, ap);
721
    va_end(ap);
722
    return (ret);
723
}
724
 
725
void
726
lcd_setbg(int red, int green, int blue)
727
{
728
    bg = RGB_RED(red) | RGB_GREEN(green) | RGB_BLUE(blue);
729
}
730
 
731
void
732
lcd_setfg(int red, int green, int blue)
733
{
734
    fg = RGB_RED(red) | RGB_GREEN(green) | RGB_BLUE(blue);
735
}
736
 
737
//
738
// Support LCD/keyboard (PS2) as a virtual I/O channel
739
//   Adapted from i386/pcmb_screen.c
740
//
741
 
742
 
743
//-----------------------------------------------------------------------------
744
// Keyboard definitions
745
 
746
#define KBDATAPORT      0x79000003    // data I/O port
747
#define KBCMDPORT       0x79000007    // command port (write)
748
#define KBSTATPORT      0x79000007    // status port  (read)
749
#define KBINRDY         0x01
750
#define KBOUTRDY        0x02
751
#define KBTXTO          0x40          // Transmit timeout - nothing there
752
#define KBTEST          0xAB
753
 
754
// Scan codes
755
 
756
#define LSHIFT    0x2a
757
#define RSHIFT    0x36
758
#define CTRL      0x1d
759
#define ALT       0x38
760
#define CAPS      0x3a
761
#define NUMS      0x45
762
 
763
#define BREAK     0x80
764
 
765
// Bits for KBFlags
766
 
767
#define KBNormal  0x0000
768
#define KBShift   0x0001
769
#define KBCtrl    0x0002
770
#define KBAlt     0x0004
771
#define KBIndex   0x0007  // mask for the above
772
 
773
#define KBExtend   0x0010
774
#define KBAck      0x0020
775
#define KBResend   0x0040
776
#define KBShiftL   (0x0080 | KBShift)
777
#define KBShiftR   (0x0100 | KBShift)
778
#define KBCtrlL    (0x0200 | KBCtrl)
779
#define KBCtrlR    (0x0400 | KBCtrl)
780
#define KBAltL     (0x0800 | KBAlt)
781
#define KBAltR     (0x1000 | KBAlt)
782
#define KBCapsLock 0x2000
783
#define KBNumLock  0x4000
784
 
785
#define KBArrowUp       0x48
786
#define KBArrowRight    0x4D
787
#define KBArrowLeft     0x4B
788
#define KBArrowDown     0x50
789
 
790
//-----------------------------------------------------------------------------
791
// Keyboard Variables
792
 
793
static  int  KBFlags = 0;
794
 
795
static  CYG_BYTE  KBPending = 0xFF;
796
 
797
static  CYG_BYTE  KBScanTable[128][4] = {
798
//  Normal    Shift    Control    Alt
799
// 0x00
800
    {  0xFF,    0xFF,    0xFF,    0xFF,   },
801
    {  0x1b,    0x1b,    0x1b,    0xFF,  },
802
    {  '1',    '!',    0xFF,    0xFF,  },
803
    {  '2',    '"',    0xFF,    0xFF,  },
804
    {  '3',    '#',    0xFF,    0xFF,  },
805
    {  '4',    '$',    0xFF,    0xFF,  },
806
    {  '5',    '%',    0xFF,    0xFF,  },
807
    {  '6',    '^',    0xFF,    0xFF,  },
808
    {  '7',    '&',    0xFF,    0xFF,  },
809
    {  '8',    '*',    0xFF,    0xFF,  },
810
    {  '9',    '(',    0xFF,    0xFF,  },
811
    {  '0',    ')',    0xFF,    0xFF,  },
812
    {  '-',    '_',    0xFF,    0xFF,  },
813
    {  '=',    '+',    0xFF,    0xFF,  },
814
    {  '\b',    '\b',    0xFF,    0xFF,  },
815
    {  '\t',    '\t',    0xFF,    0xFF,  },
816
// 0x10
817
    {  'q',    'Q',    0x11,    0xFF,  },
818
    {  'w',    'W',    0x17,    0xFF,  },
819
    {  'e',    'E',    0x05,    0xFF,  },
820
    {  'r',    'R',    0x12,    0xFF,  },
821
    {  't',    'T',    0x14,    0xFF,  },
822
    {  'y',    'Y',    0x19,    0xFF,  },
823
    {  'u',    'U',    0x15,    0xFF,  },
824
    {  'i',    'I',    0x09,    0xFF,  },
825
    {  'o',    'O',    0x0F,    0xFF,  },
826
    {  'p',    'P',    0x10,    0xFF,  },
827
    {  '[',    '{',    0x1b,    0xFF,  },
828
    {  ']',    '}',    0x1d,    0xFF,  },
829
    {  '\r',    '\r',    '\n',    0xFF,  },
830
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
831
    {  'a',    'A',    0x01,    0xFF,  },
832
    {  's',    'S',    0x13,    0xFF,  },
833
// 0x20
834
    {  'd',    'D',    0x04,    0xFF,  },
835
    {  'f',    'F',    0x06,    0xFF,  },
836
    {  'g',    'G',    0x07,    0xFF,  },
837
    {  'h',    'H',    0x08,    0xFF,  },
838
    {  'j',    'J',    0x0a,    0xFF,  },
839
    {  'k',    'K',    0x0b,    0xFF,  },
840
    {  'l',    'L',    0x0c,    0xFF,  },
841
    {  ';',    ':',    0xFF,    0xFF,  },
842
    {  0x27,    '@',    0xFF,    0xFF,  },
843
    {  '#',    '~',    0xFF,    0xFF,  },
844
    {  '`',    '~',    0xFF,    0xFF,  },
845
    {  '\\',    '|',    0x1C,    0xFF,  },
846
    {  'z',    'Z',    0x1A,    0xFF,  },
847
    {  'x',    'X',    0x18,    0xFF,  },
848
    {  'c',    'C',    0x03,    0xFF,  },
849
    {  'v',    'V',    0x16,    0xFF,  },
850
// 0x30
851
    {  'b',    'B',    0x02,    0xFF,  },
852
    {  'n',    'N',    0x0E,    0xFF,  },
853
    {  'm',    'M',    0x0D,    0xFF,  },
854
    {  ',',    '<',    0xFF,    0xFF,  },
855
    {  '.',    '>',    0xFF,    0xFF,  },
856
    {  '/',    '?',    0xFF,    0xFF,  },
857
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
858
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
859
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
860
    {  ' ',    ' ',    ' ',    ' ',  },
861
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
862
    {  0xF1,    0xE1,    0xFF,    0xFF,  },
863
    {  0xF2,    0xE2,    0xFF,    0xFF,  },
864
    {  0xF3,    0xE3,    0xFF,    0xFF,  },
865
    {  0xF4,    0xE4,    0xFF,    0xFF,  },
866
    {  0xF5,    0xE5,    0xFF,    0xFF,  },
867
// 0x40
868
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
869
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
870
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
871
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
872
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
873
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
874
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
875
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
876
 
877
    {  0x15,    0x15,    0x15,    0x15,  },
878
    {  0x10,    0x10,    0x10,    0x10,  },
879
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
880
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
881
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
882
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
883
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
884
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
885
// 0x50
886
    {  0x04,    0x04,    0x04,    0x04,  },
887
    {  0x0e,    0x0e,    0x0e,    0x0e,  },
888
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
889
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
890
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
891
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
892
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
893
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
894
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
895
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
896
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
897
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
898
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
899
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
900
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
901
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
902
// 0x60
903
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
904
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
905
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
906
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
907
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
908
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
909
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
910
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
911
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
912
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
913
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
914
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
915
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
916
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
917
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
918
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
919
// 0x70
920
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
921
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
922
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
923
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
924
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
925
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
926
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
927
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
928
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
929
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
930
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
931
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
932
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
933
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
934
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
935
    {  0xFF,    0xFF,    0xFF,    0xFF,  },
936
};
937
 
938
static int KBIndexTab[8] = { 0, 1, 2, 2, 3, 3, 3, 3 };
939
 
940
//-----------------------------------------------------------------------------
941
 
942
static __inline__ cyg_uint8
943
inb(cyg_uint32 port)
944
{
945
    cyg_uint8 val;
946
    HAL_READ_UINT8(port, val);
947
    return val;
948
}
949
 
950
static __inline__ void
951
outb(cyg_uint32 port, cyg_uint8 val)
952
{
953
    HAL_WRITE_UINT8(port, val);
954
}
955
 
956
static cyg_bool
957
KeyboardInit(void)
958
{
959
    unsigned char c, s;
960
 
961
    /* flush input queue */
962
    while ((inb(KBSTATPORT) & KBINRDY)) {
963
        (void)inb(KBDATAPORT);
964
    }
965
 
966
    /* Send self-test - controller local */
967
    while (inb(KBSTATPORT) & KBOUTRDY) ;
968
    outb(KBCMDPORT,0xAA);
969
    while ((inb(KBSTATPORT) & KBINRDY) == 0) ; /* wait input ready */
970
    if ((c = inb(KBDATAPORT)) != 0x55) {
971
#ifdef DEBUG_KBD_INIT
972
        diag_printf("Keyboard self test failed - result: %x\n", c);
973
#endif
974
        return false;
975
    }
976
 
977
    /* Enable interrupts and keyboard controller */
978
    while (inb(KBSTATPORT) & KBOUTRDY) ;
979
    outb(KBCMDPORT,0x60);
980
    while (inb(KBSTATPORT) & KBOUTRDY) ;
981
    outb(KBCMDPORT,0x45);
982
    CYGACC_CALL_IF_DELAY_US(10000);  // 10ms
983
 
984
    while (inb(KBSTATPORT) & KBOUTRDY) ;
985
    outb(KBCMDPORT,0xAE);  // Enable keyboard
986
 
987
    /* See if a keyboard is connected */
988
    while (inb(KBSTATPORT) & KBOUTRDY) ;
989
    outb(KBDATAPORT,0xFF);
990
    while (((s = inb(KBSTATPORT)) & (KBINRDY|KBTXTO)) == 0) ; /* wait input ready */
991
    if ((s & KBTXTO) || ((c = inb(KBDATAPORT)) != 0xFA)) {
992
#ifdef DEBUG_KBD_INIT
993
        diag_printf("Keyboard reset failed - no ACK: %x, stat: %x\n", c, s);
994
#endif
995
        return false;
996
    }
997
    while (((s = inb(KBSTATPORT)) & KBINRDY) == 0) ; /* wait input ready */
998
    if ((s & KBTXTO) || ((c = inb(KBDATAPORT)) != 0xAA)) {
999
#ifdef DEBUG_KBD_INIT
1000
        diag_printf("Keyboard reset failed - bad code: %x, stat: %x\n", c, s);
1001
#endif
1002
        return false;
1003
    }
1004
 
1005
    // Set scan mode
1006
    while (inb(KBSTATPORT) & KBOUTRDY) ;
1007
    outb(KBCMDPORT,0x20);
1008
    while ((inb(KBSTATPORT) & KBINRDY) == 0) ; /* wait input ready */
1009
    if (! (inb(KBDATAPORT) & 0x40)) {
1010
        /*
1011
         * Quote from PS/2 System Reference Manual:
1012
         *
1013
         * "Address hex 0060 and address hex 0064 should be
1014
         * written only when the input-buffer-full bit and
1015
         * output-buffer-full bit in the Controller Status
1016
         * register are set 0." (KBINRDY and KBOUTRDY)
1017
         */
1018
 
1019
        while (inb(KBSTATPORT) & (KBINRDY | KBOUTRDY)) ;
1020
        outb(KBDATAPORT,0xF0);
1021
        while (inb(KBSTATPORT) & (KBINRDY | KBOUTRDY)) ;
1022
        outb(KBDATAPORT,0x01);
1023
    }
1024
 
1025
    KBFlags = 0;
1026
    return true;
1027
} /* KeyboardInit */
1028
 
1029
//-----------------------------------------------------------------------------
1030
 
1031
static CYG_BYTE
1032
KeyboardAscii(CYG_BYTE scancode)
1033
{
1034
    CYG_BYTE ascii = 0xFF;
1035
 
1036
    // Start by handling all shift/ctl keys:
1037
 
1038
    switch( scancode ) {
1039
    case 0xe0:
1040
        KBFlags |= KBExtend;
1041
        return 0xFF;
1042
 
1043
    case 0xfa:
1044
        KBFlags |= KBAck;
1045
        return 0xFF;
1046
 
1047
    case 0xfe:
1048
        KBFlags |= KBResend;
1049
        return 0xFF;
1050
 
1051
    case LSHIFT:
1052
        KBFlags |= KBShiftL;
1053
        return 0xFF;
1054
 
1055
    case LSHIFT | BREAK:
1056
        KBFlags &= ~KBShiftL;
1057
        return 0xFF;
1058
 
1059
    case RSHIFT:
1060
        KBFlags |= KBShiftR;
1061
        return 0xFF;
1062
 
1063
    case RSHIFT | BREAK:
1064
        KBFlags &= ~KBShiftR;
1065
        return 0xFF;
1066
 
1067
    case CTRL:
1068
        if( KBFlags & KBExtend )
1069
        {
1070
            KBFlags |= KBCtrlR;
1071
            KBFlags &= ~KBExtend;
1072
        }
1073
        else  KBFlags |= KBCtrlL;
1074
        return 0xFF;
1075
 
1076
    case CTRL | BREAK:
1077
        if( KBFlags & KBExtend )
1078
        {
1079
            KBFlags &= ~KBCtrlR;
1080
            KBFlags &= ~KBExtend;
1081
        }
1082
        else  KBFlags &= ~KBCtrlL;
1083
        return 0xFF;
1084
 
1085
 
1086
    case ALT:
1087
        if( KBFlags & KBExtend )
1088
        {
1089
            KBFlags |= KBAltR;
1090
            KBFlags &= ~KBExtend;
1091
        }
1092
        else  KBFlags |= KBAltL;
1093
        return 0xFF;
1094
 
1095
    case ALT | BREAK:
1096
        if( KBFlags & KBExtend )
1097
        {
1098
            KBFlags &= ~KBAltR;
1099
            KBFlags &= ~KBExtend;
1100
        }
1101
        else  KBFlags &= ~KBAltL;
1102
        return 0xFF;
1103
 
1104
    case CAPS:
1105
        KBFlags ^= KBCapsLock;
1106
    case CAPS | BREAK:
1107
        return 0xFF;
1108
 
1109
    case NUMS:
1110
        KBFlags ^= KBNumLock;
1111
    case NUMS | BREAK:
1112
        return 0xFF;
1113
 
1114
    case KBArrowUp:
1115
    case KBArrowDown:
1116
        screen_pan = 0;
1117
        lcd_refresh();
1118
        break;
1119
    case KBArrowLeft:
1120
        screen_pan -= SCREEN_PAN;
1121
        if (screen_pan < 0) screen_pan = 0;
1122
        lcd_refresh();
1123
        break;
1124
    case KBArrowRight:
1125
        screen_pan += SCREEN_PAN;
1126
        if (screen_pan > (SCREEN_WIDTH-SCREEN_PAN))
1127
            screen_pan = SCREEN_WIDTH-SCREEN_PAN;
1128
        lcd_refresh();
1129
        break;
1130
 
1131
    }
1132
 
1133
    // Clear Extend flag if set
1134
    KBFlags &= ~KBExtend;
1135
 
1136
    // Ignore all other BREAK codes
1137
    if( scancode & 0x80 ) return 0xFF;
1138
 
1139
    // Here the scancode is for something we can turn
1140
    // into an ASCII value
1141
 
1142
    ascii = KBScanTable[scancode & 0x7F][KBIndexTab[KBFlags & KBIndex]];
1143
 
1144
    return ascii;
1145
 
1146
} /* KeyboardAscii */
1147
 
1148
//-----------------------------------------------------------------------------
1149
 
1150
static int
1151
KeyboardTest(void)
1152
{
1153
    // If there is a pending character, return True
1154
    if( KBPending != 0xFF ) return true;
1155
 
1156
    // If there is something waiting at the port, get it
1157
    for(;;) {
1158
        CYG_BYTE stat, code;
1159
        CYG_BYTE c;
1160
 
1161
        HAL_READ_UINT8( KBSTATPORT, stat );
1162
 
1163
        if( (stat & KBINRDY) == 0 )
1164
            break;
1165
 
1166
        HAL_READ_UINT8( KBDATAPORT, code );
1167
 
1168
        // Translate to ASCII
1169
        c = KeyboardAscii(code);
1170
 
1171
        // if it is a real ASCII char, save it and
1172
        // return True.
1173
        if( c != 0xFF ) {
1174
            KBPending = c;
1175
            return true;
1176
        }
1177
    }
1178
 
1179
    // Otherwise return False
1180
    return false;
1181
 
1182
} /* KeyboardTest */
1183
 
1184
char
1185
KeyboardChar(void)
1186
{
1187
    char c = KBPending;
1188
    KBPending = 0xFF;
1189
    return c;
1190
}
1191
 
1192
static int  _timeout = 500;
1193
 
1194
static cyg_bool
1195
lcd_comm_getc_nonblock(void* __ch_data, cyg_uint8* ch)
1196
{
1197
    if( !KeyboardTest() )
1198
        return false;
1199
    *ch = KBPending;
1200
    KBPending = 0xFF;
1201
    return true;
1202
}
1203
 
1204
static cyg_uint8
1205
lcd_comm_getc(void* __ch_data)
1206
{
1207
    cyg_uint8 ch;
1208
 
1209
    while (!lcd_comm_getc_nonblock(__ch_data, &ch)) ;
1210
    return ch;
1211
}
1212
 
1213
static void
1214
lcd_comm_putc(void* __ch_data, cyg_uint8 c)
1215
{
1216
    lcd_putc(c);
1217
}
1218
 
1219
static void
1220
lcd_comm_write(void* __ch_data, const cyg_uint8* __buf, cyg_uint32 __len)
1221
{
1222
#if 0
1223
    CYGARC_HAL_SAVE_GP();
1224
 
1225
    while(__len-- > 0)
1226
        lcd_comm_putc(__ch_data, *__buf++);
1227
 
1228
    CYGARC_HAL_RESTORE_GP();
1229
#endif
1230
}
1231
 
1232
static void
1233
lcd_comm_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
1234
{
1235
#if 0
1236
    CYGARC_HAL_SAVE_GP();
1237
 
1238
    while(__len-- > 0)
1239
        *__buf++ = lcd_comm_getc(__ch_data);
1240
 
1241
    CYGARC_HAL_RESTORE_GP();
1242
#endif
1243
}
1244
 
1245
static cyg_bool
1246
lcd_comm_getc_timeout(void* __ch_data, cyg_uint8* ch)
1247
{
1248
    int delay_count;
1249
    cyg_bool res;
1250
 
1251
    delay_count = _timeout * 2; // delay in .5 ms steps
1252
    for(;;) {
1253
        res = lcd_comm_getc_nonblock(__ch_data, ch);
1254
        if (res || 0 == delay_count--)
1255
            break;
1256
        CYGACC_CALL_IF_DELAY_US(500);
1257
    }
1258
    return res;
1259
}
1260
 
1261
static int
1262
lcd_comm_control(void *__ch_data, __comm_control_cmd_t __func, ...)
1263
{
1264
    static int vector = 0;
1265
    int ret = -1;
1266
    static int irq_state = 0;
1267
 
1268
    CYGARC_HAL_SAVE_GP();
1269
 
1270
    switch (__func) {
1271
    case __COMMCTL_IRQ_ENABLE:
1272
        ret = irq_state;
1273
        irq_state = 1;
1274
        break;
1275
    case __COMMCTL_IRQ_DISABLE:
1276
        ret = irq_state;
1277
        irq_state = 0;
1278
        break;
1279
    case __COMMCTL_DBG_ISR_VECTOR:
1280
        ret = vector;
1281
        break;
1282
    case __COMMCTL_SET_TIMEOUT:
1283
    {
1284
        va_list ap;
1285
 
1286
        va_start(ap, __func);
1287
 
1288
        ret = _timeout;
1289
        _timeout = va_arg(ap, cyg_uint32);
1290
 
1291
        va_end(ap);
1292
        break;
1293
    }
1294
    case __COMMCTL_FLUSH_OUTPUT:
1295
        ret = 0;
1296
        break;
1297
    default:
1298
        break;
1299
    }
1300
    CYGARC_HAL_RESTORE_GP();
1301
    return ret;
1302
}
1303
 
1304
static int
1305
lcd_comm_isr(void *__ch_data, int* __ctrlc,
1306
           CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
1307
{
1308
#if 0
1309
    char ch;
1310
 
1311
    cyg_drv_interrupt_acknowledge(__vector);
1312
    *__ctrlc = 0;
1313
    if (lcd_comm_getc_nonblock(__ch_data, &ch)) {
1314
        if (ch == 0x03) {
1315
            *__ctrlc = 1;
1316
        }
1317
    }
1318
    return CYG_ISR_HANDLED;
1319
#else
1320
    return 0;
1321
#endif
1322
}
1323
 
1324
void
1325
lcd_comm_init(void)
1326
{
1327
    static int init = 0;
1328
 
1329
    if (!init) {
1330
        hal_virtual_comm_table_t* comm;
1331
        int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
1332
 
1333
        init = 1;
1334
        if (!KeyboardInit()) {
1335
            // No keyboard - no LCD/CRT display
1336
            return;
1337
        }
1338
 
1339
        // Initialize screen
1340
        cursor_enable = true;
1341
        lcd_init(16);
1342
        lcd_on(true);
1343
        lcd_screen_clear();
1344
 
1345
        // Setup procs in the vector table
1346
        CYGACC_CALL_IF_SET_CONSOLE_COMM(2);  // FIXME - should be controlled by CDL
1347
        comm = CYGACC_CALL_IF_CONSOLE_PROCS();
1348
        //CYGACC_COMM_IF_CH_DATA_SET(*comm, chan);
1349
        CYGACC_COMM_IF_WRITE_SET(*comm, lcd_comm_write);
1350
        CYGACC_COMM_IF_READ_SET(*comm, lcd_comm_read);
1351
        CYGACC_COMM_IF_PUTC_SET(*comm, lcd_comm_putc);
1352
        CYGACC_COMM_IF_GETC_SET(*comm, lcd_comm_getc);
1353
        CYGACC_COMM_IF_CONTROL_SET(*comm, lcd_comm_control);
1354
        CYGACC_COMM_IF_DBG_ISR_SET(*comm, lcd_comm_isr);
1355
        CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, lcd_comm_getc_timeout);
1356
 
1357
        // Restore original console
1358
        CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
1359
    }
1360
}
1361
 
1362
#ifdef CYGPKG_REDBOOT
1363
#include <redboot.h>
1364
 
1365
// Get here when RedBoot is idle.  If it's been long enough, then
1366
// dim the LCD.  The problem is - how to determine other activities
1367
// so at this doesn't get in the way.  In the default case, this will
1368
// be called from RedBoot every 10ms (CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT)
1369
 
1370
#define MAX_IDLE_TIME (30*100)
1371
 
1372
static void
1373
idle(bool is_idle)
1374
{
1375
    static int idle_time = 0;
1376
    static bool was_idled = false;
1377
 
1378
    if (is_idle) {
1379
        if (!was_idled) {
1380
            if (++idle_time == MAX_IDLE_TIME) {
1381
                was_idled = true;
1382
                lcd_on(false);
1383
            }
1384
        }
1385
    } else {
1386
        idle_time = 0;
1387
        if (was_idled) {
1388
            was_idled = false;
1389
                lcd_on(true);
1390
        }
1391
    }
1392
}
1393
 
1394
RedBoot_idle(idle, RedBoot_AFTER_NETIO);
1395
#endif
1396
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.