lcd_console.c 4.5 KB

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