Hi Hannes,

On 03/18/15 09:37, Hannes Petermaier wrote:
> From: Hannes Petermaier <hannes.peterma...@br-automation.com>
> 
> Sometimes, for example if the display is mounted in portrait mode or even if 
> it
> mounted landscape but rotated by 180 degrees, we need to rotate our content of
> the display respectively the framebuffer, so that user can read the messages
> who are printed out.
> 
> For this we introduce the feature called "CONFIG_LCD_ROTATION", this may be
> defined in the board-configuration if needed. After this the lcd_console will
> be initialized with a given rotation from "vl_rot" out of "vidinfo_t" which is
> provided by the board specific code.
> 
> If CONFIG_LCD_ROTATION is not defined, the console will be initialized with
> 0 degrees rotation.
> 
> Signed-off-by: Hannes Petermaier <hannes.peterma...@br-automation.com>
> Signed-off-by: Hannes Petermaier <oe5...@oevsv.at>

[...]

> diff --git a/common/lcd_console.c b/common/lcd_console.c
> index cac77be..14fd890 100644
> --- a/common/lcd_console.c
> +++ b/common/lcd_console.c

[...]

> @@ -10,26 +11,16 @@
>  #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    cons.lcd_address
> -#define CONSOLE_SIZE         (CONSOLE_ROW_SIZE * cons.rows)
> +#if LCD_BPP == LCD_COLOR16
> +     #define fbptr_t ushort
> +#elif LCD_BPP == LCD_COLOR32
> +     #define fbptr_t u32
> +#else
> +     #define fbptr_t uchar
> +#endif
>  
> -struct console_t {
> -     short curr_col, curr_row;
> -     short cols, rows;
> -     void *lcd_address;
> -};
>  static struct console_t cons;
>  
> -void lcd_init_console(void *address, int rows, int cols)
> -{
> -     memset(&cons, 0, sizeof(cons));
> -     cons.cols = cols;
> -     cons.rows = rows;
> -     cons.lcd_address = address;
> -
> -}
> -
>  void lcd_set_col(short col)
>  {
>       cons.curr_col = col;
> @@ -56,61 +47,50 @@ int lcd_get_screen_columns(void)
>       return cons.cols;
>  }
>  
> -static void lcd_putc_xy(ushort x, ushort y, char c)
> +static void lcd_putc_xy0(struct console_t *pcons, ushort x, ushort y, char c)
>  {
> -     uchar *dest;
> -     ushort row;
>       int fg_color = lcd_getfgcolor();
>       int bg_color = lcd_getbgcolor();
> -     int i;
> -
> -     dest = (uchar *)(cons.lcd_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;
> +     int i, row;
> +     fbptr_t *dst = (fbptr_t *)pcons->lcd_address +
> +                               y * pcons->lcdsizex +
> +                               x;
> +
> +     for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
> +             uchar bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
> +             for (i = 0; i < VIDEO_FONT_WIDTH; ++i) {
> +                     *dst++ = (bits & 0x80) ? fg_color : bg_color;
>                       bits <<= 1;
>               }
> +             dst += (pcons->lcdsizex - VIDEO_FONT_WIDTH);
>       }
>  }
>  
> -static void console_scrollup(void)
> +static inline void console_setrow0(struct console_t *pcons, u32 row, int clr)
>  {
> -     const int rows = CONFIG_CONSOLE_SCROLL_LINES;
> -     int bg_color = lcd_getbgcolor();
> +     int i;
> +     fbptr_t *dst = (fbptr_t *)pcons->lcd_address +
> +                               row * VIDEO_FONT_HEIGHT *
> +                               pcons->lcdsizex;
>  
> -     /* Copy up rows ignoring those that will be overwritten */
> -     memcpy(CONSOLE_ROW_FIRST,
> -            cons.lcd_address + CONSOLE_ROW_SIZE * rows,
> -            CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows);
> +     for (i = 0; i < (VIDEO_FONT_HEIGHT * pcons->lcdsizex); i++)
> +             *dst++ = clr;
> +}
>  
> -     /* 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 = cons.lcd_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();
> -     cons.curr_row -= rows;
> +static inline void console_moverow0(struct console_t *pcons,
> +                                 u32 rowdst, u32 rowsrc)
> +{
> +     int i;
> +     fbptr_t *dst = (fbptr_t *)pcons->lcd_address +
> +                               rowdst * VIDEO_FONT_HEIGHT *
> +                               pcons->lcdsizex;
> +
> +     fbptr_t *src = (fbptr_t *)pcons->lcd_address +
> +                               rowsrc * VIDEO_FONT_HEIGHT *
> +                               pcons->lcdsizex;
> +
> +     for (i = 0; i < (VIDEO_FONT_HEIGHT * pcons->lcdsizex); i++)
> +             *dst++ = *src++;
>  }
>  
>  static inline void console_back(void)
> @@ -121,19 +101,65 @@ static inline void console_back(void)
>                       cons.curr_row = 0;
>       }
>  
> -     lcd_putc_xy(cons.curr_col * VIDEO_FONT_WIDTH,
> -                 cons.curr_row * VIDEO_FONT_HEIGHT, ' ');
> +     cons.fp_putc_xy(&cons,
> +                     cons.curr_col * VIDEO_FONT_WIDTH,
> +                     cons.curr_row * VIDEO_FONT_HEIGHT, ' ');
>  }
>  
>  static inline void console_newline(void)
>  {
> +     const int rows = CONFIG_CONSOLE_SCROLL_LINES;
> +     int bg_color = lcd_getbgcolor();
> +     int i;
> +
>       cons.curr_col = 0;
>  
>       /* Check if we need to scroll the terminal */
> -     if (++cons.curr_row >= cons.rows)
> -             console_scrollup();
> -     else
> -             lcd_sync();
> +     if (++cons.curr_row >= cons.rows) {
> +             for (i = 0; i < cons.rows-rows; i++)
> +                     cons.fp_console_moverow(&cons, i, i+rows);
> +             for (i = 0; i < rows; i++)
> +                     cons.fp_console_setrow(&cons, cons.rows-i-1, bg_color);
> +             cons.curr_row -= rows;
> +     }
> +     lcd_sync();
> +}
> +
> +static void console_calc_rowcol(struct console_t *pcons)
> +{
> +     pcons->cols = pcons->lcdsizex / VIDEO_FONT_WIDTH;
> +#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
> +     pcons->rows = (pcons->lcdsizey - BMP_LOGO_HEIGHT);
> +     pcons->rows /= VIDEO_FONT_HEIGHT;
> +#else
> +     pcons->rows = pcons->lcdsizey / VIDEO_FONT_HEIGHT;
> +#endif
> +}
> +
> +void __weak lcd_init_console_rot(struct console_t *pcons)
> +{
> +     return;
> +}
> +
> +void lcd_init_console(void *address, int vl_cols, int vl_rows, int vl_rot)
> +{
> +     memset(&cons, 0, sizeof(cons));
> +     cons.lcd_address = address;
> +
> +     cons.lcdsizex = vl_cols;
> +     cons.lcdsizey = vl_rows;
> +     cons.lcdrot = vl_rot;
> +
> +     cons.fp_putc_xy = &lcd_putc_xy0;
> +     cons.fp_console_moverow = &console_moverow0;
> +     cons.fp_console_setrow = &console_setrow0;
> +     console_calc_rowcol(&cons);

I think the above four lines is exactly what should be placed in the
__weak variant of lcd_init_console_rot() function (the one just above
this one).

> +
> +     lcd_init_console_rot(&cons);
> +
> +     debug("lcd_console: have %d/%d col/rws on scr %dx%d (%d deg rotated)\n",
> +           cons.cols, cons.rows, cons.lcdsizex, cons.lcdsizey, vl_rot);
> +

no need for the empty line here.

>  }
>  
>  void lcd_putc(const char c)
> @@ -165,8 +191,9 @@ void lcd_putc(const char c)
>  
>               return;
>       default:
> -             lcd_putc_xy(cons.curr_col * VIDEO_FONT_WIDTH,
> -                         cons.curr_row * VIDEO_FONT_HEIGHT, c);
> +             cons.fp_putc_xy(&cons,
> +                             cons.curr_col * VIDEO_FONT_WIDTH,
> +                             cons.curr_row * VIDEO_FONT_HEIGHT, c);
>               if (++cons.curr_col >= cons.cols)
>                       console_newline();
>       }
> @@ -235,4 +262,3 @@ U_BOOT_CMD(
>       "print string on lcd-framebuffer",
>       "    <string>"
>  );
> -
> diff --git a/common/lcd_console_rotation.c b/common/lcd_console_rotation.c
> new file mode 100644
> index 0000000..3b6bb4f
> --- /dev/null
> +++ b/common/lcd_console_rotation.c
> @@ -0,0 +1,216 @@
> +/*
> + * (C) Copyright 2015
> + * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
> + *
> + * SPDX-License-Identifier:  GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <lcd.h>
> +#include <video_font.h>              /* Get font data, width and height */
> +
> +#if LCD_BPP == LCD_COLOR16
> +     #define fbptr_t ushort
> +#elif LCD_BPP == LCD_COLOR32
> +     #define fbptr_t u32
> +#else
> +     #define fbptr_t uchar
> +#endif

