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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [arm/] [edb7xxx/] [current/] [misc/] [lcd_support.c] - Blame information for rev 786

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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