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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [arm/] [edb7xxx/] [v2_0/] [src/] [lcd_support.c] - Blame information for rev 861

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

powered by: WebSVN 2.1.0

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