[U-Boot] [PATCH 1/2] lcd: allow to not draw the logo when clearing the screen

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD plagnioj@jcrosoft.com --- common/lcd.c | 23 ++++++++++++++++------- 1 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/common/lcd.c b/common/lcd.c index 74a5c77..b5e81f1 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -78,7 +78,7 @@ static inline void lcd_putc_xy (ushort x, ushort y, uchar c);
static int lcd_init (void *lcdbase);
-static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]); +static int lcd_clear (int draw_logo); extern void lcd_ctrl_init (void *lcdbase); extern void lcd_enable (void); static void *lcd_logo (void); @@ -379,7 +379,12 @@ int drv_lcd_init (void) }
/*----------------------------------------------------------------------*/ -static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +static int do_lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + return lcd_clear(1); +} + +static int lcd_clear(int draw_logo) { #if LCD_BPP == LCD_MONOCHROME /* Setting the palette */ @@ -414,9 +419,13 @@ static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) COLOR_MASK(lcd_getbgcolor()), lcd_line_length*panel_info.vl_row); #endif - /* Paint the logo and retrieve LCD base address */ - debug ("[LCD] Drawing the logo...\n"); - lcd_console_address = lcd_logo (); + if (draw_logo) { + /* Paint the logo and retrieve LCD base address */ + debug ("[LCD] Drawing the logo...\n"); + lcd_console_address = lcd_logo (); + } else { + lcd_console_address = lcd_base; + }
console_col = 0; console_row = 0; @@ -425,7 +434,7 @@ static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) }
U_BOOT_CMD( - cls, 1, 1, lcd_clear, + cls, 1, 1, do_lcd_clear, "clear screen", "" ); @@ -439,7 +448,7 @@ static int lcd_init (void *lcdbase)
lcd_ctrl_init (lcdbase); lcd_is_enabled = 1; - lcd_clear (NULL, 1, 1, NULL); /* dummy args */ + lcd_clear (1); lcd_enable ();
/* Initialize the console */

