ili9341.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243
  1. /****************************************************************************
  2. * drivers/lcd/ili9341.c
  3. *
  4. * LCD driver for the ILI9341 LCD Single Chip Driver
  5. *
  6. * Copyright (C) 2014 Marco Krahl. All rights reserved.
  7. * Author: Marco Krahl <ocram.lhark@gmail.com>
  8. *
  9. * References: ILI9341_DS_V1.10.pdf (Rev: 1.10), "a-Si TFT LCD Single Chip
  10. * Driver 240RGBx320 Resolution and 262K color",
  11. * ILI TECHNOLOGY CORP., http://www.ilitek.com.
  12. *
  13. * Redistribution and use in source and binary forms, with or without
  14. * modification, are permitted provided that the following conditions
  15. * are met:
  16. *
  17. * 1. Redistributions of source code must retain the above copyright
  18. * notice, this list of conditions and the following disclaimer.
  19. * 2. Redistributions in binary form must reproduce the above copyright
  20. * notice, this list of conditions and the following disclaimer in
  21. * the documentation and/or other materials provided with the
  22. * distribution.
  23. * 3. Neither the name NuttX nor the names of its contributors may be
  24. * used to endorse or promote products derived from this software
  25. * without specific prior writen permission.
  26. *
  27. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  28. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  29. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  30. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  31. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  32. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  33. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  34. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  35. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  37. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  38. * POSSIBILITY OF SUCH DAMAGE.
  39. *
  40. ****************************************************************************/
  41. /****************************************************************************
  42. * Included Files
  43. ****************************************************************************/
  44. #include <nuttx/config.h>
  45. #include <sys/types.h>
  46. #include <stdint.h>
  47. #include <stdbool.h>
  48. #include <string.h>
  49. #include <errno.h>
  50. #include <debug.h>
  51. #include <nuttx/arch.h>
  52. #include <nuttx/lcd/lcd.h>
  53. #include <nuttx/lcd/ili9341.h>
  54. #include <arch/irq.h>
  55. /****************************************************************************
  56. * Pre-processor Definitions
  57. ****************************************************************************/
  58. /* This is the generic lcd driver interface for the ili9341 Single Chip LCD
  59. * driver. The driver supports multiple displays, each connected with an own
  60. * ili9341 Single Chip LCD driver. The communication with the LCD single chip
  61. * driver must be provide by a subdriver accessable trough the ili9341_dev_s
  62. * structure which is platform and MCU interface specific.
  63. *
  64. * Supported MCU interfaces (planed to support)
  65. *
  66. * Interface I
  67. *
  68. * 8080 MCU 8-bit bus interface
  69. * 8080 MCU 16-bit bus interface
  70. * 8080 MCU 9-bit bus interface
  71. * 8080 MCU 18-bit bus interface
  72. * 3-wire 9-bit data serial interface
  73. * 4-wire 8-bit data serial interface
  74. *
  75. * Interface II
  76. *
  77. * 8080 MCU 8-bit bus interface
  78. * 8080 MCU 16-bit bus interface
  79. * 8080 MCU 9-bit bus interface
  80. * 8080 MCU 18-bit bus interface
  81. * 3-wire 9-bit data serial Interface
  82. * 4-wire 8-bit data serial Interface
  83. *
  84. * Note! RGB interface will not supported by the lcd driver.
  85. * It should be use with the platform specific RGB grapic controller and the
  86. * nuttx framebuffer interface.
  87. *
  88. */
  89. /* Fundamental command and parameter definition */
  90. /* Interface control (IFCTL)
  91. *
  92. *
  93. * Parameter 1: 0x0001
  94. *
  95. * MY_EOR: 0
  96. * MX_EOR: 0
  97. * MV_EOR: 0
  98. * BGR_EOR: 0
  99. * WEMODE: 1 Reset column and page if data transfer exceeds
  100. */
  101. #define ILI9341_IFCTL_MYEOR 0
  102. #define ILI9341_IFCTL_MXEOR 0
  103. #define ILI9341_IFCTL_MVEOR 0
  104. #define ILI9341_IFCTL_BGREOR 0
  105. #define ILI9341_IFCTL_WEMODE ILI9341_INTERFACE_CONTROL_WEMODE
  106. #define ILI9341_IFCTL_PARAM1 ILI9341_IFCTL_MYEOR | ILI9341_IFCTL_MXEOR | \
  107. ILI9341_IFCTL_MVEOR | ILI9341_IFCTL_BGREOR | \
  108. ILI9341_IFCTL_WEMODE
  109. /* Parameter 2: 0x0000
  110. *
  111. * EPF: 0 65k color format for RGB interface, not used set to default
  112. * MDT: 0 Display data transfer mode, not used
  113. *
  114. * Note! If RGB666 and 16-bit 8080-I interface supported by the driver, MDT must
  115. * be defined for each selected driver instance. Leave it empty for now.
  116. */
  117. #define ILI9341_IFCTL_EPF ILI9341_INTERFACE_CONTROL_EPF(0)
  118. #define ILI9341_IFCTL_MDT ILI9341_INTERFACE_CONTROL_MDT(0)
  119. #define ILI9341_IFCTL_PARAM2 ILI9341_IFCTL_EPF | ILI9341_IFCTL_MDT
  120. /* Parameter 3: 0x0000/0x0020
  121. *
  122. * ENDIAN: 0/1 Depending on endian mode of the mcu?
  123. * DM: 0 Internal clock operation
  124. * RM: 0 System interface/VSYNC interface
  125. * RIM: 0 RGB interface mode, unimportant set to default
  126. *
  127. */
  128. #ifdef CONFIG_ENDIAN_BIG
  129. # define ILI9341_IFCTL_ENDIAN 0
  130. #else
  131. # define ILI9341_IFCTL_ENDIAN ILI9341_INTERFACE_CONTROL_ENDIAN
  132. #endif
  133. #define ILI9341_IFCTL_DM ILI9341_INTERFACE_CONTROL_DM(0)
  134. #define ILI9341_IFCTL_RM 0
  135. #define ILI9341_IFCTL_RIM 0
  136. #define ILI9341_IFCTL_PARAM3 ILI9341_IFCTL_RIM | ILI9341_IFCTL_RM | \
  137. ILI9341_IFCTL_DM | ILI9341_IFCTL_ENDIAN
  138. /* Memory access control (MADCTL) */
  139. /* Landscape: 00100000 / 00101000 / h28
  140. *
  141. * MY: 0
  142. * MX: 0
  143. * MV: 1
  144. * ML: 0
  145. * BGR: 0/1 Depending on endian mode of the mcu?
  146. * MH: 0
  147. */
  148. #define ILI9341_MADCTL_LANDSCAPE_MY 0
  149. #define ILI9341_MADCTL_LANDSCAPE_MX 0
  150. #define ILI9341_MADCTL_LANDSCAPE_MV ILI9341_MEMORY_ACCESS_CONTROL_MV
  151. #define ILI9341_MADCTL_LANDSCAPE_ML 0
  152. #ifdef CONFIG_ENDIAN_BIG
  153. # define ILI9341_MADCTL_LANDSCAPE_BGR 0
  154. #else
  155. # define ILI9341_MADCTL_LANDSCAPE_BGR ILI9341_MEMORY_ACCESS_CONTROL_BGR
  156. #endif
  157. #define ILI9341_MADCTL_LANDSCAPE_MH 0
  158. #define ILI9341_MADCTL_LANDSCAPE_PARAM1 (ILI9341_MADCTL_LANDSCAPE_MY | \
  159. ILI9341_MADCTL_LANDSCAPE_MX | \
  160. ILI9341_MADCTL_LANDSCAPE_MV | \
  161. ILI9341_MADCTL_LANDSCAPE_ML | \
  162. ILI9341_MADCTL_LANDSCAPE_BGR | \
  163. ILI9341_MADCTL_LANDSCAPE_MH)
  164. /* Portrait: 00000000 / 00001000 / h08
  165. *
  166. * MY: 0
  167. * MX: 0
  168. * MV: 0
  169. * ML: 0
  170. * BGR: 0/1 Depending on endian mode of the mcu?
  171. * MH: 0
  172. */
  173. #define ILI9341_MADCTL_PORTRAIT_MY 0
  174. #define ILI9341_MADCTL_PORTRAIT_MX ILI9341_MEMORY_ACCESS_CONTROL_MX
  175. #define ILI9341_MADCTL_PORTRAIT_MV 0
  176. #define ILI9341_MADCTL_PORTRAIT_ML ILI9341_MEMORY_ACCESS_CONTROL_ML
  177. #ifdef CONFIG_ENDIAN_BIG
  178. # define ILI9341_MADCTL_PORTRAIT_BGR 0
  179. #else
  180. # define ILI9341_MADCTL_PORTRAIT_BGR ILI9341_MEMORY_ACCESS_CONTROL_BGR
  181. #endif
  182. #define ILI9341_MADCTL_PORTRAIT_MH 0
  183. #define ILI9341_MADCTL_PORTRAIT_PARAM1 (ILI9341_MADCTL_PORTRAIT_MY | \
  184. ILI9341_MADCTL_PORTRAIT_MX | \
  185. ILI9341_MADCTL_PORTRAIT_MV | \
  186. ILI9341_MADCTL_PORTRAIT_ML | \
  187. ILI9341_MADCTL_PORTRAIT_BGR | \
  188. ILI9341_MADCTL_PORTRAIT_MH)
  189. /* RLandscape: 01100000 / 01101000 / h68
  190. *
  191. * MY: 0
  192. * MX: 1
  193. * MV: 1
  194. * ML: 0
  195. * BGR: 0/1 Depending on endian mode of the mcu?
  196. * MH: 0
  197. */
  198. #define ILI9341_MADCTL_RLANDSCAPE_MY ILI9341_MEMORY_ACCESS_CONTROL_MY
  199. #define ILI9341_MADCTL_RLANDSCAPE_MX ILI9341_MEMORY_ACCESS_CONTROL_MX
  200. #define ILI9341_MADCTL_RLANDSCAPE_MV ILI9341_MEMORY_ACCESS_CONTROL_MV
  201. #define ILI9341_MADCTL_RLANDSCAPE_ML 0
  202. #ifdef CONFIG_ENDIAN_BIG
  203. # define ILI9341_MADCTL_RLANDSCAPE_BGR 0
  204. #else
  205. # define ILI9341_MADCTL_RLANDSCAPE_BGR ILI9341_MEMORY_ACCESS_CONTROL_BGR
  206. #endif
  207. #define ILI9341_MADCTL_RLANDSCAPE_MH 0
  208. #define ILI9341_MADCTL_RLANDSCAPE_PARAM1 \
  209. (ILI9341_MADCTL_RLANDSCAPE_MY | \
  210. ILI9341_MADCTL_RLANDSCAPE_MX | \
  211. ILI9341_MADCTL_RLANDSCAPE_MV | \
  212. ILI9341_MADCTL_RLANDSCAPE_ML | \
  213. ILI9341_MADCTL_RLANDSCAPE_BGR | \
  214. ILI9341_MADCTL_RLANDSCAPE_MH)
  215. /* RPortrait: 11000000 / 11001000 / hc8
  216. *
  217. * MY: 1
  218. * MX: 1
  219. * MV: 0
  220. * ML: 0
  221. * BGR: 0/1 Depending on endian mode of the mcu?
  222. * MH: 0
  223. *
  224. */
  225. #define ILI9341_MADCTL_RPORTRAIT_MY ILI9341_MEMORY_ACCESS_CONTROL_MY
  226. #define ILI9341_MADCTL_RPORTRAIT_MX 0
  227. #define ILI9341_MADCTL_RPORTRAIT_MV 0
  228. #define ILI9341_MADCTL_RPORTRAIT_ML ILI9341_MEMORY_ACCESS_CONTROL_ML
  229. #ifdef CONFIG_ENDIAN_BIG
  230. # define ILI9341_MADCTL_RPORTRAIT_BGR 0
  231. #else
  232. # define ILI9341_MADCTL_RPORTRAIT_BGR ILI9341_MEMORY_ACCESS_CONTROL_BGR
  233. #endif
  234. #define ILI9341_MADCTL_RPORTRAIT_MH 0
  235. #define ILI9341_MADCTL_RPORTRAIT_PARAM1 (ILI9341_MADCTL_RPORTRAIT_MY | \
  236. ILI9341_MADCTL_RPORTRAIT_MX | \
  237. ILI9341_MADCTL_RPORTRAIT_MV | \
  238. ILI9341_MADCTL_RPORTRAIT_ML | \
  239. ILI9341_MADCTL_RPORTRAIT_BGR | \
  240. ILI9341_MADCTL_RPORTRAIT_MH)
  241. /* Pixel Format Set (COLMOD)
  242. *
  243. * Note! RGB interface settings (DPI) is unimportant for the MCU interface
  244. * mode but set the register to the defined state equal to the MCU interface
  245. * pixel format.
  246. *
  247. * 16 Bit MCU: 01010101 / h55
  248. *
  249. * DPI: 5 (RGB16-565 RGB interface, not used)
  250. * DBI: 5 (RGB16-565 MCU interface
  251. */
  252. #define ILI9341_PIXSET_16BITDPI ILI9341_PIXEL_FORMAT_SET_DPI(5)
  253. #define ILI9341_PIXSET_16BITDBI ILI9341_PIXEL_FORMAT_SET_DBI(5)
  254. #define ILI9341_PIXSET_16BITMCU_PARAM1 (ILI9341_PIXSET_16BITDPI | \
  255. ILI9341_PIXSET_16BITDBI)
  256. /* 18-bit MCU: 01100110 / h66 (not supported by nuttx until now)
  257. *
  258. * DPI: 6 (RGB18-666 RGB interface)
  259. * DBI: 6 (RGB18-666 MCU interface)
  260. */
  261. #define ILI9341_PIXSET_18BITDPI ILI9341_PIXEL_FORMAT_SET_DPI(6)
  262. #define ILI9341_PIXSET_18BITDBI ILI9341_PIXEL_FORMAT_SET_DBI(6)
  263. #define ILI9341_PIXSET_18BITMCU_PARAM1 (ILI9341_PIXSET_18BITDPI | \
  264. ILI9341_PIXSET_18BITDBI)
  265. /* General fix display resolution */
  266. #define ILI9341_XRES 240
  267. #define ILI9341_YRES 320
  268. /* Validate configuration */
  269. #if CONFIG_LCD_ILI9341_NINTERFACES < 1
  270. # undef CONFIG_LCD_ILI9341_IFACE0
  271. #elif CONFIG_LCD_ILI9341_NINTERFACES < 2
  272. # undef CONFIG_LCD_ILI9341_IFACE1
  273. #endif
  274. /* First LCD display */
  275. #ifdef CONFIG_LCD_ILI9341_IFACE0
  276. # if defined(CONFIG_LCD_ILI9341_IFACE0_LANDSCAPE)
  277. # define ILI9341_IFACE0_ORIENT ILI9341_MADCTL_LANDSCAPE_PARAM1
  278. # define ILI9341_IFACE0_STRIDE ILI9341_YRES
  279. # elif defined(CONFIG_LCD_ILI9341_IFACE0_PORTRAIT)
  280. # define ILI9341_IFACE0_ORIENT ILI9341_MADCTL_PORTRAIT_PARAM1
  281. # define ILI9341_IFACE0_STRIDE ILI9341_XRES
  282. # elif defined(CONFIG_LCD_ILI9341_IFACE0_RLANDSCAPE)
  283. # define ILI9341_IFACE0_ORIENT ILI9341_MADCTL_RLANDSCAPE_PARAM1
  284. # define ILI9341_IFACE0_STRIDE ILI9341_YRES
  285. # elif defined(CONFIG_LCD_ILI9341_IFACE0_RPORTRAIT)
  286. # define ILI9341_IFACE0_ORIENT ILI9341_MADCTL_RPORTRAIT_PARAM1
  287. # define ILI9341_IFACE0_STRIDE ILI9341_XRES
  288. # endif
  289. # ifdef CONFIG_LCD_ILI9341_IFACE0_RGB565
  290. # define ILI9341_IFACE0_PXFMT FB_FMT_RGB16_565
  291. # define ILI9341_IFACE0_BPP 16
  292. # define ILI9341_IFACE0_BUFFER ILI9341_IFACE0_STRIDE
  293. # else
  294. # error "undefined pixel format for lcd interface 0"
  295. # endif
  296. #endif
  297. /* Second LCD display */
  298. #ifdef CONFIG_LCD_ILI9341_IFACE1
  299. # ifdef CONFIG_LCD_ILI9341_IFACE1_LANDSCAPE
  300. # define ILI9341_IFACE1_ORIENT ILI9341_MADCTL_LANDSCAPE_PARAM1
  301. # define ILI9341_IFACE1_STRIDE ILI9341_YRES
  302. # elif CONFIG_LCD_ILI9341_IFACE1_PORTRAIT
  303. # define ILI9341_IFACE1_ORIENT ILI9341_MADCTL_PORTRAIT_PARAM1
  304. # define ILI9341_IFACE1_STRIDE ILI9341_XRES
  305. # elif CONFIG_LCD_ILI9341_IFACE1_RLANDSCAPE
  306. # define ILI9341_IFACE1_ORIENT ILI9341_MADCTL_RLANDSCAPE_PARAM1
  307. # define ILI9341_IFACE1_STRIDE ILI9341_YRES
  308. # elif CONFIG_LCD_ILI9341_IFACE1_RPORTRAIT
  309. # define ILI9341_IFACE1_ORIENT ILI9341_MADCTL_RPORTRAIT_PARAM1
  310. # define ILI9341_IFACE1_STRIDE ILI9341_XRES
  311. # endif
  312. # ifdef CONFIG_LCD_ILI9341_IFACE1_RGB565
  313. # define ILI9341_IFACE1_PXFMT FB_FMT_RGB16_565
  314. # define ILI9341_IFACE1_BPP 16
  315. # define ILI9341_IFACE1_BUFFER ILI9341_IFACE1_STRIDE
  316. # else
  317. # error "undefined pixel format for lcd interface 1"
  318. # endif
  319. #endif
  320. /****************************************************************************
  321. * Private Type Definition
  322. ****************************************************************************/
  323. /* Each single connected ili9341 LCD driver needs an own driver instance
  324. * to provide a unique getrun and putrun method. Also store fundamental
  325. * parameter in driver internal structure. This minimal overhead should be
  326. * acceptable.
  327. */
  328. struct ili9341_dev_s
  329. {
  330. /* Publically visible device structure */
  331. struct lcd_dev_s dev;
  332. /* Private driver-specific information follows */
  333. FAR struct ili9341_lcd_s *lcd;
  334. /* Driver specific putrun function */
  335. int (*putrun)(fb_coord_t row, fb_coord_t col,
  336. FAR const uint8_t * buffer, size_t npixels);
  337. #ifndef CONFIG_LCD_NOGETRUN
  338. /* Driver specific getrun function */
  339. int (*getrun)(fb_coord_t row, fb_coord_t col,
  340. FAR uint8_t * buffer, size_t npixels);
  341. #endif
  342. /* Run buffer for the device */
  343. uint16_t *runbuffer;
  344. /* Display orientation, e.g. Landscape, Portrait */
  345. uint8_t orient;
  346. /* LCD driver pixel format */
  347. uint8_t pxfmt;
  348. /* LCD driver color depth */
  349. uint8_t bpp;
  350. /* Current power state of the device */
  351. uint8_t power;
  352. };
  353. /****************************************************************************
  354. * Private Function Protototypes
  355. ****************************************************************************/
  356. /* Internal low level helpers */
  357. static inline uint16_t ili9341_getxres(FAR struct ili9341_dev_s *dev);
  358. static inline uint16_t ili9341_getyres(FAR struct ili9341_dev_s *dev);
  359. /* lcd data transfer methods */
  360. static int ili9341_putrun(int devno, fb_coord_t row, fb_coord_t col,
  361. FAR const uint8_t * buffer, size_t npixels);
  362. #ifndef CONFIG_LCD_NOGETRUN
  363. static int ili9341_getrun(int devno, fb_coord_t row, fb_coord_t col,
  364. FAR uint8_t * buffer, size_t npixels);
  365. #endif
  366. /* Definition of the public visible getrun / putrun methods
  367. * each for a single LCD driver
  368. */
  369. #ifdef CONFIG_LCD_ILI9341_IFACE0
  370. static int ili9341_putrun0(fb_coord_t row, fb_coord_t col,
  371. FAR const uint8_t *buffer, size_t npixsels);
  372. #endif
  373. #ifdef CONFIG_LCD_ILI9341_IFACE1
  374. static int ili9341_putrun1(fb_coord_t row, fb_coord_t col,
  375. FAR const uint8_t * buffer, size_t npixsels);
  376. #endif
  377. #ifndef CONFIG_LCD_NOGETRUN
  378. # ifdef CONFIG_LCD_ILI9341_IFACE0
  379. static int ili9341_getrun0(fb_coord_t row, fb_coord_t col,
  380. FAR uint8_t * buffer, size_t npixsels);
  381. # endif
  382. # ifdef CONFIG_LCD_ILI9341_IFACE1
  383. static int ili9341_getrun1(fb_coord_t row, fb_coord_t col,
  384. FAR uint8_t * buffer, size_t npixsels);
  385. # endif
  386. #endif
  387. /* lcd configuration */
  388. static int ili9341_getvideoinfo(FAR struct lcd_dev_s *dev,
  389. FAR struct fb_videoinfo_s *vinfo);
  390. static int ili9341_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
  391. FAR struct lcd_planeinfo_s *pinfo);
  392. /* lcd specific controls */
  393. static int ili9341_getpower(struct lcd_dev_s *dev);
  394. static int ili9341_setpower(struct lcd_dev_s *dev, int power);
  395. static int ili9341_getcontrast(struct lcd_dev_s *dev);
  396. static int ili9341_setcontrast(struct lcd_dev_s *dev, unsigned int contrast);
  397. /****************************************************************************
  398. * Private Data
  399. ****************************************************************************/
  400. /* Initialize driver instance 1 < LCD_ILI9341_NINTERFACES */
  401. #ifdef CONFIG_LCD_ILI9341_IFACE0
  402. static uint16_t g_runbuffer0[ILI9341_IFACE0_BUFFER];
  403. #endif
  404. #ifdef CONFIG_LCD_ILI9341_IFACE1
  405. static uint16_t g_runbuffer1[ILI9341_IFACE1_BUFFER];
  406. #endif
  407. static struct ili9341_dev_s g_lcddev[CONFIG_LCD_ILI9341_NINTERFACES] =
  408. {
  409. #ifdef CONFIG_LCD_ILI9341_IFACE0
  410. {
  411. .lcd = 0,
  412. .putrun = ili9341_putrun0,
  413. # ifndef CONFIG_LCD_NOGETRUN
  414. .getrun = ili9341_getrun0,
  415. # endif
  416. .runbuffer = g_runbuffer0,
  417. .orient = ILI9341_IFACE0_ORIENT,
  418. .pxfmt = ILI9341_IFACE0_PXFMT,
  419. .bpp = ILI9341_IFACE0_BPP,
  420. .power = 0,
  421. },
  422. #endif
  423. #ifdef CONFIG_LCD_ILI9341_IFACE1
  424. {
  425. .lcd = 0,
  426. .putrun = ili9341_putrun1,
  427. # ifndef CONFIG_LCD_NOGETRUN
  428. .getrun = ili9341_getrun1,
  429. # endif
  430. .runbuffer = g_runbuffer1,
  431. .orient = ILI9341_IFACE1_ORIENT,
  432. .pxfmt = ILI9341_IFACE1_PXFMT,
  433. .bpp = ILI9341_IFACE1_BPP,
  434. .power = 0,
  435. },
  436. #endif
  437. };
  438. /****************************************************************************
  439. * Private Functions
  440. ****************************************************************************/
  441. /****************************************************************************
  442. * Name: ili9341_getxres
  443. *
  444. * Description:
  445. * Get horicontal resolution of the connected LCD driver depending on the
  446. * configured display orientation.
  447. *
  448. * Input Parameters:
  449. * dev - Reference to private driver structure
  450. *
  451. * Returned Value:
  452. *
  453. * Horicontal resolution
  454. *
  455. ****************************************************************************/
  456. static inline uint16_t ili9341_getxres(FAR struct ili9341_dev_s *dev)
  457. {
  458. if (dev->orient == ILI9341_MADCTL_LANDSCAPE_PARAM1 ||
  459. dev->orient == ILI9341_MADCTL_RLANDSCAPE_PARAM1)
  460. {
  461. return ILI9341_YRES;
  462. }
  463. return ILI9341_XRES;
  464. }
  465. /****************************************************************************
  466. * Name: ili9341_getyres
  467. *
  468. * Description:
  469. * Get vertical resolution of the connected LCD driver depending on the
  470. * configured display orientation.
  471. *
  472. * Input Parameters:
  473. * dev - Reference to private driver structure
  474. *
  475. * Returned Value:
  476. *
  477. * Vertical resolution
  478. *
  479. ****************************************************************************/
  480. static inline uint16_t ili9341_getyres(FAR struct ili9341_dev_s *dev)
  481. {
  482. if (dev->orient == ILI9341_MADCTL_LANDSCAPE_PARAM1 ||
  483. dev->orient == ILI9341_MADCTL_RLANDSCAPE_PARAM1)
  484. {
  485. return ILI9341_XRES;
  486. }
  487. return ILI9341_YRES;
  488. }
  489. /****************************************************************************
  490. * Name: ili9341_selectarea
  491. *
  492. * Description:
  493. * Select the active area for displaying pixel
  494. *
  495. * Input Parameters:
  496. * lcd - Reference to private driver structure
  497. * x0 - Start x position
  498. * y0 - Start y position
  499. * x1 - End x position
  500. * y1 - End y position
  501. *
  502. ****************************************************************************/
  503. static void ili9341_selectarea(FAR struct ili9341_lcd_s *lcd,
  504. uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
  505. {
  506. /* Select column */
  507. lcd->sendcmd(lcd, ILI9341_COLUMN_ADDRESS_SET);
  508. lcd->sendparam(lcd, (x0 >> 8));
  509. lcd->sendparam(lcd, (x0 & 0xff));
  510. lcd->sendparam(lcd, (x1 >> 8));
  511. lcd->sendparam(lcd, (x1 & 0xff));
  512. /* Select page */
  513. lcd->sendcmd(lcd, ILI9341_PAGE_ADDRESS_SET);
  514. lcd->sendparam(lcd, (y0 >> 8));
  515. lcd->sendparam(lcd, (y0 & 0xff));
  516. lcd->sendparam(lcd, (y1 >> 8));
  517. lcd->sendparam(lcd, (y1 & 0xff));
  518. }
  519. /****************************************************************************
  520. * Name: ili9341_putrun
  521. *
  522. * Description:
  523. * Write a partial raster line to the LCD.
  524. *
  525. * Input Parameters:
  526. * devno - Number of lcd device
  527. * row - Starting row to write to (range: 0 <= row < yres)
  528. * col - Starting column to write to (range: 0 <= col <= xres-npixels)
  529. * buffer - The buffer containing the run to be writen to the LCD
  530. * npixels - The number of pixels to write to the
  531. * (range: 0 < npixels <= xres-col)
  532. *
  533. * Returned Value:
  534. *
  535. * On success - OK
  536. * On error - -EINVAL
  537. *
  538. ****************************************************************************/
  539. static int ili9341_putrun(int devno, fb_coord_t row, fb_coord_t col,
  540. FAR const uint8_t * buffer, size_t npixels)
  541. {
  542. FAR struct ili9341_dev_s *dev = &g_lcddev[devno];
  543. FAR struct ili9341_lcd_s *lcd = dev->lcd;
  544. FAR const uint16_t *src = (FAR const uint16_t *)buffer;
  545. DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0);
  546. /* Check if position outside of area */
  547. if (col + npixels > ili9341_getxres(dev) || row > ili9341_getyres(dev))
  548. {
  549. return -EINVAL;
  550. }
  551. /* Select lcd driver */
  552. lcd->select(lcd);
  553. /* Select column and area similar to the partial raster line */
  554. ili9341_selectarea(lcd, col, row, col + npixels - 1, row);
  555. /* Send memory write cmd */
  556. lcd->sendcmd(lcd, ILI9341_MEMORY_WRITE);
  557. /* Send pixel to gram */
  558. lcd->sendgram(lcd, src, npixels);
  559. /* Deselect the lcd driver */
  560. lcd->deselect(lcd);
  561. return OK;
  562. }
  563. /****************************************************************************
  564. * Name: ili9341_getrun
  565. *
  566. * Description:
  567. * Read a partial raster line from the LCD.
  568. *
  569. * Input Parameters:
  570. * devno - Number of the lcd device
  571. * row - Starting row to read from (range: 0 <= row < yres)
  572. * col - Starting column to read read (range: 0 <= col <= xres-npixels)
  573. * buffer - The buffer in which to return the run read from the LCD
  574. * npixels - The number of pixels to read from the LCD
  575. * (range: 0 < npixels <= xres-col)
  576. *
  577. * Returned Value:
  578. *
  579. * On success - OK
  580. * On error - -EINVAL
  581. *
  582. ****************************************************************************/
  583. # ifndef CONFIG_LCD_NOGETRUN
  584. static int ili9341_getrun(int devno, fb_coord_t row, fb_coord_t col,
  585. FAR uint8_t * buffer, size_t npixels)
  586. {
  587. FAR struct ili9341_dev_s *dev = &g_lcddev[devno];
  588. FAR struct ili9341_lcd_s *lcd = dev->lcd;
  589. FAR uint16_t *dest = (FAR uint16_t *)buffer;
  590. DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0);
  591. /* Check if position outside of area */
  592. if (col + npixels > ili9341_getxres(dev) || row > ili9341_getyres(dev))
  593. {
  594. return -EINVAL;
  595. }
  596. /* Select lcd driver */
  597. lcd->select(lcd);
  598. /* Select column and area similar to the partial raster line */
  599. ili9341_selectarea(lcd, col, row, col + npixels - 1, row);
  600. /* Send memory read cmd */
  601. lcd->sendcmd(lcd, ILI9341_MEMORY_READ);
  602. /* Receive pixel to gram */
  603. lcd->recvgram(lcd, dest, npixels);
  604. /* Deselect the lcd driver */
  605. lcd->deselect(lcd);
  606. return OK;
  607. }
  608. #endif
  609. /****************************************************************************
  610. * Name: ili9341_hwinitialize
  611. *
  612. * Description:
  613. * Initialize and configure the ILI9341 LCD driver hardware.
  614. *
  615. * Input Parameters:
  616. * dev - A reference to the driver specific structure
  617. *
  618. * Returned Value:
  619. *
  620. * On success - OK
  621. * On error - EINVAL
  622. *
  623. ****************************************************************************/
  624. static int ili9341_hwinitialize(FAR struct ili9341_dev_s *dev)
  625. {
  626. #ifdef CONFIG_DEBUG_LCD_INFO
  627. uint8_t param;
  628. #endif
  629. FAR struct ili9341_lcd_s *lcd = dev->lcd;
  630. /* Select spi device */
  631. lcdinfo("Initialize lcd driver\n");
  632. lcd->select(lcd);
  633. #ifdef CONFIG_DEBUG_LCD_INFO
  634. /* Read display identification */
  635. lcd->sendcmd(lcd, ILI9341_READ_ID1);
  636. lcd->recvparam(lcd, &param);
  637. lcdinfo("ili9341 LCD driver: LCD modules manufacturer ID: %d\n", param);
  638. lcd->sendcmd(lcd, ILI9341_READ_ID2);
  639. lcd->recvparam(lcd, &param);
  640. lcdinfo("ili9341 LCD driver: LCD modules driver version ID: %d\n", param);
  641. lcd->sendcmd(lcd, ILI9341_READ_ID3);
  642. lcd->recvparam(lcd, &param);
  643. lcdinfo("ili9341 LCD driver: LCD modules driver ID: %d\n", param);
  644. #endif
  645. /* Reset the lcd display to the default state */
  646. lcdinfo("ili9341 LCD driver: Software Reset\n");
  647. lcd->sendcmd(lcd, ILI9341_SOFTWARE_RESET);
  648. up_mdelay(5);
  649. lcdinfo("ili9341 LCD driver: set Memory Access Control: %04x\n", dev->orient);
  650. lcd->sendcmd(lcd, ILI9341_MEMORY_ACCESS_CONTROL);
  651. lcd->sendparam(lcd, dev->orient);
  652. /* Select column and area */
  653. ili9341_selectarea(lcd, 0, 0, ILI9341_XRES, ILI9341_YRES);
  654. /* Pixel Format set */
  655. lcd->sendcmd(lcd, ILI9341_PIXEL_FORMAT_SET);
  656. /* 16 bit RGB565 */
  657. lcdinfo("ili9341 LCD driver: Set Pixel Format: %04x\n",
  658. ILI9341_PIXSET_16BITMCU_PARAM1);
  659. lcd->sendparam(lcd, ILI9341_PIXSET_16BITMCU_PARAM1);
  660. /* 18 bit RGB666, add settings here */
  661. lcdinfo("ili9341 LCD driver: Set Interface control\n");
  662. lcd->sendcmd(lcd, ILI9341_INTERFACE_CONTROL);
  663. lcd->sendparam(lcd, ILI9341_IFCTL_PARAM1);
  664. lcd->sendparam(lcd, ILI9341_IFCTL_PARAM2);
  665. lcd->sendparam(lcd, ILI9341_IFCTL_PARAM3);
  666. /* Sleep out */
  667. lcdinfo("ili9341 LCD driver: Sleep Out\n");
  668. lcd->sendcmd(lcd, ILI9341_SLEEP_OUT);
  669. up_mdelay(120);
  670. /* Deselect the device */
  671. lcd->deselect(lcd);
  672. /* Switch display off */
  673. ili9341_setpower(&dev->dev, 0);
  674. return OK;
  675. }
  676. /****************************************************************************
  677. * Public Functions
  678. ****************************************************************************/
  679. /****************************************************************************
  680. * Name: ili9341_putrunx
  681. *
  682. * Description:
  683. * Write a partial raster line to the LCD.
  684. *
  685. * Input Parameters:
  686. * row - Starting row to write to (range: 0 <= row < yres)
  687. * col - Starting column to write to (range: 0 <= col <= xres-npixels)
  688. * buffer - The buffer containing the run to be writen to the LCD
  689. * npixels - The number of pixels to write to the
  690. * (range: 0 < npixels <= xres-col)
  691. *
  692. * Returned Value:
  693. *
  694. * On success - OK
  695. * On error - -EINVAL
  696. *
  697. ****************************************************************************/
  698. #ifdef CONFIG_LCD_ILI9341_IFACE0
  699. static int ili9341_putrun0(fb_coord_t row, fb_coord_t col,
  700. FAR const uint8_t * buffer, size_t npixels)
  701. {
  702. return ili9341_putrun(0, row, col, buffer, npixels);
  703. }
  704. #endif
  705. #ifdef CONFIG_LCD_ILI9341_IFACE1
  706. static int ili9341_putrun1(fb_coord_t row, fb_coord_t col,
  707. FAR const uint8_t * buffer, size_t npixels)
  708. {
  709. return ili9341_putrun(1, row, col, buffer, npixels);
  710. }
  711. #endif
  712. /****************************************************************************
  713. * Name: ili9341_getrunx
  714. *
  715. * Description:
  716. * Read a partial raster line from the LCD.
  717. *
  718. * Input Parameters:
  719. * row - Starting row to read from (range: 0 <= row < yres)
  720. * col - Starting column to read from (range: 0 <= col <= xres-npixels)
  721. * buffer - The buffer containing the run to be writen to the LCD
  722. * npixels - The number of pixels to read from the
  723. * (range: 0 < npixels <= xres-col)
  724. *
  725. * Returned Value:
  726. *
  727. * On success - OK
  728. * On error - -EINVAL
  729. *
  730. ****************************************************************************/
  731. #ifndef CONFIG_LCD_NOGETRUN
  732. # ifdef CONFIG_LCD_ILI9341_IFACE0
  733. static int ili9341_getrun0(fb_coord_t row, fb_coord_t col,
  734. FAR uint8_t * buffer, size_t npixels)
  735. {
  736. return ili9341_getrun(0, row, col, buffer, npixels);
  737. }
  738. # endif
  739. # ifdef CONFIG_LCD_ILI9341_IFACE1
  740. static int ili9341_getrun1(fb_coord_t row, fb_coord_t col,
  741. FAR uint8_t * buffer, size_t npixels)
  742. {
  743. return ili9341_getrun(1, row, col, buffer, npixels);
  744. }
  745. # endif
  746. #endif
  747. /****************************************************************************
  748. * Name: ili9341_getvideoinfo
  749. *
  750. * Description:
  751. * Get information about the LCD video controller configuration.
  752. *
  753. * Input Parameters:
  754. * dev - A reference to the driver specific structure
  755. * vinfo - A reference to the videoinfo structure
  756. *
  757. * Returned Value:
  758. *
  759. * On success - OK
  760. * On error - -EINVAL
  761. *
  762. ****************************************************************************/
  763. static int ili9341_getvideoinfo(FAR struct lcd_dev_s *dev,
  764. FAR struct fb_videoinfo_s *vinfo)
  765. {
  766. if (dev && vinfo)
  767. {
  768. FAR struct ili9341_dev_s *priv = (FAR struct ili9341_dev_s *)dev;
  769. vinfo->fmt = priv->pxfmt;
  770. vinfo->xres = ili9341_getxres(priv);
  771. vinfo->yres = ili9341_getyres(priv);
  772. vinfo->nplanes = 1;
  773. lcdinfo("fmt: %d xres: %d yres: %d nplanes: %d\n",
  774. vinfo->fmt, vinfo->xres, vinfo->yres, vinfo->nplanes);
  775. return OK;
  776. }
  777. return -EINVAL;
  778. }
  779. /****************************************************************************
  780. * Name: ili9341_getplaneinfo
  781. *
  782. * Description:
  783. * Get information about the configuration of each LCD color plane.
  784. *
  785. * Input Parameters:
  786. * dev - A reference to the driver specific structure
  787. * planeno - The plane number
  788. * pinfo - A reference to the planeinfo structure
  789. *
  790. * Returned Value:
  791. *
  792. * On success - OK
  793. * On error - -EINVAL
  794. *
  795. ****************************************************************************/
  796. static int ili9341_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
  797. FAR struct lcd_planeinfo_s *pinfo)
  798. {
  799. if (dev && pinfo && planeno == 0)
  800. {
  801. FAR struct ili9341_dev_s *priv = (FAR struct ili9341_dev_s *)dev;
  802. pinfo->putrun = priv->putrun;
  803. #ifndef CONFIG_LCD_NOGETRUN
  804. pinfo->getrun = priv->getrun;
  805. #endif
  806. pinfo->bpp = priv->bpp;
  807. pinfo->buffer = (FAR uint8_t *)priv->runbuffer; /* Run scratch buffer */
  808. lcdinfo("planeno: %d bpp: %d\n", planeno, pinfo->bpp);
  809. return OK;
  810. }
  811. return -EINVAL;
  812. }
  813. /****************************************************************************
  814. * Name: ili9341_getpower
  815. *
  816. * Description:
  817. * Get the LCD panel power status (0: full off - CONFIG_LCD_MAXPOWER: full on.
  818. * On backlit LCDs, this setting may correspond to the backlight setting.
  819. *
  820. * Input Parameters:
  821. * dev - A reference to the driver specific structure
  822. *
  823. * Returned Value:
  824. *
  825. * On success - OK
  826. * On error - -EINVAL
  827. *
  828. ****************************************************************************/
  829. static int ili9341_getpower(FAR struct lcd_dev_s *dev)
  830. {
  831. FAR struct ili9341_dev_s *priv = (FAR struct ili9341_dev_s *)dev;
  832. if (priv)
  833. {
  834. lcdinfo("%d\n", priv->power);
  835. return priv->power;
  836. }
  837. return -EINVAL;
  838. }
  839. /****************************************************************************
  840. * Name: ili9341_setpower
  841. *
  842. * Description:
  843. * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on).
  844. * On backlight LCDs, this setting may correspond to the backlight setting.
  845. *
  846. * Input Parameters:
  847. * dev - A reference to the driver specific structure
  848. * power - Value of the power
  849. *
  850. * Returned Value:
  851. *
  852. * On success - OK
  853. * On error - -EINVAL
  854. *
  855. ****************************************************************************/
  856. static int ili9341_setpower(FAR struct lcd_dev_s *dev, int power)
  857. {
  858. FAR struct ili9341_dev_s *priv = (FAR struct ili9341_dev_s *)dev;
  859. FAR struct ili9341_lcd_s *lcd = priv->lcd;
  860. if (dev)
  861. {
  862. lcdinfo("%d\n", power);
  863. lcd->select(lcd);
  864. if (power > 0)
  865. {
  866. /* Set backlight level */
  867. lcd->backlight(lcd, power);
  868. /* And switch LCD on */
  869. lcd->sendcmd(lcd, ILI9341_DISPLAY_ON);
  870. up_mdelay(120);
  871. }
  872. else
  873. {
  874. /* Switch LCD off */
  875. lcd->sendcmd(lcd, ILI9341_DISPLAY_OFF);
  876. }
  877. lcd->deselect(lcd);
  878. priv->power = power;
  879. return OK;
  880. }
  881. return -EINVAL;
  882. }
  883. /****************************************************************************
  884. * Name: ili9341_getcontrast
  885. *
  886. * Description:
  887. * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST).
  888. *
  889. * Input Parameters:
  890. * dev - A reference to the lcd driver structure
  891. *
  892. * Returned Value:
  893. *
  894. * On success - current contrast value
  895. * On error - -ENOSYS, not supported by the ili9341.
  896. *
  897. ****************************************************************************/
  898. static int ili9341_getcontrast(struct lcd_dev_s *dev)
  899. {
  900. lcdinfo("Not implemented\n");
  901. return -ENOSYS;
  902. }
  903. /****************************************************************************
  904. * Name: ili9341_setcontrast
  905. *
  906. * Description:
  907. * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST).
  908. *
  909. * Input Parameters:
  910. * dev - A reference to the lcd driver structure
  911. *
  912. * Returned Value:
  913. *
  914. * On success - OK
  915. * On error - -ENOSYS, not supported by the ili9341.
  916. *
  917. ****************************************************************************/
  918. static int ili9341_setcontrast(struct lcd_dev_s *dev, unsigned int contrast)
  919. {
  920. lcdinfo("contrast: %d\n", contrast);
  921. return -ENOSYS;
  922. }
  923. /****************************************************************************
  924. * Name: ili9341_initialize
  925. *
  926. * Description:
  927. * Initialize the LCD video driver internal sturcture. Also initialize the
  928. * lcd hardware if not done. The control of the LCD driver is depend on the
  929. * selected MCU interface and part of the platform specific subdriver (see
  930. * config/stm32f429i-disco/src/stm32_ili93414ws.c)
  931. *
  932. * Input Parameters:
  933. *
  934. * lcd - A reference to the platform specific driver instance to control the
  935. * ili9341 display driver.
  936. * devno - A value in the range of 0 through CONFIG_ILI9341_NINTERFACES-1.
  937. * This allows support for multiple LCD devices.
  938. *
  939. * Returned Value:
  940. *
  941. * On success, this function returns a reference to the LCD driver object for
  942. * the specified LCD driver. NULL is returned on any failure.
  943. *
  944. ****************************************************************************/
  945. FAR struct lcd_dev_s *
  946. ili9341_initialize(FAR struct ili9341_lcd_s *lcd, int devno)
  947. {
  948. if (lcd && devno >= 0 && devno < CONFIG_LCD_ILI9341_NINTERFACES)
  949. {
  950. FAR struct ili9341_dev_s *priv = &g_lcddev[devno];
  951. /* Check if initialized */
  952. if (!priv->lcd)
  953. {
  954. FAR struct lcd_dev_s *dev = &priv->dev;
  955. int ret;
  956. /* Initialize internal structure */
  957. dev->getvideoinfo = ili9341_getvideoinfo;
  958. dev->getplaneinfo = ili9341_getplaneinfo;
  959. dev->getpower = ili9341_getpower;
  960. dev->setpower = ili9341_setpower;
  961. dev->getcontrast = ili9341_getcontrast;
  962. dev->setcontrast = ili9341_setcontrast;
  963. priv->lcd = lcd;
  964. /* Initialze the LCD driver */
  965. ret = ili9341_hwinitialize(priv);
  966. if (ret == OK)
  967. {
  968. return &priv->dev;
  969. }
  970. }
  971. }
  972. return NULL;
  973. }
  974. /****************************************************************************
  975. * Name: ili9341_clear
  976. *
  977. * Description:
  978. * This is a non-standard LCD interface. Because of the various rotations,
  979. * clearing the display in the normal way by writing a sequences of runs that
  980. * covers the entire display can be very slow. Here the display is cleared by
  981. * simply setting all GRAM memory to the specified color.
  982. *
  983. * Input Parameters:
  984. * dev - A reference to the lcd driver structure
  985. * color - The background color
  986. *
  987. * Returned Value:
  988. *
  989. * On success - OK
  990. * On error - -EINVAL
  991. *
  992. ****************************************************************************/
  993. int ili9341_clear(FAR struct lcd_dev_s *dev, uint16_t color)
  994. {
  995. FAR struct ili9341_dev_s *priv = (FAR struct ili9341_dev_s *)dev;
  996. FAR struct ili9341_lcd_s *lcd = priv->lcd;
  997. uint16_t xres = ili9341_getxres(priv);
  998. uint16_t yres = ili9341_getyres(priv);
  999. uint32_t n;
  1000. if (!lcd)
  1001. {
  1002. return -EINVAL;
  1003. }
  1004. /* Select lcd driver */
  1005. lcd->select(lcd);
  1006. /* Select column and area similar to the visible area */
  1007. ili9341_selectarea(lcd, 0, 0, xres, yres);
  1008. /* Send memory write cmd */
  1009. lcd->sendcmd(lcd, ILI9341_MEMORY_WRITE);
  1010. /* clear the visible area */
  1011. for (n = 0; n < xres * yres; n++)
  1012. {
  1013. /* Send pixel to gram */
  1014. lcd->sendgram(lcd, &color, 1);
  1015. }
  1016. /* Deselect the lcd driver */
  1017. lcd->deselect(lcd);
  1018. return OK;
  1019. }