lcd_console.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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_drawchars(ushort x, ushort y, uchar *str, int count)
  49. {
  50. uchar *dest;
  51. ushort row;
  52. int fg_color, bg_color;
  53. dest = (uchar *)(lcd_console_address +
  54. y * lcd_line_length + x * NBITS(LCD_BPP) / 8);
  55. for (row = 0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) {
  56. uchar *s = str;
  57. int i;
  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. fg_color = lcd_getfgcolor();
  66. bg_color = lcd_getbgcolor();
  67. for (i = 0; i < count; ++i) {
  68. uchar c, bits;
  69. c = *s++;
  70. bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
  71. for (c = 0; c < 8; ++c) {
  72. *d++ = (bits & 0x80) ? fg_color : bg_color;
  73. bits <<= 1;
  74. }
  75. }
  76. }
  77. }
  78. static inline void lcd_putc_xy(ushort x, ushort y, uchar c)
  79. {
  80. lcd_drawchars(x, y, &c, 1);
  81. }
  82. static void console_scrollup(void)
  83. {
  84. const int rows = CONFIG_CONSOLE_SCROLL_LINES;
  85. int bg_color = lcd_getbgcolor();
  86. /* Copy up rows ignoring those that will be overwritten */
  87. memcpy(CONSOLE_ROW_FIRST,
  88. lcd_console_address + CONSOLE_ROW_SIZE * rows,
  89. CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows);
  90. /* Clear the last rows */
  91. #if (LCD_BPP != LCD_COLOR32)
  92. memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows,
  93. bg_color, CONSOLE_ROW_SIZE * rows);
  94. #else
  95. u32 *ppix = lcd_console_address +
  96. CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows;
  97. u32 i;
  98. for (i = 0;
  99. i < (CONSOLE_ROW_SIZE * rows) / NBYTES(panel_info.vl_bpix);
  100. i++) {
  101. *ppix++ = bg_color;
  102. }
  103. #endif
  104. lcd_sync();
  105. console_curr_row -= rows;
  106. }
  107. static inline void console_back(void)
  108. {
  109. if (--console_curr_col < 0) {
  110. console_curr_col = console_cols - 1;
  111. if (--console_curr_row < 0)
  112. console_curr_row = 0;
  113. }
  114. lcd_putc_xy(console_curr_col * VIDEO_FONT_WIDTH,
  115. console_curr_row * VIDEO_FONT_HEIGHT, ' ');
  116. }
  117. static inline void console_newline(void)
  118. {
  119. console_curr_col = 0;
  120. /* Check if we need to scroll the terminal */
  121. if (++console_curr_row >= console_rows)
  122. console_scrollup();
  123. else
  124. lcd_sync();
  125. }
  126. void lcd_putc(const char c)
  127. {
  128. if (!lcd_is_enabled) {
  129. serial_putc(c);
  130. return;
  131. }
  132. switch (c) {
  133. case '\r':
  134. console_curr_col = 0;
  135. return;
  136. case '\n':
  137. console_newline();
  138. return;
  139. case '\t': /* Tab (8 chars alignment) */
  140. console_curr_col += 8;
  141. console_curr_col &= ~7;
  142. if (console_curr_col >= console_cols)
  143. console_newline();
  144. return;
  145. case '\b':
  146. console_back();
  147. return;
  148. default:
  149. lcd_putc_xy(console_curr_col * VIDEO_FONT_WIDTH,
  150. console_curr_row * VIDEO_FONT_HEIGHT, c);
  151. if (++console_curr_col >= console_cols)
  152. console_newline();
  153. }
  154. }
  155. void lcd_puts(const char *s)
  156. {
  157. if (!lcd_is_enabled) {
  158. serial_puts(s);
  159. return;
  160. }
  161. while (*s)
  162. lcd_putc(*s++);
  163. lcd_sync();
  164. }
  165. void lcd_printf(const char *fmt, ...)
  166. {
  167. va_list args;
  168. char buf[CONFIG_SYS_PBSIZE];
  169. va_start(args, fmt);
  170. vsprintf(buf, fmt, args);
  171. va_end(args);
  172. lcd_puts(buf);
  173. }
  174. static int do_lcd_setcursor(cmd_tbl_t *cmdtp, int flag, int argc,
  175. char *const argv[])
  176. {
  177. unsigned int col, row;
  178. if (argc != 3)
  179. return CMD_RET_USAGE;
  180. col = simple_strtoul(argv[1], NULL, 10);
  181. row = simple_strtoul(argv[2], NULL, 10);
  182. lcd_position_cursor(col, row);
  183. return 0;
  184. }
  185. U_BOOT_CMD(
  186. setcurs, 3, 1, do_lcd_setcursor,
  187. "set cursor position within screen",
  188. " <col> <row> in character"
  189. );