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

Subversion Repositories openrisc_me

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//        lcd_support.c
4
//
5
//        Cirrus EDB7xxx eval board LCD support code
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:          1999-09-01
46
// Description:   Functions to drive LCD display
47
//####DESCRIPTIONEND####
48
 
49
// 8x8 Font - from Helios
50
 
51
#define FIRST_CHAR 0x20
52
#define LAST_CHAR  0x7E
53
#define FONT_HEIGHT 8
54
#define FONT_WIDTH  8
55
#define CURSOR_ON  0x5F
56
#define CURSOR_OFF 0x20
57
static char font_table[LAST_CHAR-FIRST_CHAR+1][8] =
58
{
59
        {        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*   */
60
        {        0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x00 }, /* ! */
61
        {        0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* " */
62
        {        0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00 }, /* # */
63
        {        0x30, 0xFC, 0x16, 0x7C, 0xD0, 0x7E, 0x18, 0x00 }, /* $ */
64
        {        0x06, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x60, 0x00 }, /* % */
65
        {        0x1C, 0x36, 0x36, 0x1C, 0xB6, 0x66, 0xDC, 0x00 }, /* & */
66
        {        0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* ' */
67
        {        0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00 }, /* ( */
68
        {        0x0C, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00 }, /* ) */
69
        {        0x00, 0x18, 0x7E, 0x3C, 0x7E, 0x18, 0x00, 0x00 }, /* * */
70
        {        0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00 }, /* + */
71
        {        0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x0C }, /* , */
72
        {        0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00 }, /* - */
73
        {        0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00 }, /* . */
74
        {        0x00, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, 0x00 }, /* / */
75
        {        0x3C, 0x66, 0x76, 0x7E, 0x6E, 0x66, 0x3C, 0x00 }, /* 0 */
76
        {        0x18, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00 }, /* 1 */
77
        {        0x3C, 0x66, 0x60, 0x30, 0x18, 0x0C, 0x7E, 0x00 }, /* 2 */
78
        {        0x3C, 0x66, 0x60, 0x38, 0x60, 0x66, 0x3C, 0x00 }, /* 3 */
79
        {        0x30, 0x38, 0x3C, 0x36, 0x7E, 0x30, 0x30, 0x00 }, /* 4 */
80
        {        0x7E, 0x06, 0x3E, 0x60, 0x60, 0x66, 0x3C, 0x00 }, /* 5 */
81
        {        0x38, 0x0C, 0x06, 0x3E, 0x66, 0x66, 0x3C, 0x00 }, /* 6 */
82
        {        0x7E, 0x60, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00 }, /* 7 */
83
        {        0x3C, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00 }, /* 8 */
84
        {        0x3C, 0x66, 0x66, 0x7C, 0x60, 0x30, 0x1C, 0x00 }, /* 9 */
85
        {        0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00 }, /* : */
86
        {        0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x0C }, /* ; */
87
        {        0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x00 }, /* < */
88
        {        0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00 }, /* = */
89
        {        0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x00 }, /* > */
90
        {        0x3C, 0x66, 0x30, 0x18, 0x18, 0x00, 0x18, 0x00 }, /* ? */
91
        {        0x3C, 0x66, 0x76, 0x56, 0x76, 0x06, 0x3C, 0x00 }, /* @ */
92
        {        0x3C, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00 }, /* A */
93
        {        0x3E, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3E, 0x00 }, /* B */
94
        {        0x3C, 0x66, 0x06, 0x06, 0x06, 0x66, 0x3C, 0x00 }, /* C */
95
        {        0x1E, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1E, 0x00 }, /* D */
96
        {        0x7E, 0x06, 0x06, 0x3E, 0x06, 0x06, 0x7E, 0x00 }, /* E */
97
        {        0x7E, 0x06, 0x06, 0x3E, 0x06, 0x06, 0x06, 0x00 }, /* F */
98
        {        0x3C, 0x66, 0x06, 0x76, 0x66, 0x66, 0x3C, 0x00 }, /* G */
99
        {        0x66, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00 }, /* H */
100
        {        0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00 }, /* I */
101
        {        0x7C, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1C, 0x00 }, /* J */
102
        {        0x66, 0x36, 0x1E, 0x0E, 0x1E, 0x36, 0x66, 0x00 }, /* K */
103
        {        0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x7E, 0x00 }, /* L */
104
        {        0xC6, 0xEE, 0xFE, 0xD6, 0xD6, 0xC6, 0xC6, 0x00 }, /* M */
105
        {        0x66, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x66, 0x00 }, /* N */
106
        {        0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00 }, /* O */
107
        {        0x3E, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x06, 0x00 }, /* P */
108
        {        0x3C, 0x66, 0x66, 0x66, 0x56, 0x36, 0x6C, 0x00 }, /* Q */
109
        {        0x3E, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x66, 0x00 }, /* R */
110
        {        0x3C, 0x66, 0x06, 0x3C, 0x60, 0x66, 0x3C, 0x00 }, /* S */
111
        {        0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00 }, /* T */
112
        {        0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00 }, /* U */
113
        {        0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00 }, /* V */
114
        {        0xC6, 0xC6, 0xD6, 0xD6, 0xFE, 0xEE, 0xC6, 0x00 }, /* W */
115
        {        0x66, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00 }, /* X */
116
        {        0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00 }, /* Y */
117
        {        0x7E, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x7E, 0x00 }, /* Z */
118
        {        0x3E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3E, 0x00 }, /* [ */
119
        {        0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00 }, /* \ */
120
        {        0x7C, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7C, 0x00 }, /* ] */
121
        {        0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* ^ */
122
        {        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF }, /* _ */
123
        {        0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* ` */
124
        {        0x00, 0x00, 0x3C, 0x60, 0x7C, 0x66, 0x7C, 0x00 }, /* a */
125
        {        0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x3E, 0x00 }, /* b */
126
        {        0x00, 0x00, 0x3C, 0x66, 0x06, 0x66, 0x3C, 0x00 }, /* c */
127
        {        0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x7C, 0x00 }, /* d */
128
        {        0x00, 0x00, 0x3C, 0x66, 0x7E, 0x06, 0x3C, 0x00 }, /* e */
129
        {        0x38, 0x0C, 0x0C, 0x3E, 0x0C, 0x0C, 0x0C, 0x00 }, /* f */
130
        {        0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x3C }, /* g */
131
        {        0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x00 }, /* h */
132
        {        0x18, 0x00, 0x1C, 0x18, 0x18, 0x18, 0x3C, 0x00 }, /* i */
133
        {        0x18, 0x00, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x0E }, /* j */
134
        {        0x06, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x00 }, /* k */
135
        {        0x1C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00 }, /* l */
136
        {        0x00, 0x00, 0x6C, 0xFE, 0xD6, 0xD6, 0xC6, 0x00 }, /* m */
137
        {        0x00, 0x00, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x00 }, /* n */
138
        {        0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00 }, /* o */
139
        {        0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x06 }, /* p */
140
        {        0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0xE0 }, /* q */
141
        {        0x00, 0x00, 0x36, 0x6E, 0x06, 0x06, 0x06, 0x00 }, /* r */
142
        {        0x00, 0x00, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x00 }, /* s */
143
        {        0x0C, 0x0C, 0x3E, 0x0C, 0x0C, 0x0C, 0x38, 0x00 }, /* t */
144
        {        0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x00 }, /* u */
145
        {        0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00 }, /* v */
146
        {        0x00, 0x00, 0xC6, 0xD6, 0xD6, 0xFE, 0x6C, 0x00 }, /* w */
147
        {        0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00 }, /* x */
148
        {        0x00, 0x00, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x3C }, /* y */
149
        {        0x00, 0x00, 0x7E, 0x30, 0x18, 0x0C, 0x7E, 0x00 }, /* z */
150
        {        0x30, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x30, 0x00 }, /* { */
151
        {        0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00 }, /* | */
152
        {        0x0C, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0C, 0x00 }, /* } */
153
        {        0x8C, 0xD6, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00 }  /* ~ */
154
};
155
 
156
#define ALPS_LH
157
#ifdef ALPS_LH
158
#define LCD_WIDTH  640
159
#define LCD_HEIGHT 240
160
#else
161
#define LCD_WIDTH  320
162
#define LCD_HEIGHT 240
163
#endif
164
// This can be 1 or 2
165
#define SCREEN_SCALE 2
166
#define NIBBLES_PER_PIXEL (1*SCREEN_SCALE)
167
#define PIXELS_PER_BYTE (2/NIBBLES_PER_PIXEL)
168
#define PIXEL_MASK      ((1<<PIXELS_PER_BYTE)-1)
169
 
170
// Physical screen info
171
static int lcd_depth;  // Should be 1, 2, or 4
172
static int lcd_width  = LCD_WIDTH;
173
static int lcd_height = LCD_HEIGHT;
174
static cyg_uint8 *lcd_base = (cyg_uint8 *)0xC0000000;
175
 
176
// Virtual screen info
177
static int curX = 0;  // Last used position
178
static int curY = 0;
179
static int width = LCD_WIDTH / (FONT_WIDTH*NIBBLES_PER_PIXEL);
180
static int height = LCD_HEIGHT / (FONT_HEIGHT*SCREEN_SCALE);
181
static int fg = 0x0F;
182
static int bg = 0x00;
183
 
184
// Functions
185
static void lcd_drawc(cyg_int8 c, int x, int y);
186
 
187
void
188
lcd_on(int depth)
189
{
190
    cyg_int32 ctl_word = 0;
191
    lcd_depth = depth;
192
    switch (depth) {
193
    case 1:
194
        *(volatile cyg_int32 *)PALLSW = 0xF0F0F0F0;
195
        *(volatile cyg_int32 *)PALMSW = 0xF0F0F0F0;
196
        ctl_word = 0;
197
        break;
198
    case 2:
199
        *(volatile cyg_int32 *)PALLSW = 0xFA50FA50;
200
        *(volatile cyg_int32 *)PALMSW = 0xFA50FA50;
201
        ctl_word = LCDCON_GSEN;
202
        break;
203
    case 4:
204
        *(volatile cyg_int32 *)PALLSW = 0x76543210;
205
        *(volatile cyg_int32 *)PALMSW = 0xFEDCBA98;
206
        ctl_word = LCDCON_GSEN | LCDCON_GSMD;
207
        break;
208
    }
209
    // Video buffer size
210
    ctl_word |= ((lcd_width * lcd_height * lcd_depth) / 128 - 1) << LCDCON_BUFSIZ_S;
211
    // Line length
212
    ctl_word |= ((lcd_width / 16) - 1) << LCDCON_LINE_LENGTH_S;
213
    // Pixel prescale
214
    ctl_word |= ((526628 / (lcd_height * lcd_width)) - 1) << LCDCON_PIX_PRESCALE_S;
215
    // AC frequency bias
216
    ctl_word |= 0 << LCDCON_AC_PRESCALE_S;
217
    *(volatile cyg_int32 *)LCDCON = ctl_word;
218
    diag_printf("Depth: %d, ctl: %x\n", depth, ctl_word);
219
 
220
#ifdef ALPS_LH
221
#define LCD_DCDC      0x02
222
#define LCD_ENABLE    0x04
223
#define LCD_BACKLIGHT 0x08
224
#define LCD_INIT (LCD_DCDC|LCD_ENABLE|LCD_BACKLIGHT)
225
    *(volatile cyg_uint8 *)PDDDR   = 0x40;      // 1's are inputs (backwards from A/B/E)
226
    *(volatile cyg_uint8 *)PDDR    = LCD_INIT;  // Enable video + backlight + DC-DC converter
227
#else
228
#ifdef _CL7111
229
    *(volatile cyg_uint8 *)PDDR    = 0x20;  // Enable video
230
    *(volatile cyg_uint8 *)PEDDR   = 0x0F;  // Register E data direction
231
    *(volatile cyg_uint8 *)PEDR   |= 0x01;  // Enable PE2
232
 
233
    *(volatile cyg_uint32 *)PMPCON = 0x500; // Enable DC-to-DC pump #1
234
#endif
235
#endif
236
 
237
    *(volatile cyg_uint8 *)FRBADDR = 0x0C;  // Highest order nibble of LCD frame address
238
 
239
    *(volatile cyg_uint32 *)SYSCON1 |= SYSCON1_LCDEN;
240
}
241
 
242
// Clear screen
243
void
244
lcd_clear(void)
245
{
246
    cyg_int8 *ptr = lcd_base;
247
    int i;
248
    for (i = 0;  i < (lcd_width*lcd_height*lcd_depth)/8;  i++) {
249
        *ptr++ = 0;
250
    }
251
    curX = 0;  curY = 0;
252
    lcd_drawc(CURSOR_ON, curX, curY);
253
}
254
 
255
// Position cursor
256
void
257
lcd_moveto(int X, int Y)
258
{
259
    lcd_drawc(CURSOR_OFF, curX, curY);
260
    if (X < 0) X = 0;
261
    if (X >= width) X = width-1;
262
    curX = X;
263
    if (Y < 0) Y = 0;
264
    if (Y >= height) Y = height-1;
265
    curY = Y;
266
    lcd_drawc(CURSOR_ON, curX, curY);
267
}
268
 
269
// Render a character at position (X,Y) with current background/foreground
270
static void
271
lcd_drawc(cyg_int8 c, int x, int y)
272
{
273
    // Note: this only works for fonts which are a multiple of 8 bits wide!
274
    cyg_uint8 *bufptr, bits;
275
    int l, p, w;
276
    switch (lcd_depth) {
277
    case 1:
278
        bufptr = lcd_base + ((y * FONT_HEIGHT * (lcd_width*lcd_depth)) + (x * FONT_WIDTH)) / 8;
279
        for (l = 0;  l < FONT_HEIGHT;  l++) {
280
            *bufptr = font_table[c][l];
281
            bufptr += (lcd_width*lcd_depth)/8;
282
        }
283
        break;
284
    case 2:
285
        diag_printf("Depth 2 not implemented\n");
286
        break;
287
    case 4:
288
        bufptr = lcd_base + ((y * (FONT_HEIGHT*SCREEN_SCALE) * (lcd_width*lcd_depth))
289
                             + (x * (FONT_WIDTH*SCREEN_SCALE) * lcd_depth)) / 8;
290
        for (l = 0;  l < FONT_HEIGHT;  l++) {
291
            for (w = 0;  w < SCREEN_SCALE;  w++) {
292
                bits = font_table[c-FIRST_CHAR][l];
293
                for (p = 0;  p < 8;  p += PIXELS_PER_BYTE) {
294
                    switch (bits & PIXEL_MASK) {
295
                    case 0:
296
                        *bufptr++ = (bg << 4) | bg;
297
                        break;
298
                    case 1:
299
#if SCREEN_SCALE == 1
300
                        *bufptr++ = (bg << 4) | fg;
301
#else
302
                        *bufptr++ = (fg << 4) | fg;
303
#endif
304
                        break;
305
#if SCREEN_SCALE == 1
306
                    case 2:
307
                        *bufptr++ = (fg << 4) | bg;
308
                        break;
309
                    case 3:
310
                        *bufptr++ = (fg << 4) | fg;
311
                        break;
312
#endif
313
                    }
314
                    bits >>= PIXELS_PER_BYTE;
315
                }
316
                bufptr += (lcd_width*lcd_depth)/8 - (8/PIXELS_PER_BYTE);
317
            }
318
        }
319
        break;
320
    }
321
}
322
 
323
// Draw one character at the current position
324
void
325
lcd_putc(cyg_int8 c)
326
{
327
    lcd_drawc(CURSOR_OFF, curX, curY);
328
    switch (c) {
329
    case '\r':
330
        curX = 0;
331
        break;
332
    case '\n':
333
        curY++;
334
        break;
335
    case '\b':
336
        curX--;
337
        if (curX < 0) {
338
            curY--;
339
            if (curY < 0) curY = 0;
340
            curX = width-1;
341
        }
342
        break;
343
    default:
344
        lcd_drawc(c, curX, curY);
345
        curX++;
346
        if (curX == width) {
347
            curY++;
348
            curX = 0;
349
        }
350
    }
351
    lcd_drawc(CURSOR_ON, curX, curY);
352
}
353
 
354
// Basic LCD 'printf()' support
355
 
356
#ifndef FALSE
357
#define FALSE 0
358
#define TRUE  1
359
#endif
360
 
361
#include <stdarg.h>
362
 
363
#define is_digit(c) ((c >= '0') && (c <= '9'))
364
 
365
static int
366
_cvt(unsigned long val, char *buf, long radix, char *digits)
367
{
368
    char temp[80];
369
    char *cp = temp;
370
    int length = 0;
371
    if (val == 0) {
372
        /* Special case */
373
        *cp++ = '0';
374
    } else {
375
        while (val) {
376
            *cp++ = digits[val % radix];
377
            val /= radix;
378
        }
379
    }
380
    while (cp != temp) {
381
        *buf++ = *--cp;
382
        length++;
383
    }
384
    *buf = '\0';
385
    return (length);
386
}
387
 
388
int
389
lcd_vprintf(void (*putc)(cyg_int8), const char *fmt0, va_list ap)
390
{
391
    char c, sign, *cp;
392
    int left_prec, right_prec, zero_fill, length, pad, pad_on_right;
393
    char buf[32];
394
    long val;
395
    while ((c = *fmt0++)) {
396
        cp = buf;
397
        length = 0;
398
        if (c == '%') {
399
            c = *fmt0++;
400
            left_prec = right_prec = pad_on_right = 0;
401
            if (c == '-') {
402
                c = *fmt0++;
403
                pad_on_right++;
404
            }
405
            if (c == '0') {
406
                zero_fill = TRUE;
407
                c = *fmt0++;
408
            } else {
409
                zero_fill = FALSE;
410
            }
411
            while (is_digit(c)) {
412
                left_prec = (left_prec * 10) + (c - '0');
413
                c = *fmt0++;
414
            }
415
            if (c == '.') {
416
                c = *fmt0++;
417
                zero_fill++;
418
                while (is_digit(c)) {
419
                    right_prec = (right_prec * 10) + (c - '0');
420
                    c = *fmt0++;
421
                }
422
            } else {
423
                right_prec = left_prec;
424
            }
425
            sign = '\0';
426
            switch (c) {
427
            case 'd':
428
            case 'x':
429
            case 'X':
430
                val = va_arg(ap, long);
431
                switch (c) {
432
                case 'd':
433
                    if (val < 0) {
434
                        sign = '-';
435
                        val = -val;
436
                    }
437
                    length = _cvt(val, buf, 10, "0123456789");
438
                    break;
439
                case 'x':
440
                    length = _cvt(val, buf, 16, "0123456789abcdef");
441
                    break;
442
                case 'X':
443
                    length = _cvt(val, buf, 16, "0123456789ABCDEF");
444
                    break;
445
                }
446
                break;
447
            case 's':
448
                cp = va_arg(ap, char *);
449
                length = strlen(cp);
450
                break;
451
            case 'c':
452
                c = va_arg(ap, long /*char*/);
453
                (*putc)(c);
454
                continue;
455
            default:
456
                (*putc)('?');
457
            }
458
            pad = left_prec - length;
459
            if (sign != '\0') {
460
                pad--;
461
            }
462
            if (zero_fill) {
463
                c = '0';
464
                if (sign != '\0') {
465
                    (*putc)(sign);
466
                    sign = '\0';
467
                }
468
            } else {
469
                c = ' ';
470
            }
471
            if (!pad_on_right) {
472
                while (pad-- > 0) {
473
                    (*putc)(c);
474
                }
475
            }
476
            if (sign != '\0') {
477
                (*putc)(sign);
478
            }
479
            while (length-- > 0) {
480
                (*putc)(c = *cp++);
481
                if (c == '\n') {
482
                    (*putc)('\r');
483
                }
484
            }
485
            if (pad_on_right) {
486
                while (pad-- > 0) {
487
                    (*putc)(' ');
488
                }
489
            }
490
        } else {
491
            (*putc)(c);
492
            if (c == '\n') {
493
                (*putc)('\r');
494
            }
495
        }
496
    }
497
}
498
 
499
int
500
lcd_printf(char const *fmt, ...)
501
{
502
        int ret;
503
        va_list ap;
504
 
505
        va_start(ap, fmt);
506
        ret = lcd_vprintf(lcd_putc, fmt, ap);
507
        va_end(ap);
508
        return (ret);
509
}
510
 

powered by: WebSVN 2.1.0

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