ili9320.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. /*!
  2. \file ili9320.c
  3. \brief LCD driver functions
  4. \version 2017-02-10, V1.0.0, firmware for GD32F30x
  5. \version 2018-10-10, V1.1.0, firmware for GD32F30x
  6. \version 2018-12-25, V2.0.0, firmware for GD32F30x
  7. \version 2020-09-30, V2.1.0, firmware for GD32F30x
  8. */
  9. /*
  10. Copyright (c) 2020, GigaDevice Semiconductor Inc.
  11. Redistribution and use in source and binary forms, with or without modification,
  12. are permitted provided that the following conditions are met:
  13. 1. Redistributions of source code must retain the above copyright notice, this
  14. list of conditions and the following disclaimer.
  15. 2. Redistributions in binary form must reproduce the above copyright notice,
  16. this list of conditions and the following disclaimer in the documentation
  17. and/or other materials provided with the distribution.
  18. 3. Neither the name of the copyright holder nor the names of its contributors
  19. may be used to endorse or promote products derived from this software without
  20. specific prior written permission.
  21. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  22. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  23. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  24. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  25. INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  26. NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  27. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  28. WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  29. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  30. OF SUCH DAMAGE.
  31. */
  32. #include "gd32f30x.h"
  33. #include "ili9320.h"
  34. #include "ili9320_font.h"
  35. /*!
  36. \brief write data to the selected LCD register
  37. \param[in] register_id: the selected register id
  38. \param[in] value: the register value to be written
  39. \param[out] none
  40. \retval none
  41. */
  42. void lcd_register_write(uint16_t register_id,uint16_t value)
  43. {
  44. *(__IO uint16_t *) (BANK0_LCD_C)= register_id;
  45. *(__IO uint16_t *) (BANK0_LCD_D)= value;
  46. }
  47. /*!
  48. \brief read the value of LCD register
  49. \param[in] register_id: the register id
  50. \param[out] none
  51. \retval the register value
  52. */
  53. uint16_t lcd_register_read(uint8_t register_id)
  54. {
  55. uint16_t data;
  56. *(__IO uint16_t *) (BANK0_LCD_C)= register_id;
  57. data = *(__IO uint16_t *) (BANK0_LCD_D);
  58. return data;
  59. }
  60. /*!
  61. \brief write command to LCD register
  62. \param[in] value: the register value to be written
  63. \param[out] none
  64. \retval none
  65. */
  66. void lcd_command_write(uint16_t value)
  67. {
  68. /* write 16-bit index, then write reg */
  69. *(__IO uint16_t *) (BANK0_LCD_D) = value;
  70. }
  71. /*!
  72. \brief prepare to write to the LCD GRAM register(R22h)
  73. \param[in] none
  74. \param[out] none
  75. \retval none
  76. */
  77. void lcd_gram_write_prepare(void)
  78. {
  79. *(__IO uint16_t *) (BANK0_LCD_C) = 0x0022;
  80. }
  81. /*!
  82. \brief write RGB code to the LCD GRAM register
  83. \param[in] rgb_code: the pixel color in RGB mode (5-6-5)
  84. \param[out] none
  85. \retval none
  86. */
  87. void lcd_gram_write(uint16_t rgb_code)
  88. {
  89. /* write 16-bit GRAM register */
  90. *(__IO uint16_t *) (BANK0_LCD_D) = rgb_code;
  91. }
  92. /*!
  93. \brief read data from GRAM
  94. \param[in] none
  95. \param[out] none
  96. \retval GRAM value
  97. */
  98. uint16_t lcd_gram_read(void)
  99. {
  100. uint16_t data;
  101. /* write GRAM register (R22h) */
  102. *(__IO uint16_t *) (BANK0_LCD_C) = 0x0022;
  103. /* dummy read (invalid data) */
  104. *(__IO uint16_t *) (BANK0_LCD_D);
  105. data = *(__IO uint16_t *) (BANK0_LCD_D);
  106. return data;
  107. }
  108. /*!
  109. \brief initialize the LCD
  110. \param[in] none
  111. \param[out] none
  112. \retval none
  113. */
  114. void lcd_init(void)
  115. {
  116. uint16_t i;
  117. if(1){ /*!< if(device_code == 0x8989) */
  118. lcd_register_write(0x0000,0x0001);
  119. lcd_register_write(0x0003,0xA8A4);
  120. lcd_register_write(0x000C,0x0000);
  121. lcd_register_write(0x000D,0x080C);
  122. lcd_register_write(0x000E,0x2B00);
  123. lcd_register_write(0x001E,0x00B0);
  124. lcd_register_write(0x0001,0x2B3F);
  125. lcd_register_write(0x0002,0x0600);
  126. lcd_register_write(0x0010,0x0000);
  127. lcd_register_write(0x0011,0x6070);
  128. lcd_register_write(0x0005,0x0000);
  129. lcd_register_write(0x0006,0x0000);
  130. lcd_register_write(0x0016,0xEF1C);
  131. lcd_register_write(0x0017,0x0003);
  132. lcd_register_write(0x0007,0x0233);
  133. lcd_register_write(0x000B,0x0000);
  134. lcd_register_write(0x000F,0x0000);
  135. lcd_register_write(0x0041,0x0000);
  136. lcd_register_write(0x0042,0x0000);
  137. lcd_register_write(0x0048,0x0000);
  138. lcd_register_write(0x0049,0x013F);
  139. lcd_register_write(0x004A,0x0000);
  140. lcd_register_write(0x004B,0x0000);
  141. lcd_register_write(0x0044,0xEF00);
  142. lcd_register_write(0x0045,0x0000);
  143. lcd_register_write(0x0046,0x013F);
  144. lcd_register_write(0x0030,0x0707);
  145. lcd_register_write(0x0031,0x0204);
  146. lcd_register_write(0x0032,0x0204);
  147. lcd_register_write(0x0033,0x0502);
  148. lcd_register_write(0x0034,0x0507);
  149. lcd_register_write(0x0035,0x0204);
  150. lcd_register_write(0x0036,0x0204);
  151. lcd_register_write(0x0037,0x0502);
  152. lcd_register_write(0x003A,0x0302);
  153. lcd_register_write(0x003B,0x0302);
  154. lcd_register_write(0x0023,0x0000);
  155. lcd_register_write(0x0024,0x0000);
  156. lcd_register_write(0x0025,0x8000);
  157. lcd_register_write(0x004e,0);
  158. lcd_register_write(0x004f,0);
  159. }else{
  160. return;
  161. }
  162. for(i=50000;i>0;i--);
  163. }
  164. /*!
  165. \brief set the cursor of LCD
  166. \param[in] x: the row-coordinate
  167. \param[in] y: the column-coordinate
  168. \param[out] none
  169. \retval none
  170. */
  171. void lcd_cursor_set(uint16_t x,uint16_t y)
  172. {
  173. lcd_register_write(0x004e,x);
  174. lcd_register_write(0x004f,y);
  175. }
  176. /*!
  177. \brief clear the LCD screen to the specified color
  178. \param[in] color: specified screen color
  179. \param[out] none
  180. \retval none
  181. */
  182. void lcd_clear(uint16_t color)
  183. {
  184. uint32_t index=0;
  185. lcd_cursor_set(0,0);
  186. /* prepare to write GRAM */
  187. lcd_gram_write_prepare();
  188. for(index=0;index<76800;index++){
  189. *(__IO uint16_t *) (BANK0_LCD_D) = color;
  190. }
  191. }
  192. /*!
  193. \brief set the point according to the specified position and color
  194. \param[in] x: the row-coordinate
  195. \param[in] y: the column-coordinate
  196. \param[in] point: specified color of the point
  197. \param[out] none
  198. \retval none
  199. */
  200. void lcd_point_set(uint16_t x,uint16_t y,uint16_t point)
  201. {
  202. if ((x > 240)||(y > 320)){
  203. return;
  204. }
  205. lcd_cursor_set(x,y);
  206. lcd_gram_write_prepare();
  207. lcd_gram_write(point);
  208. }
  209. /*!
  210. \brief get point GRAM according to the specified position
  211. \param[in] x: the row-coordinate
  212. \param[in] y: the column-coordinate
  213. \param[out] none
  214. \retval GRAM value of point
  215. */
  216. uint16_t lcd_point_get(uint16_t x,uint16_t y)
  217. {
  218. uint16_t data;
  219. if ((x > 240)||(y > 320)){
  220. return 0;
  221. }
  222. lcd_cursor_set(x,y);
  223. data = lcd_gram_read();
  224. return data;
  225. }
  226. /*!
  227. \brief set window area
  228. \param[in] start_x: the start position of row-coordinate
  229. \param[in] start_y: the start position of column-coordinate
  230. \param[in] end_x: the end position of row-coordinate
  231. \param[in] end_y: the end position of column-coordinate
  232. \param[out] none
  233. \retval none
  234. */
  235. void lcd_windows_set(uint16_t start_x,uint16_t start_y,uint16_t end_x,uint16_t end_y)
  236. {
  237. lcd_cursor_set(start_x, start_y);
  238. lcd_register_write(0x0050, start_x);
  239. lcd_register_write(0x0052, start_y);
  240. lcd_register_write(0x0051, end_x);
  241. lcd_register_write(0x0053, end_y);
  242. }
  243. /*!
  244. \brief draw a horizontal line on LCD screen
  245. \param[in] x: the row-coordinate
  246. \param[in] start_y: the start column-coordinate
  247. \param[in] end_y: the end column-coordinate
  248. \param[in] color: specified color of the point
  249. \param[in] width: line width
  250. \param[out] none
  251. \retval none
  252. */
  253. void lcd_hline_draw(uint16_t x,uint16_t start_y,uint16_t end_y,uint16_t color,uint16_t width)
  254. {
  255. uint16_t i, y;
  256. for (i = 0; i < width; i++) {
  257. uint16_t sx = x + i;
  258. for (y = start_y; y < end_y; y++) {
  259. lcd_point_set(sx, y, color);
  260. }
  261. }
  262. }
  263. /*!
  264. \brief draw a rectangle according to the specified position and color
  265. \param[in] start_x: the start position of row-coordinate
  266. \param[in] start_y: the start position of column-coordinate
  267. \param[in] end_x: the end position of row-coordinate
  268. \param[in] end_y: the end position of column-coordinate
  269. \param[in] point: specified color of the point
  270. \param[out] none
  271. \retval none
  272. */
  273. void lcd_rectangle_draw(uint16_t start_x,uint16_t start_y,uint16_t end_x,uint16_t end_y,uint16_t point)
  274. {
  275. uint16_t x,y;
  276. x=start_x;
  277. y=start_y;
  278. /* draw four lines */
  279. for(x=start_x;x<end_x;x++){
  280. /* draw a point */
  281. lcd_point_set(x,y,point);
  282. }
  283. for(y=start_y;y<end_y;y++){
  284. lcd_point_set(x,y,point);
  285. }
  286. for(x=end_x;x>start_x;x--){
  287. lcd_point_set(x,y,point);
  288. }
  289. for(y=end_y;y>start_y;y--){
  290. lcd_point_set(x,y,point);
  291. }
  292. }
  293. /*!
  294. \brief fill the specified color to a rectangle
  295. \param[in] start_x: the start position of row-coordinate
  296. \param[in] start_y: the start position of column-coordinate
  297. \param[in] end_x: the end position of row-coordinate
  298. \param[in] end_y: the end position of column-coordinate
  299. \param[in] color: specified color
  300. \param[out] none
  301. \retval none
  302. */
  303. void lcd_rectangle_fill(uint16_t start_x,uint16_t start_y,uint16_t end_x,uint16_t end_y,uint16_t color)
  304. {
  305. uint16_t x, y;
  306. x = start_x;
  307. y = start_y;
  308. for (x = start_x; x < end_x; x++) {
  309. for (y = start_y; y < end_y; y++) {
  310. lcd_point_set(x, y, color);
  311. }
  312. }
  313. }
  314. /*!
  315. \brief draw a picture on LCD screen according to the specified position
  316. \param[in] start_x: the start position of row-coordinate
  317. \param[in] start_y: the start position of column-coordinate
  318. \param[in] end_x: the end position of row-coordinate
  319. \param[in] end_y: the end position of column-coordinate
  320. \param[in] pic: the picture pointer
  321. \param[out] none
  322. \retval none
  323. */
  324. void lcd_picture_draw(uint16_t start_x,uint16_t start_y,uint16_t end_x,uint16_t end_y,uint16_t *pic)
  325. {
  326. uint32_t i, total;
  327. uint16_t *picturepointer = pic;
  328. uint16_t x,y;
  329. x = start_x;
  330. y = start_y;
  331. total = (end_x - start_x + 1) * (end_y - start_y + 1);
  332. for(i = 0; i < total; i ++){
  333. /* set point according to the specified position and color */
  334. lcd_point_set(x,y,*picturepointer++);
  335. x++;
  336. if(x > end_x){
  337. y++;
  338. x = start_x;
  339. }
  340. }
  341. }
  342. /*!
  343. \brief display a char on LCD screen according to the specified position
  344. \param[in] x: the start position of row-coordinate
  345. \param[in] y: the start position of column-coordinate
  346. \param[in] c: the char
  347. \param[in] char_color: the color of char
  348. \param[in] c_format: the struct of char format
  349. font: CHAR_FONT_8_16 or CHAR_FONT_16_24
  350. direction: CHAR_DIRECTION_HORIZONTAL or CHAR_DIRECTION_VERTICAL
  351. char_color: the color of char
  352. bk_color: the color of backgroud
  353. \param[out] none
  354. \retval none
  355. */
  356. void lcd_char_display(uint16_t x,uint16_t y,uint8_t c,char_format_struct c_format)
  357. {
  358. uint16_t i = 0, j = 0;
  359. uint8_t temp_char = 0;
  360. uint16_t temp_char_16 = 0;
  361. if(CHAR_FONT_8_16 == c_format.font){ /* 8x16 ASCII */
  362. for (i = 0; i < 16; i++) {
  363. temp_char = ascii_8x16[((c - 0x20) * 16) + i];
  364. if(CHAR_DIRECTION_HORIZONTAL == c_format.direction){
  365. for (j = 0; j < 8; j++) {
  366. if (((temp_char >> (7 - j)) & 0x01) == 0x01) {
  367. /* set point of char */
  368. lcd_point_set(x - i, y + j, c_format.char_color);
  369. } else {
  370. /* set point of background */
  371. lcd_point_set(x - i, y + j, c_format.bk_color);
  372. }
  373. }
  374. }else{
  375. for (j = 0; j < 8; j++) {
  376. if (((temp_char >> (7 - j)) & 0x01) == 0x01) {
  377. /* set point of char */
  378. lcd_point_set(x + j, y + i, c_format.char_color);
  379. } else {
  380. /* set point of background */
  381. lcd_point_set(x + j, y + i, c_format.bk_color);
  382. }
  383. }
  384. }
  385. }
  386. }else if(CHAR_FONT_16_24 == c_format.font){ /* 16x24 ASCII */
  387. for (i = 0; i < 24; i++) {
  388. temp_char_16 = ASCII_Table_16x24[((c - 0x20) * 24) + i];
  389. if(CHAR_DIRECTION_HORIZONTAL == c_format.direction){
  390. for (j = 0; j < 16; j++) {
  391. if (((temp_char_16 >> j) & 0x01) == 0x01) {
  392. /* set point of char */
  393. lcd_point_set(x - i, y + j, c_format.char_color);
  394. } else {
  395. /* set point of background */
  396. lcd_point_set(x - i, y + j, c_format.bk_color);
  397. }
  398. }
  399. }else{
  400. for (j = 0; j < 16; j++) {
  401. if (((temp_char_16 >> j) & 0x01) == 0x01) {
  402. /* set point of char */
  403. lcd_point_set(x + j, y + i, c_format.char_color);
  404. } else {
  405. /* set point of background */
  406. lcd_point_set(x + j, y + i, c_format.bk_color);
  407. }
  408. }
  409. }
  410. }
  411. }
  412. }