luat_lcd.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. #include "luat_base.h"
  2. #include "luat_lcd.h"
  3. #include "luat_gpio.h"
  4. #include "luat_spi.h"
  5. #include "luat_malloc.h"
  6. #include "luat_timer.h"
  7. #define LUAT_LOG_TAG "lcd"
  8. #include "luat_log.h"
  9. luat_color_t BACK_COLOR = WHITE, FORE_COLOR = BLACK;
  10. #define LUAT_LCD_CONF_COUNT (1)
  11. static luat_lcd_conf_t* confs[LUAT_LCD_CONF_COUNT] = {0};
  12. void luat_lcd_execute_cmds(luat_lcd_conf_t* conf, uint32_t* cmds, uint32_t count) {
  13. uint32_t cmd = 0;
  14. for (size_t i = 0; i < count; i++)
  15. {
  16. cmd = cmds[i];
  17. switch(((cmd >> 16) & 0xFFFF)) {
  18. case 0x0000 :
  19. lcd_write_cmd(conf, (const uint8_t)(cmd & 0xFF));
  20. break;
  21. case 0x0001 :
  22. luat_timer_mdelay(cmd & 0xFF);
  23. break;
  24. case 0x0002 :
  25. lcd_write_cmd(conf, (const uint8_t)(cmd & 0xFF));
  26. break;
  27. case 0x0003 :
  28. lcd_write_data(conf, (const uint8_t)(cmd & 0xFF));
  29. break;
  30. default:
  31. break;
  32. }
  33. }
  34. }
  35. int lcd_write_cmd(luat_lcd_conf_t* conf, const uint8_t cmd){
  36. size_t len;
  37. luat_gpio_set(conf->pin_dc, Luat_GPIO_LOW);
  38. #ifdef LUAT_LCD_CMD_DELAY_US
  39. if (conf->dc_delay_us){
  40. luat_timer_us_delay(conf->dc_delay_us);
  41. }
  42. #endif
  43. if (conf->port == LUAT_LCD_SPI_DEVICE){
  44. len = luat_spi_device_send((luat_spi_device_t*)(conf->lcd_spi_device), (const char*)&cmd, 1);
  45. }else{
  46. len = luat_spi_send(conf->port, (const char*)&cmd, 1);
  47. }
  48. luat_gpio_set(conf->pin_dc, Luat_GPIO_HIGH);
  49. if (len != 1){
  50. LLOGI("lcd_write_cmd error. %d", len);
  51. return -1;
  52. }else{
  53. #ifdef LUAT_LCD_CMD_DELAY_US
  54. if (conf->dc_delay_us){
  55. luat_timer_us_delay(conf->dc_delay_us);
  56. }
  57. #endif
  58. return 0;
  59. }
  60. }
  61. int lcd_write_data(luat_lcd_conf_t* conf, const uint8_t data){
  62. size_t len;
  63. if (conf->port == LUAT_LCD_SPI_DEVICE){
  64. len = luat_spi_device_send((luat_spi_device_t*)(conf->lcd_spi_device), (const char*)&data, 1);
  65. }else{
  66. len = luat_spi_send(conf->port, (const char*)&data, 1);
  67. }
  68. if (len != 1){
  69. LLOGI("lcd_write_data error. %d", len);
  70. return -1;
  71. }else{
  72. return 0;
  73. }
  74. }
  75. luat_lcd_conf_t* luat_lcd_get_default(void) {
  76. for (size_t i = 0; i < LUAT_LCD_CONF_COUNT; i++){
  77. if (confs[i] != NULL) {
  78. return confs[i];
  79. }
  80. }
  81. return NULL;
  82. }
  83. const char* luat_lcd_name(luat_lcd_conf_t* conf) {
  84. return conf->opts->name;
  85. }
  86. int luat_lcd_init(luat_lcd_conf_t* conf) {
  87. int ret = conf->opts->init(conf);
  88. if (ret == 0) {
  89. for (size_t i = 0; i < LUAT_LCD_CONF_COUNT; i++)
  90. {
  91. if (confs[i] == NULL) {
  92. confs[i] = conf;
  93. break;
  94. }
  95. }
  96. }
  97. return ret;
  98. }
  99. int luat_lcd_close(luat_lcd_conf_t* conf) {
  100. if (conf->pin_pwr != 255)
  101. luat_gpio_set(conf->pin_pwr, Luat_GPIO_LOW);
  102. return 0;
  103. }
  104. int luat_lcd_display_off(luat_lcd_conf_t* conf) {
  105. if (conf->pin_pwr != 255)
  106. luat_gpio_set(conf->pin_pwr, Luat_GPIO_LOW);
  107. lcd_write_cmd(conf,0x28);
  108. return 0;
  109. }
  110. int luat_lcd_display_on(luat_lcd_conf_t* conf) {
  111. if (conf->pin_pwr != 255)
  112. luat_gpio_set(conf->pin_pwr, Luat_GPIO_HIGH);
  113. lcd_write_cmd(conf,0x29);
  114. return 0;
  115. }
  116. int luat_lcd_sleep(luat_lcd_conf_t* conf) {
  117. if (conf->pin_pwr != 255)
  118. luat_gpio_set(conf->pin_pwr, Luat_GPIO_LOW);
  119. luat_timer_mdelay(5);
  120. lcd_write_cmd(conf,0x10);
  121. return 0;
  122. }
  123. int luat_lcd_wakeup(luat_lcd_conf_t* conf) {
  124. if (conf->pin_pwr != 255)
  125. luat_gpio_set(conf->pin_pwr, Luat_GPIO_HIGH);
  126. luat_timer_mdelay(5);
  127. lcd_write_cmd(conf,0x11);
  128. return 0;
  129. }
  130. int luat_lcd_inv_off(luat_lcd_conf_t* conf) {
  131. lcd_write_cmd(conf,0x20);
  132. return 0;
  133. }
  134. int luat_lcd_inv_on(luat_lcd_conf_t* conf) {
  135. lcd_write_cmd(conf,0x21);
  136. return 0;
  137. }
  138. int luat_lcd_set_address(luat_lcd_conf_t* conf,uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
  139. lcd_write_cmd(conf,0x2a);
  140. lcd_write_data(conf,(x1+conf->xoffset)>>8);
  141. lcd_write_data(conf,x1+conf->xoffset);
  142. lcd_write_data(conf,(x2+conf->xoffset)>>8);
  143. lcd_write_data(conf,x2+conf->xoffset);
  144. lcd_write_cmd(conf,0x2b);
  145. lcd_write_data(conf,(y1+conf->yoffset)>>8);
  146. lcd_write_data(conf,y1+conf->yoffset);
  147. lcd_write_data(conf,(y2+conf->yoffset)>>8);
  148. lcd_write_data(conf,y2+conf->yoffset);
  149. lcd_write_cmd(conf,0x2C);
  150. return 0;
  151. }
  152. int luat_lcd_set_color(luat_color_t back, luat_color_t fore){
  153. BACK_COLOR = back;
  154. FORE_COLOR = fore;
  155. return 0;
  156. }
  157. #ifndef LUAT_USE_LCD_CUSTOM_DRAW
  158. int luat_lcd_draw(luat_lcd_conf_t* conf, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, luat_color_t* color) {
  159. uint32_t size = (x2 - x1 + 1) * (y2 - y1 + 1) * 2;
  160. luat_lcd_set_address(conf, x1, y1, x2, y2);
  161. if (conf->port == LUAT_LCD_SPI_DEVICE){
  162. luat_spi_device_send((luat_spi_device_t*)(conf->lcd_spi_device), (const char*)color, size);
  163. }else{
  164. luat_spi_send(conf->port, (const char*)color, size);
  165. }
  166. return 0;
  167. }
  168. #endif
  169. int luat_lcd_clear(luat_lcd_conf_t* conf, luat_color_t color){
  170. luat_lcd_draw_fill(conf, 0, 0, conf->w, conf->h, color);
  171. return 0;
  172. }
  173. int luat_lcd_draw_fill(luat_lcd_conf_t* conf,uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2, luat_color_t color) {
  174. uint16_t i;
  175. for(i=y1;i<y2;i++)
  176. {
  177. luat_lcd_draw_line(conf, x1, i, x2, i, color);
  178. }
  179. return 0;
  180. }
  181. int luat_lcd_draw_point(luat_lcd_conf_t* conf, uint16_t x, uint16_t y, luat_color_t color) {
  182. return luat_lcd_draw(conf, x, y, x, y, &color);
  183. }
  184. int luat_lcd_draw_vline(luat_lcd_conf_t* conf, uint16_t x, uint16_t y,uint16_t h, luat_color_t color) {
  185. return luat_lcd_draw_line(conf, x, y, x, y + h, color);
  186. }
  187. int luat_lcd_draw_hline(luat_lcd_conf_t* conf, uint16_t x, uint16_t y,uint16_t w, luat_color_t color) {
  188. return luat_lcd_draw_line(conf, x, y, x+w, y, color);
  189. }
  190. int luat_lcd_draw_line(luat_lcd_conf_t* conf,uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2,luat_color_t color) {
  191. uint16_t t;
  192. uint32_t i = 0;
  193. int xerr = 0, yerr = 0, delta_x, delta_y, distance;
  194. int incx, incy, row, col;
  195. if (x1 == x2 || y1 == y2) // 直线
  196. {
  197. size_t dots = (x2 - x1 + 1) * (y2 - y1 + 1);//点数量
  198. luat_color_t* line_buf = (luat_color_t*) luat_heap_malloc(dots * sizeof(luat_color_t));
  199. if (line_buf) {
  200. for (i = 0; i < dots; i++)
  201. {
  202. line_buf[i] = color;
  203. }
  204. luat_lcd_draw(conf, x1, y1, x2, y2, line_buf);
  205. luat_heap_free(line_buf);
  206. return 0;
  207. }
  208. }
  209. delta_x = x2 - x1;
  210. delta_y = y2 - y1;
  211. row = x1;
  212. col = y1;
  213. if (delta_x > 0)incx = 1;
  214. else if (delta_x == 0)incx = 0;
  215. else
  216. {
  217. incx = -1;
  218. delta_x = -delta_x;
  219. }
  220. if (delta_y > 0)incy = 1;
  221. else if (delta_y == 0)incy = 0;
  222. else
  223. {
  224. incy = -1;
  225. delta_y = -delta_y;
  226. }
  227. if (delta_x > delta_y)distance = delta_x;
  228. else distance = delta_y;
  229. for (t = 0; t <= distance + 1; t++)
  230. {
  231. luat_lcd_draw_point(conf,row, col,color);
  232. xerr += delta_x ;
  233. yerr += delta_y ;
  234. if (xerr > distance)
  235. {
  236. xerr -= distance;
  237. row += incx;
  238. }
  239. if (yerr > distance)
  240. {
  241. yerr -= distance;
  242. col += incy;
  243. }
  244. }
  245. return 0;
  246. }
  247. int luat_lcd_draw_rectangle(luat_lcd_conf_t* conf,uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, luat_color_t color){
  248. luat_lcd_draw_line(conf,x1, y1, x2, y1, color);
  249. luat_lcd_draw_line(conf,x1, y1, x1, y2, color);
  250. luat_lcd_draw_line(conf,x1, y2, x2, y2, color);
  251. luat_lcd_draw_line(conf,x2, y1, x2, y2, color);
  252. return 0;
  253. }
  254. int luat_lcd_draw_circle(luat_lcd_conf_t* conf,uint16_t x0, uint16_t y0, uint8_t r, luat_color_t color){
  255. int a, b;
  256. int di;
  257. a = 0;
  258. b = r;
  259. di = 3 - (r << 1);
  260. while (a <= b)
  261. {
  262. luat_lcd_draw_point(conf,x0 - b, y0 - a,color);
  263. luat_lcd_draw_point(conf,x0 + b, y0 - a,color);
  264. luat_lcd_draw_point(conf,x0 - a, y0 + b,color);
  265. luat_lcd_draw_point(conf,x0 - b, y0 - a,color);
  266. luat_lcd_draw_point(conf,x0 - a, y0 - b,color);
  267. luat_lcd_draw_point(conf,x0 + b, y0 + a,color);
  268. luat_lcd_draw_point(conf,x0 + a, y0 - b,color);
  269. luat_lcd_draw_point(conf,x0 + a, y0 + b,color);
  270. luat_lcd_draw_point(conf,x0 - b, y0 + a,color);
  271. a++;
  272. //Bresenham
  273. if (di < 0)di += 4 * a + 6;
  274. else
  275. {
  276. di += 10 + 4 * (a - b);
  277. b--;
  278. }
  279. luat_lcd_draw_point(conf,x0 + a, y0 + b,color);
  280. }
  281. return 0;
  282. }
  283. int luat_lcd_show_image(luat_lcd_conf_t* conf,uint16_t x, uint16_t y, uint16_t length, uint16_t wide, const luat_color_t *image,uint8_t swap){
  284. if (x + length > conf->w || y + wide > conf->h){
  285. return -1;
  286. }
  287. if (swap)
  288. {
  289. uint32_t size = length * wide;
  290. luat_lcd_set_address(conf, x, y, x + length - 1, y + wide - 1);
  291. for (size_t i = 0; i < size; i++){
  292. char color[2] = {0};
  293. color[0] = *(image+i) >> 8;
  294. color[1] = *(image+i);
  295. if (conf->port == LUAT_LCD_SPI_DEVICE){
  296. luat_spi_device_send((luat_spi_device_t*)(conf->lcd_spi_device), (const char*)color, 2);
  297. }else{
  298. luat_spi_send(conf->port, (const char*)color, 2);
  299. }
  300. }
  301. }else{
  302. luat_lcd_draw(conf, x, y, x + length - 1, y + wide - 1, image);
  303. }
  304. return 0;
  305. }