123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- /*
- * (C) Copyright 2001-2014
- * DENX Software Engineering -- wd@denx.de
- * Compulab Ltd - http://compulab.co.il/
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
- #include <common.h>
- #include <lcd.h>
- #include <video_font.h> /* Get font data, width and height */
- #define CONSOLE_ROW_SIZE (VIDEO_FONT_HEIGHT * lcd_line_length)
- #define CONSOLE_ROW_FIRST lcd_console_address
- #define CONSOLE_SIZE (CONSOLE_ROW_SIZE * console_rows)
- static short console_curr_col;
- static short console_curr_row;
- static short console_cols;
- static short console_rows;
- static void *lcd_console_address;
- void lcd_init_console(void *address, int rows, int cols)
- {
- console_curr_col = 0;
- console_curr_row = 0;
- console_cols = cols;
- console_rows = rows;
- lcd_console_address = address;
- }
- void lcd_set_col(short col)
- {
- console_curr_col = col;
- }
- void lcd_set_row(short row)
- {
- console_curr_row = row;
- }
- void lcd_position_cursor(unsigned col, unsigned row)
- {
- console_curr_col = min_t(short, col, console_cols - 1);
- console_curr_row = min_t(short, row, console_rows - 1);
- }
- int lcd_get_screen_rows(void)
- {
- return console_rows;
- }
- int lcd_get_screen_columns(void)
- {
- return console_cols;
- }
- static void lcd_putc_xy(ushort x, ushort y, char c)
- {
- uchar *dest;
- ushort row;
- int fg_color = lcd_getfgcolor();
- int bg_color = lcd_getbgcolor();
- int i;
- dest = (uchar *)(lcd_console_address +
- y * lcd_line_length + x * NBITS(LCD_BPP) / 8);
- for (row = 0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) {
- #if LCD_BPP == LCD_COLOR16
- ushort *d = (ushort *)dest;
- #elif LCD_BPP == LCD_COLOR32
- u32 *d = (u32 *)dest;
- #else
- uchar *d = dest;
- #endif
- uchar bits;
- bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
- for (i = 0; i < 8; ++i) {
- *d++ = (bits & 0x80) ? fg_color : bg_color;
- bits <<= 1;
- }
- }
- }
- static void console_scrollup(void)
- {
- const int rows = CONFIG_CONSOLE_SCROLL_LINES;
- int bg_color = lcd_getbgcolor();
- /* Copy up rows ignoring those that will be overwritten */
- memcpy(CONSOLE_ROW_FIRST,
- lcd_console_address + CONSOLE_ROW_SIZE * rows,
- CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows);
- /* Clear the last rows */
- #if (LCD_BPP != LCD_COLOR32)
- memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows,
- bg_color, CONSOLE_ROW_SIZE * rows);
- #else
- u32 *ppix = lcd_console_address +
- CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows;
- u32 i;
- for (i = 0;
- i < (CONSOLE_ROW_SIZE * rows) / NBYTES(panel_info.vl_bpix);
- i++) {
- *ppix++ = bg_color;
- }
- #endif
- lcd_sync();
- console_curr_row -= rows;
- }
- static inline void console_back(void)
- {
- if (--console_curr_col < 0) {
- console_curr_col = console_cols - 1;
- if (--console_curr_row < 0)
- console_curr_row = 0;
- }
- lcd_putc_xy(console_curr_col * VIDEO_FONT_WIDTH,
- console_curr_row * VIDEO_FONT_HEIGHT, ' ');
- }
- static inline void console_newline(void)
- {
- console_curr_col = 0;
- /* Check if we need to scroll the terminal */
- if (++console_curr_row >= console_rows)
- console_scrollup();
- else
- lcd_sync();
- }
- void lcd_putc(const char c)
- {
- if (!lcd_is_enabled) {
- serial_putc(c);
- return;
- }
- switch (c) {
- case '\r':
- console_curr_col = 0;
- return;
- case '\n':
- console_newline();
- return;
- case '\t': /* Tab (8 chars alignment) */
- console_curr_col += 8;
- console_curr_col &= ~7;
- if (console_curr_col >= console_cols)
- console_newline();
- return;
- case '\b':
- console_back();
- return;
- default:
- lcd_putc_xy(console_curr_col * VIDEO_FONT_WIDTH,
- console_curr_row * VIDEO_FONT_HEIGHT, c);
- if (++console_curr_col >= console_cols)
- console_newline();
- }
- }
- void lcd_puts(const char *s)
- {
- if (!lcd_is_enabled) {
- serial_puts(s);
- return;
- }
- while (*s)
- lcd_putc(*s++);
- lcd_sync();
- }
- void lcd_printf(const char *fmt, ...)
- {
- va_list args;
- char buf[CONFIG_SYS_PBSIZE];
- va_start(args, fmt);
- vsprintf(buf, fmt, args);
- va_end(args);
- lcd_puts(buf);
- }
- static int do_lcd_setcursor(cmd_tbl_t *cmdtp, int flag, int argc,
- char *const argv[])
- {
- unsigned int col, row;
- if (argc != 3)
- return CMD_RET_USAGE;
- col = simple_strtoul(argv[1], NULL, 10);
- row = simple_strtoul(argv[2], NULL, 10);
- lcd_position_cursor(col, row);
- return 0;
- }
- static int do_lcd_puts(cmd_tbl_t *cmdtp, int flag, int argc,
- char *const argv[])
- {
- if (argc != 2)
- return CMD_RET_USAGE;
- lcd_puts(argv[1]);
- return 0;
- }
- U_BOOT_CMD(
- setcurs, 3, 1, do_lcd_setcursor,
- "set cursor position within screen",
- " <col> <row> in character"
- );
- U_BOOT_CMD(
- lcdputs, 2, 1, do_lcd_puts,
- "print string on lcd-framebuffer",
- " <string>"
- );
|