drv_fb.c 19 KB

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