drv_fb.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-08-29 zdzn first version
  9. */
  10. #include <rthw.h>
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #include "mbox.h"
  14. #include "drv_fb.h"
  15. #include "mmu.h"
  16. #define CHAR_W 8
  17. #define CHAR_H 12
  18. #define COLOR_DELTA 0.05
  19. static struct rt_hdmi_fb_device _hdmi;
  20. fb_t fb_info;
  21. // https://github.com/xinu-os/xinu/blob/1789b7a50b5b73c2ea76ebd764c54a034097d04d/device/framebuffer_rpi/font.c
  22. unsigned char FONT[] = {
  23. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  24. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  25. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  26. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  27. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  28. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  29. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  30. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  31. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  32. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  33. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  34. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  35. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  36. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  37. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  38. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  39. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  40. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  41. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  42. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  43. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  44. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  45. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  46. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  47. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  48. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  49. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  50. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  51. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  52. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  53. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  54. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  55. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
  56. 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, /*'!'*/
  57. 0x00, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'"'*/
  58. 0x00, 0x00, 0x14, 0x14, 0x3e, 0x14, 0x3e, 0x14, 0x14, 0x00, 0x00, 0x00, /*'#'*/
  59. 0x00, 0x00, 0x08, 0x3c, 0x0a, 0x1c, 0x28, 0x1e, 0x08, 0x00, 0x00, 0x00, /*'$'*/
  60. 0x00, 0x00, 0x06, 0x26, 0x10, 0x08, 0x04, 0x32, 0x30, 0x00, 0x00, 0x00, /*'%'*/
  61. 0x00, 0x00, 0x1c, 0x02, 0x02, 0x04, 0x2a, 0x12, 0x2c, 0x00, 0x00, 0x00, /*'&'*/
  62. 0x00, 0x18, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'''*/
  63. 0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x00, /*'('*/
  64. 0x02, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x02, 0x00, /*')'*/
  65. 0x00, 0x00, 0x00, 0x08, 0x2a, 0x1c, 0x2a, 0x08, 0x00, 0x00, 0x00, 0x00, /*'*'*/
  66. 0x00, 0x00, 0x00, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, /*'+'*/
  67. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x08, 0x04, 0x00, /*','*/
  68. 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'-'*/
  69. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, /*'.'*/
  70. 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, /*'/'*/
  71. 0x00, 0x1c, 0x22, 0x32, 0x2a, 0x26, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'0'*/
  72. 0x00, 0x08, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, /*'1'*/
  73. 0x00, 0x1c, 0x22, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3e, 0x00, 0x00, 0x00, /*'2'*/
  74. 0x00, 0x1c, 0x22, 0x20, 0x18, 0x20, 0x20, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'3'*/
  75. 0x00, 0x10, 0x18, 0x18, 0x14, 0x14, 0x3e, 0x10, 0x38, 0x00, 0x00, 0x00, /*'4'*/
  76. 0x00, 0x3e, 0x02, 0x02, 0x1e, 0x20, 0x20, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'5'*/
  77. 0x00, 0x18, 0x04, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'6'*/
  78. 0x00, 0x3e, 0x22, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x00, 0x00, 0x00, /*'7'*/
  79. 0x00, 0x1c, 0x22, 0x22, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'8'*/
  80. 0x00, 0x1c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x10, 0x0c, 0x00, 0x00, 0x00, /*'9'*/
  81. 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, /*':'*/
  82. 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x08, 0x04, 0x00, /*';'*/
  83. 0x00, 0x00, 0x00, 0x30, 0x0c, 0x03, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, /*'<'*/
  84. 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, /*'='*/
  85. 0x00, 0x00, 0x00, 0x03, 0x0c, 0x30, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, /*'>'*/
  86. 0x00, 0x1c, 0x22, 0x20, 0x10, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, /*'?'*/
  87. 0x00, 0x00, 0x1c, 0x22, 0x3a, 0x3a, 0x1a, 0x02, 0x1c, 0x00, 0x00, 0x00, /*'@'*/
  88. 0x00, 0x00, 0x08, 0x14, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x00, 0x00, 0x00, /*'A'*/
  89. 0x00, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x22, 0x22, 0x1e, 0x00, 0x00, 0x00, /*'B'*/
  90. 0x00, 0x00, 0x1c, 0x22, 0x02, 0x02, 0x02, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'C'*/
  91. 0x00, 0x00, 0x0e, 0x12, 0x22, 0x22, 0x22, 0x12, 0x0e, 0x00, 0x00, 0x00, /*'D'*/
  92. 0x00, 0x00, 0x3e, 0x02, 0x02, 0x1e, 0x02, 0x02, 0x3e, 0x00, 0x00, 0x00, /*'E'*/
  93. 0x00, 0x00, 0x3e, 0x02, 0x02, 0x1e, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, /*'F'*/
  94. 0x00, 0x00, 0x1c, 0x22, 0x02, 0x32, 0x22, 0x22, 0x3c, 0x00, 0x00, 0x00, /*'G'*/
  95. 0x00, 0x00, 0x22, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, /*'H'*/
  96. 0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, /*'I'*/
  97. 0x00, 0x00, 0x38, 0x20, 0x20, 0x20, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'J'*/
  98. 0x00, 0x00, 0x22, 0x12, 0x0a, 0x06, 0x0a, 0x12, 0x22, 0x00, 0x00, 0x00, /*'K'*/
  99. 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x3e, 0x00, 0x00, 0x00, /*'L'*/
  100. 0x00, 0x00, 0x22, 0x36, 0x2a, 0x2a, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, /*'M'*/
  101. 0x00, 0x00, 0x22, 0x26, 0x26, 0x2a, 0x32, 0x32, 0x22, 0x00, 0x00, 0x00, /*'N'*/
  102. 0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'O'*/
  103. 0x00, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, /*'P'*/
  104. 0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x30, 0x00, 0x00, /*'Q'*/
  105. 0x00, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x0a, 0x12, 0x22, 0x00, 0x00, 0x00, /*'R'*/
  106. 0x00, 0x00, 0x1c, 0x22, 0x02, 0x1c, 0x20, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'S'*/
  107. 0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, /*'T'*/
  108. 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'U'*/
  109. 0x00, 0x00, 0x22, 0x22, 0x22, 0x14, 0x14, 0x08, 0x08, 0x00, 0x00, 0x00, /*'V'*/
  110. 0x00, 0x00, 0x22, 0x22, 0x22, 0x2a, 0x2a, 0x36, 0x22, 0x00, 0x00, 0x00, /*'W'*/
  111. 0x00, 0x00, 0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x00, 0x00, /*'X'*/
  112. 0x00, 0x00, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, /*'Y'*/
  113. 0x00, 0x00, 0x3e, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3e, 0x00, 0x00, 0x00, /*'Z'*/
  114. 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, /*'['*/
  115. 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00, /*'\'*/
  116. 0x0e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0e, 0x00, /*']'*/
  117. 0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'^'*/
  118. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, /*'_'*/
  119. 0x00, 0x0c, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'`'*/
  120. 0x00, 0x00, 0x00, 0x00, 0x3c, 0x22, 0x22, 0x32, 0x2c, 0x00, 0x00, 0x00, /*'a'*/
  121. 0x00, 0x02, 0x02, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x1e, 0x00, 0x00, 0x00, /*'b'*/
  122. 0x00, 0x00, 0x00, 0x00, 0x3c, 0x02, 0x02, 0x02, 0x3c, 0x00, 0x00, 0x00, /*'c'*/
  123. 0x00, 0x20, 0x20, 0x20, 0x3c, 0x22, 0x22, 0x22, 0x3c, 0x00, 0x00, 0x00, /*'d'*/
  124. 0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x3e, 0x02, 0x1c, 0x00, 0x00, 0x00, /*'e'*/
  125. 0x00, 0x38, 0x04, 0x04, 0x1e, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, /*'f'*/
  126. 0x00, 0x00, 0x00, 0x00, 0x3c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x1c, /*'g'*/
  127. 0x00, 0x02, 0x02, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, /*'h'*/
  128. 0x00, 0x08, 0x08, 0x00, 0x0c, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00, 0x00, /*'i'*/
  129. 0x00, 0x10, 0x10, 0x00, 0x1c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0e, /*'j'*/
  130. 0x00, 0x02, 0x02, 0x02, 0x12, 0x0a, 0x06, 0x0a, 0x12, 0x00, 0x00, 0x00, /*'k'*/
  131. 0x00, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00, 0x00, /*'l'*/
  132. 0x00, 0x00, 0x00, 0x00, 0x16, 0x2a, 0x2a, 0x2a, 0x22, 0x00, 0x00, 0x00, /*'m'*/
  133. 0x00, 0x00, 0x00, 0x00, 0x1a, 0x26, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, /*'n'*/
  134. 0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'o'*/
  135. 0x00, 0x00, 0x00, 0x00, 0x1e, 0x22, 0x22, 0x22, 0x1e, 0x02, 0x02, 0x02, /*'p'*/
  136. 0x00, 0x00, 0x00, 0x00, 0x3c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x20, /*'q'*/
  137. 0x00, 0x00, 0x00, 0x00, 0x1a, 0x06, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, /*'r'*/
  138. 0x00, 0x00, 0x00, 0x00, 0x3c, 0x02, 0x1c, 0x20, 0x1e, 0x00, 0x00, 0x00, /*'s'*/
  139. 0x00, 0x08, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00, 0x00, /*'t'*/
  140. 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x32, 0x2c, 0x00, 0x00, 0x00, /*'u'*/
  141. 0x00, 0x00, 0x00, 0x00, 0x36, 0x14, 0x14, 0x08, 0x08, 0x00, 0x00, 0x00, /*'v'*/
  142. 0x00, 0x00, 0x00, 0x00, 0x22, 0x2a, 0x2a, 0x2a, 0x14, 0x00, 0x00, 0x00, /*'w'*/
  143. 0x00, 0x00, 0x00, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, /*'x'*/
  144. 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x1c, /*'y'*/
  145. 0x00, 0x00, 0x00, 0x00, 0x3e, 0x10, 0x08, 0x04, 0x3e, 0x00, 0x00, 0x00, /*'z'*/
  146. 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x10, 0x10, 0x10, 0x10, 0x20, 0x00, /*'{'*/
  147. 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, /*'|'*/
  148. 0x02, 0x04, 0x04, 0x04, 0x04, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x00, /*'}'*/
  149. 0x00, 0x04, 0x2a, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'~'*/
  150. 0x00, 0x00, 0x00, 0x08, 0x08, 0x14, 0x14, 0x22, 0x3e, 0x00, 0x00, 0x00, /*DEL*/
  151. };
  152. void newline(fb_t* fb)
  153. {
  154. uint8_t* to;
  155. uint8_t* from;
  156. int i;
  157. fb->y++;
  158. fb->x = 0;
  159. if (fb->y == (fb->height / CHAR_H))
  160. {
  161. to = (uint8_t*) fb->addr;
  162. from = to + (CHAR_H * fb->pitch);
  163. for (i = 0; i < ((fb->height - CHAR_H) * fb->pitch); i++)
  164. {
  165. *to++ = *from++;
  166. }
  167. uint32_t *addr = (uint32_t*) (fb->addr) + (fb->height - CHAR_H) * fb->width;
  168. for (i = 0; i < (CHAR_H * fb->width); i++)
  169. {
  170. *addr++ = fb->back;
  171. }
  172. fb->y--;
  173. }
  174. }
  175. void clear_line(fb_t *fb, const int line)
  176. {
  177. int i;
  178. uint32_t* addr;
  179. if (line > fb->height / CHAR_H)
  180. {
  181. fb->y = 0;
  182. }
  183. else
  184. {
  185. fb->y = line;
  186. }
  187. fb->x = 0;
  188. addr = (uint32_t*) (fb->addr + (line * CHAR_H * fb->depth * fb->width));
  189. for (i = 0; i < (CHAR_H * fb->width); i++)
  190. {
  191. *addr++ = fb->back;
  192. }
  193. }
  194. void fb_draw_char(fb_t *fb, char s)
  195. {
  196. unsigned char* addr = (unsigned char*) fb->addr;
  197. unsigned char *glyph = (unsigned char*) FONT + (s) * 12;
  198. // calculate the offset on screen
  199. int offs = (fb->y * CHAR_H * fb->pitch) + (fb->x * (CHAR_W + 1) * 4);
  200. // variables
  201. int i, j, line, mask, bytesperline = (CHAR_W + 7) / 8;
  202. // display a character
  203. for (j = 0; j < CHAR_H; j++)
  204. {
  205. // display one row
  206. line = offs;
  207. mask = 1;
  208. for (i = 0; i < CHAR_W; i++)
  209. {
  210. // if bit set, we use white color, otherwise black
  211. *((unsigned int*) (addr + line)) = ((int) *glyph) & mask ? fb->fore : fb->back;
  212. mask <<= 1;
  213. line += 4;
  214. }
  215. // adjust to next line
  216. glyph += bytesperline;
  217. offs += fb->pitch;
  218. }
  219. }
  220. void fb_print(fb_t *fb, char *s)
  221. {
  222. // draw next character if it's not zero
  223. while (*s)
  224. {
  225. // handle carrige return
  226. if (*s == '\r')
  227. {
  228. fb->x = 0;
  229. }
  230. else if (*s == '\n')
  231. {
  232. newline(fb);
  233. }
  234. else if (*s == '\t')
  235. {
  236. fb->x = ((fb->x + 4) >> 2) << 2;
  237. }
  238. else if (*s == '\b')
  239. {
  240. if (fb->x)
  241. {
  242. fb->x--;
  243. fb_draw_char(fb, ' ');
  244. }
  245. }
  246. else
  247. {
  248. fb_draw_char(fb, *s);
  249. fb->x++;
  250. }
  251. // next character
  252. if (fb->x == fb->width / CHAR_W)
  253. {
  254. newline(fb);
  255. }
  256. s++;
  257. }
  258. }
  259. rt_err_t hdmi_fb_open(rt_device_t dev, rt_uint16_t oflag)
  260. {
  261. return RT_EOK;
  262. }
  263. rt_err_t hdmi_fb_close(rt_device_t dev)
  264. {
  265. return RT_EOK;
  266. }
  267. rt_size_t hdmi_fb_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t size)
  268. {
  269. return 0;
  270. }
  271. rt_size_t hdmi_fb_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  272. {
  273. fb_print(&_hdmi.fb, (char *) buffer);
  274. #ifdef BSP_USING_HDMI_DISPLAY
  275. rt_device_t uart = rt_device_find("uart1");
  276. int old_flag = uart->open_flag;
  277. uart->open_flag |= RT_DEVICE_FLAG_STREAM;
  278. rt_device_write(uart, 0, buffer, size);
  279. uart->open_flag = old_flag;
  280. #endif
  281. return size;
  282. }
  283. rt_err_t hdmi_fb_control(rt_device_t dev, int cmd, void *args)
  284. {
  285. return RT_EOK;
  286. }
  287. const static struct rt_device_ops hdmi_fb_ops =
  288. {
  289. RT_NULL,
  290. hdmi_fb_open,
  291. hdmi_fb_close,
  292. hdmi_fb_read,
  293. hdmi_fb_write,
  294. hdmi_fb_control
  295. };
  296. static struct rt_device_graphic_info _hdmi_info;
  297. static void hdmi_draw_rect(const char* pixel, int x1, int y1, int x2, int y2)
  298. {
  299. int i, j;
  300. int line;
  301. for (j = y1; j <= y2; j++)
  302. {
  303. line = (j * _hdmi.fb.pitch) + (x1 * 4);
  304. for (i = x1; i <= x2; i++)
  305. {
  306. // if bit set, we use white color, otherwise black
  307. *((unsigned int*) (_hdmi_info.framebuffer + line)) = *(unsigned int*) pixel;
  308. line += 4;
  309. }
  310. }
  311. }
  312. static void hdmi_set_pixel(const char* pixel, int x, int y)
  313. {
  314. *(uint32_t*) (_hdmi.fb.addr + (y * _hdmi.fb.pitch + x * 4)) = *(uint32_t *) pixel;
  315. }
  316. static void hdmi_get_pixel(char* pixel, int x, int y)
  317. {
  318. uint32_t ret = 0;
  319. ret = (*(uint32_t*) (_hdmi.fb.addr + (y * _hdmi.fb.pitch + x * 4)) & 0x00FFFFFF);
  320. *pixel = ret;
  321. }
  322. static void hdmi_draw_hline(const char* pixel, int x1, int x2, int y)
  323. {
  324. hdmi_draw_rect(pixel, x1, y, x2, y);
  325. }
  326. static void hdmi_draw_vline(const char* pixel, int x, int y1, int y2)
  327. {
  328. hdmi_draw_rect(pixel, x, y1, x, y2);
  329. }
  330. static void hdmi_blit_line(const char* pixels, int x, int y, rt_size_t size)
  331. {
  332. int i = 0;
  333. uint32_t *pixel_base = (uint32_t*) (_hdmi.fb.addr + (y * _hdmi.fb.pitch + x * 4));
  334. uint32_t *colors = (uint32_t *) pixels;
  335. for (i = 0; i < size; i++)
  336. {
  337. pixel_base[i] = colors[i];
  338. }
  339. }
  340. static struct rt_device_graphic_ops hdmi_ops =
  341. {
  342. hdmi_set_pixel,
  343. hdmi_get_pixel,
  344. hdmi_draw_hline,
  345. hdmi_draw_vline,
  346. hdmi_blit_line
  347. };
  348. rt_err_t rt_hdmi_fb_device_init(struct rt_hdmi_fb_device *hdmi_fb, const char *name)
  349. {
  350. struct rt_device *device;
  351. RT_ASSERT(hdmi_fb != RT_NULL);
  352. device = &hdmi_fb->parent;
  353. device->user_data = &hdmi_ops;
  354. /* set device type */
  355. device->type = RT_Device_Class_Graphic;
  356. /* initialize device interface */
  357. #ifdef RT_USING_DEVICE_OPS
  358. device->ops = &hdmi_fb_ops;
  359. #else
  360. device->init = RT_NULL;
  361. device->open = hdmi_fb_open;
  362. device->close = hdmi_fb_close;
  363. device->read = hdmi_fb_read;
  364. device->write = hdmi_fb_write;
  365. device->control = hdmi_fb_control;
  366. #endif
  367. /* register to device manager */
  368. rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);
  369. return RT_EOK;
  370. }
  371. /**
  372. * Show a picture
  373. */
  374. void print_fb_info()
  375. {
  376. rt_kprintf("FrameBuffer Info: \n \t width %x\t height %x\t depth %x\t addr %x\t size %x\t \n", fb_info.width,
  377. fb_info.height, fb_info.depth, fb_info.addr, fb_info.size);
  378. rt_kprintf("call mbox:%x,%x,%x,%x,%x\n", mbox[0], mbox[1], mbox[2], mbox[3], mbox[4]);
  379. }
  380. int hdmi_fb_init()
  381. {
  382. unsigned int *mbox = (unsigned int*) MBOX_ADDR;
  383. mbox[0] = 35 * 4;
  384. mbox[1] = MBOX_REQUEST;
  385. mbox[2] = 0x48003; //set phy wh
  386. mbox[3] = 8;
  387. mbox[4] = 8;
  388. mbox[5] = 640; //FrameBufferInfo.width
  389. mbox[6] = 480; //FrameBufferInfo.height
  390. mbox[7] = 0x48004; //set virt wh
  391. mbox[8] = 8;
  392. mbox[9] = 8;
  393. mbox[10] = 640; //FrameBufferInfo.virtual_width
  394. mbox[11] = 480; //FrameBufferInfo.virtual_height
  395. mbox[12] = 0x48009; //set virt offset
  396. mbox[13] = 8;
  397. mbox[14] = 8;
  398. mbox[15] = 0; //FrameBufferInfo.x_offset
  399. mbox[16] = 0; //FrameBufferInfo.y.offset
  400. mbox[17] = 0x48005; //set depth
  401. mbox[18] = 4;
  402. mbox[19] = 4;
  403. mbox[20] = 32; //FrameBufferInfo.depth
  404. mbox[21] = 0x48006; //set pixel order
  405. mbox[22] = 4;
  406. mbox[23] = 4;
  407. mbox[24] = 1; //RGB, not BGR preferably
  408. mbox[25] = 0x40001; //get framebuffer, gets alignment on request
  409. mbox[26] = 8;
  410. mbox[27] = 8;
  411. mbox[28] = 4096; //FrameBufferInfo.pointer
  412. mbox[29] = 0; //FrameBufferInfo.size
  413. mbox[30] = 0x40008; //get pitch
  414. mbox[31] = 4;
  415. mbox[32] = 4;
  416. mbox[33] = 0; //FrameBufferInfo.pitch
  417. mbox[34] = MBOX_TAG_LAST;
  418. if (mbox_call(MBOX_CH_PROP, MMU_DISABLE) && mbox[20] == 32 && mbox[28] != 0)
  419. {
  420. mbox[28] &= 0x3FFFFFFF;
  421. _hdmi.fb.width = mbox[5];
  422. _hdmi.fb.height = mbox[6];
  423. _hdmi.fb.pitch = mbox[33];
  424. //_hdmi.fb.addr = (void*)((unsigned long)mbox[28]);
  425. _hdmi.fb.addr = (rt_uint32_t) mbox[28];
  426. _hdmi.fb.size = mbox[29];
  427. _hdmi.fb.depth = 32;
  428. _hdmi.fb.x = 0;
  429. _hdmi.fb.y = 0;
  430. _hdmi.fb.fore = CONSOLE_WHITE;
  431. _hdmi.fb.back = CONSOLE_BLACK;
  432. rt_hdmi_fb_device_init(&_hdmi, "hdmi");
  433. rt_hw_change_mmu_table(_hdmi.fb.addr, _hdmi.fb.size, _hdmi.fb.addr, DEVICE_MEM);
  434. fb_info.width = _hdmi.fb.width;
  435. fb_info.height = _hdmi.fb.height;
  436. fb_info.addr = _hdmi.fb.addr;
  437. fb_info.size = _hdmi.fb.size;
  438. fb_info.pitch = _hdmi.fb.pitch;
  439. fb_info.depth = _hdmi.fb.depth;
  440. _hdmi_info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888;
  441. _hdmi_info.bits_per_pixel = _hdmi.fb.depth;
  442. _hdmi_info.width = _hdmi.fb.width;
  443. _hdmi_info.height = _hdmi.fb.height;
  444. _hdmi_info.framebuffer = (rt_uint8_t *) _hdmi.fb.addr;
  445. }
  446. return 0;
  447. }
  448. INIT_DEVICE_EXPORT(hdmi_fb_init);