mio283qt9a.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931
  1. /****************************************************************************
  2. * drivers/lcd/mio283qt9a.c
  3. *
  4. * Licensed to the Apache Software Foundation (ASF) under one or more
  5. * contributor license agreements. See the NOTICE file distributed with
  6. * this work for additional information regarding copyright ownership. The
  7. * ASF licenses this file to you under the Apache License, Version 2.0 (the
  8. * "License"); you may not use this file except in compliance with the
  9. * License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  16. * License for the specific language governing permissions and limitations
  17. * under the License.
  18. *
  19. ****************************************************************************/
  20. /****************************************************************************
  21. * Included Files
  22. ****************************************************************************/
  23. #include <nuttx/config.h>
  24. #include <sys/types.h>
  25. #include <stdint.h>
  26. #include <stdbool.h>
  27. #include <string.h>
  28. #include <assert.h>
  29. #include <errno.h>
  30. #include <debug.h>
  31. #include <nuttx/arch.h>
  32. #include <nuttx/spi/spi.h>
  33. #include <nuttx/lcd/lcd.h>
  34. #include <nuttx/lcd/mio283qt9a.h>
  35. #ifdef CONFIG_LCD_MIO283QT9A
  36. /****************************************************************************
  37. * Pre-processor Definitions
  38. ****************************************************************************/
  39. /* Configuration ************************************************************/
  40. /* Check contrast selection */
  41. #if !defined(CONFIG_LCD_MAXCONTRAST)
  42. # define CONFIG_LCD_MAXCONTRAST 1
  43. #endif
  44. /* Check power setting */
  45. #if !defined(CONFIG_LCD_MAXPOWER) || CONFIG_LCD_MAXPOWER < 1
  46. # define CONFIG_LCD_MAXPOWER 1
  47. #endif
  48. #if CONFIG_LCD_MAXPOWER > 255
  49. # error "CONFIG_LCD_MAXPOWER must be less than 256 to fit in uint8_t"
  50. #endif
  51. /* Check orientation */
  52. #if defined(CONFIG_LCD_PORTRAIT)
  53. # if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) || defined(CONFIG_LCD_RPORTRAIT)
  54. # error "Cannot define both portrait and any other orientations"
  55. # endif
  56. #elif defined(CONFIG_LCD_RPORTRAIT)
  57. # if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE)
  58. # error "Cannot define both rportrait and any other orientations"
  59. # endif
  60. #elif defined(CONFIG_LCD_LANDSCAPE)
  61. # ifdef CONFIG_LCD_RLANDSCAPE
  62. # error "Cannot define both landscape and any other orientations"
  63. # endif
  64. #elif !defined(CONFIG_LCD_RLANDSCAPE)
  65. # define CONFIG_LCD_LANDSCAPE 1
  66. #endif
  67. /* Display/Color Properties *************************************************/
  68. /* Display Resolution */
  69. #if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE)
  70. # define MIO283QT9A_XRES 320
  71. # define MIO283QT9A_YRES 240
  72. #else
  73. # define MIO283QT9A_XRES 240
  74. # define MIO283QT9A_YRES 320
  75. #endif
  76. /* Color depth and format */
  77. #define MIO283QT9A_BPP 16
  78. #define MIO283QT9A_COLORFMT FB_FMT_RGB16_565
  79. /* Hardware LCD/LCD controller definitions **********************************/
  80. /* In this driver, I chose to use all literal constants for register address
  81. * and values. Some recent experiences have shown me that during LCD bringup,
  82. * it is more important to know the binary values rather than nice, people
  83. * friendly names. Sad, but true.
  84. */
  85. #define ILI9341_ID_1 0x93
  86. #define ILI9341_ID_2 0x41
  87. /****************************************************************************
  88. * Private Type Definition
  89. ****************************************************************************/
  90. /* This structure describes the state of this driver */
  91. struct mio283qt9a_dev_s
  92. {
  93. /* Publicly visible device structure */
  94. struct lcd_dev_s dev;
  95. /* Private LCD-specific information follows */
  96. FAR struct mio283qt9a_lcd_s *lcd; /* The contained platform-specific, LCD interface */
  97. uint8_t power; /* Current power setting */
  98. /* This is working memory allocated by the LCD driver for each LCD device
  99. * and for each color plane.
  100. * This memory will hold one raster line of data.
  101. * The size of the allocated run buffer must therefore be at least
  102. * (bpp * xres / 8). Actual alignment of the buffer must conform to the
  103. * bitwidth of the underlying pixel type.
  104. *
  105. * If there are multiple planes, they may share the same working buffer
  106. * because different planes will not be operate on concurrently.
  107. * However, if there are multiple LCD devices, they must each have unique
  108. * run buffers.
  109. */
  110. uint16_t runbuffer[MIO283QT9A_XRES];
  111. };
  112. /****************************************************************************
  113. * Private Function Prototypes
  114. ****************************************************************************/
  115. /* Low Level LCD access */
  116. static void mio283qt9a_putreg(FAR struct mio283qt9a_lcd_s *lcd,
  117. uint8_t regaddr,
  118. uint16_t regval);
  119. #ifndef CONFIG_LCD_NOGETRUN
  120. static uint16_t mio283qt9a_readreg(FAR struct mio283qt9a_lcd_s *lcd,
  121. uint8_t regaddr);
  122. #endif
  123. static inline void mio283qt9a_gramwrite(FAR struct mio283qt9a_lcd_s *lcd,
  124. uint16_t rgbcolor);
  125. #ifndef CONFIG_LCD_NOGETRUN
  126. static inline void mio283qt9a_readsetup(FAR struct mio283qt9a_lcd_s *lcd,
  127. FAR uint16_t *accum);
  128. static inline uint16_t mio283qt9a_gramread(FAR struct mio283qt9a_lcd_s *lcd,
  129. FAR uint16_t *accum);
  130. #endif
  131. static void mio283qt9a_setarea(FAR struct mio283qt9a_lcd_s *lcd,
  132. uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
  133. /* LCD Data Transfer Methods */
  134. static int mio283qt9a_putrun(fb_coord_t row, fb_coord_t col,
  135. FAR const uint8_t *buffer,
  136. size_t npixels);
  137. static int mio283qt9a_getrun(fb_coord_t row, fb_coord_t col,
  138. FAR uint8_t *buffer,
  139. size_t npixels);
  140. /* LCD Configuration */
  141. static int mio283qt9a_getvideoinfo(FAR struct lcd_dev_s *dev,
  142. FAR struct fb_videoinfo_s *vinfo);
  143. static int mio283qt9a_getplaneinfo(FAR struct lcd_dev_s *dev,
  144. unsigned int planeno,
  145. FAR struct lcd_planeinfo_s *pinfo);
  146. /* LCD RGB Mapping */
  147. #ifdef CONFIG_FB_CMAP
  148. # error "RGB color mapping not supported by this driver"
  149. #endif
  150. /* Cursor Controls */
  151. #ifdef CONFIG_FB_HWCURSOR
  152. # error "Cursor control not supported by this driver"
  153. #endif
  154. /* LCD Specific Controls */
  155. static int mio283qt9a_getpower(FAR struct lcd_dev_s *dev);
  156. static int mio283qt9a_setpower(FAR struct lcd_dev_s *dev, int power);
  157. static int mio283qt9a_getcontrast(FAR struct lcd_dev_s *dev);
  158. static int mio283qt9a_setcontrast(FAR struct lcd_dev_s *dev,
  159. unsigned int contrast);
  160. /* Initialization */
  161. static inline int mio283qt9a_hwinitialize(
  162. FAR struct mio283qt9a_dev_s *priv);
  163. /****************************************************************************
  164. * Private Data
  165. ****************************************************************************/
  166. /* This driver can support only a signal MIO283QT9A device.
  167. * This is due to an unfortunate decision made when the getrun and putrun
  168. * methods were designed.
  169. * The following is the single MIO283QT9A driver state instance:
  170. */
  171. static struct mio283qt9a_dev_s g_lcddev;
  172. /****************************************************************************
  173. * Private Functions
  174. ****************************************************************************/
  175. /****************************************************************************
  176. * Name: mio283qt9a_putreg
  177. *
  178. * Description:
  179. * Write to an LCD register
  180. *
  181. ****************************************************************************/
  182. static void mio283qt9a_putreg(FAR struct mio283qt9a_lcd_s *lcd,
  183. uint8_t regaddr, uint16_t regval)
  184. {
  185. /* Set the index register to the register address and write the register
  186. * contents
  187. */
  188. lcd->index(lcd, regaddr);
  189. lcd->write(lcd, regval);
  190. }
  191. /****************************************************************************
  192. * Name: mio283qt9a_readreg
  193. *
  194. * Description:
  195. * Read from an LCD register
  196. *
  197. ****************************************************************************/
  198. #ifndef CONFIG_LCD_NOGETRUN
  199. static uint16_t mio283qt9a_readreg(FAR struct mio283qt9a_lcd_s *lcd,
  200. uint8_t regaddr)
  201. {
  202. /* Set the index register to the register address and read the register
  203. * contents.
  204. */
  205. lcd->index(lcd, regaddr);
  206. return lcd->read(lcd);
  207. }
  208. #endif
  209. /****************************************************************************
  210. * Name: mio283qt9a_gramselect_write
  211. *
  212. * Description:
  213. * Setup to write multiple pixels to the GRAM memory
  214. *
  215. ****************************************************************************/
  216. static inline void mio283qt9a_gramselect_write(
  217. FAR struct mio283qt9a_lcd_s *lcd)
  218. {
  219. lcd->index(lcd, 0x2c);
  220. }
  221. /****************************************************************************
  222. * Name: mio283qt9a_gramselect_read
  223. *
  224. * Description:
  225. * Setup to read multiple pixels to the GRAM memory
  226. *
  227. ****************************************************************************/
  228. static inline void mio283qt9a_gramselect_read(
  229. FAR struct mio283qt9a_lcd_s *lcd)
  230. {
  231. lcd->index(lcd, 0x2e);
  232. lcd->readgram(lcd);
  233. }
  234. /****************************************************************************
  235. * Name: mio283qt9a_gramwrite
  236. *
  237. * Description:
  238. * Setup to read or write multiple pixels to the GRAM memory
  239. *
  240. ****************************************************************************/
  241. static inline void mio283qt9a_gramwrite(
  242. FAR struct mio283qt9a_lcd_s *lcd, uint16_t data)
  243. {
  244. lcd->write(lcd, data);
  245. }
  246. /****************************************************************************
  247. * Name: mio283qt9a_readsetup
  248. *
  249. * Description:
  250. * Prime the operation by reading one pixel from the GRAM memory if
  251. * necessary for this LCD type.
  252. * When reading 16-bit gram data, there may be some shifts in the
  253. * returned data:
  254. *
  255. * - ILI932x: Discard first dummy read; no shift in the return data
  256. *
  257. ****************************************************************************/
  258. #ifndef CONFIG_LCD_NOGETRUN
  259. static inline void mio283qt9a_readsetup(FAR struct mio283qt9a_lcd_s *lcd,
  260. FAR uint16_t *accum)
  261. {
  262. #if 0 /* Probably not necessary... untested */
  263. /* Read-ahead one pixel */
  264. *accum = lcd->read(lcd);
  265. #endif
  266. }
  267. #endif
  268. /****************************************************************************
  269. * Name: mio283qt9a_gramread
  270. *
  271. * Description:
  272. * Read one correctly aligned pixel from the GRAM memory.
  273. * Possibly shifting the data and possibly swapping red and green
  274. * components.
  275. *
  276. * - ILI932x: Unknown -- assuming colors are in the color order
  277. *
  278. ****************************************************************************/
  279. #ifndef CONFIG_LCD_NOGETRUN
  280. static inline uint16_t mio283qt9a_gramread(FAR struct mio283qt9a_lcd_s *lcd,
  281. FAR uint16_t *accum)
  282. {
  283. /* Read the value (GRAM register already selected) */
  284. return lcd->readgram(lcd);
  285. }
  286. #endif
  287. /****************************************************************************
  288. * Name: mio283qt9a_setarea
  289. *
  290. * Description:
  291. * Set the cursor position.
  292. * In landscape mode, the "column" is actually the physical
  293. * Y position and the "row" is the physical X position.
  294. *
  295. ****************************************************************************/
  296. static void mio283qt9a_setarea(FAR struct mio283qt9a_lcd_s *lcd,
  297. uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
  298. {
  299. mio283qt9a_putreg(lcd, 0x2a, (x0 >> 8)); /* Set column address x0 */
  300. lcd->write(lcd, (x0 & 0xff)); /* Set x0 */
  301. lcd->write(lcd, (x1 >> 8)); /* Set x1 */
  302. lcd->write(lcd, (x1 & 0xff)); /* Set x1 */
  303. mio283qt9a_putreg(lcd, 0x2b, (y0 >> 8)); /* Set page address y0 */
  304. lcd->write(lcd, (y0 & 0xff)); /* Set y0 */
  305. lcd->write(lcd, (y1 >> 8)); /* Set y1 */
  306. lcd->write(lcd, (y1 & 0xff)); /* Set y1 */
  307. }
  308. /****************************************************************************
  309. * Name: mio283qt9a_dumprun
  310. *
  311. * Description:
  312. * Dump the contexts of the run buffer:
  313. *
  314. * run - The buffer in containing the run read to be dumped
  315. * npixels - The number of pixels to dump
  316. *
  317. ****************************************************************************/
  318. #if 0 /* Sometimes useful */
  319. static void mio283qt9a_dumprun(FAR const char *msg,
  320. FAR uint16_t *run,
  321. size_t npixels)
  322. {
  323. int i;
  324. int j;
  325. syslog(LOG_INFO, "\n%s:\n", msg);
  326. for (i = 0; i < npixels; i += 16)
  327. {
  328. up_putc(' ');
  329. syslog(LOG_INFO, " ");
  330. for (j = 0; j < 16; j++)
  331. {
  332. syslog(LOG_INFO, " %04x", *run++);
  333. }
  334. up_putc('\n');
  335. }
  336. }
  337. #endif
  338. /****************************************************************************
  339. * Name: mio283qt9a_putrun
  340. *
  341. * Description:
  342. * This method can be used to write a partial raster line to the LCD:
  343. *
  344. * row - Starting row to write to (range: 0 <= row < yres)
  345. * col - Starting column to write to (range: 0 <= col <= xres-npixels)
  346. * buffer - The buffer containing the run to be written to the LCD
  347. * npixels - The number of pixels to write to the LCD
  348. * (range: 0 < npixels <= xres-col)
  349. *
  350. ****************************************************************************/
  351. static int mio283qt9a_putrun(fb_coord_t row, fb_coord_t col,
  352. FAR const uint8_t *buffer,
  353. size_t npixels)
  354. {
  355. FAR struct mio283qt9a_dev_s *priv = &g_lcddev;
  356. FAR struct mio283qt9a_lcd_s *lcd = priv->lcd;
  357. FAR const uint16_t *src = (FAR const uint16_t *)buffer;
  358. int i;
  359. /* Buffer must be provided and aligned to a 16-bit address boundary */
  360. DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0);
  361. /* Select the LCD */
  362. lcd->select(lcd);
  363. /* Write the run to GRAM. */
  364. mio283qt9a_setarea(lcd, col, row, col + npixels - 1, row);
  365. mio283qt9a_gramselect_write(lcd);
  366. for (i = 0; i < npixels; i++)
  367. {
  368. mio283qt9a_gramwrite(lcd, *src);
  369. src++;
  370. }
  371. /* De-select the LCD */
  372. lcd->deselect(lcd);
  373. return OK;
  374. }
  375. /****************************************************************************
  376. * Name: mio283qt9a_getrun
  377. *
  378. * Description:
  379. * This method can be used to read a partial raster line from the LCD:
  380. *
  381. * row - Starting row to read from (range: 0 <= row < yres)
  382. * col - Starting column to read read (range: 0 <= col <= xres-npixels)
  383. * buffer - The buffer in which to return the run read from the LCD
  384. * npixels - The number of pixels to read from the LCD
  385. * (range: 0 < npixels <= xres-col)
  386. *
  387. ****************************************************************************/
  388. static int mio283qt9a_getrun(fb_coord_t row, fb_coord_t col,
  389. FAR uint8_t *buffer,
  390. size_t npixels)
  391. {
  392. #ifndef CONFIG_LCD_NOGETRUN
  393. FAR struct mio283qt9a_dev_s *priv = &g_lcddev;
  394. FAR struct mio283qt9a_lcd_s *lcd = priv->lcd;
  395. FAR uint16_t *dest = (FAR uint16_t *)buffer;
  396. uint16_t accum, test;
  397. int i;
  398. /* Buffer must be provided and aligned to a 16-bit address boundary */
  399. lcdinfo("mio283qt9a_getrun row: %d col: %d npixels: %d\n",
  400. row, col, npixels);
  401. DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0);
  402. /* Read the run from GRAM. */
  403. /* Select the LCD */
  404. lcd->select(lcd);
  405. /* Red the run fram GRAM. */
  406. mio283qt9a_setarea(lcd, col, row, col + npixels - 1, row);
  407. mio283qt9a_gramselect_read(lcd);
  408. /* Prime the pump for unaligned read data */
  409. mio283qt9a_readsetup(lcd, &accum);
  410. for (i = 0; i < npixels; i++)
  411. {
  412. test = mio283qt9a_gramread(lcd, &accum);
  413. *dest++ = test;
  414. }
  415. /* De-select the LCD */
  416. lcd->deselect(lcd);
  417. return OK;
  418. #else
  419. return -ENOSYS;
  420. #endif
  421. }
  422. /****************************************************************************
  423. * Name: mio283qt9a_getvideoinfo
  424. *
  425. * Description:
  426. * Get information about the LCD video controller configuration.
  427. *
  428. ****************************************************************************/
  429. static int mio283qt9a_getvideoinfo(FAR struct lcd_dev_s *dev,
  430. FAR struct fb_videoinfo_s *vinfo)
  431. {
  432. DEBUGASSERT(dev && vinfo);
  433. lcdinfo("fmt: %d xres: %d yres: %d nplanes: 1\n",
  434. MIO283QT9A_COLORFMT, MIO283QT9A_XRES, MIO283QT9A_YRES);
  435. vinfo->fmt = MIO283QT9A_COLORFMT; /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */
  436. vinfo->xres = MIO283QT9A_XRES; /* Horizontal resolution in pixel columns */
  437. vinfo->yres = MIO283QT9A_YRES; /* Vertical resolution in pixel rows */
  438. vinfo->nplanes = 1; /* Number of color planes supported */
  439. return OK;
  440. }
  441. /****************************************************************************
  442. * Name: mio283qt9a_getplaneinfo
  443. *
  444. * Description:
  445. * Get information about the configuration of each LCD color plane.
  446. *
  447. ****************************************************************************/
  448. static int mio283qt9a_getplaneinfo(FAR struct lcd_dev_s *dev,
  449. unsigned int planeno,
  450. FAR struct lcd_planeinfo_s *pinfo)
  451. {
  452. FAR struct mio283qt9a_dev_s *priv = (FAR struct mio283qt9a_dev_s *)dev;
  453. DEBUGASSERT(dev && pinfo && planeno == 0);
  454. lcdinfo("planeno: %d bpp: %d\n", planeno, MIO283QT9A_BPP);
  455. pinfo->putrun = mio283qt9a_putrun; /* Put a run into LCD memory */
  456. pinfo->getrun = mio283qt9a_getrun; /* Get a run from LCD memory */
  457. pinfo->buffer = (FAR uint8_t *)priv->runbuffer; /* Run scratch buffer */
  458. pinfo->bpp = MIO283QT9A_BPP; /* Bits-per-pixel */
  459. return OK;
  460. }
  461. /****************************************************************************
  462. * Name: mio283qt9a_getpower
  463. *
  464. * Description:
  465. * Get the LCD panel power status
  466. * (0: full off - CONFIG_LCD_MAXPOWER: full on).
  467. * On backlit LCDs, this setting may correspond to the backlight setting.
  468. *
  469. ****************************************************************************/
  470. static int mio283qt9a_getpower(FAR struct lcd_dev_s *dev)
  471. {
  472. lcdinfo("getpower: %d\n", 0);
  473. return g_lcddev.power;
  474. }
  475. /****************************************************************************
  476. * Name: mio283qt9a_poweroff
  477. *
  478. * Description:
  479. * Enable/disable LCD panel power
  480. * (0: full off - CONFIG_LCD_MAXPOWER: full on).
  481. * On backlit LCDs, this setting may correspond to the backlight setting.
  482. *
  483. ****************************************************************************/
  484. static int mio283qt9a_poweroff(FAR struct mio283qt9a_lcd_s *lcd)
  485. {
  486. /* Select the LCD */
  487. lcdinfo("mio283qt9a_poweroff\n");
  488. lcd->select(lcd);
  489. /* Set the backlight off */
  490. lcd->backlight(lcd, 0);
  491. /* Turn the display off */
  492. mio283qt9a_putreg(lcd, 0x28, 0x0000); /* GON=0, DTE=0, D=0 */
  493. /* Deselect the LCD */
  494. lcd->deselect(lcd);
  495. /* Remember the power off state */
  496. g_lcddev.power = 0;
  497. return OK;
  498. }
  499. /****************************************************************************
  500. * Name: mio283qt9a_setpower
  501. *
  502. * Description:
  503. * Enable/disable LCD panel power
  504. * (0: full off - CONFIG_LCD_MAXPOWER: full on).
  505. * On backlit LCDs, this setting may correspond to the backlight setting.
  506. *
  507. ****************************************************************************/
  508. static int mio283qt9a_setpower(FAR struct lcd_dev_s *dev, int power)
  509. {
  510. FAR struct mio283qt9a_dev_s *priv = (FAR struct mio283qt9a_dev_s *)dev;
  511. FAR struct mio283qt9a_lcd_s *lcd = priv->lcd;
  512. lcdinfo("setpower: %d\n", power);
  513. DEBUGASSERT((unsigned)power <= CONFIG_LCD_MAXPOWER);
  514. /* Set new power level */
  515. if (power > 0)
  516. {
  517. /* Select the LCD */
  518. lcd->select(lcd);
  519. /* Set the backlight level */
  520. lcd->backlight(lcd, power);
  521. /* Then turn the display on: */
  522. mio283qt9a_putreg(lcd, 0x29, 0x00); /* GON=1, DTE=1, D=2 */
  523. /* Deselect the LCD */
  524. lcd->deselect(lcd);
  525. /* Remember the power on state */
  526. g_lcddev.power = power;
  527. }
  528. else
  529. {
  530. /* Turn the display off */
  531. mio283qt9a_poweroff(lcd);
  532. }
  533. return OK;
  534. }
  535. /****************************************************************************
  536. * Name: mio283qt9a_getcontrast
  537. *
  538. * Description:
  539. * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST).
  540. *
  541. ****************************************************************************/
  542. static int mio283qt9a_getcontrast(FAR struct lcd_dev_s *dev)
  543. {
  544. lcdinfo("Not implemented\n");
  545. return -ENOSYS;
  546. }
  547. /****************************************************************************
  548. * Name: mio283qt9a_setcontrast
  549. *
  550. * Description:
  551. * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST).
  552. *
  553. ****************************************************************************/
  554. static int mio283qt9a_setcontrast(FAR struct lcd_dev_s *dev,
  555. unsigned int contrast)
  556. {
  557. lcdinfo("contrast: %d\n", contrast);
  558. return -ENOSYS;
  559. }
  560. /****************************************************************************
  561. * Name: mio283qt9a_hwinitialize
  562. *
  563. * Description:
  564. * Initialize the LCD hardware.
  565. *
  566. ****************************************************************************/
  567. static inline int mio283qt9a_hwinitialize(FAR struct mio283qt9a_dev_s *priv)
  568. {
  569. FAR struct mio283qt9a_lcd_s *lcd = priv->lcd;
  570. #if !defined(CONFIG_LCD_NOGETRUN) || defined(CONFIG_DEBUG_LCD)
  571. uint16_t id_a;
  572. uint16_t id_b;
  573. uint16_t id_c;
  574. uint16_t id_d;
  575. #endif
  576. #ifdef CONFIG_DEBUG_LCD
  577. uint16_t id_e;
  578. #endif
  579. int ret;
  580. /* Select the LCD */
  581. lcd->select(lcd);
  582. /* Read the HIMAX ID registger (0x00) */
  583. #ifndef CONFIG_LCD_NOGETRUN
  584. id_a = mio283qt9a_readreg(lcd, 0xd3);
  585. id_b = lcd->read(lcd);
  586. id_c = lcd->read(lcd);
  587. id_d = lcd->read(lcd);
  588. lcdinfo("LCD ID: %04x %04x %04x %04x\n", id_a, id_b, id_c, id_d);
  589. UNUSED(id_a);
  590. UNUSED(id_b);
  591. /* Check if the ID is for the ILI9341 */
  592. if (id_c == ILI9341_ID_1 && id_d == ILI9341_ID_2)
  593. #endif
  594. {
  595. mio283qt9a_putreg(lcd, 0x29, 0); /* Power on */
  596. mio283qt9a_putreg(lcd, 0x13, 0); /* Normal display on */
  597. mio283qt9a_putreg(lcd, 0xc0, 0x28); /* Power control C1 */
  598. mio283qt9a_putreg(lcd, 0xc1, 0x01); /* Power control C2 BT = 1 */
  599. mio283qt9a_putreg(lcd, 0xc5, 0x24); /* VCOM control, VMH = 3.6v */
  600. lcd->write(lcd, 0x25); /* VML = -1.575v */
  601. mio283qt9a_putreg(lcd, 0x26, 0x01); /* Gamma 2.2 */
  602. mio283qt9a_putreg(lcd, 0x3a, 0x55); /* Pixel format set command */
  603. #if defined(CONFIG_LCD_LANDSCAPE)
  604. mio283qt9a_putreg(lcd, 0x36, 0x0028); /* MY=1, MX=0, MV=1, ML=0, BGR=1 */
  605. #elif defined(CONFIG_LCD_PORTRAIT)
  606. mio283qt9a_putreg(lcd, 0x36, 0x0008); /* MY=0, MX=0, MV=0, ML=0, BGR=1 */
  607. #elif defined(CONFIG_LCD_RLANDSCAPE)
  608. mio283qt9a_putreg(lcd, 0x36, 0x0068); /* MY=0, MX=1, MV=1, ML=0, BGR=1 */
  609. #elif defined(CONFIG_LCD_RPORTRAIT)
  610. mio283qt9a_putreg(lcd, 0x36, 0x00c8); /* MY=1, MX=0, MV=1, ML=0, BGR=1 */
  611. #endif
  612. /* Window setting */
  613. mio283qt9a_setarea(lcd, 0, 0, (MIO283QT9A_XRES - 1),
  614. (MIO283QT9A_YRES - 1));
  615. mio283qt9a_putreg(lcd, 0x11, 0); /* Sleep out mode */
  616. up_mdelay(25);
  617. #ifdef CONFIG_DEBUG_LCD
  618. /* Read back some info from the panel */
  619. id_a = mio283qt9a_readreg(lcd, 0x04); /* Read display information */
  620. id_b = lcd->read(lcd);
  621. id_c = lcd->read(lcd);
  622. id_d = lcd->read(lcd);
  623. lcdinfo("LCD man ID: %02x, version: %02x, driver ID: %02x\n",
  624. id_b, id_c, id_d);
  625. id_a = mio283qt9a_readreg(lcd, 0x09); /* Read display status */
  626. id_b = lcd->read(lcd);
  627. id_c = lcd->read(lcd);
  628. id_d = lcd->read(lcd);
  629. id_e = lcd->read(lcd);
  630. lcdinfo("Display status %02x, %02x, %02x, %02x, %02x\n",
  631. id_a, id_b, id_c, id_d, id_e);
  632. id_a = mio283qt9a_readreg(lcd, 0x0a); /* Read power status */
  633. id_b = lcd->read(lcd);
  634. lcdinfo("Power status %02x, %02x\n", id_a, id_b);
  635. id_a = mio283qt9a_readreg(lcd, 0x0b); /* Read MADCTL */
  636. id_b = lcd->read(lcd);
  637. lcdinfo("MADCTL %02x, %02x\n", id_a, id_b);
  638. id_a = mio283qt9a_readreg(lcd, 0x0c); /* Read pixel format */
  639. id_b = lcd->read(lcd);
  640. lcdinfo("Pixel format %02x, %02x\n", id_a, id_b);
  641. id_a = mio283qt9a_readreg(lcd, 0x0d); /* Read image format */
  642. id_b = lcd->read(lcd);
  643. lcdinfo("Image format %02x, %02x\n", id_a, id_b);
  644. id_a = mio283qt9a_readreg(lcd, 0x0e); /* read signal mode */
  645. id_b = lcd->read(lcd);
  646. lcdinfo("Signal mode %02x, %02x\n", id_a, id_b);
  647. id_a = mio283qt9a_readreg(lcd, 0x0f); /* read self diag */
  648. id_b = lcd->read(lcd);
  649. lcdinfo("Self diag %02x, %02x\n", id_a, id_b);
  650. #endif
  651. ret = OK;
  652. }
  653. #ifndef CONFIG_LCD_NOGETRUN
  654. else
  655. {
  656. lcderr("ERROR: Unsupported LCD type\n");
  657. ret = -ENODEV;
  658. }
  659. #endif
  660. /* De-select the LCD */
  661. lcd->deselect(lcd);
  662. return ret;
  663. }
  664. /****************************************************************************
  665. * Public Functions
  666. ****************************************************************************/
  667. /****************************************************************************
  668. * Name: mio283qt9a_lcdinitialize
  669. *
  670. * Description:
  671. * Initialize the LCD video hardware.
  672. * The initial state of the LCD is fully initialized, display memory
  673. * cleared, and the LCD ready to use, but with the power setting at 0
  674. * (full off).
  675. *
  676. ****************************************************************************/
  677. FAR struct lcd_dev_s *mio283qt9a_lcdinitialize(
  678. FAR struct mio283qt9a_lcd_s *lcd)
  679. {
  680. FAR struct mio283qt9a_dev_s *priv;
  681. int ret;
  682. lcdinfo("Initializing\n");
  683. /* If we could support multiple MIO283QT9A devices, this is where we would
  684. * allocate a new driver data structure... but we can't.
  685. * Why not?
  686. * Because of a bad should the form of the getrun() and putrun methods.
  687. */
  688. priv = &g_lcddev;
  689. /* Initialize the driver data structure */
  690. priv->dev.getvideoinfo = mio283qt9a_getvideoinfo;
  691. priv->dev.getplaneinfo = mio283qt9a_getplaneinfo;
  692. priv->dev.getpower = mio283qt9a_getpower;
  693. priv->dev.setpower = mio283qt9a_setpower;
  694. priv->dev.getcontrast = mio283qt9a_getcontrast;
  695. priv->dev.setcontrast = mio283qt9a_setcontrast;
  696. priv->lcd = lcd;
  697. /* Configure and enable LCD */
  698. ret = mio283qt9a_hwinitialize(priv);
  699. if (ret == OK)
  700. {
  701. /* Clear the display (setting it to the color 0=black) */
  702. mio283qt9a_clear(&priv->dev, 0x0000);
  703. /* Turn the display off */
  704. mio283qt9a_poweroff(lcd);
  705. return &g_lcddev.dev;
  706. }
  707. return NULL;
  708. }
  709. /****************************************************************************
  710. * Name: mio283qt9a_clear
  711. *
  712. * Description:
  713. * This is a non-standard LCD interface just for the stm3240g-EVAL board.
  714. * Because of the various rotations, clearing the display in the normal
  715. * way by writing a sequences of runs that covers the entire display can
  716. * be very slow. Here the display is cleared by simply setting all GRAM
  717. * memory to the specified color.
  718. *
  719. ****************************************************************************/
  720. void mio283qt9a_clear(FAR struct lcd_dev_s *dev, uint16_t color)
  721. {
  722. FAR struct mio283qt9a_dev_s *priv = (FAR struct mio283qt9a_dev_s *)dev;
  723. FAR struct mio283qt9a_lcd_s *lcd = priv->lcd;
  724. uint32_t i;
  725. /* Select the LCD and set the drawring area */
  726. lcd->select(lcd);
  727. mio283qt9a_setarea(lcd, 0, 0, (MIO283QT9A_XRES - 1),
  728. (MIO283QT9A_YRES - 1));
  729. /* Prepare to write GRAM data */
  730. mio283qt9a_gramselect_write(lcd);
  731. /* Copy color into all of GRAM.
  732. * Orientation does not matter in this case.
  733. */
  734. for (i = 0; i < MIO283QT9A_XRES * MIO283QT9A_YRES; i++)
  735. {
  736. mio283qt9a_gramwrite(lcd, color);
  737. }
  738. /* De-select the LCD */
  739. lcd->deselect(lcd);
  740. }
  741. #endif /* CONFIG_LCD_MIO283QT9A */