]> git.ipfire.org Git - people/ms/u-boot.git/blob - common/lcd_console.c
common/lcd_console: move single static variables into common (static) structure
[people/ms/u-boot.git] / common / lcd_console.c
1 /*
2 * (C) Copyright 2001-2014
3 * DENX Software Engineering -- wd@denx.de
4 * Compulab Ltd - http://compulab.co.il/
5 *
6 * SPDX-License-Identifier: GPL-2.0+
7 */
8
9 #include <common.h>
10 #include <lcd.h>
11 #include <video_font.h> /* Get font data, width and height */
12
13 #define CONSOLE_ROW_SIZE (VIDEO_FONT_HEIGHT * lcd_line_length)
14 #define CONSOLE_ROW_FIRST cons.lcd_address
15 #define CONSOLE_SIZE (CONSOLE_ROW_SIZE * cons.rows)
16
17 struct console_t {
18 short curr_col, curr_row;
19 short cols, rows;
20 void *lcd_address;
21 };
22 static struct console_t cons;
23
24 void lcd_init_console(void *address, int rows, int cols)
25 {
26 memset(&cons, 0, sizeof(cons));
27 cons.cols = cols;
28 cons.rows = rows;
29 cons.lcd_address = address;
30
31 }
32
33 void lcd_set_col(short col)
34 {
35 cons.curr_col = col;
36 }
37
38 void lcd_set_row(short row)
39 {
40 cons.curr_row = row;
41 }
42
43 void lcd_position_cursor(unsigned col, unsigned row)
44 {
45 cons.curr_col = min_t(short, col, cons.cols - 1);
46 cons.curr_row = min_t(short, row, cons.rows - 1);
47 }
48
49 int lcd_get_screen_rows(void)
50 {
51 return cons.rows;
52 }
53
54 int lcd_get_screen_columns(void)
55 {
56 return cons.cols;
57 }
58
59 static void lcd_putc_xy(ushort x, ushort y, char c)
60 {
61 uchar *dest;
62 ushort row;
63 int fg_color = lcd_getfgcolor();
64 int bg_color = lcd_getbgcolor();
65 int i;
66
67 dest = (uchar *)(cons.lcd_address +
68 y * lcd_line_length + x * NBITS(LCD_BPP) / 8);
69
70 for (row = 0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) {
71 #if LCD_BPP == LCD_COLOR16
72 ushort *d = (ushort *)dest;
73 #elif LCD_BPP == LCD_COLOR32
74 u32 *d = (u32 *)dest;
75 #else
76 uchar *d = dest;
77 #endif
78 uchar bits;
79 bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
80
81 for (i = 0; i < 8; ++i) {
82 *d++ = (bits & 0x80) ? fg_color : bg_color;
83 bits <<= 1;
84 }
85 }
86 }
87
88 static void console_scrollup(void)
89 {
90 const int rows = CONFIG_CONSOLE_SCROLL_LINES;
91 int bg_color = lcd_getbgcolor();
92
93 /* Copy up rows ignoring those that will be overwritten */
94 memcpy(CONSOLE_ROW_FIRST,
95 cons.lcd_address + CONSOLE_ROW_SIZE * rows,
96 CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows);
97
98 /* Clear the last rows */
99 #if (LCD_BPP != LCD_COLOR32)
100 memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows,
101 bg_color, CONSOLE_ROW_SIZE * rows);
102 #else
103 u32 *ppix = cons.lcd_address +
104 CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows;
105 u32 i;
106 for (i = 0;
107 i < (CONSOLE_ROW_SIZE * rows) / NBYTES(panel_info.vl_bpix);
108 i++) {
109 *ppix++ = bg_color;
110 }
111 #endif
112 lcd_sync();
113 cons.curr_row -= rows;
114 }
115
116 static inline void console_back(void)
117 {
118 if (--cons.curr_col < 0) {
119 cons.curr_col = cons.cols - 1;
120 if (--cons.curr_row < 0)
121 cons.curr_row = 0;
122 }
123
124 lcd_putc_xy(cons.curr_col * VIDEO_FONT_WIDTH,
125 cons.curr_row * VIDEO_FONT_HEIGHT, ' ');
126 }
127
128 static inline void console_newline(void)
129 {
130 cons.curr_col = 0;
131
132 /* Check if we need to scroll the terminal */
133 if (++cons.curr_row >= cons.rows)
134 console_scrollup();
135 else
136 lcd_sync();
137 }
138
139 void lcd_putc(const char c)
140 {
141 if (!lcd_is_enabled) {
142 serial_putc(c);
143
144 return;
145 }
146
147 switch (c) {
148 case '\r':
149 cons.curr_col = 0;
150 return;
151 case '\n':
152 console_newline();
153
154 return;
155 case '\t': /* Tab (8 chars alignment) */
156 cons.curr_col += 8;
157 cons.curr_col &= ~7;
158
159 if (cons.curr_col >= cons.cols)
160 console_newline();
161
162 return;
163 case '\b':
164 console_back();
165
166 return;
167 default:
168 lcd_putc_xy(cons.curr_col * VIDEO_FONT_WIDTH,
169 cons.curr_row * VIDEO_FONT_HEIGHT, c);
170 if (++cons.curr_col >= cons.cols)
171 console_newline();
172 }
173 }
174
175 void lcd_puts(const char *s)
176 {
177 if (!lcd_is_enabled) {
178 serial_puts(s);
179
180 return;
181 }
182
183 while (*s)
184 lcd_putc(*s++);
185
186 lcd_sync();
187 }
188
189 void lcd_printf(const char *fmt, ...)
190 {
191 va_list args;
192 char buf[CONFIG_SYS_PBSIZE];
193
194 va_start(args, fmt);
195 vsprintf(buf, fmt, args);
196 va_end(args);
197
198 lcd_puts(buf);
199 }
200
201 static int do_lcd_setcursor(cmd_tbl_t *cmdtp, int flag, int argc,
202 char *const argv[])
203 {
204 unsigned int col, row;
205
206 if (argc != 3)
207 return CMD_RET_USAGE;
208
209 col = simple_strtoul(argv[1], NULL, 10);
210 row = simple_strtoul(argv[2], NULL, 10);
211 lcd_position_cursor(col, row);
212
213 return 0;
214 }
215
216 static int do_lcd_puts(cmd_tbl_t *cmdtp, int flag, int argc,
217 char *const argv[])
218 {
219 if (argc != 2)
220 return CMD_RET_USAGE;
221
222 lcd_puts(argv[1]);
223
224 return 0;
225 }
226
227 U_BOOT_CMD(
228 setcurs, 3, 1, do_lcd_setcursor,
229 "set cursor position within screen",
230 " <col> <row> in character"
231 );
232
233 U_BOOT_CMD(
234 lcdputs, 2, 1, do_lcd_puts,
235 "print string on lcd-framebuffer",
236 " <string>"
237 );
238