to use the new menu framework, clear and advance echo we need to add the following escape ansi support \e[%dJ, \e[m, \e[%dm, and \e[%d;%dH
Tested on at91sam9263ek
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD plagnioj@jcrosoft.com --- common/lcd.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 71 insertions(+), 0 deletions(-)
diff --git a/common/lcd.c b/common/lcd.c index b5e81f1..dbad380 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -34,6 +34,7 @@ #include <command.h> #include <stdarg.h> #include <linux/types.h> +#include <linux/ctype.h> #include <devices.h> #if defined(CONFIG_POST) #include <post.h> @@ -172,6 +173,23 @@ static inline void console_newline (void)
/*----------------------------------------------------------------------*/
+static void invert_fg_bg_color(void) +{ + int tmp; + + tmp = lcd_color_fg; + lcd_color_fg = lcd_color_bg; + lcd_color_bg = tmp; +} + +struct ansi_parsing_state { + int inprogress; + /* is FG/BG inverted */ + int inverted; + int *pos; + int val[2]; +} state; + void lcd_putc (const char c) { if (!lcd_is_enabled) { @@ -179,6 +197,55 @@ void lcd_putc (const char c) return; }
+ if (state.inprogress) { + switch (c) { + case '[': state.val[0] = state.val[1] = 0; + state.pos = state.val; + return; + case ';': + state.pos++; + return; + case 'H': + state.inprogress = 0; + if (state.val[0] > CONSOLE_ROWS || + state.val[1] > CONSOLE_COLS) { + return; + } + + if (state.val[0]) + console_row = state.val[0] - 1; + else + console_row = 0; + if (state.val[1]) + console_col = state.val[1] - 1; + else + console_col = 0; + return; + case 'J': + if (state.val[0] == 2) + lcd_clear(0); + state.inprogress = 0; + return; + case 'm': + if ((state.val[0] == 7) || + (state.val[0] == 0 && state.inverted)) { + invert_fg_bg_color(); + state.inverted = (state.val[0] == 7); + } + state.inprogress = 0; + return; + default: + if(!isdigit(c)) { + state.inprogress = 0; + break; + } else { + *state.pos *= 10; + *state.pos += c - '0'; + return; + } + } + } + switch (c) { case '\r': console_col = 0; return; @@ -198,6 +265,10 @@ void lcd_putc (const char c) case '\b': console_back(); return;
+ case '\e': /* Escape ANSI \e[%dJ, \e[m, \e[%dm, and \e[%d;%dH */ + state.inprogress = 1; + return; + default: lcd_putc_xy (console_col * VIDEO_FONT_WIDTH, console_row * VIDEO_FONT_HEIGHT, c);

Dear Jean-Christophe PLAGNIOL-VILLARD,
In message 1245613942-10693-2-git-send-email-plagnioj@jcrosoft.com you wrote:
to use the new menu framework, clear and advance echo we need to add the following escape ansi support \e[%dJ, \e[m, \e[%dm, and \e[%d;%dH
Tested on at91sam9263ek
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD plagnioj@jcrosoft.com
common/lcd.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 71 insertions(+), 0 deletions(-)
diff --git a/common/lcd.c b/common/lcd.c index b5e81f1..dbad380 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -34,6 +34,7 @@ #include <command.h> #include <stdarg.h> #include <linux/types.h> +#include <linux/ctype.h> #include <devices.h> #if defined(CONFIG_POST) #include <post.h> @@ -172,6 +173,23 @@ static inline void console_newline (void)
/*----------------------------------------------------------------------*/
+static void invert_fg_bg_color(void) +{
- int tmp;
- tmp = lcd_color_fg;
- lcd_color_fg = lcd_color_bg;
- lcd_color_bg = tmp;
+}
+struct ansi_parsing_state {
- int inprogress;
- /* is FG/BG inverted */
- int inverted;
- int *pos;
- int val[2];
+} state;
Please make this configurable, so we don't have to add this for all systems that don't need it.
void lcd_putc (const char c) { if (!lcd_is_enabled) { @@ -179,6 +197,55 @@ void lcd_putc (const char c) return; }
- if (state.inprogress) {
switch (c) {
case '[': state.val[0] = state.val[1] = 0;
state.pos = state.val;
return;
case ';':
state.pos++;
return;
case 'H':
state.inprogress = 0;
if (state.val[0] > CONSOLE_ROWS ||
state.val[1] > CONSOLE_COLS) {
return;
}
if (state.val[0])
console_row = state.val[0] - 1;
else
console_row = 0;
Empty line here, please.
if (state.val[1])
console_col = state.val[1] - 1;
else
console_col = 0;
return;
case 'J':
if (state.val[0] == 2)
lcd_clear(0);
state.inprogress = 0;
return;
case 'm':
if ((state.val[0] == 7) ||
(state.val[0] == 0 && state.inverted)) {
invert_fg_bg_color();
state.inverted = (state.val[0] == 7);
}
state.inprogress = 0;
return;
default:
if(!isdigit(c)) {
Please don't use negative logic - use "if (isdigit(c))" and swap the branches. And mind the space after "if", please.
Thanks.
Best regards,
Wolfgang Denk

Dear Jean-Christophe PLAGNIOL-VILLARD,
In message 1245613942-10693-1-git-send-email-plagnioj@jcrosoft.com you wrote:
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD plagnioj@jcrosoft.com
common/lcd.c | 23 ++++++++++++++++------- 1 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/common/lcd.c b/common/lcd.c index 74a5c77..b5e81f1 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -78,7 +78,7 @@ static inline void lcd_putc_xy (ushort x, ushort y, uchar c);
static int lcd_init (void *lcdbase);
-static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]); +static int lcd_clear (int draw_logo); extern void lcd_ctrl_init (void *lcdbase); extern void lcd_enable (void); static void *lcd_logo (void); @@ -379,7 +379,12 @@ int drv_lcd_init (void) }
/*----------------------------------------------------------------------*/ -static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +static int do_lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{
- return lcd_clear(1);
+}
Given the fact that we have exactly one place only where we call lcd_clear() [in lcd_init()], this just adds complexity and memory footprint without adding benefits. Please omit this part.
+static int lcd_clear(int draw_logo) { #if LCD_BPP == LCD_MONOCHROME /* Setting the palette */ @@ -414,9 +419,13 @@ static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) COLOR_MASK(lcd_getbgcolor()), lcd_line_length*panel_info.vl_row); #endif
- /* Paint the logo and retrieve LCD base address */
- debug ("[LCD] Drawing the logo...\n");
- lcd_console_address = lcd_logo ();
- if (draw_logo) {
/* Paint the logo and retrieve LCD base address */
debug ("[LCD] Drawing the logo...\n");
lcd_console_address = lcd_logo ();
- } else {
lcd_console_address = lcd_base;
- }
I wonder if there is any user out there who expects that the "cls" command will also draw the logo - I am pretty sure that this is actually a bug introduced when the lcd_clear() code was extracted from lcd_init() in commit 8655b6f8 nearly 5 years ago.
To me the current implementation makes no sense. I suggest to rather fix the origona bug, i. e. move the lcd_logo() call into lcd_init() so it gets done only once, and not when running the lcd_clear() function using the "cls" commandline interface.
Please rework, and resubmit. Thanks.
Best regards,
Wolfgang Denk

On 00:17 Sun 05 Jul , Wolfgang Denk wrote:
Dear Jean-Christophe PLAGNIOL-VILLARD,
In message 1245613942-10693-1-git-send-email-plagnioj@jcrosoft.com you wrote:
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD plagnioj@jcrosoft.com
common/lcd.c | 23 ++++++++++++++++------- 1 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/common/lcd.c b/common/lcd.c index 74a5c77..b5e81f1 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -78,7 +78,7 @@ static inline void lcd_putc_xy (ushort x, ushort y, uchar c);
static int lcd_init (void *lcdbase);
-static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]); +static int lcd_clear (int draw_logo); extern void lcd_ctrl_init (void *lcdbase); extern void lcd_enable (void); static void *lcd_logo (void); @@ -379,7 +379,12 @@ int drv_lcd_init (void) }
/*----------------------------------------------------------------------*/ -static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +static int do_lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{
- return lcd_clear(1);
+}
Given the fact that we have exactly one place only where we call lcd_clear() [in lcd_init()], this just adds complexity and memory footprint without adding benefits. Please omit this part.
use the patch 2/2 for the ainsi support
+static int lcd_clear(int draw_logo) { #if LCD_BPP == LCD_MONOCHROME /* Setting the palette */ @@ -414,9 +419,13 @@ static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) COLOR_MASK(lcd_getbgcolor()), lcd_line_length*panel_info.vl_row); #endif
- /* Paint the logo and retrieve LCD base address */
- debug ("[LCD] Drawing the logo...\n");
- lcd_console_address = lcd_logo ();
- if (draw_logo) {
/* Paint the logo and retrieve LCD base address */
debug ("[LCD] Drawing the logo...\n");
lcd_console_address = lcd_logo ();
- } else {
lcd_console_address = lcd_base;
- }
I wonder if there is any user out there who expects that the "cls" command will also draw the logo - I am pretty sure that this is actually a bug introduced when the lcd_clear() code was extracted from lcd_init() in commit 8655b6f8 nearly 5 years ago.
To me the current implementation makes no sense. I suggest to rather fix the origona bug, i. e. move the lcd_logo() call into lcd_init() so it gets done only once, and not when running the lcd_clear() function using the "cls" commandline interface.
so I prefer to remove the cls command and introduce the clear command which will be availlable for all output serial & lcd
Best Regards, J.

Dear Jean-Christophe PLAGNIOL-VILLARD,
In message 20090704222746.GE30172@game.jcrosoft.org you wrote:
--- a/common/lcd.c +++ b/common/lcd.c @@ -78,7 +78,7 @@ static inline void lcd_putc_xy (ushort x, ushort y, uchar c);
static int lcd_init (void *lcdbase);
-static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]); +static int lcd_clear (int draw_logo); extern void lcd_ctrl_init (void *lcdbase); extern void lcd_enable (void); static void *lcd_logo (void); @@ -379,7 +379,12 @@ int drv_lcd_init (void) }
/*----------------------------------------------------------------------*/ -static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +static int do_lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{
- return lcd_clear(1);
+}
Given the fact that we have exactly one place only where we call lcd_clear() [in lcd_init()], this just adds complexity and memory footprint without adding benefits. Please omit this part.
use the patch 2/2 for the ainsi support
I have no idea what "ainsi" is. Do you mean ANSI?
Also, patches have to be orthogonal. Thi scode is not needed (nor useful) here, so omit it here. It it is needed in some other patch, then please add it there.
- /* Paint the logo and retrieve LCD base address */
- debug ("[LCD] Drawing the logo...\n");
- lcd_console_address = lcd_logo ();
- if (draw_logo) {
/* Paint the logo and retrieve LCD base address */
debug ("[LCD] Drawing the logo...\n");
lcd_console_address = lcd_logo ();
- } else {
lcd_console_address = lcd_base;
- }
I wonder if there is any user out there who expects that the "cls" command will also draw the logo - I am pretty sure that this is actually a bug introduced when the lcd_clear() code was extracted from lcd_init() in commit 8655b6f8 nearly 5 years ago.
To me the current implementation makes no sense. I suggest to rather fix the origona bug, i. e. move the lcd_logo() call into lcd_init() so it gets done only once, and not when running the lcd_clear() function using the "cls" commandline interface.
so I prefer to remove the cls command and introduce the clear command which will be availlable for all output serial & lcd
Add a new command instead of fixing an (obvious?) bug? This makes no sense to me. Please rather fix the real bug.
Best regards,
Wolfgang Denk
participants (2)
-
Jean-Christophe PLAGNIOL-VILLARD
-
Wolfgang Denk