drv_lcd.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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. * 2017-08-23 Tanek the first version
  9. */
  10. #include "gd32f450z_lcd_eval.h"
  11. #include <gd32f4xx.h>
  12. #include <drv_usart.h>
  13. #include <board.h>
  14. #include <finsh.h>
  15. #ifdef PKG_USING_GUIENGINE
  16. #define RT_HW_LCD_WIDTH ((uint16_t)320) /* LCD PIXEL WIDTH */
  17. #define RT_HW_LCD_HEIGHT ((uint16_t)480) /* LCD PIXEL HEIGHT */
  18. #define LCD_480_320_HSYNC ((uint32_t)10) /* Horizontal synchronization */
  19. #define LCD_480_320_HBP ((uint32_t)20) /* Horizontal back porch */
  20. #define LCD_480_320_HFP ((uint32_t)40) /* Horizontal front porch */
  21. #define LCD_480_320_VSYNC ((uint32_t)2) /* Vertical synchronization */
  22. #define LCD_480_320_VBP ((uint32_t)1) /* Vertical back porch */
  23. #define LCD_480_320_VFP ((uint32_t)4) /* Vertical front porch */
  24. #define LCD_BITS_PER_PIXEL 16
  25. static rt_uint16_t *lcd_framebuffer = RT_NULL;
  26. static rt_uint16_t *_rt_framebuffer = RT_NULL;
  27. static struct rt_device_graphic_info _lcd_info;
  28. static struct rt_device lcd;
  29. /*!
  30. \brief configure TLI GPIO
  31. \param[in] none
  32. \param[out] none
  33. \retval none
  34. */
  35. static void tli_gpio_config(void)
  36. {
  37. /* enable the periphral clock */
  38. rcu_periph_clock_enable(RCU_GPIOA);
  39. rcu_periph_clock_enable(RCU_GPIOB);
  40. rcu_periph_clock_enable(RCU_GPIOC);
  41. rcu_periph_clock_enable(RCU_GPIOD);
  42. rcu_periph_clock_enable(RCU_GPIOF);
  43. rcu_periph_clock_enable(RCU_GPIOG);
  44. /* configure HSYNC(PC6), VSYNC(PA4), PCLK(PG7), DE(PF10) */
  45. /* configure LCD_R7(PG6), LCD_R6(PA8), LCD_R5(PA12), LCD_R4(PA11), LCD_R3(PB0),
  46. LCD_G7(PD3), LCD_G6(PC7), LCD_G5(PB11), LCD_G4(PB10), LCD_G3(PG10), LCD_G2(PA6),
  47. LCD_B7(PB9), LCD_B6(PB8), LCD_B5(PA3), LCD_B4(PG12), LCD_B3(PG11) */
  48. gpio_af_set(GPIOA,GPIO_AF_14,GPIO_PIN_3);
  49. gpio_af_set(GPIOA,GPIO_AF_14,GPIO_PIN_4);
  50. gpio_af_set(GPIOA,GPIO_AF_14,GPIO_PIN_6);
  51. gpio_af_set(GPIOA,GPIO_AF_14,GPIO_PIN_12);
  52. gpio_af_set(GPIOA,GPIO_AF_14,GPIO_PIN_11);
  53. gpio_af_set(GPIOA,GPIO_AF_14,GPIO_PIN_8);
  54. gpio_af_set(GPIOB,GPIO_AF_9,GPIO_PIN_0);
  55. gpio_af_set(GPIOB,GPIO_AF_14,GPIO_PIN_10);
  56. //gpio_af_set(GPIOB,GPIO_AF_14,GPIO_PIN_11);
  57. gpio_af_set(GPIOB,GPIO_AF_14,GPIO_PIN_8);
  58. gpio_af_set(GPIOB,GPIO_AF_14,GPIO_PIN_9);
  59. gpio_af_set(GPIOC,GPIO_AF_14,GPIO_PIN_6);
  60. gpio_af_set(GPIOC,GPIO_AF_14,GPIO_PIN_7);
  61. gpio_af_set(GPIOD,GPIO_AF_14,GPIO_PIN_3);
  62. gpio_af_set(GPIOF,GPIO_AF_14,GPIO_PIN_10);
  63. gpio_af_set(GPIOG,GPIO_AF_14,GPIO_PIN_6);
  64. gpio_af_set(GPIOG,GPIO_AF_14,GPIO_PIN_7);
  65. gpio_af_set(GPIOG,GPIO_AF_9,GPIO_PIN_10);
  66. gpio_af_set(GPIOG,GPIO_AF_14,GPIO_PIN_11);
  67. gpio_af_set(GPIOG,GPIO_AF_9,GPIO_PIN_12);
  68. gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_4|GPIO_PIN_3|GPIO_PIN_6
  69. |GPIO_PIN_8|GPIO_PIN_11|GPIO_PIN_12);
  70. gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_4|GPIO_PIN_3
  71. |GPIO_PIN_6|GPIO_PIN_8|GPIO_PIN_11|GPIO_PIN_12);
  72. gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_0|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
  73. /*|GPIO_PIN_11*/);
  74. gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
  75. /*|GPIO_PIN_11*/);
  76. gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6|GPIO_PIN_7);
  77. gpio_output_options_set(GPIOC, GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ, GPIO_PIN_6|GPIO_PIN_7);
  78. gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3);
  79. gpio_output_options_set(GPIOD, GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ, GPIO_PIN_3);
  80. gpio_mode_set(GPIOF, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10);
  81. gpio_output_options_set(GPIOF, GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ, GPIO_PIN_10);
  82. gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_10|GPIO_PIN_11
  83. |GPIO_PIN_12);
  84. gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_10|GPIO_PIN_11
  85. |GPIO_PIN_12);
  86. }
  87. /*!
  88. \brief LCD Configuration
  89. \param[in] none
  90. \param[out] none
  91. \retval none
  92. */
  93. static void lcd_config(void)
  94. {
  95. /* configure the LCD control line */
  96. lcd_ctrl_line_config();
  97. lcd_disable();
  98. lcd_enable();
  99. /* configure the GPIO of TLI */
  100. tli_gpio_config();
  101. /* configure the LCD_SPI */
  102. lcd_spi_config();
  103. /* power on the LCD */
  104. //lcd_power_on();
  105. lcd_power_on3(); //New Version 3.5" TFT RGB Hardware needs use this initilize funtion ---By xufei 2016.10.21
  106. }
  107. /*!
  108. \brief configure TLI peripheral
  109. \param[in] none
  110. \param[out] none
  111. \retval none
  112. */
  113. static void tli_config(void)
  114. {
  115. tli_parameter_struct tli_init_struct;
  116. tli_layer_parameter_struct tli_layer_init_struct;
  117. rcu_periph_clock_enable(RCU_TLI);
  118. /* configure the PLLSAI clock to generate lcd clock */
  119. if(ERROR == rcu_pllsai_config(192, 2, 3, 3)){
  120. while(1);
  121. }
  122. rcu_tli_clock_div_config(RCU_PLLSAIR_DIV8);
  123. rcu_osci_on(RCU_PLLSAI_CK);
  124. if(ERROR == rcu_osci_stab_wait(RCU_PLLSAI_CK)){
  125. while(1);
  126. }
  127. /* TLI initialization */
  128. tli_init_struct.signalpolarity_hs = TLI_HSYN_ACTLIVE_LOW;
  129. tli_init_struct.signalpolarity_vs = TLI_VSYN_ACTLIVE_LOW;
  130. tli_init_struct.signalpolarity_de = TLI_DE_ACTLIVE_LOW;
  131. tli_init_struct.signalpolarity_pixelck = TLI_PIXEL_CLOCK_TLI;
  132. /* LCD display timing configuration */
  133. tli_init_struct.synpsz_hpsz = LCD_480_320_HSYNC;
  134. tli_init_struct.synpsz_vpsz = LCD_480_320_VSYNC;
  135. tli_init_struct.backpsz_hbpsz = LCD_480_320_HSYNC + LCD_480_320_HBP;
  136. tli_init_struct.backpsz_vbpsz = LCD_480_320_VSYNC + LCD_480_320_VBP;
  137. tli_init_struct.activesz_hasz = RT_HW_LCD_WIDTH + LCD_480_320_HSYNC + LCD_480_320_HBP;
  138. tli_init_struct.activesz_vasz = RT_HW_LCD_HEIGHT + LCD_480_320_VSYNC + LCD_480_320_VBP;
  139. tli_init_struct.totalsz_htsz = RT_HW_LCD_WIDTH + LCD_480_320_HSYNC + LCD_480_320_HBP + LCD_480_320_HFP;
  140. tli_init_struct.totalsz_vtsz = RT_HW_LCD_HEIGHT + LCD_480_320_VSYNC + LCD_480_320_VBP + LCD_480_320_VFP;
  141. /* LCD background color configure*/
  142. tli_init_struct.backcolor_red = 0x00;
  143. tli_init_struct.backcolor_green = 0x00;
  144. tli_init_struct.backcolor_blue = 0x00;
  145. tli_init(&tli_init_struct);
  146. lcd_framebuffer = rt_malloc(sizeof(rt_uint16_t) * RT_HW_LCD_HEIGHT * RT_HW_LCD_WIDTH);
  147. RT_ASSERT(lcd_framebuffer != NULL);
  148. rt_memset(lcd_framebuffer, 0, sizeof(rt_uint16_t) * RT_HW_LCD_WIDTH * RT_HW_LCD_HEIGHT);
  149. /* TLI layer0 configuration */
  150. tli_layer_init_struct.layer_window_leftpos = tli_init_struct.backpsz_hbpsz + 1;
  151. tli_layer_init_struct.layer_window_rightpos = tli_init_struct.backpsz_hbpsz + RT_HW_LCD_WIDTH;
  152. tli_layer_init_struct.layer_window_toppos = tli_init_struct.backpsz_vbpsz + 1;
  153. tli_layer_init_struct.layer_window_bottompos = tli_init_struct.backpsz_vbpsz + RT_HW_LCD_HEIGHT;
  154. tli_layer_init_struct.layer_ppf = LAYER_PPF_RGB565;
  155. tli_layer_init_struct.layer_sa = 0xFF;
  156. tli_layer_init_struct.layer_default_blue = 0x00;
  157. tli_layer_init_struct.layer_default_green = 0x00;
  158. tli_layer_init_struct.layer_default_red = 0x00;
  159. tli_layer_init_struct.layer_default_alpha = 0x00;
  160. tli_layer_init_struct.layer_acf1 = LAYER_ACF1_PASA;
  161. tli_layer_init_struct.layer_acf2 = LAYER_ACF2_PASA;
  162. tli_layer_init_struct.layer_frame_bufaddr = (uint32_t)lcd_framebuffer;
  163. tli_layer_init_struct.layer_frame_line_length = ((RT_HW_LCD_WIDTH * 2) + 3);
  164. tli_layer_init_struct.layer_frame_buf_stride_offset = (RT_HW_LCD_WIDTH * 2);
  165. tli_layer_init_struct.layer_frame_total_line_number = RT_HW_LCD_HEIGHT;
  166. tli_layer_init(LAYER0, &tli_layer_init_struct);
  167. }
  168. static rt_err_t rt_lcd_control(rt_device_t dev, int cmd, void *args)
  169. {
  170. switch (cmd)
  171. {
  172. case RTGRAPHIC_CTRL_RECT_UPDATE:
  173. {
  174. memcpy((void *)lcd_framebuffer, _rt_framebuffer, sizeof(rt_uint16_t)*RT_HW_LCD_HEIGHT * RT_HW_LCD_WIDTH);
  175. }
  176. break;
  177. case RTGRAPHIC_CTRL_POWERON:
  178. break;
  179. case RTGRAPHIC_CTRL_POWEROFF:
  180. break;
  181. case RTGRAPHIC_CTRL_GET_INFO:
  182. memcpy(args, &_lcd_info, sizeof(_lcd_info));
  183. break;
  184. case RTGRAPHIC_CTRL_SET_MODE:
  185. break;
  186. }
  187. return RT_EOK;
  188. }
  189. int gd32_hw_lcd_init(void)
  190. {
  191. _rt_framebuffer = rt_malloc_align(sizeof(rt_uint16_t) * RT_HW_LCD_WIDTH * RT_HW_LCD_HEIGHT, 32);
  192. if (_rt_framebuffer == RT_NULL)
  193. return -1; /* no memory yet */
  194. lcd_config();
  195. tli_config();
  196. tli_layer_enable(LAYER0);
  197. tli_reload_config(TLI_FRAME_BLANK_RELOAD_EN);
  198. tli_enable();
  199. _lcd_info.bits_per_pixel = LCD_BITS_PER_PIXEL;
  200. _lcd_info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565;
  201. _lcd_info.framebuffer = (void *)_rt_framebuffer;
  202. _lcd_info.width = RT_HW_LCD_WIDTH;
  203. _lcd_info.height = RT_HW_LCD_HEIGHT;
  204. lcd.type = RT_Device_Class_Graphic;
  205. lcd.init = NULL;
  206. lcd.open = NULL;
  207. lcd.close = NULL;
  208. lcd.read = NULL;
  209. lcd.write = NULL;
  210. lcd.control = rt_lcd_control;
  211. lcd.user_data = (void *)&_lcd_info;
  212. /* register lcd device to RT-Thread */
  213. rt_device_register(&lcd, "lcd", RT_DEVICE_FLAG_RDWR);
  214. return 0;
  215. }
  216. INIT_DEVICE_EXPORT(gd32_hw_lcd_init);
  217. #endif