lcd_console.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2001-2015
  4. * DENX Software Engineering -- wd@denx.de
  5. * Compulab Ltd - http://compulab.co.il/
  6. * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
  7. */
  8. #include <common.h>
  9. #include <command.h>
  10. #include <lcd.h>
  11. #include <log.h>
  12. #include <serial.h>
  13. #include <video_font.h> /* Get font data, width and height */
  14. #if defined(CONFIG_LCD_LOGO)
  15. #include <bmp_logo.h>
  16. #endif
  17. static struct console_t cons;
  18. void lcd_set_col(short col)
  19. {
  20. cons.curr_col = col;
  21. }
  22. void lcd_set_row(short row)
  23. {
  24. cons.curr_row = row;
  25. }
  26. void lcd_position_cursor(unsigned col, unsigned row)
  27. {
  28. cons.curr_col = min_t(short, col, cons.cols - 1);
  29. cons.curr_row = min_t(short, row, cons.rows - 1);
  30. }
  31. int lcd_get_screen_rows(void)
  32. {
  33. return cons.rows;
  34. }
  35. int lcd_get_screen_columns(void)
  36. {
  37. return cons.cols;
  38. }
  39. static void lcd_putc_xy0(struct console_t *pcons, ushort x, ushort y, char c)
  40. {
  41. int fg_color = lcd_getfgcolor();
  42. int bg_color = lcd_getbgcolor();
  43. int i, row;
  44. fbptr_t *dst = (fbptr_t *)pcons->fbbase +
  45. y * pcons->lcdsizex +
  46. x;
  47. for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
  48. uchar bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
  49. for (i = 0; i < VIDEO_FONT_WIDTH; ++i) {
  50. *dst++ = (bits & 0x80) ? fg_color : bg_color;
  51. bits <<= 1;
  52. }
  53. dst += (pcons->lcdsizex - VIDEO_FONT_WIDTH);
  54. }
  55. }
  56. static inline void console_setrow0(struct console_t *pcons, u32 row, int clr)
  57. {
  58. int i;
  59. fbptr_t *dst = (fbptr_t *)pcons->fbbase +
  60. row * VIDEO_FONT_HEIGHT *
  61. pcons->lcdsizex;
  62. for (i = 0; i < (VIDEO_FONT_HEIGHT * pcons->lcdsizex); i++)
  63. *dst++ = clr;
  64. }
  65. static inline void console_moverow0(struct console_t *pcons,
  66. u32 rowdst, u32 rowsrc)
  67. {
  68. int i;
  69. fbptr_t *dst = (fbptr_t *)pcons->fbbase +
  70. rowdst * VIDEO_FONT_HEIGHT *
  71. pcons->lcdsizex;
  72. fbptr_t *src = (fbptr_t *)pcons->fbbase +
  73. rowsrc * VIDEO_FONT_HEIGHT *
  74. pcons->lcdsizex;
  75. for (i = 0; i < (VIDEO_FONT_HEIGHT * pcons->lcdsizex); i++)
  76. *dst++ = *src++;
  77. }
  78. static inline void console_back(void)
  79. {
  80. if (--cons.curr_col < 0) {
  81. cons.curr_col = cons.cols - 1;
  82. if (--cons.curr_row < 0)
  83. cons.curr_row = 0;
  84. }
  85. cons.fp_putc_xy(&cons,
  86. cons.curr_col * VIDEO_FONT_WIDTH,
  87. cons.curr_row * VIDEO_FONT_HEIGHT, ' ');
  88. }
  89. static inline void console_newline(void)
  90. {
  91. const int rows = CONFIG_CONSOLE_SCROLL_LINES;
  92. int bg_color = lcd_getbgcolor();
  93. int i;
  94. cons.curr_col = 0;
  95. /* Check if we need to scroll the terminal */
  96. if (++cons.curr_row >= cons.rows) {
  97. for (i = 0; i < cons.rows-rows; i++)
  98. cons.fp_console_moverow(&cons, i, i+rows);
  99. for (i = 0; i < rows; i++)
  100. cons.fp_console_setrow(&cons, cons.rows-i-1, bg_color);
  101. cons.curr_row -= rows;
  102. }
  103. lcd_sync();
  104. }
  105. void console_calc_rowcol(struct console_t *pcons, u32 sizex, u32 sizey)
  106. {
  107. pcons->cols = sizex / VIDEO_FONT_WIDTH;
  108. #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
  109. pcons->rows = (pcons->lcdsizey - BMP_LOGO_HEIGHT);
  110. pcons->rows /= VIDEO_FONT_HEIGHT;
  111. #else
  112. pcons->rows = sizey / VIDEO_FONT_HEIGHT;
  113. #endif
  114. }
  115. void __weak lcd_init_console_rot(struct console_t *pcons)
  116. {
  117. return;
  118. }
  119. void lcd_init_console(void *address, int vl_cols, int vl_rows, int vl_rot)
  120. {
  121. memset(&cons, 0, sizeof(cons));
  122. cons.fbbase = address;
  123. cons.lcdsizex = vl_cols;
  124. cons.lcdsizey = vl_rows;
  125. cons.lcdrot = vl_rot;
  126. cons.fp_putc_xy = &lcd_putc_xy0;
  127. cons.fp_console_moverow = &console_moverow0;
  128. cons.fp_console_setrow = &console_setrow0;
  129. console_calc_rowcol(&cons, cons.lcdsizex, cons.lcdsizey);
  130. lcd_init_console_rot(&cons);
  131. debug("lcd_console: have %d/%d col/rws on scr %dx%d (%d deg rotated)\n",
  132. cons.cols, cons.rows, cons.lcdsizex, cons.lcdsizey, vl_rot);
  133. }
  134. void lcd_putc(const char c)
  135. {
  136. if (!lcd_is_enabled) {
  137. serial_putc(c);
  138. return;
  139. }
  140. switch (c) {
  141. case '\r':
  142. cons.curr_col = 0;
  143. return;
  144. case '\n':
  145. console_newline();
  146. return;
  147. case '\t': /* Tab (8 chars alignment) */
  148. cons.curr_col += 8;
  149. cons.curr_col &= ~7;
  150. if (cons.curr_col >= cons.cols)
  151. console_newline();
  152. return;
  153. case '\b':
  154. console_back();
  155. return;
  156. default:
  157. cons.fp_putc_xy(&cons,
  158. cons.curr_col * VIDEO_FONT_WIDTH,
  159. cons.curr_row * VIDEO_FONT_HEIGHT, c);
  160. if (++cons.curr_col >= cons.cols)
  161. console_newline();
  162. }
  163. }
  164. void lcd_puts(const char *s)
  165. {
  166. if (!lcd_is_enabled) {
  167. serial_puts(s);
  168. return;
  169. }
  170. while (*s)
  171. lcd_putc(*s++);
  172. lcd_sync();
  173. }
  174. void lcd_printf(const char *fmt, ...)
  175. {
  176. va_list args;
  177. char buf[CONFIG_SYS_PBSIZE];
  178. va_start(args, fmt);
  179. vsprintf(buf, fmt, args);
  180. va_end(args);
  181. lcd_puts(buf);
  182. }
  183. static int do_lcd_setcursor(struct cmd_tbl *cmdtp, int flag, int argc,
  184. char *const argv[])
  185. {
  186. unsigned int col, row;
  187. if (argc != 3)
  188. return CMD_RET_USAGE;
  189. col = dectoul(argv[1], NULL);
  190. row = dectoul(argv[2], NULL);
  191. lcd_position_cursor(col, row);
  192. return 0;
  193. }
  194. static int do_lcd_puts(struct cmd_tbl *cmdtp, int flag, int argc,
  195. char *const argv[])
  196. {
  197. if (argc != 2)
  198. return CMD_RET_USAGE;
  199. lcd_puts(argv[1]);
  200. return 0;
  201. }
  202. U_BOOT_CMD(
  203. setcurs, 3, 1, do_lcd_setcursor,
  204. "set cursor position within screen",
  205. " <col> <row> in character"
  206. );
  207. U_BOOT_CMD(
  208. lcdputs, 2, 1, do_lcd_puts,
  209. "print string on lcd-framebuffer",
  210. " <string>"
  211. );