/common/lcd_console.c

https://gitlab.com/my-imx6/u-boot-2015.04 · C · 270 lines · 209 code · 51 blank · 10 comment · 24 complexity · 145c505b3583d6ab62c7aafde84e55d2 MD5 · raw file

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