* [U-Boot] [RFC 1/4] common: add ansi console base implementation
2015-03-13 22:49 [U-Boot] [RFC 0/4] ansi console support for lcd driver Andrey Danin
@ 2015-03-13 22:49 ` Andrey Danin
2015-03-18 13:06 ` Nikita Kiryanov
2015-03-13 22:49 ` [U-Boot] [RFC 2/4] video: cfb_console: use common ansi implementation Andrey Danin
` (3 subsequent siblings)
4 siblings, 1 reply; 10+ messages in thread
From: Andrey Danin @ 2015-03-13 22:49 UTC (permalink / raw)
To: u-boot
This code is based on ansi implementation in cfb_console.
It is adopted to be used in lcd and cfb_console drivers.
Signed-off-by: Andrey Danin <danindrey@mail.ru>
---
common/ansi_console.c | 355 +++++++++++++++++++++++++++++++++++++++++++++++++
include/ansi_console.h | 39 ++++++
2 files changed, 394 insertions(+)
create mode 100644 common/ansi_console.c
create mode 100644 include/ansi_console.h
diff --git a/common/ansi_console.c b/common/ansi_console.c
new file mode 100644
index 0000000..08adc1b
--- /dev/null
+++ b/common/ansi_console.c
@@ -0,0 +1,355 @@
+#include <ansi_console.h>
+
+#define COL (*(console->console_col))
+#define ROW (*(console->console_row))
+
+#ifdef CONFIG_CONSOLE_ANSI_EXTENSION_ENABLED
+static void cursor_fix(struct ansi_console_t *console)
+{
+ if (ROW < 0)
+ ROW = 0;
+ if (ROW >= console->rows)
+ ROW = console->rows - 1;
+ if (COL < 0)
+ COL = 0;
+ if (COL >= console->cols)
+ COL = console->cols - 1;
+}
+
+static void cursor_set_position(struct ansi_console_t *console,
+ int row, int col)
+{
+ if (ROW != -1)
+ ROW = row;
+ if (COL != -1)
+ COL = col;
+ cursor_fix(console);
+}
+#endif /* CONFIG_CONSOLE_ANSI_EXTENSION_ENABLED */
+
+static inline void cursor_up(struct ansi_console_t *console, int n)
+{
+ ROW -= n;
+ if (ROW < 0)
+ ROW = 0;
+}
+
+static inline void cursor_down(struct ansi_console_t *console, int n)
+{
+ ROW += n;
+ if (ROW >= console->rows)
+ ROW = console->rows - 1;
+}
+
+static inline void cursor_left(struct ansi_console_t *console, int n)
+{
+ COL -= n;
+ if (COL < 0)
+ COL = 0;
+}
+
+static inline void cursor_right(struct ansi_console_t *console, int n)
+{
+ COL += n;
+ if (COL >= console->cols)
+ COL = console->cols - 1;
+}
+
+static inline void console_previous_line(struct ansi_console_t *console, int n)
+{
+ COL = 0;
+ ROW -= n;
+
+ /* Check if we need to scroll the terminal */
+ if (ROW < 0) {
+ if (console->scroll)
+ console->scroll(1 - ROW);
+ } else if (console->sync) {
+ console->sync();
+ }
+}
+
+static void console_new_line(struct ansi_console_t *console, int n)
+{
+ COL = 0;
+ ROW += n;
+
+ /* Check if we need to scroll the terminal */
+ if (ROW >= console->rows) {
+ if (console->scroll)
+ console->scroll(console->rows - ROW + 1);
+ ROW = console->rows - 1;
+ } else if (console->sync) {
+ console->sync();
+ }
+}
+
+static void console_caret_return(struct ansi_console_t *console)
+{
+ COL = 0;
+}
+
+static inline void console_back(struct ansi_console_t *console)
+{
+ if (--COL < 0) {
+ COL = console->cols - 1;
+ if (--ROW < 0)
+ ROW = 0;
+ }
+
+ console->putc_cr(COL, ROW, ' ');
+}
+
+
+static void console_putc(struct ansi_console_t *console, const char c)
+{
+ switch (c) {
+ case '\r': /* back to first column */
+ console_caret_return(console);
+ break;
+
+ case '\n': /* next line */
+ console_new_line(console, 1);
+ break;
+
+ case '\t': /* tab 8 */
+ COL |= 0x0008;
+ COL &= ~0x0007;
+
+ if (COL >= console->cols)
+ console_new_line(console, 1);
+ break;
+
+ case '\b': /* backspace */
+ console_back(console);
+ break;
+
+ case 7: /* bell */
+ break; /* ignored */
+
+ default: /* draw the char */
+ console->putc_cr(COL, ROW, c);
+ COL++;
+
+ /* check for new line */
+ if (COL >= console->cols)
+ console_new_line(console, 1);
+ }
+}
+
+
+void ansi_putc(struct ansi_console_t *console, const char c)
+{
+#ifdef CONFIG_CONSOLE_ANSI_EXTENSION_ENABLED
+ int i;
+
+ if (c == 27) {
+ for (i = 0; i < console->ansi_buf_size; ++i)
+ console_putc(console, console->ansi_buf[i]);
+ console->ansi_buf[0] = 27;
+ console->ansi_buf_size = 1;
+ return;
+ }
+
+ if (console->ansi_buf_size > 0) {
+ /*
+ * 0 - ESC
+ * 1 - [
+ * 2 - num1
+ * 3 - ..
+ * 4 - ;
+ * 5 - num2
+ * 6 - ..
+ * - cchar
+ */
+ int next = 0;
+
+ int flush = 0;
+ int fail = 0;
+
+ int num1 = 0;
+ int num2 = 0;
+ int cchar = 0;
+
+ console->ansi_buf[console->ansi_buf_size++] = c;
+
+ if (console->ansi_buf_size >= sizeof(console->ansi_buf))
+ fail = 1;
+
+ for (i = 0; i < console->ansi_buf_size; ++i) {
+ if (fail)
+ break;
+
+ switch (next) {
+ case 0:
+ if (console->ansi_buf[i] == 27)
+ next = 1;
+ else
+ fail = 1;
+ break;
+
+ case 1:
+ if (console->ansi_buf[i] == '[')
+ next = 2;
+ else
+ fail = 1;
+ break;
+
+ case 2:
+ if (console->ansi_buf[i] >= '0' &&
+ console->ansi_buf[i] <= '9') {
+ num1 = console->ansi_buf[i]-'0';
+ next = 3;
+ } else if (console->ansi_buf[i] != '?') {
+ --i;
+ num1 = 1;
+ next = 4;
+ }
+ break;
+
+ case 3:
+ if (console->ansi_buf[i] >= '0' &&
+ console->ansi_buf[i] <= '9') {
+ num1 *= 10;
+ num1 += console->ansi_buf[i]-'0';
+ } else {
+ --i;
+ next = 4;
+ }
+ break;
+
+ case 4:
+ if (console->ansi_buf[i] != ';') {
+ --i;
+ next = 7;
+ } else {
+ next = 5;
+ }
+ break;
+
+ case 5:
+ if (console->ansi_buf[i] >= '0' &&
+ console->ansi_buf[i] <= '9') {
+ num2 = console->ansi_buf[i]-'0';
+ next = 6;
+ } else {
+ fail = 1;
+ }
+ break;
+
+ case 6:
+ if (console->ansi_buf[i] >= '0' &&
+ console->ansi_buf[i] <= '9') {
+ num2 *= 10;
+ num2 += console->ansi_buf[i]-'0';
+ } else {
+ --i;
+ next = 7;
+ }
+ break;
+
+ case 7:
+ if ((console->ansi_buf[i] >= 'A' &&
+ console->ansi_buf[i] <= 'H') ||
+ console->ansi_buf[i] == 'J' ||
+ console->ansi_buf[i] == 'K' ||
+ console->ansi_buf[i] == 'h' ||
+ console->ansi_buf[i] == 'l' ||
+ console->ansi_buf[i] == 'm') {
+ cchar = console->ansi_buf[i];
+ flush = 1;
+ } else {
+ fail = 1;
+ }
+ break;
+ }
+ }
+
+ if (fail) {
+ for (i = 0; i < console->ansi_buf_size; ++i)
+ console_putc(console, console->ansi_buf[i]);
+ console->ansi_buf_size = 0;
+ return;
+ }
+
+ if (flush) {
+ if (!console->ansi_cursor_hidden &&
+ console->cursor_enable)
+ console->cursor_enable(0);
+ console->ansi_buf_size = 0;
+ switch (cchar) {
+ case 'A':
+ /* move cursor num1 rows up */
+ cursor_up(console, num1);
+ break;
+ case 'B':
+ /* move cursor num1 rows down */
+ cursor_down(console, num1);
+ break;
+ case 'C':
+ /* move cursor num1 columns forward */
+ cursor_right(console, num1);
+ break;
+ case 'D':
+ /* move cursor num1 columns back */
+ cursor_left(console, num1);
+ break;
+ case 'E':
+ /* move cursor num1 rows up at begin of row */
+ console_previous_line(console, num1);
+ break;
+ case 'F':
+ /* move cursor num1 rows down at begin of row */
+ console_new_line(console, num1);
+ break;
+ case 'G':
+ /* move cursor to column num1 */
+ cursor_set_position(console, -1, num1-1);
+ break;
+ case 'H':
+ /* move cursor to row num1, column num2 */
+ cursor_set_position(console, num1-1, num2-1);
+ break;
+ case 'J':
+ /* clear console and move cursor to 0, 0 */
+ console->clear();
+ cursor_set_position(console, 0, 0);
+ break;
+ case 'K':
+ /* clear line */
+ if (num1 == 0)
+ console->clear_line(ROW, COL, -1);
+ else if (num1 == 1)
+ console->clear_line(ROW, 0, COL);
+ else
+ console->clear_line(ROW, 0, -1);
+ break;
+ case 'h':
+ console->ansi_cursor_hidden = 0;
+ break;
+ case 'l':
+ console->ansi_cursor_hidden = 1;
+ break;
+ case 'm':
+ if (num1 == 0) { /* reset swapped colors */
+ if (console->ansi_colors_need_revert &&
+ console->swap_colors) {
+ console->swap_colors();
+ console->ansi_colors_need_revert = 0;
+ }
+ } else if (num1 == 7) { /* once swap colors */
+ if (!console->ansi_colors_need_revert &&
+ console->swap_colors) {
+ console->swap_colors();
+ console->ansi_colors_need_revert = 1;
+ }
+ }
+ break;
+ }
+ if (!console->ansi_cursor_hidden && console->cursor_set)
+ console->cursor_set();
+ }
+ } else
+#endif /* CONFIG_ANSI_CONSOLE_EXTENSION_ENABLED */
+ console_putc(console, c);
+}
diff --git a/include/ansi_console.h b/include/ansi_console.h
new file mode 100644
index 0000000..b7ec094
--- /dev/null
+++ b/include/ansi_console.h
@@ -0,0 +1,39 @@
+/*
+ * (C) Copyright 2012
+ * Pali Roh?r <pali.rohar@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*
+ * ANSI terminal
+ */
+
+#include <common.h>
+
+struct ansi_console_t {
+ void (*putc_cr)(int col, int row, const char c);
+
+ void (*clear_line)(int line, int begin, int end);
+
+ void (*clear)(void);
+ void (*swap_colors)(void);
+
+ /* Optional */
+ void (*cursor_set)(void);
+ void (*cursor_enable)(int state);
+ void (*sync)(void);
+ void (*scroll)(int n);
+
+ int cols;
+ int rows;
+ int *console_col;
+ int *console_row;
+
+ char ansi_buf[10];
+ int ansi_buf_size;
+ int ansi_colors_need_revert;
+ int ansi_cursor_hidden;
+};
+
+void ansi_putc(struct ansi_console_t *console, const char c);
--
1.9.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [U-Boot] [RFC 1/4] common: add ansi console base implementation
2015-03-13 22:49 ` [U-Boot] [RFC 1/4] common: add ansi console base implementation Andrey Danin
@ 2015-03-18 13:06 ` Nikita Kiryanov
0 siblings, 0 replies; 10+ messages in thread
From: Nikita Kiryanov @ 2015-03-18 13:06 UTC (permalink / raw)
To: u-boot
Hi Andrey,
On 03/14/2015 12:49 AM, Andrey Danin wrote:
> This code is based on ansi implementation in cfb_console.
> It is adopted to be used in lcd and cfb_console drivers.
Please describe what changes you have made (if any) from the original code.
>
> Signed-off-by: Andrey Danin <danindrey@mail.ru>
> ---
> common/ansi_console.c | 355 +++++++++++++++++++++++++++++++++++++++++++++++++
> include/ansi_console.h | 39 ++++++
> 2 files changed, 394 insertions(+)
> create mode 100644 common/ansi_console.c
> create mode 100644 include/ansi_console.h
>
[...]
> +
> +static void console_putc(struct ansi_console_t *console, const char c)
> +{
> + switch (c) {
> + case '\r': /* back to first column */
> + console_caret_return(console);
> + break;
> +
> + case '\n': /* next line */
> + console_new_line(console, 1);
> + break;
> +
> + case '\t': /* tab 8 */
> + COL |= 0x0008;
> + COL &= ~0x0007;
This seems buggy. Not only does this limit us to one tab, it can potentially move the cursor
backwards. The LCD version of COL += 8 seems more correct.
--
Regards,
Nikita Kiryanov
^ permalink raw reply [flat|nested] 10+ messages in thread
* [U-Boot] [RFC 2/4] video: cfb_console: use common ansi implementation
2015-03-13 22:49 [U-Boot] [RFC 0/4] ansi console support for lcd driver Andrey Danin
2015-03-13 22:49 ` [U-Boot] [RFC 1/4] common: add ansi console base implementation Andrey Danin
@ 2015-03-13 22:49 ` Andrey Danin
2015-03-13 22:49 ` [U-Boot] [RFC 3/4] lcd: use ansi console Andrey Danin
` (2 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Andrey Danin @ 2015-03-13 22:49 UTC (permalink / raw)
To: u-boot
Signed-off-by: Andrey Danin <danindrey@mail.ru>
---
drivers/video/Makefile | 2 +-
drivers/video/cfb_console.c | 381 ++++----------------------------------------
2 files changed, 33 insertions(+), 350 deletions(-)
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 22a316b..0819ee9 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -8,7 +8,7 @@
obj-$(CONFIG_ATI_RADEON_FB) += ati_radeon_fb.o videomodes.o
obj-$(CONFIG_ATMEL_HLCD) += atmel_hlcdfb.o
obj-$(CONFIG_ATMEL_LCD) += atmel_lcdfb.o
-obj-$(CONFIG_CFB_CONSOLE) += cfb_console.o
+obj-$(CONFIG_CFB_CONSOLE) += cfb_console.o ansi_console.o
obj-$(CONFIG_EXYNOS_DP) += exynos_dp.o exynos_dp_lowlevel.o
obj-$(CONFIG_EXYNOS_FB) += exynos_fb.o exynos_fimd.o
obj-$(CONFIG_EXYNOS_MIPI_DSIM) += exynos_mipi_dsi.o exynos_mipi_dsi_common.o \
diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
index a81affa..f3e3f28 100644
--- a/drivers/video/cfb_console.c
+++ b/drivers/video/cfb_console.c
@@ -91,6 +91,12 @@
#include <malloc.h>
#include <linux/compiler.h>
+#ifdef CONFIG_CFB_CONSOLE_ANSI
+#define CONFIG_ANSI_CONSOLE_EXTENSION_ENABLED
+#endif
+#include <ansi_console.h>
+
+
/*
* Console device defines with SMI graphic
* Any other graphic must change this section
@@ -300,11 +306,6 @@ void console_cursor(int state);
#define CONSOLE_ROW_LAST (video_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE)
#define CONSOLE_SIZE (CONSOLE_ROW_SIZE * CONSOLE_ROWS)
-/* By default we scroll by a single line */
-#ifndef CONFIG_CONSOLE_SCROLL_LINES
-#define CONFIG_CONSOLE_SCROLL_LINES 1
-#endif
-
/* Macros */
#ifdef VIDEO_FB_LITTLE_ENDIAN
#define SWAP16(x) ((((x) & 0x00ff) << 8) | \
@@ -361,12 +362,7 @@ static u32 eorx, fgx, bgx; /* color pats */
static int cfb_do_flush_cache;
-#ifdef CONFIG_CFB_CONSOLE_ANSI
-static char ansi_buf[10];
-static int ansi_buf_size;
-static int ansi_colors_need_revert;
-static int ansi_cursor_hidden;
-#endif
+static struct ansi_console_t ansi_console;
static const int video_font_draw_table8[] = {
0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
@@ -624,6 +620,12 @@ static void video_putchar(int xx, int yy, unsigned char c)
video_drawchars(xx, yy + video_logo_height, &c, 1);
}
+static void video_putchar_cr(int col, int row, const char c)
+{
+ video_putchar(col * VIDEO_FONT_WIDTH, row * VIDEO_FONT_HEIGHT,
+ (unsigned char)c);
+}
+
#if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR)
static void video_set_cursor(void)
{
@@ -742,9 +744,8 @@ static void console_clear_line(int line, int begin, int end)
#endif
}
-static void console_scrollup(void)
+static void console_scrollup(int rows)
{
- const int rows = CONFIG_CONSOLE_SCROLL_LINES;
int i;
/* copy up rows ignoring the first one */
@@ -773,20 +774,6 @@ static void console_scrollup(void)
console_row -= rows;
}
-static void console_back(void)
-{
- console_col--;
-
- if (console_col < 0) {
- console_col = CONSOLE_COLS - 1;
- console_row--;
- if (console_row < 0)
- console_row = 0;
- }
-}
-
-#ifdef CONFIG_CFB_CONSOLE_ANSI
-
static void console_clear(void)
{
#ifdef VIDEO_HW_RECTFILL
@@ -802,58 +789,6 @@ static void console_clear(void)
#endif
}
-static void console_cursor_fix(void)
-{
- if (console_row < 0)
- console_row = 0;
- if (console_row >= CONSOLE_ROWS)
- console_row = CONSOLE_ROWS - 1;
- if (console_col < 0)
- console_col = 0;
- if (console_col >= CONSOLE_COLS)
- console_col = CONSOLE_COLS - 1;
-}
-
-static void console_cursor_up(int n)
-{
- console_row -= n;
- console_cursor_fix();
-}
-
-static void console_cursor_down(int n)
-{
- console_row += n;
- console_cursor_fix();
-}
-
-static void console_cursor_left(int n)
-{
- console_col -= n;
- console_cursor_fix();
-}
-
-static void console_cursor_right(int n)
-{
- console_col += n;
- console_cursor_fix();
-}
-
-static void console_cursor_set_position(int row, int col)
-{
- if (console_row != -1)
- console_row = row;
- if (console_col != -1)
- console_col = col;
- console_cursor_fix();
-}
-
-static void console_previousline(int n)
-{
- /* FIXME: also scroll terminal ? */
- console_row -= n;
- console_cursor_fix();
-}
-
static void console_swap_colors(void)
{
eorx = fgx;
@@ -864,76 +799,15 @@ static void console_swap_colors(void)
static inline int console_cursor_is_visible(void)
{
- return !ansi_cursor_hidden;
-}
-#else
-static inline int console_cursor_is_visible(void)
-{
- return 1;
-}
-#endif
-
-static void console_newline(int n)
-{
- console_row += n;
- console_col = 0;
-
- /* Check if we need to scroll the terminal */
- if (console_row >= CONSOLE_ROWS) {
- /* Scroll everything up */
- console_scrollup();
- }
-}
-
-static void console_cr(void)
-{
- console_col = 0;
+ return !ansi_console.ansi_cursor_hidden;
}
static void parse_putc(const char c)
{
- static int nl = 1;
-
if (console_cursor_is_visible())
CURSOR_OFF;
- switch (c) {
- case 13: /* back to first column */
- console_cr();
- break;
-
- case '\n': /* next line */
- if (console_col || (!console_col && nl))
- console_newline(1);
- nl = 1;
- break;
-
- case 9: /* tab 8 */
- console_col |= 0x0008;
- console_col &= ~0x0007;
-
- if (console_col >= CONSOLE_COLS)
- console_newline(1);
- break;
-
- case 8: /* backspace */
- console_back();
- break;
-
- case 7: /* bell */
- break; /* ignored */
-
- default: /* draw the char */
- video_putchar(console_col * VIDEO_FONT_WIDTH,
- console_row * VIDEO_FONT_HEIGHT, c);
- console_col++;
-
- /* check for newline */
- if (console_col >= CONSOLE_COLS) {
- console_newline(1);
- nl = 0;
- }
- }
+ ansi_putc(&ansi_console, c);
if (console_cursor_is_visible())
CURSOR_SET;
@@ -941,214 +815,7 @@ static void parse_putc(const char c)
static void video_putc(struct stdio_dev *dev, const char c)
{
-#ifdef CONFIG_CFB_CONSOLE_ANSI
- int i;
-
- if (c == 27) {
- for (i = 0; i < ansi_buf_size; ++i)
- parse_putc(ansi_buf[i]);
- ansi_buf[0] = 27;
- ansi_buf_size = 1;
- return;
- }
-
- if (ansi_buf_size > 0) {
- /*
- * 0 - ESC
- * 1 - [
- * 2 - num1
- * 3 - ..
- * 4 - ;
- * 5 - num2
- * 6 - ..
- * - cchar
- */
- int next = 0;
-
- int flush = 0;
- int fail = 0;
-
- int num1 = 0;
- int num2 = 0;
- int cchar = 0;
-
- ansi_buf[ansi_buf_size++] = c;
-
- if (ansi_buf_size >= sizeof(ansi_buf))
- fail = 1;
-
- for (i = 0; i < ansi_buf_size; ++i) {
- if (fail)
- break;
-
- switch (next) {
- case 0:
- if (ansi_buf[i] == 27)
- next = 1;
- else
- fail = 1;
- break;
-
- case 1:
- if (ansi_buf[i] == '[')
- next = 2;
- else
- fail = 1;
- break;
-
- case 2:
- if (ansi_buf[i] >= '0' && ansi_buf[i] <= '9') {
- num1 = ansi_buf[i]-'0';
- next = 3;
- } else if (ansi_buf[i] != '?') {
- --i;
- num1 = 1;
- next = 4;
- }
- break;
-
- case 3:
- if (ansi_buf[i] >= '0' && ansi_buf[i] <= '9') {
- num1 *= 10;
- num1 += ansi_buf[i]-'0';
- } else {
- --i;
- next = 4;
- }
- break;
-
- case 4:
- if (ansi_buf[i] != ';') {
- --i;
- next = 7;
- } else
- next = 5;
- break;
-
- case 5:
- if (ansi_buf[i] >= '0' && ansi_buf[i] <= '9') {
- num2 = ansi_buf[i]-'0';
- next = 6;
- } else
- fail = 1;
- break;
-
- case 6:
- if (ansi_buf[i] >= '0' && ansi_buf[i] <= '9') {
- num2 *= 10;
- num2 += ansi_buf[i]-'0';
- } else {
- --i;
- next = 7;
- }
- break;
-
- case 7:
- if ((ansi_buf[i] >= 'A' && ansi_buf[i] <= 'H')
- || ansi_buf[i] == 'J'
- || ansi_buf[i] == 'K'
- || ansi_buf[i] == 'h'
- || ansi_buf[i] == 'l'
- || ansi_buf[i] == 'm') {
- cchar = ansi_buf[i];
- flush = 1;
- } else
- fail = 1;
- break;
- }
- }
-
- if (fail) {
- for (i = 0; i < ansi_buf_size; ++i)
- parse_putc(ansi_buf[i]);
- ansi_buf_size = 0;
- return;
- }
-
- if (flush) {
- if (!ansi_cursor_hidden)
- CURSOR_OFF;
- ansi_buf_size = 0;
- switch (cchar) {
- case 'A':
- /* move cursor num1 rows up */
- console_cursor_up(num1);
- break;
- case 'B':
- /* move cursor num1 rows down */
- console_cursor_down(num1);
- break;
- case 'C':
- /* move cursor num1 columns forward */
- console_cursor_right(num1);
- break;
- case 'D':
- /* move cursor num1 columns back */
- console_cursor_left(num1);
- break;
- case 'E':
- /* move cursor num1 rows up at begin of row */
- console_previousline(num1);
- break;
- case 'F':
- /* move cursor num1 rows down@begin of row */
- console_newline(num1);
- break;
- case 'G':
- /* move cursor to column num1 */
- console_cursor_set_position(-1, num1-1);
- break;
- case 'H':
- /* move cursor to row num1, column num2 */
- console_cursor_set_position(num1-1, num2-1);
- break;
- case 'J':
- /* clear console and move cursor to 0, 0 */
- console_clear();
- console_cursor_set_position(0, 0);
- break;
- case 'K':
- /* clear line */
- if (num1 == 0)
- console_clear_line(console_row,
- console_col,
- CONSOLE_COLS-1);
- else if (num1 == 1)
- console_clear_line(console_row,
- 0, console_col);
- else
- console_clear_line(console_row,
- 0, CONSOLE_COLS-1);
- break;
- case 'h':
- ansi_cursor_hidden = 0;
- break;
- case 'l':
- ansi_cursor_hidden = 1;
- break;
- case 'm':
- if (num1 == 0) { /* reset swapped colors */
- if (ansi_colors_need_revert) {
- console_swap_colors();
- ansi_colors_need_revert = 0;
- }
- } else if (num1 == 7) { /* once swap colors */
- if (!ansi_colors_need_revert) {
- console_swap_colors();
- ansi_colors_need_revert = 1;
- }
- }
- break;
- }
- if (!ansi_cursor_hidden)
- CURSOR_SET;
- }
- } else {
- parse_putc(c);
- }
-#else
parse_putc(c);
-#endif
if (cfb_do_flush_cache)
flush_cache(VIDEO_FB_ADRS, VIDEO_SIZE);
}
@@ -2234,6 +1901,22 @@ static int video_init(void)
if (cfb_do_flush_cache)
flush_cache(VIDEO_FB_ADRS, VIDEO_SIZE);
+ memset(&ansi_console, 0, sizeof(ansi_console));
+ ansi_console.putc_cr = video_putchar_cr;
+ ansi_console.cols = CONSOLE_COLS;
+ ansi_console.rows = CONSOLE_ROWS;
+
+#if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR)
+ ansi_console.cursor_set = video_set_cursor;
+ ansi_console.cursor_enable = console_cursor;
+#endif
+ ansi_console.scroll = console_scrollup;
+ ansi_console.clear_line = console_clear_line;
+ ansi_console.clear = console_clear;
+ ansi_console.swap_colors = console_swap_colors;
+ ansi_console.console_col = &console_col;
+ ansi_console.console_row = &console_row;
+
return 0;
}
--
1.9.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [U-Boot] [RFC 3/4] lcd: use ansi console
2015-03-13 22:49 [U-Boot] [RFC 0/4] ansi console support for lcd driver Andrey Danin
2015-03-13 22:49 ` [U-Boot] [RFC 1/4] common: add ansi console base implementation Andrey Danin
2015-03-13 22:49 ` [U-Boot] [RFC 2/4] video: cfb_console: use common ansi implementation Andrey Danin
@ 2015-03-13 22:49 ` Andrey Danin
2015-03-13 22:49 ` [U-Boot] [RFC 4/4] paz00: enable bootmenu Andrey Danin
2015-03-18 12:58 ` [U-Boot] [RFC 0/4] ansi console support for lcd driver Nikita Kiryanov
4 siblings, 0 replies; 10+ messages in thread
From: Andrey Danin @ 2015-03-13 22:49 UTC (permalink / raw)
To: u-boot
Signed-off-by: Andrey Danin <danindrey@mail.ru>
---
common/Makefile | 2 +-
common/lcd.c | 24 ----------
common/lcd_console.c | 122 +++++++++++++++++++++++++++++---------------------
include/lcd_console.h | 33 ++++++++++++++
4 files changed, 105 insertions(+), 76 deletions(-)
diff --git a/common/Makefile b/common/Makefile
index 7216a13..790d76d 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -199,7 +199,7 @@ obj-$(CONFIG_I2C_EDID) += edid.o
obj-$(CONFIG_KALLSYMS) += kallsyms.o
obj-y += splash.o
obj-$(CONFIG_SPLASH_SOURCE) += splash_source.o
-obj-$(CONFIG_LCD) += lcd.o lcd_console.o
+obj-$(CONFIG_LCD) += lcd.o lcd_console.o ansi_console.o
obj-$(CONFIG_LCD_DT_SIMPLEFB) += lcd_simplefb.o
obj-$(CONFIG_LYNXKDI) += lynxkdi.o
obj-$(CONFIG_MENU) += menu.o
diff --git a/common/lcd.c b/common/lcd.c
index f33942c..d408e08 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -47,11 +47,7 @@ DECLARE_GLOBAL_DATA_PTR;
static int lcd_init(void *lcdbase);
static void lcd_logo(void);
-static void lcd_setfgcolor(int color);
-static void lcd_setbgcolor(int color);
-static int lcd_color_fg;
-static int lcd_color_bg;
int lcd_line_length;
char lcd_is_enabled = 0;
static void *lcd_base; /* Start of framebuffer memory */
@@ -311,26 +307,6 @@ ulong lcd_setmem(ulong addr)
return addr;
}
-static void lcd_setfgcolor(int color)
-{
- lcd_color_fg = color;
-}
-
-int lcd_getfgcolor(void)
-{
- return lcd_color_fg;
-}
-
-static void lcd_setbgcolor(int color)
-{
- lcd_color_bg = color;
-}
-
-int lcd_getbgcolor(void)
-{
- return lcd_color_bg;
-}
-
#ifdef CONFIG_LCD_LOGO
__weak void lcd_logo_set_cmap(void)
{
diff --git a/common/lcd_console.c b/common/lcd_console.c
index 8bf83b9..b30fa3a 100644
--- a/common/lcd_console.c
+++ b/common/lcd_console.c
@@ -7,6 +7,7 @@
*/
#include <common.h>
+#include <ansi_console.h>
#include <lcd.h>
#include <video_font.h> /* Get font data, width and height */
@@ -14,11 +15,19 @@
#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 int console_curr_col;
+static int console_curr_row;
+static int console_cols;
+static int console_rows;
static void *lcd_console_address;
+static int lcd_color_fg;
+static int lcd_color_bg;
+
+static struct ansi_console_t ansi_console;
+
+static inline void lcd_putc_cr(int col, int row, const char c);
+static void console_scrollup(int rows);
+static inline void console_clear_line(int line, int begin, int end);
void lcd_init_console(void *address, int rows, int cols)
{
@@ -27,6 +36,23 @@ void lcd_init_console(void *address, int rows, int cols)
console_cols = cols;
console_rows = rows;
lcd_console_address = address;
+
+ memset(&ansi_console, 0, sizeof(ansi_console));
+ ansi_console.putc_cr = lcd_putc_cr;
+ ansi_console.cols = console_cols;
+ ansi_console.rows = console_rows;
+#if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR)
+#warning Cursor is not implemented for LCD ANSI console
+ ansi_console.cursor_set = NULL;
+ ansi_console.cursor_enable = NULL;
+#endif
+ ansi_console.sync = lcd_sync;
+ ansi_console.scroll = console_scrollup;
+ ansi_console.clear_line = console_clear_line;
+ ansi_console.clear = lcd_clear;
+ ansi_console.swap_colors = lcd_swap_colors;
+ ansi_console.console_col = &console_curr_col;
+ ansi_console.console_row = &console_curr_row;
}
void lcd_set_col(short col)
@@ -39,6 +65,33 @@ void lcd_set_row(short row)
console_curr_row = row;
}
+int lcd_getbgcolor(void)
+{
+ return lcd_color_bg;
+}
+
+void lcd_setbgcolor(int color)
+{
+ lcd_color_bg = color;
+}
+
+int lcd_getfgcolor(void)
+{
+ return lcd_color_fg;
+}
+
+void lcd_setfgcolor(int color)
+{
+ lcd_color_fg = color;
+}
+
+void lcd_swap_colors(void)
+{
+ int tmp = lcd_getbgcolor();
+ lcd_setbgcolor(lcd_getfgcolor());
+ lcd_setfgcolor(tmp);
+}
+
void lcd_position_cursor(unsigned col, unsigned row)
{
console_curr_col = min_t(short, col, console_cols - 1);
@@ -96,9 +149,13 @@ static inline void lcd_putc_xy(ushort x, ushort y, uchar c)
lcd_drawchars(x, y, &c, 1);
}
-static void console_scrollup(void)
+static inline void lcd_putc_cr(int col, int row, const char c)
+{
+ lcd_putc_xy(col * VIDEO_FONT_WIDTH, row * VIDEO_FONT_HEIGHT, (uchar)c);
+}
+
+static void console_scrollup(int rows)
{
- const int rows = CONFIG_CONSOLE_SCROLL_LINES;
int bg_color = lcd_getbgcolor();
/* Copy up rows ignoring those that will be overwritten */
@@ -124,27 +181,16 @@ static void console_scrollup(void)
console_curr_row -= rows;
}
-static inline void console_back(void)
+static inline void console_clear_line(int line, int begin, int end)
{
- if (--console_curr_col < 0) {
- console_curr_col = console_cols - 1;
- if (--console_curr_row < 0)
- console_curr_row = 0;
- }
+ short i = 0;
- lcd_putc_xy(console_curr_col * VIDEO_FONT_WIDTH,
- console_curr_row * VIDEO_FONT_HEIGHT, ' ');
-}
+ if (end == -1)
+ end = console_cols - 1;
-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();
+ for (i = begin; i < end; ++i)
+ lcd_putc_xy(i * VIDEO_FONT_WIDTH,
+ line * VIDEO_FONT_HEIGHT, ' ');
}
void lcd_putc(const char c)
@@ -155,33 +201,7 @@ void lcd_putc(const char 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();
- }
+ ansi_putc(&ansi_console, c);
}
void lcd_puts(const char *s)
diff --git a/include/lcd_console.h b/include/lcd_console.h
index 429214d..ea66ddb 100644
--- a/include/lcd_console.h
+++ b/include/lcd_console.h
@@ -40,6 +40,39 @@ void lcd_set_col(short col);
void lcd_set_row(short row);
/**
+ * lcd_getbgcolor() - Get current background color value
+ *
+ * @return: Color value
+ */
+int lcd_getbgcolor(void);
+
+/**
+ * lcd_setbgcolor() - Set background color value
+ *
+ * @color: Color value
+ */
+void lcd_setbgcolor(int color);
+
+/**
+ * lcd_getfgcolor() - Get current foreground color value
+ *
+ * @return: Color value
+ */
+int lcd_getfgcolor(void);
+
+/**
+ * lcd_setfgcolor() - Set foreground color value
+ *
+ * @color: Color value
+ */
+void lcd_setfgcolor(int color);
+
+/**
+ * lcd_swap_colors() - Swap background and foreground color values
+ */
+void lcd_swap_colors(void);
+
+/**
* lcd_position_cursor() - Position the cursor on the screen
*
* Position the cursor at the given coordinates on the screen.
--
1.9.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [U-Boot] [RFC 4/4] paz00: enable bootmenu
2015-03-13 22:49 [U-Boot] [RFC 0/4] ansi console support for lcd driver Andrey Danin
` (2 preceding siblings ...)
2015-03-13 22:49 ` [U-Boot] [RFC 3/4] lcd: use ansi console Andrey Danin
@ 2015-03-13 22:49 ` Andrey Danin
2015-03-16 18:14 ` Stephen Warren
2015-03-18 12:58 ` [U-Boot] [RFC 0/4] ansi console support for lcd driver Nikita Kiryanov
4 siblings, 1 reply; 10+ messages in thread
From: Andrey Danin @ 2015-03-13 22:49 UTC (permalink / raw)
To: u-boot
Signed-off-by: Andrey Danin <danindrey@mail.ru>
---
include/configs/paz00.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/include/configs/paz00.h b/include/configs/paz00.h
index 284419f..17063d0 100644
--- a/include/configs/paz00.h
+++ b/include/configs/paz00.h
@@ -64,6 +64,11 @@
#define CONFIG_SYS_WHITE_ON_BLACK
#define CONFIG_CONSOLE_SCROLL_LINES 10
+#define CONFIG_CONSOLE_ANSI_EXTENSION_ENABLED
+#define CONFIG_CMD_BOOTMENU
+#define CONFIG_MENU
+#define CONFIG_AUTOBOOT_KEYED
+
#include "tegra-common-post.h"
#endif /* __CONFIG_H */
--
1.9.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [U-Boot] [RFC 4/4] paz00: enable bootmenu
2015-03-13 22:49 ` [U-Boot] [RFC 4/4] paz00: enable bootmenu Andrey Danin
@ 2015-03-16 18:14 ` Stephen Warren
2015-03-17 7:58 ` Andrey Danin
0 siblings, 1 reply; 10+ messages in thread
From: Stephen Warren @ 2015-03-16 18:14 UTC (permalink / raw)
To: u-boot
On 03/13/2015 04:49 PM, Andrey Danin wrote:
> Signed-off-by: Andrey Danin <danindrey@mail.ru>
Some explanation of what these new options do might be nice; the
features/benefits they enable.
Are any of the options generally useful? If so, should they be enabled
in tegra-common*.h?
You also didn't Cc Tom Warren (Tegra maintainer) so he likely won't see
the emails and hence won't apply this patch.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [U-Boot] [RFC 4/4] paz00: enable bootmenu
2015-03-16 18:14 ` Stephen Warren
@ 2015-03-17 7:58 ` Andrey Danin
2015-03-17 15:14 ` Stephen Warren
0 siblings, 1 reply; 10+ messages in thread
From: Andrey Danin @ 2015-03-17 7:58 UTC (permalink / raw)
To: u-boot
On 16.03.2015 21:14, Stephen Warren wrote:
> On 03/13/2015 04:49 PM, Andrey Danin wrote:
>> Signed-off-by: Andrey Danin <danindrey@mail.ru>
>
> Some explanation of what these new options do might be nice; the
> features/benefits they enable.
>
> Are any of the options generally useful? If so, should they be enabled
> in tegra-common*.h?
>
> You also didn't Cc Tom Warren (Tegra maintainer) so he likely won't see
> the emails and hence won't apply this patch.
Thanks for the reply Stephen! I will add Tom Warren to Cc next time.
Bootmenu allows to create user friendly menu to choose different boot
options. For example next 3 lines in boot config
---
setenv bootmenu_0 "Boot kernel = setenv bootargs ..."
setenv bootmenu_1 "Boot recovery = setenv bootargs ..."
bootmenu 20
---
will generate bootmenu with 3 options:
---
*** U-Boot Boot Menu ***
Boot kernel
Boot recovery
U-Boot console
Press UP/DOWN to move, ENTER to select
---
More information about bootmenu is available at doc/README.bootmenu
I was focused on console part for this RFC. This patch is for testing
purposes. I will use tegra config instead of paz00 next time to allow
other users of tegra devices to try changes.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [U-Boot] [RFC 4/4] paz00: enable bootmenu
2015-03-17 7:58 ` Andrey Danin
@ 2015-03-17 15:14 ` Stephen Warren
0 siblings, 0 replies; 10+ messages in thread
From: Stephen Warren @ 2015-03-17 15:14 UTC (permalink / raw)
To: u-boot
On 03/17/2015 01:58 AM, Andrey Danin wrote:
> On 16.03.2015 21:14, Stephen Warren wrote:
>> On 03/13/2015 04:49 PM, Andrey Danin wrote:
>>> Signed-off-by: Andrey Danin <danindrey@mail.ru>
>>
>> Some explanation of what these new options do might be nice; the
>> features/benefits they enable.
>>
>> Are any of the options generally useful? If so, should they be enabled
>> in tegra-common*.h?
>>
>> You also didn't Cc Tom Warren (Tegra maintainer) so he likely won't see
>> the emails and hence won't apply this patch.
>
> Thanks for the reply Stephen! I will add Tom Warren to Cc next time.
>
>
> Bootmenu allows to create user friendly menu to choose different boot
> options. For example next 3 lines in boot config
> ---
> setenv bootmenu_0 "Boot kernel = setenv bootargs ..."
> setenv bootmenu_1 "Boot recovery = setenv bootargs ..."
> bootmenu 20
> ---
> will generate bootmenu with 3 options:
> ---
> *** U-Boot Boot Menu ***
>
> Boot kernel
> Boot recovery
> U-Boot console
>
>
> Press UP/DOWN to move, ENTER to select
> ---
>
> More information about bootmenu is available at doc/README.bootmenu
OK. Might it be better to use an extlinux.conf file? It already has
support for displaying a menu for all the options in the file, and
allowing the user to select which to boot. (Although I suspect the
extlinux.conf menu could be prettied up some). I suppose your example
above are more than just selecting which kernel to boot though, so
perhaps extlinux.conf wouldn't work.
> I was focused on console part for this RFC. This patch is for testing
> purposes. I will use tegra config instead of paz00 next time to allow
> other users of tegra devices to try changes.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [U-Boot] [RFC 0/4] ansi console support for lcd driver
2015-03-13 22:49 [U-Boot] [RFC 0/4] ansi console support for lcd driver Andrey Danin
` (3 preceding siblings ...)
2015-03-13 22:49 ` [U-Boot] [RFC 4/4] paz00: enable bootmenu Andrey Danin
@ 2015-03-18 12:58 ` Nikita Kiryanov
4 siblings, 0 replies; 10+ messages in thread
From: Nikita Kiryanov @ 2015-03-18 12:58 UTC (permalink / raw)
To: u-boot
Hi Andrey,
On 03/14/2015 12:49 AM, Andrey Danin wrote:
> Main reason for this patches is ability to use bootmenu
> on devices that use lcd driver (like Toshiba AC100).
>
> Lcd driver doesn't have ansi support while cfb_console does.
> Ansi related code was moved from cfb_console to separate place.
> Then this code was used in both cfb_console and lcd driver.
>
> There are other duplicated code between cfb_console and lcd.
>
> I'm not very experienced with video subsystem. Maybe there is a
> better/more proper way to add ansi support for Toshiba AC100.
I think you have the right idea. As you pointed out, there's a lot of
duplication between lcd code and video code which should be eliminated,
and this is a step in that direction.
Hannes Petermaier is currently also working on lcd console functionality
(Introduce lcd_console rotation), and I recommend that you sync with his
patches (V2 has just been posted).
>
> ---
>
> Andrey Danin (4):
> common: add ansi console base implementation
> video: cfb_console: use common ansi implementation
> lcd: use ansi console
> paz00: enable bootmenu
>
> common/Makefile | 2 +-
> common/ansi_console.c | 355 +++++++++++++++++++++++++++++++++++++++++
> common/lcd.c | 24 ---
> common/lcd_console.c | 122 ++++++++------
> drivers/video/Makefile | 2 +-
> drivers/video/cfb_console.c | 381 ++++----------------------------------------
> include/ansi_console.h | 39 +++++
> include/configs/paz00.h | 5 +
> include/lcd_console.h | 33 ++++
> 9 files changed, 537 insertions(+), 426 deletions(-)
> create mode 100644 common/ansi_console.c
> create mode 100644 include/ansi_console.h
>
--
Regards,
Nikita Kiryanov
^ permalink raw reply [flat|nested] 10+ messages in thread