That is a duplication of the code in lcd_console.c.
If we can get rid of these size games, probably we should have in the lcd.h,
or lcd_console.h, or ...

> +
> +static void lcd_putc_xy90(struct console_t *pcons, ushort x, ushort y, char 
> c)
> +{
> +     int fg_color = lcd_getfgcolor();
> +     int bg_color = lcd_getbgcolor();
> +     int col, i;
> +
> +     fbptr_t *dst = (fbptr_t *)pcons->lcd_address +
> +                               (x+1) * pcons->lcdsizex -
> +                               y;
> +
> +     uchar msk = 0x80;
> +     uchar *pfont = video_fontdata + c * VIDEO_FONT_HEIGHT;
> +     for (col = 0; col < VIDEO_FONT_WIDTH; ++col) {
> +             for (i = 0; i < VIDEO_FONT_HEIGHT; ++i)
> +                     *dst-- = (*(pfont + i) & msk) ? fg_color : bg_color;
> +             msk >>= 1;
> +             dst += (pcons->lcdsizex + VIDEO_FONT_HEIGHT);
> +     }
> +}
> +
> +static inline void console_setrow90(struct console_t *pcons, u32 row, int 
> clr)
> +{
> +     int i, j;
> +     fbptr_t *dst = (fbptr_t *)pcons->lcd_address +
> +                               pcons->lcdsizex -
> +                               row*VIDEO_FONT_HEIGHT+1;
> +
> +     for (j = 0; j < pcons->lcdsizey; j++) {
> +             for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
> +                     *dst-- = clr;
> +             dst += (pcons->lcdsizex + VIDEO_FONT_HEIGHT);
> +     }
> +}
> +
> +static inline void console_moverow90(struct console_t *pcons,
> +                                   u32 rowdst, u32 rowsrc)
> +{
> +     int i, j;
> +     fbptr_t *dst = (fbptr_t *)pcons->lcd_address +
> +                               pcons->lcdsizex -
> +                               (rowdst*VIDEO_FONT_HEIGHT+1);
> +
> +     fbptr_t *src = (fbptr_t *)pcons->lcd_address +
> +                               pcons->lcdsizex -
> +                               (rowsrc*VIDEO_FONT_HEIGHT+1);
> +
> +     for (j = 0; j < pcons->lcdsizey; j++) {
> +             for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
> +                     *dst-- = *src--;
> +             src += (pcons->lcdsizex + VIDEO_FONT_HEIGHT);
> +             dst += (pcons->lcdsizex + VIDEO_FONT_HEIGHT);
> +     }
> +}
> +static void lcd_putc_xy180(struct console_t *pcons, ushort x, ushort y, char 
> c)
> +{
> +     int fg_color = lcd_getfgcolor();
> +     int bg_color = lcd_getbgcolor();
> +     int i, row;
> +     fbptr_t *dst = (fbptr_t *)pcons->lcd_address +
> +                               pcons->lcdsizex +
> +                               pcons->lcdsizey * pcons->lcdsizex -
> +                               y * pcons->lcdsizex -
> +                               (x+1);
> +
> +     for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
> +             uchar bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
> +
> +             for (i = 0; i < VIDEO_FONT_WIDTH; ++i) {
> +                     *dst-- = (bits & 0x80) ? fg_color : bg_color;
> +                     bits <<= 1;
> +             }
> +             dst -= (pcons->lcdsizex - VIDEO_FONT_WIDTH);
> +     }
> +}
> +
> +static inline void console_setrow180(struct console_t *pcons, u32 row, int 
> clr)
> +{
> +     int i;
> +     fbptr_t *dst = (fbptr_t *)pcons->lcd_address +
> +                               (pcons->rows-row-1) * VIDEO_FONT_HEIGHT *
> +                               pcons->lcdsizex;
> +
> +     for (i = 0; i < (VIDEO_FONT_HEIGHT * pcons->lcdsizex); i++)
> +             *dst++ = clr;
> +}
> +
> +static inline void console_moverow180(struct console_t *pcons,
> +                                   u32 rowdst, u32 rowsrc)
> +{
> +     int i;
> +     fbptr_t *dst = (fbptr_t *)pcons->lcd_address +
> +                               (pcons->rows-rowdst-1) * VIDEO_FONT_HEIGHT *
> +                               pcons->lcdsizex;
> +
> +     fbptr_t *src = (fbptr_t *)pcons->lcd_address +
> +                               (pcons->rows-rowsrc-1) * VIDEO_FONT_HEIGHT *
> +                               pcons->lcdsizex;
> +
> +     for (i = 0; i < (VIDEO_FONT_HEIGHT * pcons->lcdsizex); i++)
> +             *dst++ = *src++;
> +}
> +
> +static void lcd_putc_xy270(struct console_t *pcons, ushort x, ushort y, char 
> c)
> +{
> +     int fg_color = lcd_getfgcolor();
> +     int bg_color = lcd_getbgcolor();
> +     int i, col;
> +     fbptr_t *dst = (fbptr_t *)pcons->lcd_address +
> +                               pcons->lcdsizey * pcons->lcdsizex -
> +                               (x+1) * pcons->lcdsizex +
> +                               y;
> +
> +     uchar msk = 0x80;
> +     uchar *pfont = video_fontdata + c * VIDEO_FONT_HEIGHT;
> +     for (col = 0; col < VIDEO_FONT_WIDTH; ++col) {
> +             for (i = 0; i < VIDEO_FONT_HEIGHT; ++i)
> +                     *dst++ = (*(pfont + i) & msk) ? fg_color : bg_color;
> +             msk >>= 1;
> +             dst -= (pcons->lcdsizex + VIDEO_FONT_HEIGHT);
> +     }
> +}
> +
> +static inline void console_setrow270(struct console_t *pcons, u32 row, int 
> clr)
> +{
> +     int i, j;
> +     fbptr_t *dst = (fbptr_t *)pcons->lcd_address +
> +                               row*VIDEO_FONT_HEIGHT;
> +
> +     for (j = 0; j < pcons->lcdsizey; j++) {
> +             for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
> +                     *dst++ = clr;
> +             dst += (pcons->lcdsizex - VIDEO_FONT_HEIGHT);
> +     }
> +}
> +
> +static inline void console_moverow270(struct console_t *pcons,
> +                                  u32 rowdst, u32 rowsrc)
> +{
> +     int i, j;
> +     fbptr_t *dst = (fbptr_t *)pcons->lcd_address +
> +                               rowdst*VIDEO_FONT_HEIGHT;
> +
> +     fbptr_t *src = (fbptr_t *)pcons->lcd_address +
> +                               rowsrc*VIDEO_FONT_HEIGHT;
> +
> +     for (j = 0; j < pcons->lcdsizey; j++) {
> +             for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
> +                     *dst++ = *src++;
> +             src += (pcons->lcdsizex - VIDEO_FONT_HEIGHT);
> +             dst += (pcons->lcdsizex - VIDEO_FONT_HEIGHT);
> +     }
> +}
> +
> +static void console_calc_rowcol_rot(struct console_t *pcons)
> +{
> +     u32 cols, rows;
> +
> +     if (pcons->lcdrot == 1 || pcons->lcdrot == 3) {
> +             cols = pcons->lcdsizey;
> +             rows = pcons->lcdsizex;
> +     } else {
> +             cols = pcons->lcdsizex;
> +             rows = pcons->lcdsizey;
> +     }
> +
> +     pcons->cols = cols / VIDEO_FONT_WIDTH;
> +#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
> +     pcons->rows = (rows - BMP_LOGO_HEIGHT);
> +     pcons->rows /= VIDEO_FONT_HEIGHT;
> +#else
> +     pcons->rows = rows / VIDEO_FONT_HEIGHT;
> +#endif
> +}
> +
> +void lcd_init_console_rot(struct console_t *pcons)
> +{
> +     if (pcons->lcdrot == 0) {
> +             return;
> +     } else if (pcons->lcdrot == 1) {
> +             pcons->fp_putc_xy = &lcd_putc_xy90;
> +             pcons->fp_console_moverow = &console_moverow90;
> +             pcons->fp_console_setrow = &console_setrow90;
> +     } else if (pcons->lcdrot == 2) {
> +             pcons->fp_putc_xy = &lcd_putc_xy180;
> +             pcons->fp_console_moverow = &console_moverow180;
> +             pcons->fp_console_setrow = &console_setrow180;
> +     } else if (pcons->lcdrot == 3) {
> +             pcons->fp_putc_xy = &lcd_putc_xy270;
> +             pcons->fp_console_moverow = &console_moverow270;
> +             pcons->fp_console_setrow = &console_setrow270;
> +     } else {
> +             puts("lcd_init_console_rot: invalid framebuffer rotation!\n");

How about
printf("%s: invalid framebuffer rotation!\n", __func__);
?

> +             puts("                      using def. 0 degree rotation.\n");
> +             return;
> +     }
> +     console_calc_rowcol_rot(pcons);
> +}
> diff --git a/include/lcd.h b/include/lcd.h
> index f049fd3..1329280 100644
> --- a/include/lcd.h
> +++ b/include/lcd.h
> @@ -51,6 +51,7 @@ void lcd_set_flush_dcache(int flush);
>  typedef struct vidinfo {
>       ushort  vl_col;         /* Number of columns (i.e. 160) */
>       ushort  vl_row;         /* Number of rows (i.e. 100) */
> +     ushort  vl_rot;         /* Rotation of Display (0, 1, 2, 3) */
>       u_char  vl_bpix;        /* Bits per pixel, 0 = 1 */
>       ushort  *cmap;          /* Pointer to the colormap */
>       void    *priv;          /* Pointer to driver-specific data */
> diff --git a/include/lcd_console.h b/include/lcd_console.h
> index 429214d..6612a38 100644
> --- a/include/lcd_console.h
> +++ b/include/lcd_console.h
> @@ -9,6 +9,16 @@
>  #define CONFIG_CONSOLE_SCROLL_LINES 1
>  #endif
>  
> +struct console_t {
> +     short curr_col, curr_row;
> +     short cols, rows;
> +     void *lcd_address;
> +     u32 lcdsizex, lcdsizey, lcdrot;
> +     void (*fp_putc_xy)(struct console_t *pcons, ushort x, ushort y, char c);
> +     void (*fp_console_moverow)(struct console_t *pcons,
> +                                u32 rowdst, u32 rowsrc);
> +     void (*fp_console_setrow)(struct console_t *pcons, u32 row, int clr);
> +};
>  /**
>   * lcd_init_console() - Initialize lcd console parameters
>   *
> @@ -16,11 +26,11 @@
>   * console has.
>   *
>   * @address: Console base address
> - * @rows: Number of rows in the console
> - * @cols: Number of columns in the console
> + * @vl_rows: Number of rows in the console
> + * @vl_cols: Number of columns in the console
> + * @vl_rot: Rotation of display in degree (0 - 90 - 180 - 270) 
> counterlockwise
>   */
> -void lcd_init_console(void *address, int rows, int cols);
> -
> +void lcd_init_console(void *address, int vl_cols, int vl_rows, int vl_rot);
>  /**
>   * lcd_set_col() - Set the number of the current lcd console column
>   *
> 

-- 
Regards,
Igor.
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to