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