gd32f303e_lcd_eval.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. /*!
  2. \file gd32f303e_lcd_eval.c
  3. \brief LCD driver functions
  4. */
  5. /*
  6. Copyright (C) 2017 GigaDevice
  7. 2017-05-19, V1.0.0, demo for GD32F30x
  8. */
  9. #include "gd32f30x.h"
  10. #include "gd32f303e_lcd_eval.h"
  11. #include "lcd_font.h"
  12. /*!
  13. \brief lcd peripheral initialize
  14. \param[in] none
  15. \param[out] none
  16. \retval none
  17. */
  18. void exmc_lcd_init(void)
  19. {
  20. exmc_norsram_parameter_struct lcd_init_struct;
  21. exmc_norsram_timing_parameter_struct lcd_timing_init_struct;
  22. /* EXMC clock enable */
  23. rcu_periph_clock_enable(RCU_EXMC);
  24. /* GPIO clock enable */
  25. rcu_periph_clock_enable(RCU_GPIOD);
  26. rcu_periph_clock_enable(RCU_GPIOE);
  27. rcu_periph_clock_enable(RCU_GPIOG);
  28. /* configure EXMC_D[0~15]*/
  29. /* PD14(EXMC_D0), PD15(EXMC_D1),PD0(EXMC_D2), PD1(EXMC_D3), PD8(EXMC_D13), PD9(EXMC_D14), PD10(EXMC_D15) */
  30. gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1| GPIO_PIN_8 | GPIO_PIN_9 |
  31. GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15);
  32. /* PE7(EXMC_D4), PE8(EXMC_D5), PE9(EXMC_D6), PE10(EXMC_D7), PE11(EXMC_D8), PE12(EXMC_D9),
  33. PE13(EXMC_D10), PE14(EXMC_D11), PE15(EXMC_D12) */
  34. gpio_init(GPIOE, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 |
  35. GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 |
  36. GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
  37. /* configure PE2(EXMC_A23) */
  38. gpio_init(GPIOE, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
  39. /* configure NOE and NWE */
  40. gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4 | GPIO_PIN_5);
  41. /* configure EXMC NE1 */
  42. gpio_init(GPIOG, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
  43. lcd_timing_init_struct.asyn_access_mode = EXMC_ACCESS_MODE_A;
  44. lcd_timing_init_struct.syn_data_latency = EXMC_DATALAT_2_CLK;
  45. lcd_timing_init_struct.syn_clk_division = EXMC_SYN_CLOCK_RATIO_DISABLE;
  46. lcd_timing_init_struct.bus_latency = 2;
  47. lcd_timing_init_struct.asyn_data_setuptime = 10;
  48. lcd_timing_init_struct.asyn_address_holdtime = 2;
  49. lcd_timing_init_struct.asyn_address_setuptime = 5;
  50. lcd_init_struct.norsram_region = EXMC_BANK0_NORSRAM_REGION1;
  51. lcd_init_struct.write_mode = EXMC_ASYN_WRITE;
  52. lcd_init_struct.extended_mode = DISABLE;
  53. lcd_init_struct.asyn_wait = DISABLE;
  54. lcd_init_struct.nwait_signal = DISABLE;
  55. lcd_init_struct.memory_write = ENABLE;
  56. lcd_init_struct.nwait_config = EXMC_NWAIT_CONFIG_BEFORE;
  57. lcd_init_struct.wrap_burst_mode = DISABLE;
  58. lcd_init_struct.nwait_polarity = EXMC_NWAIT_POLARITY_LOW;
  59. lcd_init_struct.burst_mode = DISABLE;
  60. lcd_init_struct.databus_width = EXMC_NOR_DATABUS_WIDTH_16B;
  61. lcd_init_struct.memory_type = EXMC_MEMORY_TYPE_SRAM;
  62. lcd_init_struct.address_data_mux = DISABLE;
  63. lcd_init_struct.read_write_timing = &lcd_timing_init_struct;
  64. lcd_init_struct.write_timing = &lcd_timing_init_struct;
  65. exmc_norsram_init(&lcd_init_struct);
  66. exmc_norsram_enable(EXMC_BANK0_NORSRAM_REGION1);
  67. }
  68. /*!
  69. \brief write data to the selected LCD register
  70. \param[in] register_id: the selected register id
  71. \param[in] value: the register value to be written
  72. \param[out] none
  73. \retval none
  74. */
  75. void lcd_register_write(uint16_t register_id,uint16_t value)
  76. {
  77. *(__IO uint16_t *) (BANK0_LCD_C)= register_id;
  78. *(__IO uint16_t *) (BANK0_LCD_D)= value;
  79. }
  80. /*!
  81. \brief read the value of LCD register
  82. \param[in] register_id: the register id
  83. \param[out] none
  84. \retval the register value
  85. */
  86. uint16_t lcd_register_read(uint8_t register_id)
  87. {
  88. uint16_t data;
  89. *(__IO uint16_t *) (BANK0_LCD_C)= register_id;
  90. data = *(__IO uint16_t *) (BANK0_LCD_D);
  91. return data;
  92. }
  93. /*!
  94. \brief write command to LCD register
  95. \param[in] value: the register value to be written
  96. \param[out] none
  97. \retval none
  98. */
  99. void lcd_command_write(uint16_t value)
  100. {
  101. /* write 16-bit index, then write reg */
  102. *(__IO uint16_t *) (BANK0_LCD_D) = value;
  103. }
  104. /*!
  105. \brief prepare to write to the LCD GRAM register(R22h)
  106. \param[in] none
  107. \param[out] none
  108. \retval none
  109. */
  110. void lcd_gram_write_prepare(void)
  111. {
  112. *(__IO uint16_t *) (BANK0_LCD_C) = 0x0022;
  113. }
  114. /*!
  115. \brief write RGB code to the LCD GRAM register
  116. \param[in] rgb_code: the pixel color in RGB mode (5-6-5)
  117. \param[out] none
  118. \retval none
  119. */
  120. void lcd_gram_write(uint16_t rgb_code)
  121. {
  122. /* write 16-bit GRAM register */
  123. *(__IO uint16_t *) (BANK0_LCD_D) = rgb_code;
  124. }
  125. /*!
  126. \brief read data from GRAM
  127. \param[in] none
  128. \param[out] none
  129. \retval GRAM value
  130. */
  131. uint16_t lcd_gram_read(void)
  132. {
  133. uint16_t data;
  134. /* write GRAM register (R22h) */
  135. *(__IO uint16_t *) (BANK0_LCD_C) = 0x0022;
  136. /* dummy read (invalid data) */
  137. *(__IO uint16_t *) (BANK0_LCD_D);
  138. data = *(__IO uint16_t *) (BANK0_LCD_D);
  139. return data;
  140. }
  141. /*!
  142. \brief initialize the LCD
  143. \param[in] none
  144. \param[out] none
  145. \retval none
  146. */
  147. void lcd_init(void)
  148. {
  149. uint16_t i;
  150. if(1){ /*!< if(device_code == 0x8989) */
  151. lcd_register_write(0x0000,0x0001);
  152. lcd_register_write(0x0003,0xA8A4);
  153. lcd_register_write(0x000C,0x0000);
  154. lcd_register_write(0x000D,0x080C);
  155. lcd_register_write(0x000E,0x2B00);
  156. lcd_register_write(0x001E,0x00B0);
  157. lcd_register_write(0x0001,0x2B3F);
  158. lcd_register_write(0x0002,0x0600);
  159. lcd_register_write(0x0010,0x0000);
  160. lcd_register_write(0x0011,0x6070);
  161. lcd_register_write(0x0005,0x0000);
  162. lcd_register_write(0x0006,0x0000);
  163. lcd_register_write(0x0016,0xEF1C);
  164. lcd_register_write(0x0017,0x0003);
  165. lcd_register_write(0x0007,0x0233);
  166. lcd_register_write(0x000B,0x0000);
  167. lcd_register_write(0x000F,0x0000);
  168. lcd_register_write(0x0041,0x0000);
  169. lcd_register_write(0x0042,0x0000);
  170. lcd_register_write(0x0048,0x0000);
  171. lcd_register_write(0x0049,0x013F);
  172. lcd_register_write(0x004A,0x0000);
  173. lcd_register_write(0x004B,0x0000);
  174. lcd_register_write(0x0044,0xEF00);
  175. lcd_register_write(0x0045,0x0000);
  176. lcd_register_write(0x0046,0x013F);
  177. lcd_register_write(0x0030,0x0707);
  178. lcd_register_write(0x0031,0x0204);
  179. lcd_register_write(0x0032,0x0204);
  180. lcd_register_write(0x0033,0x0502);
  181. lcd_register_write(0x0034,0x0507);
  182. lcd_register_write(0x0035,0x0204);
  183. lcd_register_write(0x0036,0x0204);
  184. lcd_register_write(0x0037,0x0502);
  185. lcd_register_write(0x003A,0x0302);
  186. lcd_register_write(0x003B,0x0302);
  187. lcd_register_write(0x0023,0x0000);
  188. lcd_register_write(0x0024,0x0000);
  189. lcd_register_write(0x0025,0x8000);
  190. lcd_register_write(0x004e,0);
  191. lcd_register_write(0x004f,0);
  192. }else{
  193. return;
  194. }
  195. for(i=50000;i>0;i--);
  196. }
  197. /*!
  198. \brief set the cursor of LCD
  199. \param[in] x: the row-coordinate
  200. \param[in] y: the column-coordinate
  201. \param[out] none
  202. \retval none
  203. */
  204. void lcd_cursor_set(uint16_t x,uint16_t y)
  205. {
  206. lcd_register_write(0x004e,x);
  207. lcd_register_write(0x004f,y);
  208. }
  209. /*!
  210. \brief clear the LCD screen to the specified color
  211. \param[in] color: specified screen color
  212. \param[out] none
  213. \retval none
  214. */
  215. void lcd_clear(uint16_t color)
  216. {
  217. uint32_t index=0;
  218. lcd_cursor_set(0,0);
  219. /* prepare to write GRAM */
  220. lcd_gram_write_prepare();
  221. for(index=0;index<76800;index++){
  222. *(__IO uint16_t *) (BANK0_LCD_D) = color;
  223. }
  224. }
  225. /*!
  226. \brief set the point according to the specified position and color
  227. \param[in] x: the row-coordinate
  228. \param[in] y: the column-coordinate
  229. \param[in] point: specified color of the point
  230. \param[out] none
  231. \retval none
  232. */
  233. void lcd_point_set(uint16_t x,uint16_t y,uint16_t point)
  234. {
  235. if ((x > 240)||(y > 320)){
  236. return;
  237. }
  238. lcd_cursor_set(x,y);
  239. lcd_gram_write_prepare();
  240. lcd_gram_write(point);
  241. }
  242. /*!
  243. \brief get point GRAM according to the specified position
  244. \param[in] x: the row-coordinate
  245. \param[in] y: the column-coordinate
  246. \param[out] none
  247. \retval GRAM value of point
  248. */
  249. uint16_t lcd_point_get(uint16_t x,uint16_t y)
  250. {
  251. uint16_t data;
  252. if ((x > 240)||(y > 320)){
  253. return 0;
  254. }
  255. lcd_cursor_set(x,y);
  256. data = lcd_gram_read();
  257. return data;
  258. }
  259. /*!
  260. \brief set window area
  261. \param[in] start_x: the start position of row-coordinate
  262. \param[in] start_y: the start position of column-coordinate
  263. \param[in] end_x: the end position of row-coordinate
  264. \param[in] end_y: the end position of column-coordinate
  265. \param[out] none
  266. \retval none
  267. */
  268. void lcd_windows_set(uint16_t start_x,uint16_t start_y,uint16_t end_x,uint16_t end_y)
  269. {
  270. lcd_cursor_set(start_x, start_y);
  271. lcd_register_write(0x0050, start_x);
  272. lcd_register_write(0x0052, start_y);
  273. lcd_register_write(0x0051, end_x);
  274. lcd_register_write(0x0053, end_y);
  275. }
  276. /*!
  277. \brief draw a horizontal line on LCD screen
  278. \param[in] x: the row-coordinate
  279. \param[in] start_y: the start column-coordinate
  280. \param[in] end_y: the end column-coordinate
  281. \param[in] color: specified color of the point
  282. \param[in] width: line width
  283. \param[out] none
  284. \retval none
  285. */
  286. void lcd_hline_draw(uint16_t x,uint16_t start_y,uint16_t end_y,uint16_t color,uint16_t width)
  287. {
  288. uint16_t i, y;
  289. for (i = 0; i < width; i++) {
  290. uint16_t sx = x + i;
  291. for (y = start_y; y < end_y; y++) {
  292. lcd_point_set(sx, y, color);
  293. }
  294. }
  295. }
  296. /*!
  297. \brief draw a rectangle according to the specified position and color
  298. \param[in] start_x: the start position of row-coordinate
  299. \param[in] start_y: the start position of column-coordinate
  300. \param[in] end_x: the end position of row-coordinate
  301. \param[in] end_y: the end position of column-coordinate
  302. \param[in] point: specified color of the point
  303. \param[out] none
  304. \retval none
  305. */
  306. void lcd_rectangle_draw(uint16_t start_x,uint16_t start_y,uint16_t end_x,uint16_t end_y,uint16_t point)
  307. {
  308. uint16_t x,y;
  309. x=start_x;
  310. y=start_y;
  311. /* draw four lines */
  312. for(x=start_x;x<end_x;x++){
  313. /* draw a point */
  314. lcd_point_set(x,y,point);
  315. }
  316. for(y=start_y;y<end_y;y++){
  317. lcd_point_set(x,y,point);
  318. }
  319. for(x=end_x;x>start_x;x--){
  320. lcd_point_set(x,y,point);
  321. }
  322. for(y=end_y;y>start_y;y--){
  323. lcd_point_set(x,y,point);
  324. }
  325. }
  326. /*!
  327. \brief fill the specified color to a rectangle
  328. \param[in] start_x: the start position of row-coordinate
  329. \param[in] start_y: the start position of column-coordinate
  330. \param[in] end_x: the end position of row-coordinate
  331. \param[in] end_y: the end position of column-coordinate
  332. \param[in] color: specified color
  333. \param[out] none
  334. \retval none
  335. */
  336. void lcd_rectangle_fill(uint16_t start_x,uint16_t start_y,uint16_t end_x,uint16_t end_y,uint16_t color)
  337. {
  338. uint16_t x, y;
  339. x = start_x;
  340. y = start_y;
  341. for (x = start_x; x < end_x; x++) {
  342. for (y = start_y; y < end_y; y++) {
  343. lcd_point_set(x, y, color);
  344. }
  345. }
  346. }
  347. /*!
  348. \brief draw a picture on LCD screen according to the specified position
  349. \param[in] start_x: the start position of row-coordinate
  350. \param[in] start_y: the start position of column-coordinate
  351. \param[in] end_x: the end position of row-coordinate
  352. \param[in] end_y: the end position of column-coordinate
  353. \param[in] pic: the picture pointer
  354. \param[out] none
  355. \retval none
  356. */
  357. void lcd_picture_draw(uint16_t start_x,uint16_t start_y,uint16_t end_x,uint16_t end_y,uint16_t *pic)
  358. {
  359. uint32_t i, total;
  360. uint16_t *picturepointer = pic;
  361. uint16_t x,y;
  362. x = start_x;
  363. y = start_y;
  364. total = (end_x - start_x + 1) * (end_y - start_y + 1);
  365. for(i = 0; i < total; i ++){
  366. /* set point according to the specified position and color */
  367. lcd_point_set(x,y,*picturepointer++);
  368. x++;
  369. if(x > end_x){
  370. y++;
  371. x = start_x;
  372. }
  373. }
  374. }
  375. /*!
  376. \brief display a char on LCD screen according to the specified position
  377. \param[in] x: the start position of row-coordinate
  378. \param[in] y: the start position of column-coordinate
  379. \param[in] c: the char
  380. \param[in] char_color: the color of char
  381. \param[in] c_format: the struct of char format
  382. font: CHAR_FONT_8_16 or CHAR_FONT_16_24
  383. direction: CHAR_DIRECTION_HORIZONTAL or CHAR_DIRECTION_VERTICAL
  384. char_color: the color of char
  385. bk_color: the color of backgroud
  386. \param[out] none
  387. \retval none
  388. */
  389. void lcd_char_display(uint16_t x,uint16_t y,uint8_t c,char_format_struct c_format)
  390. {
  391. uint16_t i = 0, j = 0;
  392. uint8_t temp_char = 0;
  393. uint16_t temp_char_16 = 0;
  394. if(CHAR_FONT_8_16 == c_format.font){ /* 8x16 ASCII */
  395. for (i = 0; i < 16; i++) {
  396. temp_char = ascii_8x16[((c - 0x20) * 16) + i];
  397. if(CHAR_DIRECTION_HORIZONTAL == c_format.direction){
  398. for (j = 0; j < 8; j++) {
  399. if (((temp_char >> (7 - j)) & 0x01) == 0x01) {
  400. /* set point of char */
  401. lcd_point_set(x - i, y + j, c_format.char_color);
  402. } else {
  403. /* set point of background */
  404. lcd_point_set(x - i, y + j, c_format.bk_color);
  405. }
  406. }
  407. }else{
  408. for (j = 0; j < 8; j++) {
  409. if (((temp_char >> (7 - j)) & 0x01) == 0x01) {
  410. /* set point of char */
  411. lcd_point_set(x + j, y + i, c_format.char_color);
  412. } else {
  413. /* set point of background */
  414. lcd_point_set(x + j, y + i, c_format.bk_color);
  415. }
  416. }
  417. }
  418. }
  419. }else if(CHAR_FONT_16_24 == c_format.font){ /* 16x24 ASCII */
  420. for (i = 0; i < 24; i++) {
  421. temp_char_16 = ASCII_Table_16x24[((c - 0x20) * 24) + i];
  422. if(CHAR_DIRECTION_HORIZONTAL == c_format.direction){
  423. for (j = 0; j < 16; j++) {
  424. if (((temp_char_16 >> j) & 0x01) == 0x01) {
  425. /* set point of char */
  426. lcd_point_set(x - i, y + j, c_format.char_color);
  427. } else {
  428. /* set point of background */
  429. lcd_point_set(x - i, y + j, c_format.bk_color);
  430. }
  431. }
  432. }else{
  433. for (j = 0; j < 16; j++) {
  434. if (((temp_char_16 >> j) & 0x01) == 0x01) {
  435. /* set point of char */
  436. lcd_point_set(x + j, y + i, c_format.char_color);
  437. } else {
  438. /* set point of background */
  439. lcd_point_set(x + j, y + i, c_format.bk_color);
  440. }
  441. }
  442. }
  443. }
  444. }
  445. }