lcd_console.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /*
  2. * (C) Copyright 2001-2014
  3. * DENX Software Engineering -- wd@denx.de
  4. * Compulab Ltd - http://compulab.co.il/
  5. *
  6. * SPDX-License-Identifier: GPL-2.0+
  7. */
  8. #include <common.h>
  9. #include <lcd.h>
  10. #include <video_font.h> /* Get font data, width and height */
  11. #define CONSOLE_ROW_SIZE (VIDEO_FONT_HEIGHT * lcd_line_length)
  12. #define CONSOLE_ROW_FIRST lcd_console_address
  13. #define CONSOLE_SIZE (CONSOLE_ROW_SIZE * console_rows)
  14. static short console_curr_col;
  15. static short console_curr_row;
  16. static short console_cols;
  17. static short console_rows;
  18. static void *lcd_console_address;
  19. void lcd_init_console(void *address, int rows, int cols)
  20. {
  21. console_curr_col = 0;
  22. console_curr_row = 0;
  23. console_cols = cols;
  24. console_rows = rows;
  25. lcd_console_address = address;
  26. }
  27. void lcd_set_col(short col)
  28. {
  29. console_curr_col = col;
  30. }
  31. void lcd_set_row(short row)
  32. {
  33. console_curr_row = row;
  34. }
  35. void lcd_position_cursor(unsigned col, unsigned row)
  36. {
  37. console_curr_col = min_t(short, col, console_cols - 1);
  38. console_curr_row = min_t(short, row, console_rows - 1);
  39. }
  40. int lcd_get_screen_rows(void)
  41. {
  42. return console_rows;
  43. }
  44. int lcd_get_screen_columns(void)
  45. {
  46. return console_cols;
  47. }
  48. static void lcd_putc_xy(ushort x, ushort y, char c)
  49. {
  50. uchar *dest;
  51. ushort row;
  52. int fg_color = lcd_getfgcolor();
  53. int bg_color = lcd_getbgcolor();
  54. int i;
  55. dest = (uchar *)(lcd_console_address +
  56. y * lcd_line_length + x * NBITS(LCD_BPP) / 8);
  57. for (row = 0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) {
  58. #if LCD_BPP == LCD_COLOR16
  59. ushort *d = (ushort *)dest;
  60. #elif LCD_BPP == LCD_COLOR32
  61. u32 *d = (u32 *)dest;
  62. #else
  63. uchar *d = dest;
  64. #endif
  65. uchar bits;
  66. bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
  67. for (i = 0; i < 8; ++i) {
  68. *d++ = (bits & 0x80) ? fg_color : bg_color;
  69. bits <<= 1;
  70. }
  71. }
  72. }
  73. static void console_scrollup(void)
  74. {
  75. const int rows = CONFIG_CONSOLE_SCROLL_LINES;
  76. int bg_color = lcd_getbgcolor();
  77. /* Copy up rows ignoring those that will be overwritten */
  78. memcpy(CONSOLE_ROW_FIRST,
  79. lcd_console_address + CONSOLE_ROW_SIZE * rows,
  80. CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows);
  81. /* Clear the last rows */
  82. #if (LCD_BPP != LCD_COLOR32)
  83. memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows,
  84. bg_color, CONSOLE_ROW_SIZE * rows);
  85. #else
  86. u32 *ppix = lcd_console_address +
  87. CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows;
  88. u32 i;
  89. for (i = 0;
  90. i < (CONSOLE_ROW_SIZE * rows) / NBYTES(panel_info.vl_bpix);
  91. i++) {
  92. *ppix++ = bg_color;
  93. }
  94. #endif
  95. lcd_sync();
  96. console_curr_row -= rows;
  97. }
  98. static inline void console_back(void)
  99. {
  100. if (--console_curr_col < 0) {
  101. console_curr_col = console_cols - 1;
  102. if (--console_curr_row < 0)
  103. console_curr_row = 0;
  104. }
  105. lcd_putc_xy(console_curr_col * VIDEO_FONT_WIDTH,
  106. console_curr_row * VIDEO_FONT_HEIGHT, ' ');
  107. }
  108. static inline void console_newline(void)
  109. {
  110. console_curr_col = 0;
  111. /* Check if we need to scroll the terminal */
  112. if (++console_curr_row >= console_rows)
  113. console_scrollup();
  114. else
  115. lcd_sync();
  116. }
  117. void lcd_putc(const char c)
  118. {
  119. if (!lcd_is_enabled) {
  120. serial_putc(c);
  121. return;
  122. }
  123. switch (c) {
  124. case '\r':
  125. console_curr_col = 0;
  126. return;
  127. case '\n':
  128. console_newline();
  129. return;
  130. case '\t': /* Tab (8 chars alignment) */
  131. console_curr_col += 8;
  132. console_curr_col &= ~7;
  133. if (console_curr_col >= console_cols)
  134. console_newline();
  135. return;
  136. case '\b':
  137. console_back();
  138. return;
  139. default:
  140. lcd_putc_xy(console_curr_col * VIDEO_FONT_WIDTH,
  141. console_curr_row * VIDEO_FONT_HEIGHT, c);
  142. if (++console_curr_col >= console_cols)
  143. console_newline();
  144. }
  145. }
  146. void lcd_puts(const char *s)
  147. {
  148. if (!lcd_is_enabled) {
  149. serial_puts(s);
  150. return;
  151. }
  152. while (*s)
  153. lcd_putc(*s++);
  154. lcd_sync();
  155. }
  156. void lcd_printf(const char *fmt, ...)
  157. {
  158. va_list args;
  159. char buf[CONFIG_SYS_PBSIZE];
  160. va_start(args, fmt);
  161. vsprintf(buf, fmt, args);
  162. va_end(args);
  163. lcd_puts(buf);
  164. }
  165. static int do_lcd_setcursor(cmd_tbl_t *cmdtp, int flag, int argc,
  166. char *const argv[])
  167. {
  168. unsigned int col, row;
  169. if (argc != 3)
  170. return CMD_RET_USAGE;
  171. col = simple_strtoul(argv[1], NULL, 10);
  172. row = simple_strtoul(argv[2], NULL, 10);
  173. lcd_position_cursor(col, row);
  174. return 0;
  175. }
  176. static int do_lcd_puts(cmd_tbl_t *cmdtp, int flag, int argc,
  177. char *const argv[])
  178. {
  179. if (argc != 2)
  180. return CMD_RET_USAGE;
  181. lcd_puts(argv[1]);
  182. return 0;
  183. }
  184. U_BOOT_CMD(
  185. setcurs, 3, 1, do_lcd_setcursor,
  186. "set cursor position within screen",
  187. " <col> <row> in character"
  188. );
  189. U_BOOT_CMD(
  190. lcdputs, 2, 1, do_lcd_puts,
  191. "print string on lcd-framebuffer",
  192. " <string>"
  193. );